-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlevel38.ts
More file actions
71 lines (62 loc) · 12.1 KB
/
level38.ts
File metadata and controls
71 lines (62 loc) · 12.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import { Level } from './types';
export const level38: Level = {
id: 38,
title: "Use-After-Free: Reincarnation",
description: "Use-After-Free (UAF): Temporal memory safety violation. C++ object lifecycle: Allocation (new/malloc) → Usage (method calls via vtable) → Deallocation (delete/free) → Memory returned to heap. Bug: Dangling pointer (ptr still points to freed memory) + Memory reuse (heap allocator assigns same address to new object) = Type confusion (old pointer now controls new object's data). Exploitation: C++ objects store vtable pointer at offset 0 (virtual function dispatch table). Vtable contains function pointers (render(), update(), destroy()). UAF flow: Object A allocated at 0x08100000 (vtable → 0x08048000), Object A freed (memory released, ptr_A still 0x08100000), Object B allocated at 0x08100000 (vtable → 0x08048100), Call ptr_A->method() (CPU reads vtable from 0x08100000, finds Object B's vtable, executes wrong function). Attacker control: Craft Object B with fake vtable → ptr_A->method() jumps to attacker address → Code execution. Real scenario: Browser DOM nodes, C++ string objects, file handles. This level: player_obj freed at 0xB7F00000, dangling pointer remains. Allocate fake_vtable object at same address. Demonstrate vtable hijacking via heap reuse. Use SystemMonitor > Heap View (visualize allocations), Hex Editor (craft fake vtable bytes), Memory Scanner (track pointers).",
requiredSkill: "Heap Exploitation",
objective: (s) => {
const freedObjStr = (s.baseAddress || '').toLowerCase().replace('0x', '').padStart(8, '0');
const newObjStr = (s.libcBase || '').toLowerCase().replace('0x', '').padStart(8, '0');
const vtablePtrStr = (s.eip || '').toLowerCase().replace('0x', '').padStart(8, '0');
const freedObjValid = freedObjStr === 'b7f00000';
const newObjValid = newObjStr === 'b7f00000';
const vtableHijacked = vtablePtrStr === 'deadbeef';
const objectSizeValid = s.sortValue1 === 64;
const reuseCountValid = s.sortValue2 >= 1;
const fakeVtableValid = (s.payload || '').length >= 8 && s.payload.toLowerCase().includes('deadbeef');
const heapReuseValid = s.heap.some(h => h.id === 'fake_vtable' && h.active === true);
const uafSuccess = s.isAdmin === true;
return freedObjValid && newObjValid && vtableHijacked && objectSizeValid && reuseCountValid && fakeVtableValid && heapReuseValid && uafSuccess;
},
hint: "Seven-stage use-after-free exploitation via vtable hijacking. Stage 1: Read FREED_OBJ pointer (baseAddress, original object address before free(), value: 0xB7F00000). Stage 2: Allocate NEW_OBJ at same address (libcBase, heap reuse via allocator, must match FREED_OBJ: 0xB7F00000). Stage 3: Set VTABLE_PTR to hijacked address (eip pointer, fake vtable location, value: 0xDEADBEEF). Stage 4: Set OBJECT_SIZE = 64 (sortValue1 int, size of C++ object with vtable, bytes). Stage 5: Set REUSE_COUNT = 1+ (sortValue2 int, number of successful memory reuses). Stage 6: Craft FAKE_VTABLE payload (payload string, contains vtable bytes with function pointers, must include 'DEADBEEF' hex). Stage 7: Allocate heap object 'fake_vtable' (SystemMonitor > Heap View, create new allocation, active=true) → UAF_SUCCESS auto-triggers. Use Memory Scanner to read FREED_OBJ address, Hex Editor to craft vtable bytes at 0xB7F00000, Heap View to visualize reuse. Real exploit: Object freed → New object allocated → Old pointer calls virtual method → CPU reads vtable from new object → Jumps to attacker-controlled address → Shell spawned. Vtable structure: [0x00: vptr → fake_vtable] [fake_vtable: 0xDEADBEEF → shellcode].",
tutorPersona: "Tavis Ormandy/Google Project Zero: The memory is freed, but the pointer remembers. That memory is the battlefield. History: 2001-2005 - Use-After-Free emerges in C/C++ applications. Early UAF bugs: dangling pointers after free(), exploited via heap feng shui (predictable allocator behavior). 2007 - Microsoft Internet Explorer UAF exploits (CVE-2007-0064, animated cursor vulnerability). First high-profile UAF: IE loads ANI file → Parses ANIHEADER → Frees icon array → Continues processing → Accesses freed array → Attacker allocated shellcode at same address → Code execution. Exploitation technique: Heap spraying (allocate thousands of objects to occupy freed slot) + Type confusion (freed object type A, replaced with type B). 2010 - Operation Aurora (CVE-2010-0249, IE6/IE7/IE8 UAF). Chinese APT campaign, targeted Google/Adobe/Juniper. Exploit: IE processes HTML → Creates CTreeNode object → Frees node during DOM manipulation → Allocates attacker-controlled object → Uses freed pointer → Vtable hijacked → Shellcode executes → 0-day used in wild for months. Wake-up call: UAF became primary browser exploitation technique. 2012-2014 - Pwn2own competitions dominated by UAF exploits. Chrome, Firefox, IE, Safari all vulnerable. Pattern: Complex C++ object hierarchies (DOM, JavaScript engine, rendering) + Manual memory management (new/delete) + Asynchronous operations (timers, network callbacks) = UAF goldmine. Example: Chrome BindingSecurityCheck UAF (Pwn2own 2012, Vupen): Set timer callback → Navigate page (frees objects) → Timer fires (accesses freed object) → Controlled allocation → Vtable overwrite → Sandbox escape. 2015 - Google Project Zero founded (Tavis Ormandy, Ben Hawkes, Ian Beer). Mission: Find 0-days in popular software, force vendors to fix before disclosure. UAF discoveries: CVE-2015-0311 (Flash Player UAF, exploited in Angler Exploit Kit), CVE-2015-1641 (Word RTF UAF, used by APT groups), CVE-2015-5119 (Flash ByteArray UAF, Hacking Team leak). UAF anatomy (C++ perspective): class Player { virtual void render(); virtual void update(); }; Player* ptr = new Player(); // Heap: 0xB7F00000 [vtable_ptr: 0x08048000] [data...] delete ptr; // Memory freed, ptr still 0xB7F00000 (DANGLING!) FakeObject* evil = new FakeObject(); // Heap allocator reuses 0xB7F00000, // Now: [vtable_ptr: 0xDEADBEEF] [shellcode...] ptr->render(); // CPU: load vtable from 0xB7F00000 → finds 0xDEADBEEF → call [0xDEADBEEF] → Shellcode executes! Vtable hijacking mechanics: C++ virtual functions use vtable (array of function pointers). Object's first 4 bytes (x86) point to vtable. Virtual call: mov eax, [this] // Load object pointer, mov eax, [eax] // Load vtable pointer (offset 0), call [eax+offset] // Call function pointer from vtable. Attacker crafts fake vtable with controlled pointers → Redirect execution. Heap feng shui: Technique to force allocator to reuse specific address. Steps: 1. Spray heap with objects of target size (make allocator predictable). 2. Free target object (create hole). 3. Trigger allocation of attacker-controlled object (fill hole). 4. Use dangling pointer (accesses attacker object). Example (simplified): for (i=0; i<1000; i++) alloc(64); // Spray, free(target_obj); // Hole at 0xB7F00000, alloc_controlled(64); // Fills 0xB7F00000, use_dangling_ptr(); // UAF! 2016-2018 - Browser vendors harden: Chrome Oilpan garbage collector (C++ objects managed by GC, reduces UAF). Firefox Quantum rewrite (Rust components, memory safety). Microsoft Edge isolated heap (critical objects in separate heap). Safari JIT cage (isolate JIT code from object heap). Result: UAF rate decreased but not eliminated. 2017 - Real-world UAF exploits continue: CVE-2017-5070 (Chrome V8 UAF, type confusion in JavaScript arrays). CVE-2017-0199 (Office OLE UAF, RTF documents execute HTA). CVE-2017-11882 (Equation Editor UAF, 17-year-old bug in Office). Modern UAF challenges: ASLR (need info leak to find vtable addresses). CFI (Control Flow Integrity, restricts indirect calls). Heap hardening (metadata checksums, delayed free, random allocation). Sandbox (exploit must escape renderer process). Multi-stage exploit required: Stage 1: Info leak (defeat ASLR, find heap/vtable addresses). Stage 2: UAF (gain arbitrary write or vtable hijack). Stage 3: ROP chain (bypass CFI/DEP). Stage 4: Sandbox escape (elevate privileges). Detection and mitigation: 2015 - AddressSanitizer (ASAN, Google). Compiler instrumentation: Tracks allocation/deallocation, Detects use-after-free at runtime, Terminates with stack trace. Slowdown: 2x (acceptable for testing, not production). 2018 - Hardened allocators: PartitionAlloc (Chrome, isolate object types in separate partitions, type A cannot reuse type B's memory). Scudo (Android, randomize chunk headers, checksums detect corruption). Result: UAF harder to exploit, not impossible. 2020-2024 - Modern UAF landscape: Browsers: Reduced but not eliminated (Pwn2own 2023 still had UAF). IoT/Embedded: Widespread (no ASAN, no hardening). Linux kernel: Critical target (CVE-2021-22555, Netfilter UAF → container escape, CVE-2022-0847, DirtyPipe exploited UAF-like bug). Mobile: Android/iOS browser engines (WebKit, Blink). Exploitation flow (modern): 1. Info leak (leak heap address, vtable address). 2. Heap feng shui (spray, free, allocate). 3. UAF trigger (use dangling pointer). 4. Vtable hijack (fake vtable with ROP gadgets). 5. Stack pivot (redirect stack to controlled buffer). 6. ROP chain (disable CFI, call mprotect/VirtualProtect). 7. Shellcode (spawn shell or load stage 2). 8. Sandbox escape (exploit browser broker or kernel). Project Zero methodology: Fuzzing (AFL++, LibFuzzer, find crashes). Triage (ASAN, identify UAF vs other bug). Root cause analysis (understand object lifecycle). Exploit development (proof exploitability). Vendor notification (90-day disclosure deadline). Public disclosure (blog post, CVE assignment). The Reincarnation: When an object dies, its soul (pointer) lingers. If you place a new body (object) in the same grave (address), the soul will animate the new body. The system cannot tell the difference between the original and the impostor. UAF is resurrection with replacement. Defenses (2024): Memory-safe languages (Rust, Go, Swift - eliminate manual memory management). Garbage collection (Java, C#, Python - automatic deallocation). Smart pointers (C++ unique_ptr, shared_ptr - RAII). Sanitizers (ASAN, MSan, UBSan - testing). Hardened allocators (PartitionAlloc, Scudo - production). CFI (indirect call validation - runtime). The eternal truth: As long as manual memory management exists, UAF will exist. The only perfect defense is to never free memory manually. But performance demands control, and control demands trust, and trust is the vulnerability.",
memoryLayout: [
{ key: 'baseAddress', label: 'FREED_OBJ', type: 'pointer', offset: 0x0, isStatic: true },
{ key: 'libcBase', label: 'NEW_OBJ', type: 'pointer', offset: 0x4 },
{ key: 'eip', label: 'VTABLE_PTR', type: 'pointer', offset: 0x8 },
{ key: 'sortValue1', label: 'OBJECT_SIZE', type: 'int', offset: 0x10 },
{ key: 'sortValue2', label: 'REUSE_COUNT', type: 'int', offset: 0x14 },
{ key: 'payload', label: 'FAKE_VTABLE', type: 'string', offset: 0x100 },
{ key: 'isAdmin', label: 'UAF_SUCCESS', type: 'bool', offset: 0x30 }
],
initialState: {
baseAddress: 'B7F00000',
libcBase: '00000000',
eip: '00000000',
sortValue1: 0,
sortValue2: 0,
payload: '',
isAdmin: false,
heap: [{ id: 'player_obj', size: 64, active: false }]
},
update: (s) => {
const freedObj = parseInt((s.baseAddress || 'B7F00000').replace('0x', ''), 16);
const newObj = parseInt((s.libcBase || '00000000').replace('0x', ''), 16);
const vtablePtr = parseInt((s.eip || '00000000').replace('0x', ''), 16);
const expectedFreedObj = 0xB7F00000;
const expectedVtable = 0xDEADBEEF;
const expectedSize = 64;
const addressMatch = newObj === freedObj && freedObj === expectedFreedObj;
const vtableHijacked = vtablePtr === expectedVtable;
const sizeValid = s.sortValue1 === expectedSize;
const reuseValid = s.sortValue2 >= 1;
const fakeVtableValid = (s.payload || '').toLowerCase().includes('deadbeef');
const heapValid = s.heap.some(h => h.id === 'fake_vtable' && h.active === true);
const updates: any = {};
if (addressMatch && vtableHijacked && sizeValid && reuseValid && fakeVtableValid && heapValid) {
updates.isAdmin = true;
}
return updates;
},
platforms: [{ id: 'p1', x: 0, y: 280, width: 800, height: 40, type: 'static' }]
};