Sploitus

Exploit for Type Confusion in Mozilla Firefox

githubexploit Β· 2026-08-20

Exploit Code

README101 lines
## https://sploitus.com/exploit?id=C27C317E-CC21-5FC5-8EEB-BA10DFD85D34
# CVE-2026-2796 β€” SpiderMonkey WebAssembly Sandbox Escape

Proof-of-concept exploit chain for **CVE-2026-2796**, a JIT miscompilation /
type-confusion in Mozilla SpiderMonkey's WebAssembly import optimization
("JavaScript: WebAssembly" component). A crafted wasm module obtains
**arbitrary read/write of the entire host process** and **arbitrary native
code execution**, escaping the WebAssembly sandbox.

- **CVE:** CVE-2026-2796 (CWE-843, type confusion)
- **Affected:** Firefox () &&
+      boundThis.toObject().as().isWasm()) {
+    return nullptr;
+  }
```

With the check missing, the import is treated as an *originally-wasm*
function: the JS wrapper β€” and with it the **signature check** β€” is skipped.
A wasm function can therefore be invoked through a declared import type that
does not match its real type. Values pass through unchanged in registers;
only their *interpretation* changes (e.g. an attacker-controlled `i64` is
used as a `(ref $t)` GC pointer, and vice versa).

## Exploit chain (poc/)

| File | Stage | Result |
|---|---|---|
| `poc-crash.js` | Signature confusion | `i64.const 0xDEADBEEF` dereferenced as a funcref pointer β†’ SIGSEGV at `0xdeadbf2f` |
| `poc-addrof.js` | addrOf + fakeobj | Confusion both directions (`i64` ↔ `(ref $t)`) β†’ fake `WasmArrayObject` (`numElements_` @+16, `data_` @+24, inline elements @+40) β†’ **arbitrary R/W anywhere in the process** |
| `poc-recon.js` | Layout recon | JSFunction native ptr @+0x20 β†’ binary base leak; `WasmFuncRef` typeDef ptr @+0x40 |
| `poc-forge.js` | Control flow | Forged funcref passes the `call_ref` type check; **call target loaded from [funcref+0x38]** |
| `poc-rce.js` | Code execution | Forged funcref β†’ `system("touch /tmp/CVE-2026-2796-PWNED")` via leaked `system()` (binary base + GOT entry @ base+0x11d47b0) |

The confusion primitive is obtained exactly as in Mozilla's own regression
test (`js/src/jit-test/tests/wasm/regress/bug2013165.js`): import
`Function.prototype.call.bind(wasmExport)` into a second module whose import
declaration carries a different signature, then `ref.func` + `call_ref`.

## Building the vulnerable shell

```sh
# Firefox source @ 2fbc0748c460b38fc95407a3f14c41d12fb12026 (2026-01-14,
# Firefox 148 nightly β€” predates the fix). Any pre-148 revision works.
cd js/src
../../configure --enable-debug --enable-optimize --without-intl-api \
  --enable-project=js   # objdir e.g. js/src/_obj
cd _obj && make -j8
# binary: dist/bin/js   (reports "JavaScript-C149.0a1")
```

## Running

```sh
JS=/path/to/dist/bin/js
$JS poc/poc-crash.js     # SIGSEGV at 0xdeadbf2f
$JS poc/poc-addrof.js    # prints [+] arbitrary read OK / write OK
$JS poc/poc-recon.js     # dumps JSFunction / WasmFuncRef memory
$JS poc/poc-forge.js     # crashes with PC = planted canary
rm -f /tmp/CVE-2026-2796-PWNED
$JS poc/poc-rce.js       # creates /tmp/CVE-2026-2796-PWNED via system()
```

On a patched build (Firefox β‰₯ 148), `poc-crash.js` instead throws
`TypeError: bad type` β€” the signature check is restored.

## Portability notes

Offsets are for **macOS arm64** (`js` shell, this exact revision/build flags):
`WasmArrayObject` { +16 numElements, +24 data_, +40 inline data },
`JSFunction` native @ +0x20, `WasmFuncRef` { +0x40 typeDef, +0x38 call
target }. They are empirically validated at runtime by the PoCs' self-tests;
other builds/architectures need re-derivation (the recon PoC automates most
of it). No PAC on arm64 (non-arm64e) binaries; JIT regions are not writable
at call time, so the chain hijacks an existing call target instead of
injecting code.

## Scope / honest limitations

This escapes the **wasm engine sandbox** (linear-memory / GC confinement)
and yields native code execution *in the current process*. In a real browser
attack this lands inside the Firefox **content process**; escaping the OS
sandbox (the "second bug": IPC confusion or kernel exploit) is a separate
problem and is not part of this PoC.

## Mitigations

- Update to Firefox / Thunderbird β‰₯ 148.
- Defense in depth: `javascript.options.wasm=false` blocks the trigger vector.

## References

- [MFSA-2026-13](https://www.mozilla.org/security/advisories/mfsa2026-13/)
- [NVD: CVE-2026-2796](https://nvd.nist.gov/vuln/detail/CVE-2026-2796)
- Fix: https://github.com/mozilla-firefox/firefox/commit/e2acef6711967949cd0825869034165383c482e1
- Tests: https://github.com/mozilla-firefox/firefox/commit/0605ac40b002d576688190a5b9921b8dcd1b6b96

## Disclaimer

For security research, education, and defensive testing only. The
vulnerability is patched in current Firefox/Thunderbird releases. Do not use
against systems you do not own or have explicit authorization to test.