# S3 Bucket Discovery

> Techniques for discovering exposed AWS S3 buckets through permutation, DNS enumeration, and metadata analysis to identify misconfigured storage assets.

- **URL:** https://hackindex.io/platforms/aws/reconnaissance/s3-bucket-discovery
- **Path:** AWS > Reconnaissance
- **Up:** [Reconnaissance](https://hackindex.io/platforms/aws/reconnaissance.md)
- **Published:** 2026-05-24
- **Updated:** 2026-05-24

S3 bucket names are globally unique and often predictable. Discovery happens before you have any credentials: you are looking for buckets that are publicly accessible or whose names leak useful information.

## Certificate Transparency

Certificates issued for `*.s3.amazonaws.com` subdomains and custom domain CNAMEs often expose bucket names. Search crt.sh:

```
https://crt.sh/?q=%25.$DOMAIN
```

Look for entries where the common name or SAN matches an S3 pattern:

```
assets.example.com → CNAME → assets.example.com.s3.amazonaws.com
```

Any CNAME pointing to `*.s3.amazonaws.com` is a bucket name.

## Google Dorks

```
site:s3.amazonaws.com "$DOMAIN"
site:s3.amazonaws.com "$COMPANY"
site:$DOMAIN filetype:pdf
inurl:s3.amazonaws.com "$COMPANY"
```

Also search for exposed content directly:

```
site:s3.amazonaws.com inurl:backup
site:s3.amazonaws.com inurl:dump
site:s3.amazonaws.com inurl:config
```

## Passive DNS and Subdomain Enumeration

Run standard subdomain enumeration against the target domain. S3-backed subdomains resolve to AWS IP ranges and have `s3.amazonaws.com` CNAMEs.

```bash
subfinder -d $DOMAIN -silent | httpx -silent -follow-redirects -title -status-code | grep -i s3
```

```bash
amass enum -passive -d $DOMAIN | grep -i s3
```

## Permutation Brute-Forcing

S3Scanner tests a wordlist of bucket names for existence and public access.

```bash
pipx install s3scanner
```

Generate permutations from the target name:

```bash
cat > buckets.txt <<EOF
$COMPANY
$COMPANY-backup
$COMPANY-dev
$COMPANY-staging
$COMPANY-prod
$COMPANY-assets
$COMPANY-static
$COMPANY-media
$COMPANY-uploads
$COMPANY-data
$COMPANY-logs
$COMPANY-internal
$COMPANY-public
$COMPANY-private
$COMPANY-files
$COMPANY-www
EOF
```

```bash
s3scanner scan --buckets-file buckets.txt
# [found] $COMPANY-backup - AuthUsers can read, Everyone can read
# [found] $COMPANY-assets - Everyone can read
# [not found] $COMPANY-dev
```

`Everyone can read` = publicly accessible without credentials. `AuthUsers` = any authenticated AWS account can read: still exploitable.

## DNS Brute-Force via S3 Endpoint

Direct bucket URL format: `https://$BUCKET.s3.amazonaws.com`

A `301` or `200` response means the bucket exists. A `403` means it exists but is not public. A `404` means it does not exist.

**Quick existence check**

```bash
curl -s -o /dev/null -w "%{http_code}" https://$BUCKET.s3.amazonaws.com
```

**Batch check from wordlist**

```bash
while read bucket; do
    code=$(curl -s -o /dev/null -w "%{http_code}" "https://$bucket.s3.amazonaws.com")
    echo "$code $bucket"
done < buckets.txt | grep -v "^404"
```

`403` is still a hit: it confirms the bucket exists even though it is not public. Note the name for authenticated enumeration later.

## What to Do With a Found Bucket

- `200` on `https://$BUCKET.s3.amazonaws.com`: bucket lists its contents without credentials. Proceed to enumeration.
- `403`: bucket exists, private. Test with credentials during enumeration phase.
- CNAME to `s3.amazonaws.com` returning `NoSuchBucket`: potential subdomain takeover. The bucket name is not claimed. Register it to capture traffic.

See [S3 Bucket Enumeration and ACL Review](https://hackindex.io/platforms/aws/enumeration/s3/s3-bucket-enumeration-and-acl-review) for authenticated access.
