Skip to content

Latest commit

 

History

History
139 lines (104 loc) · 5.13 KB

File metadata and controls

139 lines (104 loc) · 5.13 KB

v8CTF M150 exploit PoC

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.

What the PoC does

The page combines three public V8 issues:

  1. CVE-2026-15903 creates an out-of-bounds byte-read oracle and leaks a compressed V8 object address.
  2. CVE-2026-15776 leaves a stale HeapNumber reference in RegExp.lastIndex. Heap grooming reclaims the slot as a forged JSArray, producing arbitrary read/write inside the V8 pointer-compression cage.
  3. Chromium issue 537948358 lets a hidden JSPI WasmResume builtin 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.

Running it

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 8000

Then 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.html

The 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.

Expected output

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.

Important limitations

  • Exact Chrome/V8 build, architecture, object layouts, offsets, and ROP gadgets are hard-coded.
  • ASLR is handled per renderer through an ExternalString resource-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.

Attribution

This is an n-day integration and exact-build adaptation. I did not discover the initial vulnerabilities.

Himanshu Anand performed the chain integration, exact-build adaptation, diagnostic work, live validation, and write-up with disclosed LLM assistance.

Responsible use

This code is published for education, reproducibility, and defensive research. Use it only on systems you own or have explicit permission to test.