
Catena completa per Firefox: CVE-2026-2796 confusione di tipi in wasm -> RCE del processo contenuto, più CVE-2026-2768 analisi di escape del processo padre (entrambi corretti in Firefox 148)
Ricerca sullo sfruttamento di Firefox a catena completa: una type confusion in WebAssembly per l'esecuzione di codice nel renderer, concatenata a un bug del processo padre per una fuga dalla sandbox. Entrambi i bug sono stati corretti in Firefox 148 (MFSA-2026-13); il target qui è un albero Firefox 148-nightly @ 2fbc0748c4 (2026-01-14), che precede entrambe le correzioni.
page loads crafted wasm module
│
CVE-2026-2796: Function.prototype.call.bind unwrap skips signature check
│ → i64 ↔ (ref $t) confusion → addrOf/fakeobj
│ → fake WasmArrayObject → arbitrary R/W in the CONTENT process
│ → forged WasmFuncRef → hijack call target ([funcref+0x38])
▼
native code exec INSIDE the sandboxed content process (sbLevel 3)
│ (sandbox blocks exec/fork — need a parent bug)
▼
CVE-2026-2768: forge IndexedDB add/put IPC with out-of-range
mAutoIncrementKeyOffsets (ParamTraits<Key> validates nothing)
│ → parent writes 8 bytes at attacker-controlled offset
▼
memory corruption in the UNSANDBOXED parent process = full escape
| Demo | Dove | Risultato |
|---|---|---|
poc/shell/poc-crash.js | js shell | 0xDEADBEEF dereferenziato come funcref → SIGSEGV a 0xdeadbf2f |
poc/shell/poc-addrof.js | js shell | i self-test di R/W arbitrario passano |
poc/shell/poc-forge.js | js shell | controllo del PC: crash sul canary piazzato |
poc/shell/poc-rce.js | js shell | system("id > /tmp/CVE-2026-2796-PWNED; open -a Calculator") — il file contiene uid=501(sid) ..., Calculator si apre |
poc/browser/stage1-browser.html | Nightly (sbLevel 3 content) | R/W arbitrario nella tab in sandbox; il funcref contraffatto salta a 0x4141414141414141 → la tab crasha, il padre sopravvive |
poc/browser/stage1-browser-cmd.html | Nightly (sbLevel 3 content) | fa leak della base XUL, risolve posix_spawnp (0x187xxxxx), la chiama con /bin/sh -c "touch /tmp/PWNED-FROM-CONTENT" → la sandbox di macOS nega l'exec: il file non viene creato, la pagina resta intatta — prova che la RCE nel content da sola ≠ esecuzione di comandi |
poc/browser/sandbox-proof.html | Nightly (sbLevel 3 content) | exec nativa entro le regole della sandbox: getpid() restituisce il PID reale della tab (coincide con ps), e la write(1, ...) libc grezza finisce nel log di terminale del browser — niente fork/exec, nessuna apertura di file |
poc/browser/fd3-proof.html | Nightly (sbLevel 3 content) | scrive 32 byte grezzi su fd 3 (la socket IPDL del padre): il parser IPC del padre consuma byte dell'attaccante (Message needs unreceived descriptors ... num_handles:33), scarta il messaggio e uccide la tab ("Exiting due to channel error") — la primitiva di trasporto che lo stage 2 trasforma in arma con messaggi IndexedDB ben formati ma malevoli |
poc/browser/stage2-trigger.html | Nightly | raggiungibilità in puro JS del percorso del bug nel padre (chiavi di indice auto-incrementali ) |
Vedi docs/full-escape.md per l'analisi della causa radice dello stage 2 (diff delle correzioni, serializzazione IPC, strategia di sfruttamento).
# Tree: mozilla-firefox/firefox @ 2fbc0748c4 (2026-01-14, pre-FF148)
# 1) js shell (stage-1 development, unsandboxed):
cd js/src && ../../configure --enable-debug --enable-optimize \
--without-intl-api --enable-project=js && cd _obj && make -j8
# 2) full browser (stage 2). mozconfig:
# export CC=/usr/bin/clang ; export CXX=/usr/bin/clang++
# ac_add_options --enable-application=browser
# ac_add_options --disable-debug --enable-optimize
# ac_add_options --disable-crashreporter --disable-updater --disable-tests
# ac_add_options --enable-sandbox
# ac_add_options --without-wasm-sandboxed-libraries
# requires: node, cbindgen, rustc >= 1.87, macOS CLT SDK
# local build notes:
# - private header sys/fileport.h shim added to objdir dist/include/sys/
# - one compile guard added: NSGlassEffectView (macOS 26 SDK symbol) wrapped
# in #if __MAC_OS_X_VERSION_MAX_ALLOWED >= 260000 in widget/cocoa/
# nsCocoaWindow.mm (build-environment fix, no security impact)
Esegui le PoC del browser: avvia obj-browser/dist/Nightly.app con un profilo che imposta browser.dom.window.dump.enabled=true, apri i file HTML tramite file://, controlla lo stdout per l'output di dump(). Il crash della tab appare come process <pid> exited on signal 10 nel log del processo padre.
WasmArrayObject: numElements @+16, data ptr @+24, dati inline @+40.
WasmFuncRef: typeDef ptr @+0x40, call target @+0x38. Puntatore nativo di JSFunction @+0x20. js shell: os_system @ base+0x1a9f8, GOT di system @ base+0x11d47b0. Browser: base XUL individuata scandendo all'indietro da un puntatore a codice nativo WebIDL (JSFunction di console.log +0x20) fino al magic 0xfeedfacf Mach-O; GOT di _posix_spawnp @ XUL+0x9bb7d30, GOT di _getpid @ XUL+0x9bb7600, GOT di _write @ XUL+0x9bb87e0. Le finestre dei fake-array devono risiedere in un array out-of-line (malloc'd) — gli oggetti inline/nursery vengono spostati dal GC durante le scansioni lunghe.
L'esecuzione di codice nel renderer tramite CVE-2026-2796 è pienamente dimostrata (shell e browser). L'analisi della fuga dalla sandbox di CVE-2026-2768 è verificata a livello di codice sorgente contro il diff della correzione; il trigger end-to-end live della corruzione del padre è un lavoro in corso (vedi docs). Questa ricerca è a scopo difensivo/didattico; le vulnerabilità sono state corrette nelle release attuali.
e2acef67 di mozilla-firefox/firefoxc5dea6ec di mozilla-firefox/firefoxEsclusivamente per ricerca sulla sicurezza, formazione e test difensivi. Non utilizzare su sistemi che non possiedi o per cui non hai esplicita autorizzazione al test.
[1,2,3,4]