-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlevel42.ts
More file actions
67 lines (59 loc) · 10.1 KB
/
level42.ts
File metadata and controls
67 lines (59 loc) · 10.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
import { Level } from './types';
export const level42: Level = {
id: 42,
title: "Stack Pivot: The Shift",
description: "Stack Pivoting: Redirect stack pointer to controlled memory region for large ROP chains. Problem: Vulnerable buffer small (16-32 bytes) → insufficient space for ROP chain. Solution: Pivot ESP/RSP to heap/BSS with controlled data. Gadgets: XCHG EAX,ESP (swaps registers), MOV ESP,EAX (direct assignment), ADD ESP,offset (stack shift), LEA ESP,[EBX+offset] (calculated pivot). Technique: Leak heap address → Store large ROP chain on heap → Overflow buffer with pivot gadget address → Gadget executes: ESP→heap → Continue ROP from heap. Real scenario: Small stack buffer (recv 32 bytes) but need 200-byte ROP chain → Allocate heap spray → Pivot to heap → Execute full chain. This level: Demonstrate pivot by setting ESP to heap range (0x005xxxxx), OLD_ESP saves original, NEW_ESP points to heap, PIVOT_GADGET=XCHG address, ROP_CHAIN on heap. Use ExploitWorkshop to build chain, Memory Scanner to set ESP values.",
requiredSkill: "Stack Pivoting",
objective: (s) => {
const oldEspValid = (s.baseAddress || '').toLowerCase().startsWith('0xbfff') || (s.baseAddress || '').toLowerCase().startsWith('bfff');
const newEspValid = (s.libcBase || '').toLowerCase().startsWith('0x005') || (s.libcBase || '').toLowerCase().startsWith('005');
const pivotGadgetValid = (s.eip || '').toLowerCase().replace('0x', '').padStart(8, '0') === '08048350';
const heapAddrValid = s.sortValue1 >= 0x00500000 && s.sortValue1 <= 0x00600000;
const ropLengthValid = s.sortValue2 >= 10;
const chainValid = s.activeROPChain.length >= 6;
const pivotSuccess = s.isAdmin === true;
return oldEspValid && newEspValid && pivotGadgetValid && heapAddrValid && ropLengthValid && chainValid && pivotSuccess;
},
hint: "Seven-stage stack pivot exploitation for large ROP chains. Stage 1: Read OLD_ESP (baseAddress, original stack pointer, value: 0xBFFF0xxx typical stack range). Stage 2: Set NEW_ESP (libcBase, heap address for pivot, value: 0x005xxxxx heap range). Stage 3: Set PIVOT_GADGET (eip, gadget address for XCHG EAX,ESP, value: 0x08048350). Stage 4: Set HEAP_ADDR (sortValue1 int, decimal heap address, value: 5242880-6291456 / 0x500000-0x600000). Stage 5: Set ROP_LENGTH (sortValue2 int, number of gadgets in chain, value: 10+). Stage 6: Build ROP_CHAIN (activeROPChain array, add 6+ gadgets via ExploitWorkshop, stored on heap). Stage 7: Execute pivot → ESP=heap → Chain executes → PIVOT_SUCCESS=true. Use Memory Scanner HEX tab: OLD_ESP (read current), NEW_ESP (set heap addr), PIVOT_GADGET (0x08048350). Real pivot gadgets: XCHG EAX,ESP (94 c3), MOV ESP,EAX (89 c4 c3), POP ESP (5c c3). Pivot sequence: Overflow buffer → Overwrite RET with gadget_addr → Gadget: XCHG EAX,ESP (EAX contains heap address) → ESP now points to heap → ROP chain on heap executes → Unlimited chain length.",
tutorPersona: "Dino Dai Zovi & Vincenzo Iozzo/Kernel Exploitation via Uninitialized Stack (Stack Pivoting Origins): When the ground is too narrow, move the ground. History: 2008 - Stack pivoting emerges as ROP refinement technique. Problem: Small vulnerable buffers (16-32 bytes from recv, read, stack frame) insufficient for large ROP chains. Aleph One's 1996 'Smashing the Stack' assumed large buffers. Modern exploits need 100s of bytes (ROP syscall chains, mprotect+shellcode combos). 2009 - 'Return-Oriented Rootkits' (Dino Dai Zovi, Blackhat 2009). Introduced stack pivoting for kernel exploitation. Kernel stack limited (4KB-8KB), need heap for large chains. Technique: Find XCHG ESP gadget → Pivot stack to controlled heap region → Execute arbitrary-length ROP. 2010 - Browser exploitation (Pwn2Own, Firefox/IE/Chrome exploits). JavaScript heap spraying → Allocate large controlled region → Pivot ESP to heap spray → ROP from JS-controlled memory. Example: Spray 0x20000000 with ROP sled → Pivot ESP to 0x20001000 → Execute ROP regardless of ASLR (spray fills address space). 2011 - 'Q: Exploit Hardening Made Easy' (Qira Framework, later PEDA/GEF). Automated gadget finding including pivot gadgets (XCHG, MOV ESP, ADD ESP). Gadget classification: Stack pivot, Stack lift (ADD ESP, offset), Register pivot (LEA ESP, [EBX+offset]). 2012 - Android exploitation (StageFright precursors, mediaserver vulnerabilities). JNI buffer overflows → Small native stack → Pivot to Java heap → ROP from controlled Dalvik memory. 2013 - BROP (Blind Return-Oriented Programming, Andrea Bittau). Exploit ASLR without info leak → Find gadgets blindly → Stack pivot essential (need consistent target address). Technique: Probe for crash offset → Find STOP gadget (sleep, blocking read) → Build stack reading primitive → Find pivot gadget → Execute full chain. 2014 - iOS exploitation (Evasi0n, Pangu jailbreaks). ARM stack pivoting: MOV SP,R0 gadget → Pivot to heap → ROP on iOS despite code signing + ASLR. ARM differences: SP (stack pointer) = R13, gadgets rarer (Thumb/ARM mode mixing). 2015 - SROP (Sigreturn-Oriented Programming, Erik Bosman). Kernel sigreturn syscall restores full CPU state from stack → Ultimate pivot (set all registers including RSP). Exploitation: Craft fake sigreturn frame → Call sigreturn (syscall 15 on x64) → RSP/RIP/all regs controlled → Perfect pivot. 2016 - Browser JIT exploitation (Chrome V8, Firefox IonMonkey). JIT spraying: Compile JavaScript → Shellcode-like bytes in JIT pages → Pivot RIP to JIT region → Execute attacker-controlled code. Stack pivot less critical (control RIP directly) but used for multi-stage payloads. 2017 - 'Stack Clash' (Qualys CVE-2017-1000364). Stack pointer manipulation → Stack grows into heap/mmap → Overlap regions → Exploit ld.so during SUID execution. Related concept: Stack movement via alloca, not traditional pivot but similar effect. 2018 - Kernel SMAP/SMEP bypasses (Supervisor Mode Access Prevention). Stack pivot essential → Can't execute user pages → Must ROP from kernel .text → Need space for long chains → Pivot to kernel heap (kmalloc slabs). Technique: Leak kmalloc address (info leak) → Spray kernel heap (heap feng shui) → Pivot to slab → ROP from kernel memory. 2019 - WebAssembly exploitation. WASM linear memory → Controlled region → Pivot native stack to WASM memory → ROP or shellcode from WASM-allocated pages. 2020 - Microsoft Exchange (ProxyLogon CVE-2021-26855 + chain). Deserialization → limited control → Pivot to session heap → ROP chain for ACL bypass → Pre-auth RCE. 2021 - Chrome V8 Turbofan (CVE-2021-30551, 0-day). Type confusion → Overwrite ArrayBuffer → Arbitrary R/W → Pivot stack to controlled heap → Escape sandbox → Full system compromise. 2022 - Linux kernel io_uring (CVE-2022-29582). UAF in io_uring → Control kernel stack pointer → Pivot to controlled ring buffer → ROP to disable SMEP/SMAP → Execute payload → Root. 2023 - TP-Link router exploits (Pwn2Own Toronto 2023). Stack overflow in httpd → 64-byte buffer → Pivot to heap (allocated for POST data) → 1KB ROP chain → Router takeover. Modern mitigations: Shadow Stack (Intel CET, AMD 2023). Separate hardware stack for return addresses → Pivot detected (SS and normal stack diverge → crash). ARM PAC/BTI (Pointer Authentication + Branch Target Identification). Return addresses signed → Forged stack frame detected → Pivot fails. Control Flow Integrity (CFI). Forward-edge CFI limits call targets, backward-edge (return) CFI limits RET targets → Pivot gadgets become invalid targets. Still vulnerable: Legacy systems (no CET), ARM devices (limited PAC deployment), embedded (MIPS, RISC-V, custom architectures). Exploitation flow: Identify small buffer (analyze vulnerable function stack frame) → Find pivot gadget (ROPgadget --search 'xchg .*, esp', 'mov esp') → Leak/allocate heap address → Spray heap with ROP chain → Overflow buffer with: [JUNK] [POP EAX; RET] [HEAP_ADDR] [XCHG EAX,ESP; RET] → Pivot executes → ESP=heap → ROP chain continues. Advanced: Blind pivot (BROP technique, probe for working pivot without ASLR defeat), Double pivot (pivot twice to avoid detection, stack→heap→stack in RWX region), Frame pivot (pivot EBP instead of ESP, control stack frame pointer for arbitrary read/write). Key insight: Stack is just a pointer. Change the pointer, change reality. When constrained by space, expand your universe. Stack pivoting turns small overflow into unlimited code execution capability.",
memoryLayout: [
{ key: 'baseAddress', label: 'OLD_ESP', type: 'pointer', offset: 0x0 },
{ key: 'libcBase', label: 'NEW_ESP', type: 'pointer', offset: 0x4 },
{ key: 'eip', label: 'PIVOT_GADGET', type: 'pointer', offset: 0x8 },
{ key: 'sortValue1', label: 'HEAP_ADDR', type: 'int', offset: 0x10 },
{ key: 'sortValue2', label: 'ROP_LENGTH', type: 'int', offset: 0x14 },
{ key: 'activeROPChain', label: 'ROP_CHAIN', type: 'array', offset: 0x300 },
{ key: 'isAdmin', label: 'PIVOT_SUCCESS', type: 'bool', offset: 0x30 }
],
initialState: {
baseAddress: 'BFFF0000',
libcBase: '00000000',
eip: '00000000',
sortValue1: 0,
sortValue2: 0,
activeROPChain: [],
isAdmin: false,
esp: 'BFFF0000',
heap: []
},
update: (s) => {
const oldEsp = parseInt((s.baseAddress || 'BFFF0000').replace('0x', ''), 16);
const newEsp = parseInt((s.libcBase || '00000000').replace('0x', ''), 16);
const pivotGadget = parseInt((s.eip || '00000000').replace('0x', ''), 16);
const expectedGadget = 0x08048350; // XCHG EAX, ESP; RET
const heapRangeStart = 0x00500000;
const heapRangeEnd = 0x00600000;
const updates: any = {};
const gadgetValid = pivotGadget === expectedGadget;
const espInHeap = newEsp >= heapRangeStart && newEsp <= heapRangeEnd;
const chainLong = s.activeROPChain.length >= 6;
const ropLengthSet = s.sortValue2 >= 10;
const heapAddrSet = s.sortValue1 >= heapRangeStart && s.sortValue1 <= heapRangeEnd;
if (gadgetValid && espInHeap && chainLong && ropLengthSet && heapAddrSet) {
updates.isAdmin = true;
updates.esp = s.libcBase; // Pivot complete
}
return updates;
},
platforms: [{ id: 'p1', x: 0, y: 280, width: 800, height: 40, type: 'static' }]
};