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-84118-who-labeled-the-crit-as-a-high — Prova de conceito para CVE-2026-84118, um use-after-free no GC do SpiderMonkey que leva a leitura/escrita fora dos limites e potencial execução de código. Inclui gatilho determinístico de SEGV e pesquisa sobre escalada para leitura arbitrária e derrota do ASLR. | Kitploit
Ferramentas/GitHubGitHub/sneakynachos/cve-2026-84118-who-labeled-the-crit-as-a-high
Forensia de MemóriaAnálise de VulnerabilidadesExploraçãoSegurança WebExploração de Binários
GitHubsneakynachos/cve-2026-84118-who-labeled-the-crit-as-a-high

CVE-2026-84118-who-labeled-the-crit-as-a-high

Prova de conceito para CVE-2026-84118, um use-after-free no GC do SpiderMonkey que leva a leitura/escrita fora dos limites e potencial execução de código. Inclui gatilho determinístico de SEGV e pesquisa sobre escalada para leitura arbitrária e derrota do ASLR.

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
Ver Repositório
1há 11 horasAinda não revisado

CVE-2026-84118 — Use-after-free no GC do SpiderMonkey (Bug 2057457)

Este é um daqueles casos em que a Mozilla classificou um Critical como High. Então alguém pode querer ir atualizar o Firefox e cobrar o pagamento dos caçadores de bugs originais, se for esse o caso.

O RESUMO: Você pode fazer uma primitiva R de OOB em um ponteiro controlado e então começar a subir e descer a partir desse ponteiro. Então, se você apontar o ponteiro controlado para um array, parabéns, você pode fazer coisas divertidas.

O PoC só tem a parte do SEGV, então o resto é uma aventura divertida de apontar para um array e pular para o WASM de sua escolha.

Prova de conceito determinística de SEGV em build de release para Firefox/SpiderMonkey 154.0.1. Corrigido na 155 (reformulação do AtomMarking). Severidade Mozilla: HIGH.

Executando o PoC

root@kitploit:~
/path/to/release/js poc.js

Reproduzido na 154.0.1: 3/3 em um shell otimizado simples (SIGSEGV, exit 139), 5/5 em um shell release+gczeal, falha idêntica a cada execução:

root@kitploit:~
SEGV no endereço 0x000000000014 (READ)
JS::shadow::Zone::gcState()  <- zone == nullptr, offset +0x14

Causa raiz

A 154 confunde os bitmaps de marcação de átomos por zona com o rastreamento de referências. Um Symbol mantido apenas fracamente — aqui, capturado como um campo Value fraco dentro de um stub IC CacheIR de Baseline — e referenciado a partir de uma zona não coletada nunca é remarcado quando a zona de átomos é coletada em um GC com escopo de zona. O resultado é uma aresta obsoleta para uma célula varrida/realocada.

O golpe fatal no build de release é um segundo bug estático: MightBeForwarded<JS::Symbol> é codificado como false, então IsForwarded retorna false sem verificar (gc/Marking-inl.h:92-97) e todo caminho de correção de ponteiro condicionado a ele silenciosamente ignora a aresta. Quando a zona de átomos é compactada, as arestas fortes são atualizadas corretamente, mas esta aresta CacheIR fraca fica permanentemente pendurada no endereço antigo do Symbol vítima. (Builds de debug detectam isso como Assertion failure: !t->isForwarded(), gc/Marking-inl.h:94.)

Como o PoC transforma a aresta pendurada em um SEGV

O PoC não apenas deixa um ponteiro obsoleto para heap reutilizável — ele faz com que a página de suporte seja desmapeada (munmap), então a próxima desreferência já causa falha.

  1. Isolamento de chunks por zona. Os pools de chunks do GC são por zona (Zone::availableChunks/fullChunks), então chunks da zona de átomos contêm apenas arenas da zona de átomos. O destino de um chunk pode ser controlado puramente por ciclos de vida de átomos/símbolos.
  2. Preparação do heap. 300 Symbols "ímã" (mantidos vivos) ocupam um chunk inicial e servem como destino da compactação. 150.000 Symbols descartáveis então preenchem ~4 novos chunks de 1 MB, de modo que o Symbol vítima cai no meio do spray em um chunk contendo apenas symbols de spray condenados.
  3. A dança do symbol mantido fracamente (linhas 21-31, frágil em relação ao bytecode — deve permanecer verbatim): c.eval(b) faz o IC de chamada de nível superior capturar o Symbol em um campo de stub fraco; b = undefined remove a última raiz forte; o spray é descartado; dois GCs com escopo de zona (gc("zone"), schedulezone(c) + schedulezone("") + gc("zone") — a string vazia agenda a zona de átomos) varrem o spray morto, compactam a vítima na arena dos ímãs, pulam a correção da aresta fraca e liberam a arena da vítima. Seu chunk agora está completamente vazio.
  4. munmap. gcparam("minEmptyChunkCount", 0) faz com que todo chunk vazio seja expirável; durante sleep(0.5) a BackgroundDecommitTask executa -> -> — um munmap real do chunk da vítima. (O decommit em nível de arena é apenas — zeros legíveis — a liberação de chunk inteiro é o único caminho de munmap, e é por isso que o isolamento de chunks na etapa 1 importa.)

Além do crash de página nula

Isto não é apenas um DoS. Escalonamentos demonstrados (PoCs e logs nos diretórios de pesquisa GC-NDAY/ e CHAIN/):

  • Endereço de falha escolhido pelo atacante (segv9): após o munmap, uma inversão de semispace de minorgc() faz o nursery reivindicar o VA liberado; um spray bruto de doubles densos escreve um qword do atacante sobre o campo zone do cabeçalho da arena obsoleta. A varredura então desreferencia attacker_ptr + 0x14 — determinístico 3/3 em 0x424242424256.
  • Controle de veredito + leituras repetíveis: o valor carregado seleciona o veredito de vivacidade da aresta fraca; um veredito "LIVE" mantém a aresta pendurada e a desreferencia novamente em todo GC principal subsequente (leituras escolhidas pelo atacante + um oráculo observável por script de 1 bit). Um veredito "DEAD" se autocura.
  • Cadeia de dois bugs: um js::Zone* real vazado por meio de um canal lateral especulativo separado foi plantado através deste refill; o coletor consumiu os metadados de arena forjados sem causar falha (uma planta de controle perturbada em 1 bit crasha), demonstrando a composição derrota-de-ASLR -> planta-de-UAF.
  • Negativo limitado: fakeobj direto através desta família de stubs é arquiteturalmente bloqueado — a compactação corrige arestas fortes corretamente, apenas arestas fracas ficam penduradas, e seus consumidores de varredura são apenas de ramificação.
Baixar ferramenta
expireEmptyChunkPool
FreeChunkPool
UnmapPages
madvise(MADV_DONTNEED)
  • A desreferência que causa a falha. O gc() final varre dados JIT: sweepJitDataOnMainThread -> ICEntry::traceWeak -> TraceWeakCacheIRStub lê o ponteiro Symbol obsoleto e então SweepingTracer::onEdge (gc/Marking.cpp:3195) realiza aritmética de chunk no endereço obsoleto para carregar o campo zone do cabeçalho da arena. A página se foi/foi zerada, então zone == nullptr, e zone->isGCSweeping() lê nullptr + 0x14 (shadow::Zone::gcState) -> SIGSEGV. No momento da falha, rcx contém o ponteiro Symbol obsoleto e rdx a base do chunk desmapeado.