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-15718-who-put-ptrs-in-my-wasm — Cadeia de exploit PoC para CVE-2026-15718: compilador baseline wasm do SpiderMonkey array.fill missing-sync -> ponteiro inválido -> addrOf/fakeobj -> R/W arbitrário -> RCE | Kitploit
Ferramentas/GitHubGitHub/sneakynachos/cve-2026-15718-who-put-ptrs-in-my-wasm
Análise de VulnerabilidadesExploraçãoEngenharia ReversaSegurança WebDesenvolvimento de PayloadsExploração de Binários
GitHubsneakynachos/cve-2026-15718-who-put-ptrs-in-my-wasm

CVE-2026-15718-who-put-ptrs-in-my-wasm

Cadeia de exploit PoC para CVE-2026-15718: compilador baseline wasm do SpiderMonkey array.fill missing-sync -> ponteiro inválido -> addrOf/fakeobj -> R/W arbitrário -> RCE

Ver Repositório
1há 1 diaAinda 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

CVE-2026-15718 — quem colocou ponteiros no meu wasm

Cadeia de exploits de prova de conceito para CVE-2026-15718, uma má compilação por falta de sync() no compilador baseline do WebAssembly do SpiderMonkey da Mozilla (componente "JavaScript: WebAssembly"). Um único array.fill de zero iterações gera uma primitiva fakeobj; a cadeia evolui para leitura/escrita arbitrária do processo hospedeiro e execução arbitrária de código nativo (posix_spawnp("/bin/sh", ...)).

  • CVE: CVE-2026-15718 (CWE-763, liberação de ponteiro inválido)
  • Afetados: Firefox < 152.0.6, Firefox ESR < 140.13, Thunderbird < 140.13
  • Corrigido em: Firefox 152.0.6 / ESR 140.13 / Thunderbird 140.13, 14/07/2026
  • Bug upstream: Mozilla Bug 2045443 (MFSA-2026-67)
  • Commit da correção: 4441102e62e8 ("Bug 2045443", uma linha)

Causa raiz

BaseCompiler::emitArrayFill() () emite o laço de preenchimento do sem chamar primeiro:

js/src/wasm/WasmBaselineCompile.cpp
array.fill
sync()
root@kitploit:~
   if (elementType.isRefRepr()) {
     freePtr(RegPtr(PreBarrierReg));
   }

+  sync();
+
   // Perform the fill loop using `numElements` as the loop variable ...

sync() esvazia a pilha de valores do compilador baseline (stk_), movendo os registradores para a pilha de máquina. A pós-barreira imprecisa por iteração do laço de preenchimento (emitPostBarrierEdgeImprecise) chama sync() internamente — mas somente se o laço executar. O rótulo de saída do laço (done) é um ponto de junção de dois caminhos:

  • laço executou pelo menos uma vez (elementos reftype): stk_ foi sincronizado — todo operando reside em um slot da pilha de máquina;
  • zero iterações (numElements == 0): stk_ não foi tocado — operandos ainda residem apenas em registradores.

O modelo estático do compilador após a junção sempre reflete o caminho sincronizado, então o código emitido depois de array.fill lê operandos de slots da pilha que uma execução de zero iterações nunca escreveu. Um operando reftype lido dessa forma é um ponteiro inválido (obsoleto) (CWE-763).

Primitiva: técnica de slot plant/read

A dessincronização é bidirecional entre duas funções wasm com molduras idênticas:

  • plant (n = 1, laço executa): o sync() dentro do laço escreve um valor no slot — uma ref real (addrOf) ou um i64 controlado (setup do fakeobj);
  • read (n = 0, zero iterações): o slot nunca é escrito; a função gêmea lê o slot obsoleto de volta — como i64 (vazamento) ou como (ref $t) (fakeobj).

Cadeia do exploit (poc/)

ArquivoEstágioResultado
poc-min.js (+ gen_trigger.py)demonstração da dessincronizaçãoo caminho de controle retorna o valor correto; o caminho de zero iterações retorna um ponteiro-lixo lido do slot nunca escrito
chain.js (+ gen_chain.py, chain.tpl.js, build.sh)cadeia completaaddrOf + fakeobj → WasmArrayObject falso → R/W arbitrário → vazamento da base da XUL → varredura de imports Mach-O em tempo de execução → funcref forjado → posix_spawnp("/bin/sh", ["-c", "touch /tmp/CVE-2026-15718-PWNED"])

Detalhes dos estágios em chain.js:

  1. plantSpray/plantCmd/plantFun/plantExt + leak — addrOf para arrays wasm, funcrefs e objetos JS (externref).
  2. sprayV + fakeRd/fakeWr — fakeobj; WasmArrayObject falso (numElements_ @+16, data_ @+24, elementos inline @+40) com a janela falsa mantida em um array fora de linha (allocado via malloc) para que o GC não possa movê-la durante a varredura.
  3. Vaze a entrada nativa de uma JSFunction (+0x20), varra para trás página a página pelo magic do Mach-O (0xfeedfacf) → base da XUL.
  4. Resolução de símbolos totalmente dinâmica: percorra os load commands Mach-O da XUL por meio da leitura arbitrária (LC_SEGMENT_64/LC_SYMTAB/LC_DYSYMTAB + tabela de símbolos indireta) para localizar a entrada __stubs de _posix_spawnp. Sem offsets fixos; o stub executa lazy binding na primeira chamada.
  5. Forje um funcref (typeDef @+0x40 copiado de um ref.func real, alvo da chamada @+0x38 = endereço do stub) e invoque-o via call_ref com posix_spawnp(pid, "/bin/sh", 0, 0, [sh, -c, cmd], 0).

Execução

Testado com um xpcshell (ou o shell js / navegador) compilado a partir de uma árvore anterior à 152.0.6 (a build de referência aqui é Firefox 149.0a1, 14/01/2026):

root@kitploit:~
# demonstração mínima da dessincronização
xpcshell poc/poc-min.js

# cadeia completa (regenera chain.js a partir do template + gerador)
(cd poc && sh build.sh)
rm -f /tmp/CVE-2026-15718-PWNED
xpcshell poc/chain.js    # cria /tmp/CVE-2026-15718-PWNED
ls -l /tmp/CVE-2026-15718-PWNED

O harness define javascript.options.wasm_optimizingjit=false para fixar o tier baseline durante a longa varredura do Mach-O (o bug é exclusivo do baseline; no navegador, o gatilho executa bem abaixo do limite de tier-up, então isso não é necessário lá). tools/xul_slots.py é um validador offline que lista os slots nomeados de stub/GOT da XUL (usado para verificar cruzadamente o walker em tempo de execução).

Notas de portabilidade

Os offsets são para macOS arm64, nesta árvore/build exata (WasmArrayObject { +16 numElements, +24 data_, +40 inline }, JSFunction native @ +0x20, WasmFuncRef { +0x38/+0x48 alvo da chamada, +0x40 typeDef }). Todos eles são re-derivados em tempo de execução pelos autotestes da cadeia; apenas os layouts das estruturas são assumidos. Sem preocupações com PAC (XUL é um binário arm64, não arm64e); o stub de lazy binding resolve o alvo na primeira chamada, então não são necessários offsets de dyld shared cache.

Escopo / limitações honestas

Este PoC executa em um processo de shell sem sandbox. Em um ataque real ao Firefox, a cadeia termina dentro do processo de conteúdo, onde a sandbox do macOS nega posix_spawnp — é necessário um bug separado de escape da sandbox do SO para um comprometimento total (veja, por exemplo, a análise de estágio 2 em CVE-2026-2796-and-CVE-2026-2768-escape-the-wasm-box).

Mitigações

  • Atualize para Firefox / Thunderbird ≥ 152.0.6 (ESR ≥ 140.13).
  • Defesa em profundidade: javascript.options.wasm=false bloqueia o vetor de gatilho.

Referências

  • MFSA-2026-67
  • NVD: CVE-2026-15718
  • Correção: https://github.com/mozilla-firefox/firefox/commit/4441102e62e8

Aviso de isenção

Apenas para pesquisa de segurança, educação e testes defensivos. A vulnerabilidade está corrigida nas versões atuais do Firefox/Thunderbird. Não use contra sistemas que você não possui ou para os quais não tem autorização explícita para testar.

Baixar ferramenta