The single-page proof of concept that recovered a real flag from Google's v8CTF M150 challenge.
v8CTF{1785916837:02b9910f32b5064c14c693a910748736031da940}
The exploit targets one historical build only:
| Component | Exact target |
|---|---|
| Chrome for Testing | 150.0.7871.46, Linux x86-64 |
| V8 | 15.0.245.13 |
| V8 revision | 968f19a8970f8d91702d86f0ec1522f3909781b7 |
| PoC | exp.html |
| PoC SHA-256 | 5027829e71ecc9cbd74b7490bb44b59ac7cb41f759f118a202fbfa6a651f9707 |
Full technical write-up: I had some free time, so I tried to pwn V8.
The page combines three public V8 issues:
- CVE-2026-15903 creates an out-of-bounds byte-read oracle and leaks a compressed V8 object address.
- CVE-2026-15776 leaves a stale
HeapNumberreference inRegExp.lastIndex. Heap grooming reclaims the slot as a forgedJSArray, producing arbitrary read/write inside the V8 pointer-compression cage. - Chromium issue 537948358 lets a hidden JSPI
WasmResumebuiltin and its JS Dispatch Table entry disagree about fixed-arity stack cleanup. The mismatch provides a native stack pivot outside the V8 sandbox.
The final ROP chain reuses code already present in the exact Chrome binary:
open64("/flag/flag", O_RDONLY)
read(fd, writable_buffer, 0x100)
write(2, writable_buffer, bytes_read)
_exit(42)
There is no shellcode, reverse shell, persistence, or callback.
This is an exact-build historical exploit, not a script for current Chrome. Use an isolated Linux VM or disposable research environment that you own.
Download the official Linux x86-64 target build:
https://storage.googleapis.com/chrome-for-testing-public/150.0.7871.46/linux64/chrome-linux64.zip
The page automatically enables the complete chain when its URL path ends in
/exp.html. Serve it with that filename:
python3 -m http.server 8000Then launch the exact Chrome binary in the same challenge-style configuration:
./chrome-linux64/chrome \
--headless=new \
--no-sandbox \
--enable-logging=stderr \
--user-data-dir=/tmp/v8ctf-m150-profile \
http://127.0.0.1:8000/exp.htmlThe PoC expects a readable file at /flag/flag. For local testing, create only
a harmless synthetic file inside your isolated environment, for example:
V8CTF{local_test_only}
Do not run an obsolete browser with --no-sandbox on a normal workstation.
The original challenge intentionally disabled Chrome's process sandbox. The PoC
escapes the in-process V8 sandbox into the native renderer; it does not claim a
Chrome broker/OS sandbox escape, host escape, or container escape.
Before native control, successful stages emit markers such as:
V8CTF-CAGE-RW:15903-feedback:ordinary-oob-isNaN=true
V8CTF-CAGE-RW:15903-addrof:victim=0x........:count=64
V8CTF-CAGE-RW:jspi-prepared:moduleA=1:moduleB=1:promises=2
If the complete chain succeeds, the ORW stage prints the contents of
/flag/flag to Chrome's captured stderr.
Heap grooming is probabilistic. The preserved direct package succeeded in 1 of 5 fresh local runs. A separate tunnel-hosted tuning batch reached 5 of 10 under different delivery conditions. Neither met v8CTF's required 80% reliability. One flag proves exploitability; it does not prove reliable competition reproduction.
- Exact Chrome/V8 build, architecture, object layouts, offsets, and ROP gadgets are hard-coded.
- ASLR is handled per renderer through an
ExternalStringresource-vtable leak. - Heap layout and garbage-collection timing can make the exploit fail silently or crash the renderer.
- The successful challenge configuration used
--no-sandbox. - This repository does not include live-service clients, challenge automation, proof-of-work tooling, raw service logs, or submission archives.
This is an n-day integration and exact-build adaptation. I did not discover the initial vulnerabilities.
- CVE-2026-15903 V8 fix
- CVE-2026-15776 V8 fix
- Salvatore Gulizia (
Serotav): CVE-2026-15776: From Regex to RCE - Jihyeon Jeong (
p0-tato), Chromium issue 537948358: JSPI/JDT fix - Exact V8 source snapshot
- Official v8CTF rules
Himanshu Anand performed the chain integration, exact-build adaptation, diagnostic work, live validation, and write-up with disclosed LLM assistance.
This code is published for education, reproducibility, and defensive research. Use it only on systems you own or have explicit permission to test.