Chrome Exploiting

Reading time: 6 minutes

tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks

Ta strona oferuje ogólny, ale praktyczny przegląd nowoczesnego "pełnego łańcucha" procesu eksploatacji przeciwko Google Chrome 130, oparty na serii badań “101 Chrome Exploitation” (Część-0 — Wstęp). Celem jest dostarczenie pentesterom i deweloperom exploitów minimalnej wiedzy niezbędnej do powtórzenia lub dostosowania technik do własnych badań.

1. Przegląd architektury Chrome

Zrozumienie powierzchni ataku wymaga wiedzy o tym, gdzie kod jest wykonywany i które piaskownice mają zastosowanie.

+-------------------------------------------------------------------------+
|                             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 (Izolacja): uprawnienia pamięci są ograniczone, aby zapobiec dowolnemu odczytowi/zapisowi z JITowanego JS / Wasm.
  • Podział Renderer ↔ Przeglądarka zapewniony przez Mojo/IPC przesyłanie wiadomości; renderer nie ma dostępu do natywnego FS/sieci.
  • OS sandboksy dodatkowo ograniczają każdy proces (Windows Integrity Levels / seccomp-bpf / profile sandboxów macOS).

Zatem zdalny atakujący potrzebuje trzech kolejnych prymitywów:

  1. Korupcja pamięci wewnątrz V8, aby uzyskać dowolny RW wewnątrz sterty V8.
  2. Druga wada pozwalająca atakującemu na ucieczkę z sandboxu V8 do pełnej pamięci renderera.
  3. Ostateczna ucieczka z sandboxu (często logika, a nie korupcja pamięci), aby wykonać kod poza sandboxem Chrome OS.

2. Etap 1 – WebAssembly Type-Confusion (CVE-2025-0291)

Wada w optymalizacji Turboshaft TurboFan błędnie klasyfikuje typy referencyjne WasmGC, gdy wartość jest produkowana i konsumowana wewnątrz pojedynczej pętli bloku podstawowego.

Efekt:

  • Kompilator pomija sprawdzenie typu, traktując referencję (externref/anyref) jako int64.
  • Opracowany Wasm pozwala na nakładanie nagłówka obiektu JS z danymi kontrolowanymi przez atakującego → addrOf() & fakeObj() AAW / AAR prymitywy.

Minimalny PoC (fragment):

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)))

Optymalizacja wyzwalaczy i obiekty spray z 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: dowolne odczyty/zapisy w V8.


3. Etap 2 – Ucieczka z piaskownicy V8 (problem 379140430)

Gdy funkcja Wasm jest kompilowana w trybie tier-up, generowany jest wrapper JS ↔ Wasm. Błąd związany z niezgodnością sygnatury powoduje, że wrapper zapisuje poza końcem zaufanego obiektu Tuple2, gdy funkcja Wasm jest ponownie optymalizowana wciąż na stosie.

Nadpisanie 2 × 64-bitowych pól obiektu Tuple2 umożliwia odczyt/zapis na dowolnym adresie wewnątrz procesu Renderera, skutecznie omijając piaskownicę V8.

Kluczowe kroki w exploicie:

  1. Wprowadź funkcję w stan Tier-Up, przełączając między kodem turbofan/baseline.
  2. Wyzwól tier-up, utrzymując odniesienie na stosie (Function.prototype.apply).
  3. Użyj AAR/AAW z Etapu-1, aby znaleźć i uszkodzić sąsiedni Tuple2.

Identyfikacja wrappera:

js
function wrapperGen(arg) {
return f(arg);
}
%WasmTierUpFunction(f);          // force tier-up (internals-only flag)
wrapperGen(0x1337n);

Po uszkodzeniu posiadamy w pełni funkcjonalny renderer R/W primitive.


4. Etap 3 – Ucieczka z piaskownicy Renderer → OS (CVE-2024-11114)

Interfejs IPC Mojo blink.mojom.DragService.startDragging() może być wywoływany z Renderer z częściowo zaufanymi parametrami. Tworząc strukturę DragData wskazującą na dowolną ścieżkę pliku, renderer przekonuje przeglądarkę do wykonania natywnego przeciągania i upuszczania poza piaskownicą renderera.

Wykorzystując to, możemy programowo „przeciągnąć” złośliwy plik EXE (wcześniej umieszczony w lokalizacji z możliwością zapisu dla wszystkich) na pulpit, gdzie Windows automatycznie wykonuje określone typy plików po ich upuszczeniu.

Przykład (uproszczony):

js
const payloadPath = "C:\\Users\\Public\\explorer.exe";

chrome.webview.postMessage({
type: "DragStart",
data: {
title: "MyFile",
file_path: payloadPath,
mime_type: "application/x-msdownload"
}
});

Nie jest konieczne dodatkowe uszkodzenie pamięci – błąd logiczny daje nam możliwość wykonania dowolnego pliku z uprawnieniami użytkownika.


5. Pełny przepływ łańcucha

  1. Użytkownik odwiedza złośliwą stronę internetową.
  2. Etap 1: Moduł Wasm wykorzystuje CVE-2025-0291 → sterta V8 AAR/AAW.
  3. Etap 2: Niedopasowanie opakowania uszkadza Tuple2 → ucieczka z piaskownicy V8.
  4. Etap 3: startDragging() IPC → ucieczka z piaskownicy OS i wykonanie ładunku.

Wynik: Zdalne wykonanie kodu (RCE) na hoście (Chrome 130, Windows/Linux/macOS).


6. Ustawienia laboratorium i debugowania

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

Przydatne flagi podczas uruchamiania development builda Chrome:

bash
chrome.exe --no-sandbox --disable-gpu --single-process --js-flags="--allow-natives-syntax"

Wnioski

  • Błędy JIT WebAssembly pozostają niezawodnym punktem wejścia – system typów jest wciąż młody.
  • Uzyskanie drugiego błędu korupcji pamięci wewnątrz V8 (np. niedopasowanie wrappera) znacznie upraszcza ucieczkę z piaskownicy V8.
  • Słabości na poziomie logiki w uprzywilejowanych interfejsach IPC Mojo są często wystarczające do ostatecznej ucieczki z piaskownicy – zwracaj uwagę na błędy niepamięciowe.

Odniesienia

tip

Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Ucz się i ćwicz Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Wsparcie dla HackTricks