# Chrome Exploiting {{#include ../banners/hacktricks-training.md}} > This page provides a high-level yet **practical** overview of a modern "full-chain" exploitation workflow against Google Chrome 130 based on the research series **“101 Chrome Exploitation”** (Part-0 — Preface). > The goal is to give pentesters and exploit-developers the minimum background necessary to reproduce or adapt the techniques for their own research. ## 1. Chrome Architecture Recap Understanding the attack surface requires knowing where code is executed and which sandboxes apply. ``` +-------------------------------------------------------------------------+ | Chrome Browser | | | | +----------------------------+ +-----------------------------+ | | | Renderer Process | | Browser/main Process | | | | [No direct OS access] | | [OS access] | | | | +----------------------+ | | | | | | | V8 Sandbox | | | | | | | | [JavaScript / Wasm] | | | | | | | +----------------------+ | | | | | +----------------------------+ +-----------------------------+ | | | IPC/Mojo | | | V | | | +----------------------------+ | | | | GPU Process | | | | | [Restricted OS access] | | | | +----------------------------+ | | +-------------------------------------------------------------------------+ ``` Layered defence-in-depth: * **V8 sandbox** (Isolate): memory permissions are restricted to prevent arbitrary read/write from JITed JS / Wasm. * **Renderer ↔ Browser split** ensured via **Mojo/IPC** message passing; the renderer has *no* native FS/network access. * **OS sandboxes** further contain each process (Windows Integrity Levels / `seccomp-bpf` / macOS sandbox profiles). A *remote* attacker therefore needs **three** successive primitives: 1. Memory corruption inside V8 to get **arbitrary RW inside the V8 heap**. 2. A second bug allowing the attacker to **escape the V8 sandbox to full renderer memory**. 3. A final sandbox-escape (often logic rather than memory corruption) to execute code **outside of the Chrome OS sandbox**. --- ## 2. Stage 1 – WebAssembly Type-Confusion (CVE-2025-0291) A flaw in TurboFan’s **Turboshaft** optimisation mis-classifies **WasmGC reference types** when the value is produced and consumed inside a *single basic block loop*. Effect: * The compiler **skips the type-check**, treating a *reference* (`externref/anyref`) as an *int64*. * Crafted Wasm allows overlapping a JS object header with attacker-controlled data → addrOf() & fakeObj() **AAW / AAR primitives**. Minimal PoC (excerpt): ```WebAssembly (module (type $t0 (func (param externref) (result externref))) (func $f (param $p externref) (result externref) (local $l externref) block $exit loop $loop local.get $p ;; value with real ref-type ;; compiler incorrectly re-uses it as int64 in the same block br_if $exit ;; exit condition keeps us single-block br $loop end end) (export "f" (func $f))) ``` Trigger optimisation & spray objects from JS: ```js const wasmMod = new WebAssembly.Module(bytes); const wasmInst = new WebAssembly.Instance(wasmMod); const f = wasmInst.exports.f; for (let i = 0; i < 1e5; ++i) f({}); // warm-up for JIT // primitives let victim = {m: 13.37}; let fake = arbitrary_data_backed_typedarray; let addrVict = addrOf(victim); ``` Outcome: **arbitrary read/write within V8**. --- ## 3. Stage 2 – Escaping the V8 Sandbox (issue 379140430) When a Wasm function is tier-up-compiled, a **JS ↔ Wasm wrapper** is generated. A signature-mismatch bug causes the wrapper to write past the end of a trusted **`Tuple2`** object when the Wasm function is re-optimised *while still on the stack*. Overwriting the 2 × 64-bit fields of the `Tuple2` object yields **read/write on any address inside the Renderer process**, effectively bypassing the V8 sandbox. Key steps in exploit: 1. Get function into **Tier-Up** state by alternating turbofan/baseline code. 2. Trigger tier-up while keeping a reference on the stack (`Function.prototype.apply`). 3. Use Stage-1 AAR/AAW to find & corrupt the adjacent `Tuple2`. Wrapper identification: ```js function wrapperGen(arg) { return f(arg); } %WasmTierUpFunction(f); // force tier-up (internals-only flag) wrapperGen(0x1337n); ``` After corruption we possess a fully-featured **renderer R/W primitive**. --- ## 4. Stage 3 – Renderer → OS Sandbox Escape (CVE-2024-11114) The **Mojo** IPC interface `blink.mojom.DragService.startDragging()` can be called from the Renderer with *partially trusted* parameters. By crafting a `DragData` structure pointing to an **arbitrary file path** the renderer convinces the browser to perform a *native* drag-and-drop **outside the renderer sandbox**. Abusing this we can programmatically “drag” a malicious EXE (previously dropped in a world-writable location) onto the Desktop, where Windows automatically executes certain file-types once dropped. Example (simplified): ```js const payloadPath = "C:\\Users\\Public\\explorer.exe"; chrome.webview.postMessage({ type: "DragStart", data: { title: "MyFile", file_path: payloadPath, mime_type: "application/x-msdownload" } }); ``` No additional memory corruption is necessary – the **logic flaw** gives us arbitrary file execution with the user’s privileges. --- ## 5. Full Chain Flow 1. **User visits** malicious webpage. 2. **Stage 1**: Wasm module abuses CVE-2025-0291 → V8 heap AAR/AAW. 3. **Stage 2**: Wrapper mismatch corrupts `Tuple2` → escape V8 sandbox. 4. **Stage 3**: `startDragging()` IPC → escape OS sandbox & execute payload. Result: **Remote Code Execution (RCE)** on the host (Chrome 130, Windows/Linux/macOS). --- ## 6. Lab & Debugging Setup ```bash # Spin-up local HTTP server w/ PoCs npm i -g http-server git clone https://github.com/Petitoto/chromium-exploit-dev cd chromium-exploit-dev http-server -p 8000 -c -1 # Windows kernel debugging "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbgx.exe" -symbolpath srv*C:\symbols*https://msdl.microsoft.com/download/symbols ``` Useful flags when launching a *development* build of Chrome: ```bash chrome.exe --no-sandbox --disable-gpu --single-process --js-flags="--allow-natives-syntax" ``` --- ## Takeaways * **WebAssembly JIT bugs** remain a reliable entry-point – the type system is still young. * Obtaining a second memory-corruption bug inside V8 (e.g. wrapper mismatch) greatly simplifies **V8-sandbox escape**. * Logic-level weaknesses in privileged Mojo IPC interfaces are often sufficient for a **final sandbox escape** – keep an eye on *non-memory* bugs. ## References * [101 Chrome Exploitation — Part 0 (Preface)](https://opzero.ru/en/press/101-chrome-exploitation-part-0-preface/) * [Chromium security architecture](https://chromium.org/developers/design-documents/security) {{#include ../banners/hacktricks-training.md}}