옵션
집 Skill 브라우저 자동화 browser-exploitation-v8

browser-exploitation-v8

yaklang/hack-skills yaklang/hack-skills

브라우저 및 V8 익스플로잇 가이드. JIT 타입 혼동, 잘못된 경계 제거, V8 샌드박스 우회 등 자바스크립트 엔진 취약점을 악용하여 Chrome/Chromium에서 렌더러 RCE 및 샌드박스 탈출을 달성할 때 사용합니다.

...모든 것을 확장하십시오
17
업데이트 된 시간 2026년 8월 25일

소개 browser-exploitation-v8

Google의 V8(Chrome/Chromium) 내 자바스크립트 엔진 취약점을 악용하기 위한 보안 테스트 가이드입니다. 이 문서는 V8 컴파일 파이프라인을 상세히 설명합니다. 소스 코드가 AST(구문 분석 트리)로 파싱된 후 Ignition 바이트코드로 해석되고, Sparkplug, Maglev, TurboFan 최적화 JIT를 통해 점진적으로 최적화되며, 추측 실행이 실패할 경우 바이트코드로 다시 비최적화되는 과정을 다룹니다. 기본적인 내부 구조도 문서화되어 있습니다: 태그된 포인터(SMI 및 힙 객체), 4GB 영역 내 케이지(cage) 기준점으로부터 32비트 오프셋을 통해 객체를 참조하는 포인터 압축, 맵(숨겨진 클래스), 요소 유형, 쓰기 배리어, 그리고 오리노코(Orinoco) 가비지 컬렉터 등이 포함됩니다.

자료의 대부분은 일반적인 버그 유형과 이를 악용하는 데 사용되는 기본 요소를 정리하고 있습니다. 버그 유형에는 JIT 유형 혼동, 잘못된 경계 검사 제거, 프로토타입 체인 혼동, TurboFan 축소 및 타입 관련 버그, SharedArrayBuffer 경합 조건, 내장 함수의 오프-바이-원(off-by-one) 오류 등이 포함됩니다. 이 자료는 메모리 손상 버그를 바탕으로 (객체-요소 및 double-element 배열을 혼동시켜) 고전적인 addrof 및 fakeobj 프라이미티브를 구축하고, 손상된 Float64Array 또는 ArrayBuffer 백킹 스토어를 통해 임의의 읽기/쓰기로 확대하며, 혼동된 배열 경계 및 WASM RWX 페이지를 통한 경계 초과 액세스를 다룹니다.

통제되고 승인된 환경에서 렌더러 RCE 및 샌드박스 탈출 체인을 연구하거나 재현할 때 사용하십시오. 이 문서는 JIT 최적화를 강제하는 방법(함수를 여러 번 호출하거나 d8의 %OptimizeFunctionOnNextCall 내장 함수를 호출)과, 백킹 스토어 포인터가 샌드박스 내부에 머무르기 때문에 전체 프로세스 메모리에 접근하려면 별도의 샌드박스 탈출이 필요하다는 점에서 V8 샌드박스와 포인터 압축이 악용을 어떻게 제한하는지 설명합니다. 관련 링크는 샌드박스 탈출 기법, 힙 악용, 스택 오버플로 및 ROP, 바이너리 보호 우회 등을 다루며, V8_EXPLOITATION_PATTERNS.md 문서를 통해 더 심층적인 내용을 확인할 수 있습니다.

자주 묻는 질문

이 플레이북은 어떤 V8 버그 유형을 다루나요?

JIT 유형 혼동, 잘못된 경계 검사 제거, 프로토타입 체인 혼동, TurboFan 축소 및 타입 관련 버그, SharedArrayBuffer 경합 조건, 내장 함수의 오프-바이-원 오류 등이 있습니다.

이 플레이북에서 설명하는 핵심 익스플로잇 프리미티브는 무엇입니까?

addrof(객체 주소 유출) 및 fakeobj(객체 참조 위조)로, 객체 요소 배열과 이중 요소 배열을 혼동시켜 생성한 뒤, 손상된 Float64Array 또는 ArrayBuffer 백킹 스토어를 통해 임의의 읽기/쓰기로 결합됩니다.

V8 샌드박스 및 포인터 압축은 익스플로잇에 어떤 영향을 미칩니까?

V8 8.0부터는 객체가 4GB 영역 내의 케이지(cage) 기준점으로부터 32비트 오프셋으로 주소 지정되며, ArrayBuffer 백킹 스토어는 샌드박스 포인터이므로, 전체 프로세스 메모리에 접근하려면 별도의 샌드박스 탈출이 필요합니다.

테스트를 위해 함수가 JIT 최적화되도록 강제하려면 어떻게 해야 하나요?

TurboFan을 트리거할 수 있도록 해당 함수를 여러 번(예: 100,000회 반복) 호출하거나, d8 셸에서 함수를 호출하기 전에 %OptimizeFunctionOnNextCall 내장 함수를 사용합니다.

이와 관련된 기술은 무엇입니까?

sandbox-escape-techniques(IPC/Mojo 렌더러 탈출), heap-exploitation, stack-overflow-and-rop, binary-protection-bypass, 그리고 상세한 템플릿을 위한 V8_EXPLOITATION_PATTERNS.md 고급 참조 자료입니다.

모든 파일

파일 2개V8_EXPLOITATION_PATTERNS.md8.9KB보기SKILL.md11.5 KB보기
GitHub에서 보기

AI LOAD INSTRUCTION: Expert V8/Chrome exploitation techniques. Covers V8 compilation pipeline, JIT type confusion, addrof/fakeobj primitives, ArrayBuffer corruption, WASM RWX pages, V8 sandbox (pointer compression), and Chrome sandbox escape overview. Distilled from ctf-wiki browser sections, Project Zero research, and CTF competition patterns. Base models often confuse V8 object representation details and miss the pointer compression barrier.

0. RELATED ROUTING

  • sandbox-escape-techniques — Chrome renderer sandbox escape via IPC/Mojo
  • heap-exploitation — general heap concepts applicable to V8 heap
  • stack-overflow-and-rop — ROP concepts for native code execution after V8 escape
  • binary-protection-bypass — ASLR/NX bypass in browser context

Advanced Reference

Load V8_EXPLOITATION_PATTERNS.md when you need:

  • Detailed exploitation patterns and code templates
  • Heap layout manipulation and GC interaction
  • V8 sandbox bypass techniques
  • Object map confusion patterns

1. V8 ARCHITECTURE

Compilation Pipeline

JavaScript Source    ↓ Parser  AST (Abstract Syntax Tree)    ↓ Ignition  Bytecode (interpreted, profiling)    ↓ Sparkplug (non-optimizing baseline, V8 ≥ 9.1)  Baseline code (fast startup)    ↓ Maglev (mid-tier, V8 ≥ 10.2)  Mid-optimized code    ↓ TurboFan (optimizing JIT)  Optimized machine code (with speculative optimizations)    ↓ Deoptimization (if speculation fails)  Back to Ignition bytecode

Key V8 Concepts

ConceptDescription
Tagged pointersSMI (Small Integer): value << 1, HeapObject: ptr | 1
Pointer compressionV8 ≥ 8.0: objects addressed via 32-bit offset from cage base (4GB sandbox)
Maps (Hidden Classes)Define object shape: property names, types, offsets
Elements kindsInternal array type: PACKED_SMI_ELEMENTS, PACKED_DOUBLE_ELEMENTS, PACKED_ELEMENTS, etc.
Write barrierGC bookkeeping when heap pointers are written
Garbage collectionOrinoco GC: minor (Scavenge) and major (Mark-Compact)

Object Representation (64-bit, pointer compression)

HeapObject in V8 heap (compressed):  +0x00: Map pointer (compressed, 32-bit offset)  +0x04: Properties/Hash  +0x08: Elements pointer (compressed)  +0x0C: Length (for arrays)  +0x10: Inline properties or backing store data

2. COMMON V8 BUG CLASSES

Bug ClassDescriptionExample
JIT Type ConfusionTurboFan assumes wrong type after optimizationSpeculative type guard eliminated, wrong operation applied
Incorrect Bounds EliminationJIT removes array bounds check based on wrong range analysisCheckBounds node eliminated → OOB access
Prototype Chain ConfusionOptimization assumes stable prototype, mutations invalidatePrototype change after optimization → wrong property access
Turbofan Reduction BugIncorrect strength reduction or constant foldingInteger overflow in range analysis
Race ConditionSharedArrayBuffer + worker thread raceType confusion via concurrent modification
Off-by-one in BuiltinBoundary error in built-in function implementationString/Array bounds
Typer BugIncorrect type range computation in TurboFanTyper says value is in [0, N] but can be N+1

Triggering JIT Optimization

function vuln(arr) {    // ... vulnerable code path ...}// Force optimization by calling many timesfor (let i = 0; i < 100000; i++) {    vuln(arr);}// Or use V8 intrinsics (d8 only):%OptimizeFunctionOnNextCall(vuln);vuln(arr);

3. EXPLOITATION PRIMITIVES

addrof — Leak Object Address

// Goal: get the raw heap address of a JavaScript object// Method: type confusion between object array and float array// If we can confuse PACKED_ELEMENTS array with PACKED_DOUBLE_ELEMENTS:// - Write object reference to element of object array// - Read same element as double from confused float array// - Float bits = compressed pointer of the objectfunction addrof(obj) {    // Setup depends on specific bug    // Typically: trigger type confusion so array reads obj ref as float    object_array[0] = obj;    return ftoi(confused_float_array[0]);  // float-to-int conversion}

fakeobj — Create Fake Object Reference

// Goal: create a JS reference to an arbitrary heap address// Method: reverse of addrof — write float (raw pointer bits) to float array,//         read from confused object array → treated as object referencefunction fakeobj(addr) {    confused_float_array[0] = itof(addr);  // int-to-float conversion    return object_array[0];                 // now a "pointer" to addr}

Building Arbitrary R/W from addrof + fakeobj

// 1. Create a Float64Array with known layoutlet rw_array = new Float64Array(0x100);let rw_array_addr = addrof(rw_array);// 2. Fake a Float64Array object at controlled address with modified backing_store// 3. Corrupt backing_store pointer to target address// 4. Read/write through the fake Float64Array → arbitrary R/Wfunction read64(addr) {    // Set fake array's backing_store = addr    write_to_fake_backingstore(addr);    return fake_float64array[0];}function write64(addr, value) {    write_to_fake_backingstore(addr);    fake_float64array[0] = value;}

4. OOB READ/WRITE VIA CONFUSED ARRAY BOUNDS

When TurboFan incorrectly eliminates bounds checks:

function trigger(arr, idx) {    // TurboFan thinks idx is always < arr.length    // But due to bug, idx can exceed bounds    return arr[idx];  // OOB read}// OOB read adjacent memory (next heap object's metadata)// OOB write to corrupt next object's map/elements/length

What's Adjacent in V8 Heap?

Objects are allocated sequentially in V8's young generation (new space). By controlling allocation order:

let arr1 = new Array(0x10);    // spray objectlet arr2 = new Float64Array(0x10);  // target: adjacent to arr1// OOB from arr1 can reach arr2's metadata// Corrupt arr2's length → unconstrained OOB on arr2

5. ARRAYBUFFER ARBITRARY R/W

ArrayBuffer's backing store is a raw pointer to allocated memory. Corrupting it gives absolute memory R/W.

let ab = new ArrayBuffer(0x100);let view = new DataView(ab);// If we can overwrite ab's backing_store pointer:// ab.backing_store = target_addr// view.getFloat64(0) → reads 8 bytes from target_addr// view.setFloat64(0, val) → writes to target_addr

V8 Sandbox (Pointer Compression) Impact

Since V8 ≥ 8.0 (pointer compression) and V8 sandbox (≥ 11.x):

  • ArrayBuffer.backing_store is a sandbox pointer (within the V8 cage, 4GB region)
  • Cannot directly point outside the V8 cage
  • Need sandbox escape to get full process memory access

6. WASM RWX PAGE

WebAssembly JIT code is placed on RWX (Read-Write-Execute) pages on some platforms.

// Allocate WASM module → JIT compiles to RWX pagelet wasm_code = new Uint8Array([0x00, 0x61, 0x73, 0x6d, ...]);let mod = new WebAssembly.Module(wasm_code);let instance = new WebAssembly.Instance(mod);// instance.exports.func → points to RWX page// If we can find and write to this page:// 1. addrof(instance) → find WASM instance object// 2. Follow pointers: instance → jump_table_start → RWX page// 3. Use arbitrary write to overwrite RWX page with shellcode// 4. Call instance.exports.func() → executes shellcode

Modern Chrome: W^X enforcement means WASM pages are either RW or RX, not RWX simultaneously. JIT code is written in RW mode, then switched to RX. Exploitation requires finding a write window or using JIT spray.

7. V8 SANDBOX

Architecture (V8 ≥ 11.x)

Process Virtual Address Space:┌──────────────────────────────────────┐│  V8 Sandbox Cage (4GB region)        ││  ├── V8 Heap (JS objects)            ││  ├── ArrayBuffer backing stores      ││  ├── WASM memory                     ││  └── External pointer table          │├──────────────────────────────────────┤│  Process memory outside cage         ││  ├── libc, Chrome code               ││  ├── Stack                           ││  └── Other allocations               │└──────────────────────────────────────┘

Sandbox Escape Vectors

VectorMethod
External pointer tableCorrupt entries in the external pointer table to reference arbitrary addresses
WASM code pointerOverwrite WASM function entry to jump to controlled shellcode
JIT code corruptionWrite to JIT code page via race condition or confused pointer
Mojo IPC (Chrome)Exploit Chrome IPC to attack browser process from compromised renderer
Backing store seal bypassFind type confusion to get unsandboxed pointer

8. CHROME SANDBOX ESCAPE (OVERVIEW)

After renderer RCE (via V8 exploit), the process is still sandboxed. Full compromise requires:

StageTargetExample
Renderer exploitV8 / Blink DOMType confusion → shellcode
IPC/Mojo bugChrome IPC layerUse-after-free in Mojo interface
Browser process exploitPrivileged browser processCode execution outside sandbox

Mojo interfaces (Chrome's IPC) expose attack surface: find UAF or type confusion in Mojo message handlers.

9. TOOLS

# V8 debuggingd8 --allow-natives-syntax exploit.js  # Enable V8 intrinsics (%DebugPrint, etc.)d8 --trace-turbo exploit.js           # Dump TurboFan IRd8 --print-opt-code exploit.js        # Print optimized machine code# Turbolizer: visual TurboFan IR graph# Chrome DevTools Memory panel: heap snapshots# Build V8 for debugginggit clone https://chromium.googlesource.com/v8/v8.gitgclient syncgn gen out/debug --args='is_debug=true v8_enable_sandbox=false'ninja -C out/debug d8

10. DECISION TREE

V8 vulnerability identified├── Bug type?│   ├── JIT type confusion → trigger optimization, confuse array element kinds│   ├── Bounds check elimination → OOB read/write on array│   ├── Typer bug → incorrect range leads to OOB│   └── Builtin bug → direct memory corruption primitive│├── Build primitives│   ├── Can confuse object array ↔ float array?│   │   └── addrof + fakeobj → arbitrary R/W within V8 heap│   ├── OOB on array?│   │   └── Corrupt adjacent object (length/backing_store) → expand to full R/W│   └── Direct write primitive?│       └── Target WASM instance or ArrayBuffer metadata│├── V8 sandbox enabled?│   ├── YES (modern Chrome) →│   │   ├── R/W limited to V8 cage (4GB)│   │   ├── Need sandbox escape: external pointer table corruption,│   │   │   WASM code pointer overwrite, or Mojo bug│   │   └── Then proceed to shellcode execution│   └── NO (older V8, CTF, d8) →│       ├── Corrupt ArrayBuffer backing_store → absolute R/W│       └── Overwrite WASM RWX page → shellcode│├── Code execution method│   ├── WASM RWX page available? → write shellcode, call WASM func│   ├── JIT code writable? → overwrite JIT code│   └── ROP needed? → corrupt stack or return address│└── Full browser exploit chain    ├── Stage 1: V8 bug → renderer RCE    ├── Stage 2: Mojo IPC bug → browser process compromise    └── Stage 3: OS-level escalation (if needed)

모든 파일

2개 파일

browser-exploitation-v8 설치

스킬 파일을 다운로드하여 .claude/skills/ 디렉터리에 압축을 풀어주세요.

ZIP 다운로드

저장소를 클론하고 스킬 파일을 프로젝트에 복사하세요.

git clone https://github.com/yaklang/hack-skills/blob/main/skills/browser-exploitation-v8/SKILL.md # Copy SKILL.md to your .claude/skills/ directory

복사 복사
빠른 설정: skill 폴더를 .claude/skills/로 복사하면 Claude가 해당 스킬을 자동으로 감지하여 사용합니다.

관련 스킬

playwright-cli
업데이트 된 시간 2026년 6월 29일
frontend-testing-best-practices
업데이트 된 시간 2026년 7월 7일
Playwright Browser Automation
업데이트 된 시간 2026년 6월 29일
playwright-generate-test
업데이트 된 시간 2026년 6월 29일
OR