
Laboratório privado de ASLR do Nginx Rift, cadeia de exploits e gravações de demonstração
Prova de conceito de RCE para CVE-2026-42945, um overflow crítico de heap buffer no ngx_http_rewrite_module do NGINX introduzido em 2008. O bug permite execução remota de código não autenticada contra servidores que usam as diretivas rewrite e set.
Este fork estende o PoC original com uma cadeia de bypass de ASLR que combina o overflow do NGINX com uma primitiva comum de LFI/leitura arbitrária de arquivos no mesmo host. A primitiva de leitura de arquivos é usada para recuperar os mapas do worker do nginx, a libc e o /proc/<worker>/mem em tempo real e, em seguida, derivar remotamente o endereço de system() e alvos de heap utilizáveis.
Versões anteriores deste laboratório derrubavam intencionalmente um worker do nginx para fazer o serviço gravar um core dump e, em seguida, obtinham e analisavam esse core dump por meio da primitiva de leitura de arquivos para recuperar o estado do processo sensível a ASLR, incluindo alvos de heap. Neste repositório, coreless é apenas uma abreviação para "sem core dump de crash legível": o caminho padrão atual substitui essa dependência do core de crash por leituras ao vivo da memória via procfs, enquanto o caminho legado preservado core-guided ainda usa o core dump do worker gerado.
Esta vulnerabilidade — juntamente com outros três problemas de corrupção de memória (CVE-2026-42946, CVE-2026-40701, CVE-2026-42934) — foi descoberta autonomamente pelo sistema de análise de segurança da depthfirst após um único clique de integração do código-fonte do NGINX.
Quer encontrar problemas como este no seu próprio código? Experimente o mesmo sistema em https://depthfirst.com/open-defense.
O mecanismo de script do NGINX usa um processo em duas passagens: primeiro calcula o tamanho necessário do buffer e depois copia os dados. O flag is_args é definido no mecanismo principal quando uma substituição de rewrite contém ?, mas a passagem de cálculo de comprimento é executada em um sub-mecanismo recém-zerado. Portanto:
is_args = 0 → retorna o comprimento bruto da captura.is_args = 1 → chama ngx_escape_uri com NGX_ESCAPE_ARGS, expandindo cada byte escapável para 3 bytes.A cópia transborda o buffer de heap subdimensionado com dados de URI controlados pelo atacante. A exploração usa heap feng shui entre requisições para corromper o ponteiro cleanup de um ngx_pool_t adjacente (pulverizado via corpos de POST, já que bytes de URI não podem conter null bytes), redirecionando-o para um ngx_pool_cleanup_s falso que invoca system() na destruição do pool.
Leia mais sobre este bug em nosso relatório técnico.
| Produto | Afetadas | Corrigidas em |
|---|---|---|
| NGINX Open Source | 0.6.27 – 1.30.0 | 1.31.0, 1.30.1 |
| NGINX Plus | R32 – R36 | R36 P4, R35 P2, R32 P6 |
Comunicado completo do fornecedor: https://my.f5.com/manage/s/article/K000160932



Este fork mantém o PoC de divulgação original intacto, mas adiciona uma segunda trilha de pesquisa focada em uma questão mais realista:
O bug pode ser explorado contra uma VM Linux x86_64 real com ASLR ativado, sem depender de offsets fixos do Docker/laboratório?
A resposta neste fork de pesquisa é sim, com restrições importantes. As cadeias funcionais não desativam o ASLR e não usam os endereços fixos originais de heap/libc. Em vez disso, elas derivam o estado em tempo de execução por meio de primitivas acessíveis por HTTP na mesma porta e, em seguida, selecionam o alvo final de heap a partir dos dados de divulgação obtidos remotamente.
Agora existem duas trilhas de exploração com ASLR ativado, sendo o caminho coreless tratado como o melhor PoC atual:
nginx_rifter.py: o ponto de entrada limpo e autossuficiente de avaliação e exploração integrada. Seu método de exploração padrão agora é a cadeia coreless /proc/<nginx-worker>/mem.nginx_rifter_core_v2_1.py: a versão legada preservada de nginx_rifter.py guiada por core. É útil para reproduzir o caminho de pesquisa mais antigo com core de crash testado em VM, mas não é mais o PoC preferido.tools/proc_mem_coreless_exploit.py: o harness de pesquisa coreless autônomo anterior. Sua lógica foi incorporada ao nginx_rifter.py; a ferramenta permanece para repetição de experimentos brutos.A topologia do alvo é intencionalmente na mesma porta:
/api/.../lfi.php?file=.../phpinfo.phpO caminho atual coreless proc-mem executa as seguintes etapas de alto nível:
/proc/<pid>/maps do worker do nginx e o arquivo da libc mapeada.system() para esse worker./proc/<worker>/mem por meio da primitiva de leitura de arquivos.O caminho legado guiado por core faz uma derivação semelhante do endereço base e, em seguida, derruba intencionalmente um worker, lê o arquivo de core gerado via LFI e minera esse core em busca de slots fake-cleanup pulverizados. Isso foi uma ponte de pesquisa útil, mas depende de políticas de core dump e permissões de sistema de arquivos que são menos comuns em implantações padrão.
Isso não é o mesmo que o demo determinístico original em Docker. O caminho de VM x86_64 mantém o ASLR normal do Linux ativado e recalcula endereços específicos do processo a cada execução. O caminho coreless em Docker também mantém o ASLR ativado e remove o requisito incomum de core legível, mas depende do comportamento de permissões do procfs que deve ser verificado para a classe de alvo.
Este fork é um laboratório de pesquisa controlado. As cadeias com ASLR ativado dependem de condições fortes que não são premissas universais de produção:
/proc/<pid>/maps do worker do nginx com o mesmo UID, a libc mapeada e o /proc/<pid>/mem em grandes offsets mapeados./proc/<pid>/maps do worker do nginx com o mesmo UID, a libc mapeada e o core do worker gerado.phpinfo() e /proc/<pid>/maps são suficientes para recuperar os endereços base de PIE/libc, mas não são suficientes, por si só, para recuperar o objeto/janela exato de heap necessário para esta exploração. A cadeia antiga usava um core de crash legível para essa divulgação final. A cadeia padrão atual usa /proc/<worker>/mem em vez disso, o que está mais próximo de uma consequência real de leitura arbitrária de arquivos em implantações com o mesmo UID, pois expõe a memória viva do worker sem alterar a política de core dump.
Limites importantes restantes:
/proc/<pid>/mem é protegido por ptrace. Funcionou no laboratório Docker e em uma verificação de mesmo UID contra o modelo da imagem oficial nginx:stable, mas processos de aplicativos com UIDs diferentes devem falhar sob as proteções padrão do procfs.O ponto de entrada limpo atual é o nginx_rifter.py, uma ferramenta de avaliação em primeiro lugar, pensada para se aproximar de como um testador autorizado avaliaria uma implantação conhecida e vulnerável do nginx com uma primitiva de leitura de arquivos locais acessível por HTTP.
Em comparação com o runner de demo inicial, o nginx_rifter.py melhora o fluxo de trabalho de várias maneiras:
--exploit seja fornecido explicitamente.HOST:PORT, e a primitiva de leitura de arquivos é modular por meio de --file-read-template./proc/self/status, /proc/self/maps e acessibilidade procfs do worker com o mesmo UID.system(), IDs de build, hashes de binários, detalhes do SO e configurações de proc-mem/core por meio da primitiva remota.rewrite + set.nginx_rifter.py; o método padrão é o coreless proc-mem.O nginx_rifter.py atual é autossuficiente. Ele não importa mais nem chama externamente versões anteriores do PoC de demonstração ou o tools/proc_mem_coreless_exploit.py para avaliação ou exploração.
A implementação mais antiga de nginx_rifter.py guiada por core é preservada como nginx_rifter_core_v2_1.py.
O novo artifacts/nginx_rifter_v3_coreless_exploit_20260519.gif mostra o caminho de exploração coreless do nginx_rifter.py v3 integrado. O demo4.gif mostra o fluxo de avaliação e exploração explícita da ferramenta anterior all-in-one guiada por core. O nginx-aslr-demo.gif anterior permanece como o demo original de exploração com ASLR ativado.
Testado no Ubuntu 24.04.3 LTS.
Reprodução original em Docker com ASLR desativado:
./setup.sh — construir o container.docker compose -f env/docker-compose.yml up — iniciar o servidor NGINX vulnerável.python3 poc.py --shell — obter um shell.Para o fluxo de reprodução local em Docker, consulte LAB.md.
Cadeia legada guiada por core em VM com ASLR ativado:
./nginx_rifter_core_v2_1.py --target <target-host>:19321 --exploit --cmd id --fast
Ferramenta v3 de avaliação em primeiro lugar:
./nginx_rifter.py --target <target-host>:19321
O nginx_rifter.py é o avaliador atual orientado a cenários reais e o ponto de entrada integrado do PoC. Seu modo padrão não executa o caminho de exploração com crash. Ele cria um perfil da primitiva de leitura de arquivos via HTTP, verifica leituras por intervalo e binárias, faz fingerprint do SO/nginx/libc, descobre workers do nginx e mapas relevantes para ASLR, testa a legibilidade do /proc/<worker>/mem com o mesmo UID, tenta recuperar os caminhos de configuração do nginx por meio de leituras de pid/cmdline/config, sinaliza candidatos a rotas vulneráveis com rewrite + set e imprime uma matriz de viabilidade para a cadeia coreless atual.
O nginx_rifter.py atual é autossuficiente. Ele não importa mais nem chama externamente versões anteriores do PoC de demonstração ou o harness de pesquisa proc-mem autônomo para avaliação ou exploração.
Para uma forma personalizada de LFI/download:
./nginx_rifter.py --target <target-host>:19321 \
--file-read-template 'http://{host}:{port}/download?path={path_url}{range_query}'
A execução da exploração é explícita:
./nginx_rifter.py --target <target-host>:19321 --exploit --cmd id --fast
# Discovery-only exploit smoke test, no spray/probe
./nginx_rifter.py --target <target-host>:19321 --exploit --derive-only --cmd id
O método de exploração padrão é o coreless proc-mem. As seguintes opções já estão selecionadas por padrão, pois foram as mais confiáveis para a prova coreless em Docker:
--exploit-method proc-mem
--target-len 6
--max-region 268435456
O modo legado com core legível ainda está disponível para comparação, mas o script versionado é mais claro para reproduzir esse caminho mais antigo:
./nginx_rifter_core_v2_1.py --target <target-host>:19321 --exploit --cmd id --fast
Demo legado de terminal para gravação:
./demo_ctf_exploit_v1_9.py --host <target-host>:19321 --cmd id --clear
O demo_ctf_exploit_v1_9.py é o runner antigo voltado ao operador para o caminho de laboratório guiado por core. O ponto de entrada atual preferido do PoC é o nginx_rifter.py.
A primitiva padrão de leitura de arquivos é a rota PHP deste fork:
/lfi.php?file=<path>&offset=<n>&length=<n>
Para um aplicativo CTF conhecidamente vulnerável ou uma plataforma de testes diferente, o vetor de leitura de arquivos é modular:
./nginx_rifter.py --target <target-host>:19321 --exploit --cmd id \
--target-profile generic \
--file-read-template 'http://{host}:{port}/download?path={path_url}{range_query}'
O template suporta {host}, {port}, {path_url}, {offset}, {length} e {range_query}. O perfil genérico ignora as verificações de configuração do nginx específicas deste fork, mas a exploração padrão ainda precisa das mesmas capacidades subjacentes: mapas /proc legíveis do worker do nginx, libc legível e /proc/<worker>/mem legível. phpinfo() é opcional; use --phpinfo-path '' para desativá-lo.
Ressalva de realismo: a classe de bug LFI/leitura de arquivos e o modelo de implantação do nginx/PHP-FPM no mesmo host são realistas. A cadeia proc-mem é mais realista do que a cadeia anterior com core de crash, pois não exige habilitar ou ler core dumps do worker. Ainda assim, não é uma premissa universal de produção padrão: o layout de processos com o mesmo UID, a política do procfs/Yama, as configurações de namespace do container e a qualidade da primitiva de leitura de arquivos decidem se /proc/<worker>/mem é alcançável.
Sondas de pesquisa sem LFI:
python3 tools/non_lfi_leak_probe.py --target <target-host>:19321
python3 tools/non_lfi_active_response_probe.py --target <target-host>:19321
Estas são sondas de pesquisa negativas, não pontos de entrada de exploração. Elas exercitam sumidouros passivos refletidos e uma forma inicial de over-read em resposta atrasada sem usar LFI, phpinfo, procfs, cores, acesso a debugger ou bases ASLR ao vivo fixas.
Notas adicionais de laboratório e logs de execução estão em docs/, especialmente:
docs/CTF_PLAN.mddocs/CTF_FINDINGS.mddocs/CTF_TESTS.mddocs/CTF_EXPERIMENT_LOG.mddocs/DEMO_POC_IMPROVEMENTS.mddocs/KNOWN_LAYOUT_PATTERNS.mddocs/VAGRANT_ESXI.mddocs/CORELESS_ASLR_PLAN.mddocs/CORELESS_ASLR_FINDINGS.mddocs/NON_LFI_ASLR_BYPASS_LOG.mddocs/DEMO_RECORDING_WORKFLOW.md