คลัง
web

Session Testing

Session Testing คือการตรวจการจัดการ session/token เพื่อหาจุดที่ทำให้ขโมย ปลอม หรือคง session ของคนอื่นได้ ครอบคลุม cookie attributes (HttpOnly/Secure/SameSite), session fixation, predictable/weak token, การไม่ invalidate หลัง logout/เปลี่ยนรหัส, token รั่วผ่าน URL/Referer, และ JWT บทนี้ไล่ทุกจุดพร้อม request จริงและ workflow

Intermediate#session#cookie#fixation#session-hijacking#samesite#jwt#token#web

attribute ของ session cookie เป็นด่านแรก — flag ที่ขาดไปแต่ละตัวเปิดช่องโจมตีคนละแบบ ตรวจ Set-Cookie ตอน login เสมอ

attributeถ้าขาด → เสี่ยงหมายเหตุ
HttpOnlyJS อ่าน cookie ได้ → XSS ขโมย sessionsession cookie ต้องมีเสมอ
Securecookie ส่งผ่าน HTTP → ดักได้บังคับ HTTPS-only
SameSiteไม่กัน CSRF/cross-siteStrict/Lax/None (None ต้องมี Secure)
Domain กว้างcookie รั่วไปทุก subdomainหลีกเลี่ยง .example.com ถ้าไม่จำเป็น
Path กว้างcookie ส่งไป path ที่ไม่เกี่ยวจำกัด scope เท่าที่ใช้
Expires/Max-Age ยาวsession อยู่นานเกินควรมี idle + absolute timeout
เช็ค cookie flags
curl -sI https://target/login | grep -i set-cookie
# ตัวอย่างที่ดี:
# Set-Cookie: session=...; HttpOnly; Secure; SameSite=Lax; Path=/
# ที่ขาด flag → ตั้งสมมติฐานตามตาราง แล้วไปพิสูจน์ผลกระทบ
SameSite กับพฤติกรรม cross-site request
Strict ไม่แนบ cookie ทุก cross-site Lax (default) แนบเฉพาะ top-level GET → CSRF บาง GET ยังได้ None แนบทุก cross-site → ต้องพึ่ง CSRF token SameSite = ด่านแรกกัน CSRF

2. Session fixation

Session fixation เกิดเมื่อ server ไม่สร้าง session id ใหม่หลัง login ผู้โจมตี 'กำหนด' session id ให้เหยื่อล่วงหน้า (ผ่านลิงก์/cookie injection) พอเหยื่อ login ด้วย id นั้น ผู้โจมตีที่รู้ id เดียวกันก็เข้าบัญชีเหยื่อได้ทันที

  1. 1จด session id ก่อน login (ยังไม่ยืนยันตัวตน)
  2. 2login ให้สำเร็จ แล้วดู session id อีกครั้ง
  3. 3ถ้า id เหมือนเดิม = เสี่ยง fixation (server ควร regenerate)
  4. 4จำลองการโจมตี: ตั้ง id ที่รู้ให้ 'เหยื่อ' (ผ่าน ?sessionid= หรือ cookie ที่ set ได้) แล้วรอ login
  5. 5หลังเหยื่อ login ลองใช้ id เดิม → ถ้าเข้าได้ = fixation ยืนยัน
จุดที่ทำให้ตั้ง id ให้เหยื่อได้: session id รับผ่าน URL parameter, cookie ที่ subdomain อื่น set แล้ว scope กว้าง, หรือ app ยอมรับ session id ที่ผู้ใช้ส่งมาแทนสร้างเอง การป้องกันคือ regenerate id ทุกครั้งที่ระดับสิทธิ์เปลี่ยน (login/privesc)

3. Predictable / weak token

session id ที่ดีต้องสุ่มด้วย CSPRNG และยาวพอ (≥128 บิต entropy) ถ้า id เรียงลำดับ, เป็น base64 ของค่าที่เดาได้, หรือมี entropy ต่ำ ผู้โจมตีคาดเดา/enumerate session ของคนอื่นได้

  • เก็บ token หลายอัน: สร้างบัญชีหลายรอบเก็บ session id มาเทียบหา pattern (เลขเรียง, timestamp, counter)
  • Decode: ลอง base64/hex/URL-decode — ข้างในอาจเป็น userid:timestamp หรือ JSON
  • วัด entropy: ใช้ Burp Sequencer เก็บ token จำนวนมากแล้ววิเคราะห์ randomness
  • Structure leak: token ที่มี username/role/email ฝังอยู่ = แก้เพื่อ escalate ได้ (คล้าย JWT ที่ไม่เซ็น)
ตรวจ token ที่ดูเป็น encoded
import base64
tok = "dXNlcjoxMDA1OnJvbGU6dXNlcg=="   # ตัวอย่าง cookie ที่ได้มา
print(base64.b64decode(tok))
# b'user:1005:role:user'  → เดา id คนอื่น + ลองแก้ role:admin
# ถ้าไม่มี signature/HMAC → ปลอมได้ทันที
ถ้า token ถอดเป็น structure ที่แก้แล้ว server ยอมรับ = broken session token (คล้าย mass assignment ในระดับ session)

4. Session lifecycle & invalidation

session ที่ 'ไม่ตาย' คือปัญหา — หลัง logout, เปลี่ยนรหัส, หรือ admin สั่ง revoke แล้ว token เก่าต้องใช้ไม่ได้ทันที ทดสอบด้วยการเก็บ token ไว้ก่อนเหตุการณ์แล้วลองใช้หลังจากนั้น

เหตุการณ์token เก่าควรเป็นอย่างไรวิธีทดสอบ
Logoutใช้ไม่ได้ทันที (server-side)logout แล้ว replay request เก่าด้วย token เดิม
เปลี่ยนรหัสผ่านsession อื่นทั้งหมดต้องหลุดlogin 2 ที่, เปลี่ยนรหัสที่หนึ่ง, ทดสอบอีกที่
Idle timeoutหมดอายุหลังไม่ใช้งานทิ้งไว้แล้วลองใช้
Absolute timeoutหมดอายุตามเวลาจริงใช้ token ข้ามวัน
Concurrent loginจำกัด/แจ้งเตือนตาม policylogin หลายที่พร้อมกัน
จุดพลาดที่พบบ่อย: logout ลบแค่ cookie ฝั่ง client แต่ server ยังถือ session ว่า valid — ผู้โจมตีที่ขโมย token ไปแล้วใช้ต่อได้ ทดสอบเสมอด้วยการ replay token หลัง logout

5. Token leakage & hijacking chain

  • Token ใน URL: ?sessionid= รั่วผ่าน Referer header, browser history, proxy/access log, และ analytics
  • ผ่าน XSS: ถ้าไม่มี HttpOnly → document.cookie ส่งออกได้ (ดู XSS)
  • ผ่าน network: ไม่มี Secure → ดักบน HTTP/Wi-Fi สาธารณะ
  • ผ่าน subdomain: Domain กว้าง (.example.com) → subdomain ที่ถูก compromise อ่าน cookie ได้
  • Cache: response ที่มี token ถูก cache โดย CDN/proxy
workflow ทดสอบ session
ตรวจ Set-Cookie: HttpOnly/Secure/SameSite ครบไหม
session id เป็นอย่างไร?
เรียง/เดาได้/decode ได้predictable → enumerate/ปลอม
สุ่มแข็งแรงไป fixation/lifecycle
id เปลี่ยนหลัง login ไหม?
จดก่อน-หลัง
ไม่เปลี่ยนsession fixation
token หลัง logout/เปลี่ยนรหัส ยังใช้ได้ไหม?
ยังใช้ได้invalidation flaw
token รั่วทางไหน? URL/Referer/XSS/subdomain
พบช่อง → hijack / คง session ของเหยื่อ

6. เมื่อ session เป็น JWT

ถ้า token เป็น JWT (สาม segment คั่นด้วยจุด, ขึ้นต้น eyJ) การทดสอบเปลี่ยนไปเน้นที่ signature — ดูหัวข้อ JWT Attacks สำหรับ alg=none, weak HMAC secret (crack ด้วย hashcat), kid injection, และ algorithm confusion (RS256→HS256)

แยกแยะ JWT vs opaque session
# JWT: base64url 3 ส่วน, decode ส่วนแรกได้ header JSON
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMDA1In0.abc...
  header  = {"alg":"HS256","typ":"JWT"}
  payload = {"sub":"1005","role":"user"}   ← แก้ role แล้วต้องเซ็นใหม่

# Opaque: สุ่มล้วน อ้างอิง state ฝั่ง server → ทดสอบ predictability/lifecycle แทน

7. ตัวอย่าง CTF & Real-world

CTF: cookie auth=YWRtaW46ZmFsc2U= ถอด base64 ได้ admin:false เปลี่ยนเป็น admin:true แล้ว encode กลับ → ยกสิทธิ์ทันทีเพราะ token ไม่มี signature เป็นตัวอย่าง weak session token คลาสสิก

Real-world: เว็บออก session id ผ่าน URL ?jsessionid= เพื่อรองรับเบราว์เซอร์ไม่รับ cookie — id หลุดเข้า Referer เมื่อผู้ใช้คลิกลิงก์ออกไปเว็บอื่น ผู้ดูแลเว็บภายนอกเก็บ id จาก Referer log แล้ว hijack session ได้ทันที เป็นเหตุผลว่าทำไม session ต้องอยู่ใน cookie เท่านั้น

8. ข้อผิดพลาด & การป้องกัน

  • ดูแค่ flag แล้วจบ: ต้องพิสูจน์ผลกระทบจริง (fixation/reuse/predictability)
  • ลืมทดสอบไขว้ 2 session: เปลี่ยนรหัสที่ session หนึ่งแล้วลืมเช็คอีก session
  • ตัดสิน logout จาก client: cookie หายแต่ server ยังถือ valid — ต้อง replay ทดสอบ
  • ลืม subdomain/Domain scope: cookie รั่วข้าม subdomain
การป้องกัน (blue team): session id สุ่มด้วย CSPRNG ≥128 บิต, ตั้ง HttpOnly; Secure; SameSite=Lax/Strict, regenerate id หลัง login/privesc, invalidate ฝั่ง server จริงเมื่อ logout/เปลี่ยนรหัส (revoke ทุก session), มี idle+absolute timeout, ห้ามใส่ token ใน URL, และผูก session กับสัญญาณ (เช่น binding อ่อนๆ กับ User-Agent) โดยไม่ทำให้ใช้งานพัง

9. Quick Reference

  • เช็ค Set-Cookie: HttpOnly + Secure + SameSite + Domain/Path แคบ
  • fixation: จด id ก่อน-หลัง login → ต้องเปลี่ยน
  • predictable: เก็บหลาย token, decode, Burp Sequencer
  • invalidation: token หลัง logout/เปลี่ยนรหัสต้องตาย (replay ทดสอบ)
  • leak: URL/Referer, XSS (ไม่มี HttpOnly), network (ไม่มี Secure), subdomain
  • JWT → ดู JWT Attacks (alg=none, weak secret, RS256→HS256)
  • ป้องกัน: CSPRNG, regenerate, invalidate จริง, cookie flags ครบ, ไม่ใส่ token ใน URL

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

สมมติ login เว็บเป้าหมายได้แล้ว มีแค่ Kali เปล่าๆ อยากรู้ว่า session/token ที่ได้มามีช่องให้ขโมย/ปลอมไหม — ทำตามนี้ทีละขั้น

  1. 1login แล้วดู Set-Cookie ด้วย curl -sI (หรือ Burp) ตรวจว่ามี HttpOnly / Secure / SameSite ครบไหม
  2. 2จด session id/token ทันทีก่อน login และหลัง login เทียบกัน (เช็ค fixation)
  3. 3login/สมัครใหม่หลายรอบ เก็บ token แต่ละครั้งไว้ วางใน Burp Sequencer เพื่อวัด randomness
  4. 4วาง token ใน CyberChef (From Base64 / From Hex) ดูว่ามี structure ที่อ่าน/แก้ได้ไหม (เช่น user:role)
  5. 5logout แล้วเก็บ token เดิมไว้ ลอง replay request เก่าด้วย token นั้นดูว่ายังใช้ได้ไหม
  6. 6ถ้าเปลี่ยนรหัสผ่านได้ ลอง login 2 ที่พร้อมกัน เปลี่ยนรหัสที่หนึ่ง แล้วเช็คอีกที่ว่า session หลุดไหม
  7. 7ถ้า token ขึ้นต้น eyJ (เป็น JWT) เอาไปวางที่ jwt.io ดู header/payload
  8. 8ถ้าไม่มี HttpOnly ลองยืนยันด้วย PoC XSS ง่ายๆ (document.cookie) ในช่องที่รับ input ได้
ตัดสินใจ: session/token นี้มีช่องให้เล่นตรงไหน
token เป็น JWT (eyJ...) หรือ opaque random?
✅ เป็น JWT→ ไปตรวจ signature ต่อที่ JWT Attacks
❌ opaque→ ตรวจ predictability
เก็บหลาย token เทียบ pattern (Burp Sequencer / CyberChef decode)
เดา/decode ได้ไหม?
✅ เดา/decode ได้→ ปลอม token / enumerate ของคนอื่น
❌ สุ่มแข็งแรง→ ไปเช็ค fixation
จด id ก่อน-หลัง login เทียบกัน
id เปลี่ยนไหม?
✅ ไม่เปลี่ยน→ session fixation ยืนยัน
❌ เปลี่ยนทุกครั้ง→ ไปเช็ค invalidation แทน
logout แล้ว replay token เก่า
token เก่ายังใช้ได้ไหม?
✅ ยังใช้ได้→ invalidation flaw ยืนยัน
❌ ใช้ไม่ได้แล้ว→ ป้องกันแน่น ลองดู CSRF/XSS ของฝั่ง client แทน
พบช่อง → hijack / คง session ของเหยื่อได้
ขั้นตอน/งานเครื่องมือใน Kaliติดตั้งเพิ่ม (ถ้าไม่มี)เครื่องมือออนไลน์
ตรวจ cookie flagscurl--
ดักจับ/แก้ไข tokenBurp Suite Community--
วัด entropy ของ tokenBurp Sequencer--
decode token (base64/hex)--CyberChef
ถอด/แก้ JWT-git clone https://github.com/ticarpi/jwt_tooljwt.io
crack weak JWT secrethashcat-crackstation.net
🚑 ถ้าตันสนิท ลองท่าถัดไป: JWT Attacks — ถ้า token เป็น JWT ที่ signature อ่อน · CSRF — ถ้า SameSite=None ต้องพึ่ง token แยก ลองดูว่า CSRF token ผูก session จริงไหม · XSS — ถ้าไม่มี HttpOnly หาช่องฉีด JS เพื่อขโมย cookie · Access Control — ถ้า session ใช้ได้ปกติแต่สิทธิ์/role ที่ผูกไว้ผิดพลาด

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

โน้ตของฉัน

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