## https://sploitus.com/exploit?id=D04570B6-6F8B-5B7A-8A26-F57C9D9133BF
# CVE-2024-29943, but with wasm
Because chaining a *real* Pwn2Own bug to WASM JIT shellcode is somehow more
satisfying than beating up a training bug from 2018 that politely held still
for you.
## Why this N-day replaces `Smalls.blaze()`
The original repo is built on doar-e's `Array.prototype.blaze()` β a lovely
bug, truly, except for the tiny detail that it **never existed in any shipping
Firefox**. It was a custom backdoor in a teaching build. Adorable.
**CVE-2024-29943** is the real deal: a sec-critical IonMonkey range-analysis
bug used at **Pwn2Own 2024** by Manfred Paul against actual, honest-to-god
Firefox ( OOB r/w on a Uint8Array (bounds checks? what bounds checks?)
-> corrupt adjacent ArrayBuffer (addrof / fakeobj / arb r/w, the usual)
-> hand-built WASM module, shellcode hidden in f64.const immediates
-> WasmInstanceObject -> Instance -> Code -> CodeTier -> ModuleSegment
-> bytes_ = the RWX JIT page the JIT so generously wrote for us
-> scan for our marker, patch the export's entry stub
movabs rax, shellcode ; jmp rax
-> add() now runs *our* code. Thanks, JIT. Very helpful.
```
No ROP. No `VirtualProtect`. No emscripten. `gen_wasm.py` emits a 131-byte
module by hand, because pulling in an entire toolchain to write 9 doubles
felt excessive.
The WASM-JIT-page shellcode technique itself comes from
[WasmBlazeFox](https://github.com/SneakyNachos/WasmBlazeFox). This repo is
what happens when you point it at a bug that actually ships.
## Files
- `poc.js` β jandem's minimal trigger. Crashes things. Poetry.
- `exploit.js` β the full chain. The part Mozilla's PoC left as an exercise
for the reader, except the reader is us and we brought wasm.
- `gen_wasm.py` β hand-assembles the module and verifies the round trip,
because "trust me bro" is not a build system.
- `test.gdb` β ptype/breakpoint helpers for re-deriving offsets on whatever
build you're staring at today.
## Reproducing
1. Build a vulnerable js shell: gecko-dev @
`afbdf6822c9e9f9b6d44b9ea6904cb10878126b1` (Firefox ~124, pre-124.0.1),
Linux x86-64. Yes, you actually have to build it. We're sorry.
2. Run:
```
./js --no-threads --spectre-mitigations=off poc.js # trigger only
./js --no-threads --spectre-mitigations=off exploit.js # full chain
```
Yes, `--spectre-mitigations=off`. We are aware of what year it is. The bug
needs index masking off, per the bug comments. Don't deploy this to prod,
etc., etc.
## Notes / caveats
- The wasm export is called exactly once before the hijack. Call it more and
Ion will get clever, constant-fold our shellcode into one sad double, and
ruin everyone's day. Baseline tier is where the magic lives.
- Object offsets (`WASM_INSTANCE_OFF_CODE = 0xa8`, `funcExports + 448`,
`FuncExport + 8`, ...) come from the vulnerable commit's headers. Different
build? `test.gdb` has the `ptype /o` commands. Do the homework.
- The default payload's libxul GOT deltas are from ex6's build. Recalculate
for yours, or pipe your own shellcode through `gen_wasm.py`. We're not your
shellcode butler.
## References
- https://bugzilla.mozilla.org/show_bug.cgi?id=1886849 (Mozilla's own PoC)
- https://nvd.nist.gov/vuln/detail/CVE-2024-29943
- https://www.mozilla.org/security/advisories/mfsa2024-15/
- https://github.com/bjrjk/CVE-2024-29943 (full writeup + slides)
- https://doar-e.github.io/blog/2018/11/19/introduction-to-spidermonkey-exploitation/