คลัง
web

Directory Enumeration

Directory/content enumeration คือการค้นหา path, ไฟล์ และ endpoint ที่ไม่มีลิงก์ตรงๆ บนหน้าเว็บ ด้วยการเดาจาก wordlist แล้วอ่าน HTTP status/ขนาด response เพื่อแยกของจริงออกจาก noise เทคนิคนี้เปิดเผย admin panel, ไฟล์ backup/source, API ที่ซ่อน, และ path ที่นำไปสู่ช่องโหว่ บทนี้ลงลึกทุกเครื่องมือหลัก (ffuf, feroxbuster, gobuster, dirsearch), การเลือก wordlist, การกรอง false positive, recursion, และการรับมือ WAF/rate limit

BeginnerIntermediate#enumeration#fuzzing#ffuf#feroxbuster#gobuster#dirsearch#wordlist#vhost

1. แนวคิด — ทำไมต้อง brute path

เว็บมักมี path ที่เข้าถึงได้แต่ไม่มีลิงก์บนหน้า (/admin, /backup, /api, /.git) การ enumerate คือยิง request เดา path จาก wordlist แล้วดู HTTP status/ขนาด response — 200/301/302/403/401 บ่งชี้ว่ามีอยู่ (403/401 = มีแต่ห้ามเข้า ก็ยังเป็นเบาะแสว่าอะไรซ่อนอยู่)

Statusความหมายทำอะไรต่อ
200 OKมีอยู่และเข้าถึงได้เปิดดู, brute ต่อในโฟลเดอร์
301/302redirect (มักคือโฟลเดอร์ที่ต้องมี /)ตาม redirect, recurse เข้าไป
401มีอยู่ ต้อง authลอง default cred / bypass
403 Forbiddenมีอยู่แต่ห้ามเข้าลอง path bypass (//, %2e, header)
405method ผิด แต่ endpoint มีจริงเปลี่ยน method (GET↔POST)
404ไม่มี (ปกติ)ข้าม — แต่ระวัง soft-404
Fuzzing loop — wordlist → filter → ของจริง
wordlist admin,api,.. HTTP req /FUZZ filter code/size/word hit จริง /admin 200 noise ทิ้ง (404/soft) recurse
ก่อน brute ให้ fingerprint stack ก่อน (ดู Information Gathering) — จะได้เลือก extension ที่เกี่ยว: PHP→.php,.phtml,.bak, .NET→.aspx,.asmx,.config, Java→.jsp,.do,.action

2. เครื่องมือและคำสั่ง (ทีละตัว)

ffuf — เร็ว ยืดหยุ่นที่สุด
# directory/file พื้นฐาน
ffuf -u https://target/FUZZ -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt \
  -mc 200,301,302,307,401,403 -c

# หา extension เฉพาะ (ตาม stack ที่ fingerprint ได้)
ffuf -u https://target/FUZZ -w wordlist.txt -e .php,.bak,.txt,.zip,.old,.~ -c

# auto-calibrate กัน soft-404 (ffuf หา baseline เอง)
ffuf -u https://target/FUZZ -w wordlist.txt -ac -c

# กรองด้วยขนาด/จำนวนคำ/บรรทัด ตัด false positive
ffuf -u https://target/FUZZ -w wordlist.txt -fc 404 -fs 4242 -fw 12

# recursion อัตโนมัติ (เจอโฟลเดอร์ → ยิงต่อ)
ffuf -u https://target/FUZZ -w wordlist.txt -recursion -recursion-depth 2 -e /

# ปรับความเร็ว: -t threads, -rate req/s, -p delay
ffuf -u https://target/FUZZ -w wordlist.txt -t 40 -rate 100 -p 0.1
-mc match code, -fc filter code, -fs filter size, -fw filter word, -ac auto-calibrate, -c สีสวย
feroxbuster — recursive อัตโนมัติ ครบในตัว
feroxbuster -u https://target -w wordlist.txt -x php,txt,bak,zip

# ปรับ depth, threads, filter status/size
feroxbuster -u https://target -w wordlist.txt -d 3 -t 50 \
  --filter-status 404 --filter-size 0

# ตาม redirect + สแกน link ที่เจอในหน้า (--extract-links)
feroxbuster -u https://target -w wordlist.txt --extract-links --redirects

# เก็บ output ต่อได้ (resume)
feroxbuster -u https://target -w wordlist.txt -o ferox.txt --resume-from ferox.state
จุดเด่น: เจอโฟลเดอร์แล้วเจาะลึกต่อให้เอง + ดึงลิงก์จาก HTML/JS มา fuzz ต่อ
gobuster + dirsearch
# gobuster โหมด dir
gobuster dir -u https://target -w wordlist.txt -x php,html,txt \
  -s 200,204,301,302,307,401,403 -b '' -t 40

# gobuster โหมด vhost (หา virtual host)
gobuster vhost -u https://target.com -w subdomains.txt --append-domain

# dirsearch — มาพร้อม wordlist + จัดการ extension เอง
dirsearch -u https://target -e php,html,js,bak,zip -x 404,403 -r
# -r recursive, -x exclude status, -e extensions
gobuster -b '' ปิด default blacklist เพื่อเห็น 403; dirsearch -r recurse อัตโนมัติ

3. Wordlist — เลือกและไล่ระดับ

wordlist ที่ดีสำคัญกว่าเครื่องมือ เริ่มจากเล็ก/เจาะจงก่อน แล้วค่อยขยาย ยิ่งใหญ่ยิ่งช้าและเสี่ยงโดนบล็อก เลือกให้เข้ากับ stack และประเภทเป้าหมาย (API vs เว็บทั่วไป)

Wordlist (SecLists)ขนาดใช้เมื่อ
Discovery/Web-Content/common.txt~4.7kรอบแรก เร็ว หาของชัดๆ
raft-medium-directories.txt~30kรอบสอง คุ้มค่า/ครอบคลุมดี
raft-large-*.txt / big.txt~120k+เจาะลึกเมื่อรอบแรกไม่พอ
Discovery/Web-Content/api/api-endpoints.txtหลากหลายเป้าหมายเป็น API/REST
directory-list-2.3-medium.txt (dirbuster)~220kbrute หนักตอนมีเวลา
raft-*-files.txtหลากหลายเน้นหาไฟล์ (ไม่ใช่โฟลเดอร์)
Flag สำคัญ (ffuf)หน้าที่
-mc / -fcmatch / filter ตาม status code
-fs / -fw / -flfilter ตามขนาด / จำนวนคำ / บรรทัด
-acauto-calibrate หา baseline soft-404 เอง
-recursion -recursion-depth Nเจาะโฟลเดอร์ลูกอัตโนมัติ
-e / -H / -Xextensions / เพิ่ม header / เปลี่ยน method
-t / -rate / -pthreads / req ต่อวินาที / delay
-mr / -frmatch / filter ด้วย regex ใน response
  • SecLists อยู่ที่ /usr/share/seclists/Discovery/Web-Content/ (ติดตั้ง: apt install seclists)
  • ไล่ระดับ: common.txt → raft-medium → raft-large/big.txt (เล็กไปใหญ่)
  • เจอโฟลเดอร์แล้ว recurse เข้าไปต่อ (feroxbuster/ffuf -recursion ทำเอง)
  • หา extension ตาม stack: .php .aspx .jsp .json .bak .old .zip .tar.gz .swp .~
  • backup/source: ลองต่อท้ายไฟล์ที่รู้จักด้วย .bak .old .orig ~ .save (เช่น index.php.bak)
  • API: ใช้ wordlist สาย api + ลอง /api/v1 /api/v2 /swagger.json /openapi.json /graphql

4. เทคนิคขั้นสูง — recursion, bypass 403, vhost

bypass 403 / กรอง soft-404 / vhost
# soft-404: หน้า not-found คืน 200 → หา baseline size ก่อน
curl -s -o /dev/null -w '%{size_download}\n' https://target/thisdoesnotexist_zzz
# ได้ 4242 → ffuf ... -fs 4242

# bypass 403 ด้วยการดัด path (ลองหลายแบบ)
ffuf -u https://target/adminFUZZ -w <(printf '/\n/.\n//\n/..;/\n%%2e/\n?\n#\n') -mc 200

# bypass ด้วย header
ffuf -u https://target/admin -w /dev/null -H "X-Original-URL: /admin" -mc all
curl -s https://target/admin -H "X-Forwarded-For: 127.0.0.1"
curl -s https://target/admin -H "X-Rewrite-URL: /admin"

# vhost fuzzing (เว็บซ่อนหลัง Host header)
ffuf -u http://TARGET_IP/ -H "Host: FUZZ.target.com" \
  -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -ac
403 bypass ได้ผลเมื่อ WAF/reverse-proxy กรองแค่ path ตรงๆ แต่ backend ยอมรับ path ที่ normalize แล้ว
ถ้าทุก path คืน 200 (soft-404) ให้ยิง path มั่วๆ ที่ไม่มีจริงก่อน เพื่อวัดขนาด/จำนวนคำของหน้า not-found แล้ว filter ด้วย -fs/-fw หรือปล่อย -ac ให้ ffuf จัดการเอง

5. CTF & Pentest Walkthrough

  1. 1CTF: ffuf รอบแรกด้วย common.txt เจอ /dev (301) → recurse เข้าไปเจอ /dev/backup.zip → unzip ได้ source + flag
  2. 2CTF: หน้าเว็บโล่ง → ffuf -e .php,.txt,.bak เจอ index.php.bak → ดาวน์โหลดอ่าน source เห็น logic ตรวจ flag
  3. 3Pentest: fingerprint เป็น .NET → ffuf -e .aspx,.asmx,.config เจอ web.config.bak → เผย connection string ฐานข้อมูล
  4. 4Pentest: /admin คืน 403 → ลอง header X-Original-URL: /admin ผ่าน → เข้าแผง admin ได้
  5. 5Pentest: vhost fuzzing บน IP เดียว เจอ dev.target.com (ต่าง size) → เว็บ staging เปิด debug + ไม่มี auth

6. ข้อผิดพลาดที่พบบ่อย & Troubleshooting

อาการสาเหตุทางแก้
ผลออกมาเป็น 200 ทุกอันsoft-404หา baseline size → -fs, หรือ -ac
ยิงไปสักพักโดนบล็อก/timeoutrate limit / WAFลด -t และ -rate, เพิ่ม -p delay, สุ่ม UA
ไม่เจออะไรเลยทั้งที่ควรมีwordlist ไม่ตรง / ไม่ใส่ extensionเปลี่ยน wordlist, เพิ่ม -e ตาม stack
403 เต็มไปหมดWAF กันหรือ default denyลอง bypass path/header, ยืนยันว่ามีจริง
เจอซ้ำๆ ขนาดเท่ากันเยอะหน้า redirect/error รวมfilter ด้วย -fs/-fw หรือ -fr regex
ช้ามากwordlist ใหญ่ + recursion ลึกเริ่ม common.txt, จำกัด depth, แยกรอบ
การ brute แรงๆ สร้าง request มหาศาลและอาจล่มเว็บหรือทำให้ IP โดนแบน ทำเฉพาะเป้าหมายที่ได้รับอนุญาต และปรับ -rate/-t ให้เหมาะกับความทนของเซิร์ฟเวอร์

7. Quick Reference

  • ffuf -u https://target/FUZZ -w wordlist -mc 200,301,302,401,403 -ac
  • -e .php,.bak,.zip,.old,~ หา backup/source
  • feroxbuster -u URL -w wl -x php,bak --extract-links = recursive + ดึงลิงก์
  • wordlist: common.txt → raft-medium → big.txt (เล็กไปใหญ่)
  • soft-404 → -fs/-fw หรือ -ac
  • 403/401 ก็เป็นเบาะแส (มีอยู่แต่ห้ามเข้า) → ลอง bypass path/header
  • vhost: ffuf -H 'Host: FUZZ.target' -ac
  • โดนบล็อก → ลด -t/-rate, เพิ่ม -p delay
  • เจอ path → recurse ต่อ แล้วส่งต่อ Parameter Discovery

🧭 จับมือทำทีละขั้น (มีแค่ Kali) + ถ้าติดไปไหนต่อ

สมมติ fingerprint เว็บเสร็จแล้ว รู้ stack คร่าวๆ แต่ยังไม่รู้ว่ามี path/ไฟล์อะไรซ่อนอยู่บ้าง มีแค่ Kali เปล่าๆ ทำตามนี้ทีละขั้น

  1. 1ติดตั้ง wordlist ให้ครบก่อน (ถ้ายังไม่มี): sudo apt install seclists
  2. 2รันรอบแรกด้วย wordlist เล็ก: ffuf -u https://target/FUZZ -w /usr/share/seclists/Discovery/Web-Content/common.txt -mc 200,301,302,401,403
  3. 3ถ้าทุก path คืน 200 หมด (soft-404) ให้วัด baseline ก่อน: curl -s -o /dev/null -w '%{size_download}\n' https://target/thisdoesnotexist_zzz
  4. 4เอาขนาดที่ได้ไปกรองออก: ffuf -u https://target/FUZZ -w wordlist.txt -fs <ขนาดที่วัดได้> หรือใช้ -ac ให้ ffuf หาเอง
  5. 5ขยาย wordlist เป็น raft-medium-directories.txt ถ้ารอบแรกได้น้อยเกินไป
  6. 6เพิ่ม extension ตาม stack ที่ fingerprint ได้ เช่น ffuf ... -e .php,.bak,.zip,.old (สำหรับ PHP)
  7. 7เจอโฟลเดอร์ (301) ให้เปิด -recursion -recursion-depth 2 ให้มันเจาะลึกเข้าไปเองต่อ
  8. 8ถ้าเจอ 403 อย่าข้าม ลอง bypass ด้วย header: curl -s https://target/admin -H 'X-Original-URL: /admin'
  9. 9ถ้าเป็น IP เดียวหรือสงสัยว่ามีหลายเว็บ ลอง vhost fuzzing: ffuf -u http://TARGET_IP/ -H 'Host: FUZZ.target.com' -w subdomains.txt -ac
  10. 10รวบรวม path ทั้งหมดที่เจอ แล้วส่งต่อไปทำ Parameter Discovery บน endpoint ที่ดูน่าสนใจ
Decision flow — จับมือทำ Directory Enumeration
รัน ffuf รอบแรกด้วย common.txt
-mc 200,301,302,401,403
ผลออกมาเป็น 200 ทุกอันไหม (soft-404)?
✅ ใช่ ทุกอันเป็น 200→ วัด baseline size แล้ว filter ด้วย -fs/-ac
❌ ไม่ใช่ ผลดูสมเหตุสมผล→ ขยาย wordlist ต่อ
ขยายเป็น raft-medium + เพิ่ม extension ตาม stack
เจอ path/ไฟล์ที่น่าสนใจไหม?
✅ เจอ (admin, backup, api)→ recurse เข้าไปต่อ
❌ ยังไม่เจออะไรเลย→ ลอง vhost fuzzing หรือ wordlist ใหญ่ขึ้น
เจอ 403 Forbidden ไหม?
✅ เจอ 403→ ลอง bypass header/path
❌ ไม่มี 403→ ข้ามไปสรุปผล
ลองครบทุกท่าแล้วยังไม่เจออะไรเลย?
✅ ยังไม่เจอจริงๆ→ ตันสนิท
❌ เจอ path ที่ใช้ได้แล้ว→ ส่งต่อ parameter discovery
ขั้นตอน/งานเครื่องมือใน Kaliติดตั้งเพิ่ม (ถ้าไม่มี)เครื่องมือออนไลน์
brute path/ไฟล์หลักffuf, gobuster--
recursive brute อัตโนมัติ-apt install feroxbuster-
wordlist มาตรฐาน-apt install seclists-
บันทึกและวิเคราะห์ผลdirsearchpipx install dirsearch-
bypass 403 ด้วยมือcurl + header--
vhost fuzzingffuf, gobuster--
สแกน misconfig เสริมnikto--
🚑 ถ้าตันสนิท ลองท่าถัดไป: Parameter Discovery — ถ้าเจอ path/endpoint แล้วแต่ไม่รู้ว่ารับ parameter อะไร ให้เจาะลึกด้วย arjun ต่อ; Information Gathering — ถ้า brute เท่าไหร่ก็ไม่เจออะไรเลย ให้กลับไปหาเบาะแสจาก JS/robots/git ก่อน; LFI — ถ้าเจอ path ที่รับชื่อไฟล์เป็น parameter (เช่น ?file=) ให้ต่อไปทดสอบ path traversal; File Upload — ถ้าเจอฟอร์มอัปโหลดไฟล์ระหว่างทาง

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

โน้ตของฉัน

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