Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
bucky — An S3 account ID enumeration and bucket discovery tool | Kitploit
Tools/GitHubGitHub/umair9747/bucky
OSINT (Open Source Intelligence)ReconnaissanceVulnerability AnalysisInformation GatheringPenetration TestingCloud Security
GitHubumair9747/bucky

bucky

An S3 account ID enumeration and bucket discovery tool

View Repository
215 months agoReviewed by Kitploit

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

Bucky

An S3 account ID enumeration and bucket discovery tool




Given a single accessible S3 bucket, bucky extracts the 12-digit AWS account ID that owns it, then discovers additional buckets belonging to the same account by fuzzing bucket names against a wordlist — all in one command.

What It Does

  1. Enumerates the account ID — Uses the s3:ResourceAccount IAM condition key to brute-force the 12-digit AWS account ID one digit at a time through inline STS session policies
  2. Discovers more buckets — Fuzzes bucket names from a wordlist to find additional buckets owned by the same account using concurrent workers
  3. Reports everything — Account ID, bucket region, and all discovered buckets

Why This Matters

S3 bucket names originally shared a single global namespace, which gave rise to bucketsquatting — attackers could squat on names they expected organizations to create. AWS addressed this by rolling out account-regional namespaces, a naming scheme that ties each bucket to its owning account and region:

root@kitploit:~
{name}-{accountID}-{region}-an

A bucket called myapp-123456789123-eu-north-1-an would live at https://myapp-123456789123-eu-north-1-an.s3.eu-north-1.amazonaws.com. AWS now recommends this format for new buckets, though it is not yet the default. (For background on how the new namespace kills bucketsquatting, see One Cloud Please.)

The trade-off is that the account ID and region are now baked into the bucket name itself. Once an attacker obtains a target's account ID, they can pair it with a wordlist and systematically construct valid bucket URLs — and S3 will confirm whether each one exists, even if the bucket is private. That response alone is useful reconnaissance.

Bucky exploits exactly this. Drawing on research from Pwned Labs, it first recovers the 12-digit account ID from any accessible bucket using the s3-account-search technique, then brute-forces the {name}-{accountID}-{region}-an pattern to uncover the target's broader S3 footprint.

How the Technique Works

  1. You create an IAM role in your own AWS account that has s3:ListBucket or s3:GetObject on the target bucket
  2. You call sts:AssumeRole on that role, passing an inline session policy with a s3:ResourceAccount condition like "1*"
  3. If the target bucket's owning account starts with 1, the HeadBucket call succeeds; otherwise it returns 403
  4. Repeat for each digit position (0–9) until all 12 digits are discovered
  5. The inline session policy acts as a permission boundary — it intersects with the role's permissions, so access is only granted when the condition matches

This requires at most 120 API calls (12 positions × 10 digits) and typically completes in under a minute.

Installation

Using go install

root@kitploit:~
go install github.com/umair9747/bucky@latest

From Source

root@kitploit:~
git clone https://github.com/umair9747/bucky.git
cd bucky
go build -o bucky .
sudo mv bucky /usr/local/bin/

Updating

root@kitploit:~
bucky --update

This pulls and installs the latest version from the repository.

Prerequisites: IAM Role Setup

Before using bucky, you need an IAM role in your own AWS account that can access the target S3 bucket. The target bucket must be publicly accessible or have a bucket policy that allows access from your account.

Step 1: Create the Trust Policy

Create trust-policy.json — this allows your IAM user to assume the role:

root@kitploit:~
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<YOUR_ACCOUNT_ID>:root"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

Replace <YOUR_ACCOUNT_ID> with your 12-digit AWS account ID. You can scope the principal down to a specific IAM user or role ARN instead of :root.

Step 2: Create the Permissions Policy

Create s3-policy.json — the role needs broad S3 read access (the s3:ResourceAccount condition in bucky's inline session policy handles account-level filtering):

root@kitploit:~
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket",
        "s3:GetObject"
      ],
      "Resource": "*"
    }
  ]
}

Step 3: Create the Role

root@kitploit:~
aws iam create-role \
  --role-name bucky-role \
  --assume-role-policy-document file://trust-policy.json

aws iam put-role-policy \
  --role-name bucky-role \
  --policy-name S3ReadAccess \
  --policy-document file://s3-policy.json

Step 4: Get the Role ARN

root@kitploit:~
aws iam get-role --role-name bucky-role --query 'Role.Arn' --output text
# Output: arn:aws:iam::123456789012:role/bucky-role

Step 5: Ensure AssumeRole Permission

If your IAM user doesn't already have sts:AssumeRole permission, attach it:

root@kitploit:~
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "sts:AssumeRole",
      "Resource": "arn:aws:iam::<YOUR_ACCOUNT_ID>:role/bucky-role"
    }
  ]
}

Usage

Full Workflow (Default)

The primary way to use bucky — enumerate the account ID from a known bucket, then fuzz for more buckets in one shot:

root@kitploit:~
bucky \
  --role-arn arn:aws:iam::123456789012:role/bucky-role \
  --bucket target-bucket \
  --wordlist wordlists/default.txt \
  --access-key AKIA... \
  --secret-key wJal...

With a known object key (improves reliability):

root@kitploit:~
bucky \
  --role-arn arn:aws:iam::123456789012:role/bucky-role \
  --bucket s3://target-bucket/index.html \
  --wordlist wordlists/default.txt \
  --workers 20

Multiple buckets (comma-separated):

root@kitploit:~
bucky \
  --role-arn arn:aws:iam::123456789012:role/bucky-role \
  --bucket bucket1,bucket2,bucket3 \
  --wordlist wordlists/default.txt

Multiple buckets from a file:

root@kitploit:~
bucky \
  --role-arn arn:aws:iam::123456789012:role/bucky-role \
  --bucket-file targets.txt \
  --wordlist wordlists/default.txt

Save results to JSON:

root@kitploit:~
bucky --bucket target-bucket --wordlist wordlists/default.txt --json
bucky --bucket target-bucket --wordlist wordlists/default.txt --json --output results.json

Output:

root@kitploit:~
=== Phase 1: Account ID Enumeration ===
[*] Verifying access to bucket: target-bucket
[+] Access confirmed
[+] Bucket region: us-west-2
[*] Enumerating account ID...
  [██████████████████████████████] 12/12 | 675351422352

[+] Account ID: 675351422352

=== Phase 2: Bucket Discovery ===
[*] Fuzzing buckets for account: 675351422352
[*] Loaded 312 candidates from wordlist
[+] FOUND: target-backups
[+] FOUND: target-logs
  [██████████████████████████████] 312/312 | 2 found

=== Summary ===
Account ID : 675351422352
Source     : target-bucket
Region     : us-west-2
Discovered : 2 additional bucket(s)
             - target-backups
             - target-logs

Enumerate Only

If you only need the account ID:

root@kitploit:~
bucky enum \
  --role-arn arn:aws:iam::123456789012:role/bucky-role \
  --bucket target-bucket

Multiple buckets and JSON output work with subcommands too:

root@kitploit:~
bucky enum --bucket bucket1,bucket2 --json
bucky enum --bucket-file targets.txt --json --output results.json

Fuzz Only

If you already have an account ID and want to discover buckets:

root@kitploit:~
bucky fuzz \
  --role-arn arn:aws:iam::123456789012:role/bucky-role \
  --account-id 675351422352 \
  --wordlist wordlists/default.txt \
  --workers 20

Environment Variables

All flags can be set via environment variables. Flags take precedence when both are set.

Example with Environment Variables

root@kitploit:~
export AWS_ACCESS_KEY_ID=AKIA...
export AWS_SECRET_ACCESS_KEY=wJal...
export BUCKY_ROLE_ARN=arn:aws:iam::123456789012:role/bucky-role

# Now just specify the target
bucky --bucket target-bucket --wordlist wordlists/default.txt

Wordlists

Bucky ships with a default wordlist at wordlists/default.txt containing ~300 common S3 bucket naming patterns:

  • Generic names (backups, logs, data, assets, uploads)
  • AWS service patterns (cloudtrail-logs, terraform-state, lambda-artifacts)
  • Environment variants (prod-logs, staging-data, dev-backups)
  • Application patterns (api, web-assets, cdn-origin)
  • Infrastructure (ci-artifacts, , )

Custom Wordlists

For targeted engagements, generate a custom wordlist by prepending the organization name:

root@kitploit:~
ORG="acme"
while read -r line; do
  [[ "$line" =~ ^#.*$ || -z "$line" ]] && continue
  echo "${ORG}-${line}"
  echo "${line}-${ORG}"
  echo "${ORG}${line}"
done < wordlists/default.txt > wordlists/acme.txt

Any wordlist compatible with tools like ffuf or gobuster works. Format: one bucket name per line, # comments, blank lines ignored.

Commands Reference

CommandDescription
buckyFull workflow — enumerate account ID then fuzz for more buckets
bucky enumEnumerate the 12-digit account ID from a known bucket
bucky fuzzFuzz bucket names against a known account ID

Flags

Global flags (all commands):

bucky (full workflow):

FlagDescription
--bucket

bucky enum:

FlagDescription
--bucketTarget S3 bucket(s), comma-separated
--bucket-fileFile with bucket names/URLs, one per line

bucky fuzz:

FlagDescription
--account-id

Bucket Input Formats

The --bucket flag and --bucket-file accept multiple input formats. Bucky automatically extracts the bucket name (and optional key) from:

FormatExample
Plain namemy-bucket
S3 URIs3://my-bucket/path/to/key

Multiple buckets can be passed comma-separated via --bucket:

root@kitploit:~
--bucket bucket1,s3://bucket2/key,https://bucket3.s3.amazonaws.com/

Or listed one per line in a file via --bucket-file:

root@kitploit:~
my-bucket
s3://another-bucket/index.html
https://third.s3.us-east-1.amazonaws.com/

When multiple buckets resolve to the same account ID, bucky deduplicates and runs fuzzing only once per unique account.

JSON Output

Use --json to save results to a JSON file. The default filename is bucky-{uuid}.json in the current directory, or specify a path with --output:

root@kitploit:~
bucky --bucket target-bucket --wordlist wordlists/default.txt --json
bucky --bucket target-bucket --wordlist wordlists/default.txt --json --output results.json

Output format:

root@kitploit:~
{
  "timestamp": "2024-01-15T10:30:00Z",
  "results": [
    {
      "bucket": "target-bucket",
      "account_id": "675351422352",
      "region": "ap-south-1",
      "discovered_buckets": [
        "dev-675351422352-ap-south-1-an.s3.ap-south-1.amazonaws.com",
        "prod-675351422352-ap-south-1-an.s3.ap-south-1.amazonaws.com"
      ]
    }
  ]
}

Bucket Region Handling

Bucky automatically detects the region of target buckets. When S3 returns a 301 redirect (bucket is in a different region than --region), bucky resolves the correct region via the x-amz-bucket-region HTTP response header and caches it for all subsequent requests. No manual region configuration is needed for the target bucket.

Let's Connect!

If you have any questions or feedback about Genzai or just want to connect with me, feel free to reach out via LinkedIn or Email.

Download Tool
VariableFlagDescription
AWS_ACCESS_KEY_ID--access-keyAWS access key ID
AWS_SECRET_ACCESS_KEY--secret-keyAWS secret access key
AWS_SESSION_TOKEN--session-tokenAWS session token (for temporary credentials)
AWS_REGION--regionAWS region (default: us-east-1)
AWS_DEFAULT_REGION--regionFallback if AWS_REGION is not set
AWS_PROFILE--profileAWS named profile from ~/.aws/credentials
BUCKY_ROLE_ARN--role-arnARN of the IAM role to assume
BUCKY_BUCKET--bucketTarget S3 bucket name
BUCKY_ACCOUNT_ID--account-idTarget AWS account ID (fuzz only)
BUCKY_WORDLIST--wordlistPath to wordlist file
BUCKY_WORKERS--workersConcurrent fuzzing workers (default: 10)
build-output
docker-images
FlagDescription
--access-keyAWS access key ID
--secret-keyAWS secret access key
--session-tokenAWS session token
--regionAWS region (default: us-east-1)
--profileAWS named profile
--role-arnARN of the IAM role to assume
--jsonSave results to JSON file
--outputJSON output file path (default: bucky-{uuid}.json)
Target S3 bucket(s), comma-separated
--bucket-fileFile with bucket names/URLs, one per line
--wordlistPath to wordlist file
--workersConcurrent workers (default: 10)
Target 12-digit AWS account ID
--wordlistPath to wordlist file
--workersConcurrent workers (default: 10)
--regionsComma-separated regions for name mutations
Virtual-hosted URL
https://my-bucket.s3.us-west-2.amazonaws.com/key
Path-style URLhttps://s3.us-west-2.amazonaws.com/my-bucket/key