HTTP/2 Bomb — การโจมตีแบบ DoS จากระยะไกล มุ่งเป้าไปที่ nginx, Apache, IIS, Envoy และ Cloudflare Pingora

การโจมตีแบบ Remote Denial-of-Service ที่เพิ่งถูกเปิดเผยในชื่อ “HTTP/2 Bomb” ได้มุ่งเป้าไปที่การตั้งค่าเริ่มต้นของ HTTP/2 บนเว็บเซิร์ฟเวอร์ที่มีการใช้งานอย่างแพร่หลายที่สุดในโลก ได้แก่ nginx, Apache httpd, Microsoft IIS, Envoy และ Cloudflare Pingora การโจมตีนี้ทำให้ผู้โจมตีเพียงคนเดียวที่ใช้อินเทอร์เน็ตบ้านทั่วไป สามารถใช้หน่วยความจำของเซิร์ฟเวอร์ไปหลายสิบกิกะไบต์ได้ภายในเวลาไม่กี่วินาที

การโจมตีดังกล่าวถูกพบโดยนักวิจัยชื่อ Quang Luong ผ่านการใช้เครื่องมือ Codex โดยเป็นการนำสองเทคนิคซึ่งเป็นที่รู้จักในวงการความปลอดภัยไซเบอร์มานานเกือบหนึ่งทศวรรษมาทำงานร่วมกัน ได้แก่ HPACK compression bomb และการหน่วงการเชื่อมต่อแบบ Slowloris-style connection hold

การโจมตีแบบ Remote DoS ผ่านช่องโหว่ HTTP/2 Bomb

HPACK (RFC 7541) คือรูปแบบ header compression แบบ Stateful ของโปรโตคอล HTTP/2 โดยการเชื่อมต่อแต่ละฝั่งจะมีการเก็บ Dynamic table สำหรับ header ที่เพิ่งถูกใช้งานไป ผู้ส่งสามารถนำ header ใส่เข้าไปเพียงครั้งเดียว และหลังจากนั้นสามารถอ้างอิงถึง header ดังกล่าวได้โดยใช้ Index ขนาดเพียง 1 ไบต์ ซึ่งทางฝั่งผู้รับจะต้องสร้างสำเนาเต็มของเฮดเดอร์นั้นขึ้นมาใหม่ในทุก ๆ ครั้งที่มีการอ้างอิงถึง

ตามข้อมูลจาก Jun Rong และ Duc Phan การโจมตีผ่านช่องโหว่นี้จะเริ่มต้นด้วยการใส่ header 1 ตัวเข้าไปใน dynamic table จากนั้นจะส่งการอ้างอิง Index ขนาด 1 ไบต์จำนวนหลายพันครั้งเข้ามาใน Request เดียว วิธีนี้ทำให้ผู้โจมตีเสียแบนด์วิดท์ในการส่งข้อมูลแค่ 1 ไบต์ต่อการอ้างอิง แต่กลับไปบังคับให้เซิร์ฟเวอร์ต้อง Allocate Memory ตั้งแต่ประมาณ 70 ไบต์ (บน nginx, IIS, Pingora) ไปจนถึงประมาณ 4,000 ไบต์ (บน Apache httpd, Envoy) ต่อการอ้างอิง 1 ครั้ง

องค์ประกอบที่สอง คือการใช้ประโยชน์จาก Per-stream flow control ของ HTTP/2 (RFC 9113) โดยฝั่งไคลเอนต์ (ผู้โจมตี) จะแจ้งขนาด zero-byte flow-control window ที่ศูนย์ไบต์ เพื่อขัดขวางไม่ให้เซิร์ฟเวอร์ส่งการตอบกลับได้จนเสร็จสมบูรณ์

จากนั้นจะใช้วิธีทยอยส่งเฟรม WINDOW_UPDATE ขนาด 1 ไบต์เข้ามาเรื่อย ๆ เพื่อรีเซ็ตเวลา Send timeout อย่างต่อเนื่อง ทำให้การจัดสรรหน่วยความจำทั้งหมดถูก Pinning นานเท่าที่ผู้โจมตีต้องการ ซึ่งถือเป็นการเปลี่ยนจากการ Transient amplification กลายเป็น Persistent memory hold ในที่สุด

Quang Luong ระบุว่า จากการวิเคราะห์ด้วย Shodan พบเว็บไซต์ที่เปิดให้เข้าถึงได้แบบ Public-facing มากกว่า 880,000 แห่ง ที่รองรับโปรโตคอล HTTP/2 และใช้งานเซิร์ฟเวอร์เหล่านี้ตัวใดตัวหนึ่งอยู่ แม้ว่าหลายเว็บไซต์จะมีระบบ CDN คั่นอยู่ด้านหน้า ซึ่งช่วยลดความเสี่ยงจากการถูกโจมตี หรือการเข้าถึงโดยตรงก็ตาม

สำหรับเซิร์ฟเวอร์ที่ใช้วิธีจำกัด Header-field count แทนที่จะเป็นขนาดของข้อมูล Decoded size อย่างเช่น Apache และ Envoy การโจมตีนี้จะใช้วิธีหลบเลี่ยงผ่านทาง Cookie header โดยเอกสารมาตรฐาน RFC 9113 มาตรา 8.2.3 ได้อนุญาตอย่างชัดเจนให้สามารถแบ่ง Cookie header ออกเป็น 1 ฟิลด์ต่อ 1 Crumb ได้ ซึ่งทั้ง Apache และ Envoy ไม่ได้นำส่วนย่อยเหล่านี้ไปนับรวมในขีดจำกัดของจำนวนฟิลด์

Envoy จะนำแต่ละส่วนย่อยมาต่อท้ายกันใน Buffer การอ้างอิงถึงค่าคุกกี้ขนาด 4 KB ซ้ำ ๆ กันถึง 32,768 ครั้ง จะสร้างอัตราส่วนทางตรรกะที่ประมาณ 3,600:1 โดยจากการวัดอัตราส่วนหน่วยความจำที่ใช้งานจริงพบว่าพุ่งสูงถึงประมาณ 5,700:1 บนสตรีมเดียว เมื่อมีภาระการทำงาน Allocator overhead ในขณะที่ Apache httpd จะสร้างสตริงคุกกี้รวมขึ้นมาใหม่ทั้งหมดในทุก ๆ ส่วนย่อยที่เข้ามา โดยจะปล่อยให้ข้อมูลชุดเก่าค้างอยู่ในระบบจนกว่าจะมีการเคลียร์สตรีม ซึ่งทำให้เกิดการขยายผลในอัตราส่วนถึงประมาณ 4,000:1 แม้ว่าจะเป็นคุกกี้เปล่าก็ตาม

Mitigations

  • nginx: อัปเกรดเป็นเวอร์ชัน 1.29.8 ขึ้นไป หากไม่สามารถทำได้ ให้ปิดการทำงานโดยตั้งค่า http2 off;
  • Apache httpd: อัปเดตไปใช้โมดูล mod_http2 เวอร์ชัน 2.0.41 จากไฟล์ติดตั้งแบบ Standalone releases หากไม่สามารถทำได้ ให้ตั้งค่า Protocols http/1.1 เพื่อปิดการใช้งาน HTTP/2
  • Microsoft IIS / Envoy / Cloudflare Pingora: ยังไม่มีแพตช์แก้ไข ณ เวลาที่เขียนบทความนี้ แนะนำให้ปิดการใช้งาน HTTP/2 หรือใช้ Proxy ด้านหน้าเพื่อบังคับจำกัดจำนวนเฮดเดอร์สูงสุดต่อหนึ่ง request
  • เซิร์ฟเวอร์ทั้งหมด: จำกัดการใช้งาน Per-worker memory ผ่าน cgroups, คำสั่ง ulimit -v หรือการจำกัดทรัพยากรในระดับคอนเทนเนอร์ การปล่อยให้เวิร์กเกอร์ถูกสั่งปิดการทำงานด้วยระบบ OOM (Out-Of-Memory) แล้วเริ่มการทำงานขึ้นมาใหม่ ถือเป็นรูปแบบการจัดการข้อผิดพลาดที่ดีกว่าการปล่อยให้เครื่องเซิร์ฟเวอร์ดึงพื้นที่ Swap มาใช้งานอย่างมาก

ทีมวิจัยสรุปว่า ช่องโหว่ประเภทนี้สะท้อนให้เห็นถึงข้อบกพร่องในข้อกำหนดของมาตรฐาน RFC 7541 โดยในหัวข้อ 7.3 ได้ประเมินความเสี่ยงด้านหน่วยความจำไว้เป็นเพียงเรื่องของ Amplification ratio และถือว่าการตั้งค่า SETTINGS_HEADER_TABLE_SIZE เป็นขอบเขตที่เพียงพอแล้ว

ข้อกำหนดดังกล่าวไม่ได้คำนึงถึงภาระการประมวลผลแฝงในการจัดการข้อมูลของแต่ละรายการ ซึ่งการ Amplification ในครั้งนี้ เกิดจากข้อมูล Allocator metadata ที่ครอบอยู่บน header ที่แทบจะว่างเปล่าล้วน ๆ ทำให้สามารถหลบเลี่ยงขีดจำกัด Decoded-size limit ได้ทั้งหมด ส่งผลให้ผู้พัฒนาระบบอิสระทั้ง 5 รายที่อ่านข้อกำหนดในหัวข้อเดียวกันนี้ ปล่อยซอฟต์แวร์ออกมาพร้อมกับช่องโหว่ตัวเดียวกันทั้งหมด

ที่มา: Cybersecuritynews