0142 | DDoS : TCP FIN Flood

อ่า มาต่ออันที่ 3 กันครับ ใครเห็นชื่อแปลกๆ นี่ไม่ได้พิมพ์ผิดนะครับ มันคือ FIN Flood จริงๆ

โดยก่อนอื่นต้องว่ากันด้วยการเชื่อมต่อ connection ของ TCP ก่อนครับ เนื่องจากเจ้า TCP เนี่ย เป็น protocol ที่เป็น stateful connection คือต้องมีการรับ และตอบกลับก่อนเพื่อที่จะสร้างการเชื่อมต่อกันได้สมบูรณ์ ซึ่งจะกำกับด้วย TCP Flag ที่มีทั้งหมด 9 ตัว แต่มีตัวที่ใช้หลักๆ ประมาณนี้ครับ

  • ACK Acknowledge เป็น Flag ที่ถูกแปะบ่อยที่สุด เพราะมันแปะที่ SYN ไม่ได้ที่เดียว นอกนั้นแปะไว้ได้หมดเลย
  • PSH Push data บอกว่ามีการส่งข้อมูลแนบไปกับ flag อื่น(ที่ไม่ใช่ SYN) ด้วย
  • RST Reset เป็นการสั่งตัด connection แบบไม่สนสถานะ คือถ้าเจอไอ้นี่ปุ๊ปจะขึ้น connection has been reset เลยครับ เกิดจากพวกระบบ block หรือโปรแกรมที่ทำงานบน connection นั้นดับไปแบบ error ครับ
  • SYN สถานะเริ่มเชื่อมต่อ ไอ้นี่จะโผล่มาแค่สองครั้ง (2 packet แรก) เท่านั้น
  • FIN ร้องขอจบการเชื่อมต่อ

โดยมีขั้นตอนการทำงาน (state) เป็นแผนภาพแบบง่ายๆ (สาบานว่าง่ายแล้ว) ดังนี้ครับ


ภาพประกอบจาก Wikipedia : TCP

จากด้านบน … อธิบาย “การทำงานปกติ” ได้ประมาณนี้ครับ

  • client ส่ง SYN ไปหา server ระบุ flag เป็น SYN พร้อมเลข sequence number (seq) ของ syn
  • server ตอบกลับด้วย flag SYN + ACK พร้อมกับเลข seq เดิมของ SYN จาก client และเลข seq ของการ ack
  • client ตอบกลับหา server ด้วย flag ACK และอาจมีข้อมูลที่ต้องการส่งแนบติดไปด้วยเลยแล้วแต่กรณี
  • สถานะของ connection จะกลายเป็น ESTABLISHED สามารถรับส่งข้อมูลระหว่าง server ได้โดยใช้ seq ของ syn และ ack ตั้งต้นเรียงไปเรื่อยๆ ได้
  • เมื่อฝ่ายใดฝ่ายหนึ่ง (1) ต้องการยุติการเชื่อมต่อ ก็จะส่งข้อมูลชุดสุดท้าย (ถ้ามี) ไปพร้อมกับ flag FIN
  • ฝ่ายที่รับข้อมูล (2) จะตอบกลับด้วย ACK สำหรับการตัดการเชื่อมต่อจากฝ่ายตั้งต้น ระหว่างนี้ เครื่อง (1) จะไม่สามารถส่งข้อมูลได้อีก แต่ยังสามารถรับข้อมูลจาก (2) ได้เรื่อยๆ เรียกสถานะนี้ว่า TCP Half-Open ครับ
  • เมื่อ (2) ส่งข้อมูลจนหมด และต้องการยุติการเชื่อมต่อ ก็ให้ส่ง FIN ไปหา (1)
  • จากนั้น (1) ก็จะตอบ ACK กลับไป เป็นอันยุติการเชื่อมต่อ

จะเห็นข้อสังเกตดังนี้ครับ

  • SYN จะโผล่เดี่ยวๆ หรือโผล่คู่กับ ACK เท่านั้น และโผล่แค่ 2 ครั้งตลอดการเชื่อมต่อ ฝั่ง client 1 ครั้ง และฝั่ง server อีก 1 ครั้ง
  • FIN โผล่ได้หลังจากการเชื่อมต่อ (3-way handshake) เสร็จสมบูรณ์แล้วเท่านั้น หมายความว่าต้องเกิด SYN-SYNACK-ACK ครบกระบวนการเสมอ
  • RST จะเกิดได้เมื่อ packet ทำงานผิดขั้นตอน มีตัวอะไรมาขัดขวางการเชื่อมต่อ หรือโปรแกรมที่เป็นเจ้าของ connection นั้นเกิดปิดการทำงานไปแบบผิดปกติ ก็จะเป็นหน้าที่ของ OS ที่ทำการส่ง reset ไปให้อีกฝ่ายครับ

ทีนี้ ช่องโหว่ของมันก็อยู่ที่เจ้าข้อ 2-3 นั่นแหละครับ โดยเป็นบั๊กแค่บาง OS (ที่เก่าๆ) เท่านั้น คือเมื่อมีการส่ง FIN มาที่ connection ที่ยังไม่มีสถานะ ตัว OS จะส่ง RST กลับไปตาม FIN นั้น ทำให้เกิดการ generate packet ปริมาณมหาศาล ทั้งเข้าและออกจนทำให้เครื่อง server หยุดการทำงานได้เลยครับ สาเหตุก็เพราะต้องมาค้นหาการเชื่อมต่อก่อนการรับการเชื่อมต่อนั่นเอง

รูปแบบการยิงแบบนี้สามารถแก้ไขได้ง่ายๆ ด้วยวิธี stateful inspection ครับ คือในเมื่อมันมีเงื่อนไขว่า connection ต้องอยู่ในสถานะ ESTABLISHED เท่านั้น packet แรกที่อยู่ดีๆ ก็ FIN เลยมันจะกลายเป็นสถานะ INVALID ทันทีครับ ดังนั้นเราสามารถ drop ได้ด้วยคำสั่งดังนี้

iptables -A FORWARD -p tcp -m state --state INVALID -j DROP

สั้น และง่าย และเนื่องจากมันไม่ต้องการการตรวจสอบการเชื่อมต่อก่อน ถึงแม้จะเป็น stateful ก็ตาม ทำให้รองรับการโจมตีลักษณะนี้ได้ค่อนข้างสูงครับ และไม่เปลือง connection tracking ของ iptables ด้วย (ไม่เจอ connection ใน memory ก็ยิงเป็น invalid ได้เลย ไม่ต้องสร้าง state ขึ้นมารับมัน)

Tags: , ,