คลัง
web

Business Logic Vulnerabilities

Business Logic Vulnerabilities คือช่องโหว่จากตรรกะที่ออกแบบผิด ไม่ใช่บั๊กทางเทคนิค — เกิดเมื่อระบบเชื่อ 'สมมติฐานที่ผิด' เช่น เชื่อราคาที่ client ส่งมา, เชื่อว่าผู้ใช้ทำตามขั้นตอน, ไม่คิดถึงค่าติดลบ/ศูนย์/ใหญ่มาก บทนี้ไล่รูปแบบที่พบบ่อย (price/quantity manipulation, ข้ามขั้นตอน, ใช้ซ้ำ, race), วิธีคิดในการทดสอบ, พร้อม request จริงและ decision flow ช่องนี้ scanner หาไม่เจอ — ต้องเข้าใจ domain ของแอป

IntermediateAdvanced#business-logic#workflow#validation#logic-flaw#price-manipulation#race-condition#web#ctf

1. หลักการ — สมมติฐานที่ผิด

ช่องโหว่ประเภทนี้ไม่มี payload ตายตัว เกิดจากการที่ระบบ เชื่อ assumption ที่ผิด เช่น เชื่อว่าราคาที่ client ส่งมาถูกต้อง, เชื่อว่าผู้ใช้เดินตามขั้นตอน 1→2→3, หรือไม่ได้คิดถึงค่าติดลบ/ค่าศูนย์/ค่าใหญ่มาก กุญแจคือ เข้าใจ workflow ที่ตั้งใจ แล้วถามว่า 'ถ้าทำนอกเหนือจากที่ตั้งใจจะเกิดอะไร'

logic flaw: ระบบเชื่อ input จาก client
CLIENT (แก้ได้) price=0, qty=-1, step=3 SERVER เชื่อค่าที่ส่งมา? trust boundary ทุกค่าที่ข้ามเส้นนี้ต้อง re-validate ที่ server
business logic หาด้วยเครื่องมืออัตโนมัติแทบไม่ได้ ต้องเข้าใจ domain ของแอป (ร้านค้า, ธนาคาร, จองตั๋ว) — เป็นจุดที่ผู้ทดสอบที่คิดเชิงตรรกะได้เปรียบ scanner ชัดเจนที่สุด

2. รูปแบบที่พบบ่อย

รูปแบบตัวอย่างผลกระทบ
เชื่อค่าจาก clientprice=0, discount=100 ใน requestซื้อของฟรี/ลดเกินจริง
ค่าติดลบquantity=-1 → ยอดเงินเพิ่มแทนลดเติมเงินตัวเอง
ข้ามขั้นตอนเข้าหน้า confirm โดยไม่ผ่านหน้าจ่ายเงินได้ของโดยไม่จ่าย
แก้ค่าที่ไม่ควรแก้เปลี่ยน user_id/account/status ใน requestIDOR/privesc
ใช้ซ้ำใช้คูปอง/gift card เดิมหลายครั้ง (race)ส่วนลดทวีคูณ
Integer overflow/roundจำนวนมากจน overflow / ปัดเศษเข้าข้างตัวยอดเพี้ยน
ลำดับสลับ (TOCTOU)แก้ตะกร้าหลังคำนวณราคาแล้วจ่ายราคาเก่าของถูก
สมมติค่า enum จำกัดส่ง currency/role/tier ที่ไม่มีในลิสต์ได้สิทธิ์/เรตพิเศษ

3. ตัวอย่าง request จริง

Price manipulation — เชื่อราคาจาก client
# checkout ส่งราคามาจาก client เอง (แทนคำนวณที่ server)
POST /api/checkout HTTP/1.1
Content-Type: application/json

{"item":"laptop","price":1,"quantity":1}
# เปลี่ยน price 49900 → 1 หรือ 0 → จ่ายน้อย/ฟรี
# ถ้า server เชื่อ = business logic flaw
server ที่ถูกต้องต้องคำนวณราคาจาก item id เองเสมอ ไม่รับ price จาก client
ค่าติดลบ — quantity/amount
# ซื้อจำนวนติดลบ → บาง backend คิดเป็นเครดิตคืน
POST /api/cart/add   {"item":"gift","quantity":-5,"price":1000}
# หรือ transfer ติดลบ = ดึงเงินจากปลายทางมาหาเรา
POST /api/transfer   {"to":"victim","amount":-1000}
ข้ามขั้นตอน (forced browsing ใน workflow)
# ปกติ: /cart → /shipping → /payment → /confirm
# ข้ามตรงไปหน้า confirm โดยไม่ผ่าน payment
POST /api/order/confirm HTTP/1.1
{"order_id":"12345"}
# ถ้าไม่มี state check ว่าจ่ายเงินแล้ว → ได้ของฟรี
Coupon/gift card reuse ผ่าน race
# ยิง apply-coupon พร้อมกันหลาย request ก่อน server mark ว่าใช้แล้ว
POST /api/coupon/apply   {"code":"SAVE50"}   x 20 พร้อมกัน
# ถ้า check-then-use ไม่ atomic → คูปองถูกใช้หลายครั้ง
# ดูหัวข้อ Race Condition สำหรับเทคนิค single-packet attack
logic flaw หลายอย่างกลายเป็น critical เมื่อ chain กับ race condition

4. วิธีคิดในการทดสอบ

  1. 1วาดแผนผัง workflow ที่ตั้งใจให้ครบ (ทุกขั้นตอนปกติ + state ที่ควรเป็น)
  2. 2ที่แต่ละขั้น ถาม: 'ถ้าข้าม / ทำซ้ำ / ทำสลับลำดับ / ทำพร้อมกัน จะเกิดอะไร'
  3. 3ดูทุกค่าที่ client ส่ง — ลองค่าขอบ: 0, ติดลบ, ใหญ่มาก (overflow), ทศนิยม, string, array, null
  4. 4ลองแก้ค่าที่ 'ไม่ควรแก้ได้': ราคา, ส่วนลด, สิทธิ์, สถานะ order, เจ้าของ, currency, tier
  5. 5หา assumption ที่ซ่อนอยู่ — อะไรที่ระบบ 'คิดว่าผู้ใช้จะไม่ทำ' แล้วลองทำสิ่งนั้น
  6. 6ตรวจว่า validation อยู่ที่ client อย่างเดียวไหม (JS กันแต่ server ไม่กัน)
ทดสอบ workflow — ถามทุกจุด
map workflow ที่ตั้งใจ (ขั้นตอน + state)
ที่แต่ละขั้นลองอะไร?
ข้ามขั้นเรียก endpoint ปลายตรงๆ
ทำซ้ำreplay/ใช้ token เดิม (race)
สลับลำดับแก้ค่าหลังคำนวณ (TOCTOU)
ค่าขอบติดลบ/0/overflow/ทศนิยม
server re-validate ค่าที่ส่งไหม?
ไม่ re-validatelogic flaw
chain: race / IDOR / privesc เพิ่มความรุนแรง
ได้ของฟรี/เงิน/สิทธิ์เกิน = ยืนยัน

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

CTF (PortSwigger): ร้านค้าให้ส่วนลด 'ซื้อครบ $X ลด' โดยเช็คยอดตอนกด apply — แต่แก้ตะกร้าได้หลัง apply จึงใส่ของแพงให้ครบเกณฑ์ apply ส่วนลด แล้วลบของแพงออกก่อน checkout → ได้ส่วนลดโดยไม่ต้องซื้อจริง (TOCTOU ในราคา)

Real-world: แอปเติมเงินยอมรับ amount จาก client ในขั้นยืนยัน แม้ขั้นชำระจริงจะ fix ยอด — ผู้โจมตีจ่าย $1 แต่แก้ amount=1000 ในขั้น confirm ระบบเครดิตอ่านจาก confirm → เติมเงิน $1000 จ่ายจริง $1 เป็น pattern 'สอง endpoint เชื่อคนละค่า' ที่พบบ่อยใน payment

โจทย์assumption ที่ผิดลองทำ
ร้านค้า/ตะกร้าราคา/ยอดจาก client ถูกต้องprice=0, qty ติดลบ, แก้หลัง apply
คูปอง/รางวัลใช้ได้ครั้งเดียวreuse + race
สมัคร/upgradetier/role มาจาก flow ปกติส่ง tier=premium ตรงๆ
โอนเงินamount ≥ 0 เสมอamount ติดลบ, overflow
multi-step wizardต้องผ่านทุก stepเรียก step ปลายข้ามการจ่าย

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

  • หาแบบ scanner: ยิง payload มั่วโดยไม่เข้าใจ flow — logic flaw ต้องอ่าน domain
  • ลืมค่าขอบ: ทดสอบแค่ค่าปกติ ไม่ลอง ติดลบ/0/ใหญ่มาก
  • ดูทีละ request: logic flaw หลายอย่างเกิดจากลำดับ/สองendpoint ที่เชื่อคนละค่า
  • เชื่อ validation ฝั่ง client: ปิด JS แล้วยิงตรง server อาจไม่กัน
การป้องกัน (blue team): อย่าเชื่อค่าใดจาก client — คำนวณราคา/สิทธิ์/สถานะที่ server จาก id เท่านั้น, validate ทุกค่ารวมค่าขอบ (ปฏิเสธติดลบ/เกินขอบเขต), enforce ลำดับ workflow ด้วย server-side state machine, ทำ operation ที่ 'ใช้ครั้งเดียว' ให้ atomic (กัน race), และเขียน test เชิง abuse-case ไม่ใช่แค่ happy path

7. Quick Reference

  • logic flaw ไม่ใช่บั๊กเทคนิค — ไม่มี payload ตายตัว ต้องเข้าใจ domain
  • เชื่อค่า client: แก้ price/discount/qty/role/status
  • ค่าขอบ: ติดลบ, 0, ใหญ่มาก (overflow), ทศนิยม, string/array/null
  • ข้าม/ทำซ้ำ/สลับลำดับ workflow; TOCTOU: แก้หลังคำนวณ
  • chain กับ race (คูปอง/เงิน) และ IDOR (แก้ owner)
  • หา 'สอง endpoint เชื่อคนละค่า' ในระบบ payment
  • ป้องกัน: re-validate ที่ server ทุกค่า, state machine, atomic, abuse-case test

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

สมมติเจอเว็บ e-commerce/booking ที่มี workflow หลายขั้น (ตะกร้า→checkout→ยืนยัน) มีแค่ Kali เปล่าๆ ทำตามนี้ทีละขั้นเพื่อหา logic flaw

  1. 1เปิด Burp Suite ตั้ง proxy แล้วเดินแอปแบบ user ปกติทั้ง flow ให้ Burp เก็บทุก request ไว้ครบ
  2. 2จากประวัติใน Burp เขียนแผนผัง workflow ที่ตั้งใจไว้ (บันทึกใน notes): แต่ละ step คู่กับ endpoint ที่เกี่ยวข้อง
  3. 3หา request ที่มีตัวเลขสำคัญ (price/qty/amount/discount) ส่งเข้า Repeater
  4. 4ใน Repeater ลองค่าขอบ: 0, ติดลบ, ทศนิยม, ตัวเลขใหญ่มาก (overflow) แล้วดูว่า server ยอมรับไหม
  5. 5ลองข้ามขั้นตอน: เรียก endpoint ของ step ท้ายๆ ตรงๆ (เช่น /order/confirm) โดยไม่ผ่าน step ก่อนหน้า
  6. 6ลองแก้ field ที่ไม่ควรแก้ได้ (owner_id, status, tier, currency) ใน body แล้วดูว่า server เชื่อไหม
  7. 7ถ้ามี coupon/gift card ที่ควรใช้ครั้งเดียว ลองส่ง apply-coupon ซ้ำๆ พร้อมกันด้วย Burp Turbo Intruder
  8. 8เช็คว่า validate อยู่ที่ client อย่างเดียวไหม โดยปิด JS แล้วยิง request ตรงจาก Repeater
  9. 9เจอราคาผิด/ได้ของฟรี → เก็บ request/response ไว้เป็นหลักฐานพร้อมอธิบาย assumption ที่พัง
ตัดสินใจ: ไล่ทดสอบ workflow ทีละจุด
map workflow: จดทุก step + endpoint จาก Burp history
ลองค่าขอบ (0/ติดลบ/overflow) ในตัวเลขสำคัญ (price/qty/amount)
✅ server เชื่อค่าที่ส่งมา→ logic flaw ยืนยัน (ราคา/ยอดผิด)
❌ server re-validate→ ไปลองข้ามขั้นตอน
ลองข้ามขั้นตอน / เรียก endpoint ปลายตรงๆ
✅ ข้ามได้ ทำงานสำเร็จ→ ได้ของ/บริการโดยไม่ผ่าน step ที่ควรผ่าน
❌ กันไว้ (ตรวจ state)→ ไปลองแก้ field ที่ไม่ควรแก้ได้
ลองแก้ field ที่ไม่ควรแก้ได้ (owner_id/status/tier/currency) ใน body
✅ server ยอมรับ field แปลกปลอม→ ยกสิทธิ์/เปลี่ยนสถานะสำเร็จ
❌ ไม่ยอมรับเลย→ ลอง race condition กับ resource ที่ใช้ครั้งเดียว
logic flaw ยืนยัน → เก็บหลักฐาน + อธิบาย assumption ที่พัง
ขั้นตอน/งานเครื่องมือใน Kaliติดตั้งเพิ่ม (ถ้าไม่มี)เครื่องมือออนไลน์
ดักจับ/แก้ค่าตัวเลขBurp Suite Community--
ยิง request พร้อมกัน (race)-BApp Store: Turbo Intruder-
ทดสอบค่าขอบอัตโนมัติBurp Intruder--
เขียน script ทดสอบ logic เองpython3pip install requests-
จัดรูป/อ่าน response JSON--CyberChef (JSON Beautify)
🚑 ถ้าตันสนิท ลองท่าถัดไป: Race Condition — ถ้า resource ใช้ครั้งเดียว (coupon/สต็อก/เงิน) แต่ check-then-use ไม่ atomic · IDOR — ถ้าปัญหาจริงๆ คือแก้ owner_id ของ resource คนอื่น · Access Control — ถ้าจุดที่พังคือสิทธิ์/role มากกว่าตรรกะธุรกิจ · OAuth Attacks — ถ้า workflow เกี่ยวข้องกับการเชื่อมบัญชี/ชำระเงินผ่าน third-party

โน้ตของฉัน

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