David Brumley Carnegie Mellon University Credit Some slides
David Brumley Carnegie Mellon University Credit: Some slides from Ed Schwartz
Control Flow Hijack: Always control + computation shellcode (aka payload) computation padding + &buf control Return-oriented programming (ROP): shellcode without code injection 2
Motivation: Return-to-libc Attack ret transfers control to system, which finds arguments on stack Overwrite return address with address of libc function • setup fake return address and argument(s) • ret will “call” libc function … ptr to argv “/bin/sh” argc return addr &system caller’s ebp %ebp buf (64 bytes) argv[1] No injected code! buf %esp 3
Attack Surface: Linux Unrandomized Program Image Randomized Libc Stack Heap 2/1/2012 4
Attack Surface: Windows Unrandomized Randomized Program Image Libc Stack Heap 2/1/2012 5
How do we exploit DEP-defended systems where the text section isn’t randomized? 6
Find an instruction sequence, aka gadget, to calculate the address at exploit time. … ptr to argv “/bin/sh” argc return addr &system caller’s ebp What if we don’t know the absolute address to “/bin/sh”? (objdump gives addresses, but we don’t know ASLR constants) %ebp buf (64 bytes) argv[1] buf %esp 7
Writes Computed “/bin/sh” &system Idea! Get a copy of ESP to calculate address of “/bin/sh” on randomized stack. This overcomes ASLR because ASLR only protects against knowing absolute addresses. gadgets to … compute argv ptr to “/bin/sh” argc return addr caller’s ebp buf “/bin/sh” argv[1] buf 8
Return Oriented Programming Techniques 1. Return chaining 2. Semantic equivalence 3. ROP on Windows 9
Return Chaining • Suppose we want to call 2 functions in our exploit: foo(arg 1, arg 2) bar(arg 3, arg 4) What does this do? • Stack unwinds up • First function returns into code to advance stack pointer – e. g. , pop; ret Overwritten ret addr arg 4 arg 3 &(pop-ret) bar arg 2 arg 1 &(pop-ret) foo 10
Return Chaining • When foo is executing, &pop-ret is at the saved EIP slot. • When foo returns, it executes pop-ret to clear up arg 1 (pop), arg 2 (pop), and transfer control to bar (ret) arg 4 arg 3 &(pop-ret) bar arg 2 arg 1 &(pop-ret) foo 11
There are many semantically equivalent ways to achieve the same net shellcode effect 12
Equivalence Mem[v 2] = v 1 Desired Logic . . . v 2. . . v 1 esp Stack a 1: mov eax, [esp] a 2: mov ebx, [esp+8] a 3: mov [ebx], eax Implementation 1 13
Gadgets Mem[v 2] = v 1 Desired Logic eax v 1 ebx eip a 1 Suppose a 5 and a 3 on stack a 1: a 2: a 3: a 4: a 5: a 5 v 2 a 3 v 1 esp Stack pop eax; ret pop ebx; ret mov [ebx], eax Implementation 2 14
Gadgets a 5 v 2 a 3 v 1 Mem[v 2] = v 1 Desired Logic esp Stack eax v 1 ebx eip a 31 a 1: a 2: a 3: a 4: a 5: pop eax; ret pop ebx; ret mov [ebx], eax Implementation 2 15
Gadgets a 5 v 2 a 3 v 1 Mem[v 2] = v 1 Desired Logic esp Stack eax v 1 ebx v 2 eip a 3 a 1: a 2: a 3: a 4: a 5: pop eax; ret pop ebx; ret mov [ebx], eax Implementation 2 16
Gadgets a 5 v 2 a 3 v 1 Mem[v 2] = v 1 Desired Logic esp Stack eax v 1 ebx v 2 eip a 54 a 1: a 2: a 3: a 4: a 5: pop eax; ret pop ebx; ret mov [ebx], eax Implementation 2 17
Gadgets a 5 v 2 a 3 v 1 Mem[v 2] = v 1 Desired Logic esp Stack eax v 1 ebx v 2 eip a 5 a 1: a 2: a 3: a 4: a 5: pop eax; Gadget 1 ret pop ebx; Gadget 2 ret mov [ebx], eax Implementation 2 18
Equivalence Mem[v 2] = v 1 Desired Logic semantically equivalent a 1: mov eax, [esp] a 2: mov ebx, [esp+8] a 3: mov [ebx], eax Implementation 1 a 3 v 2 a 2 v 1 Stack esp “Gadgets” a 1: pop eax; ret a 2: pop ebx; ret a 3: mov [ebx], eax Implementation 2 19
Gadgets • A gadget is a set of instructions for carrying out a semantic action – mov, add, etc. • Gadgets typically have a number of instructions – One instruction = native instruction set – More instructions = synthesize <- ROP • Gadgets in ROP generally (but not always) end in return 20
ROP Programming 1. Disassemble code 2. Identify useful code sequences as gadgets 3. Assemble gadgets into desired shellcode 21
Image by Dino Dai Zovi 22
ROP Overview Idea: We forge shell code out of existing application logic gadgets Requirements: vulnerability + gadgets + some unrandomized code (we need to know the addresses of gadgets) 23
Return-Oriented Programming (ROP) … Mem[v 2] = v 1 argv Desired Shellcode return addr argc caller’s ebp • Find needed instruction gadgets at addresses a 1, a 2, and a 3 in existing code • Overwrite stack to execute a 1, a 2, and then a 3 %ebp buf (64 bytes) argv[1] buf %esp 24
Return-Oriented Programming (ROP) a 3 v… 2 Mem[v 2] = v 1 argv a 2 Desired Shellcode return a 1 addr argc v 1 caller’s ebp a 1: pop eax; ret a 2: pop ebx; ret a 3: mov [ebx], eax Desired store executed! %ebp buf (64 bytes) argv[1] buf %esp 25
Quiz void foo(char *input){ char buf[512]; . . . strcpy (buf, input); return; ret instr } a 1: add eax, 0 x 80; pop %ebp; ret a 2: pop %eax; ret Draw a stack diagram and ROP exploit to pop a value 0 x. BBBB into eax and add 0 x 80. Known Gadgets 26
Quiz void foo(char *input){ char buf[512]; . . . strcpy (buf, input); return; } a 1: add eax, 0 x 80; pop %ebp; ret a 2: pop %eax; ret gadget 1 + data Overwrite buf AAAAA. . . a 2 0 x. BBBB a 1 <data for pop ebp> a 1 0 x. BBBB a 2 saved ret saved ebp buf gadget 2 27
ROPing Windows LPVOID WINAPI Virtual. Protect( LPVOID lp. Address, // dynamically determined base addr to pages to change SIZE_T dw. Size, // size of the region in bytes DWORD fl. New. Protect, // 0 x 40 = EXECUTE_READWRITE DWORD fl. Protect // A ptr to a variable for prev. arg ); Virtual. Protect() can un-DEP a memory region 28
Virtual. Protect Diagram fl. Protect (a ptr to mem) LPVOID WINAPI Virtual. Protect( LPVOID lp. Address, SIZE_T dw. Size, DWORD fl. New. Protect, DWORD fl. Protect ); fl. New. Protect (static) dw. Size (dynamic) lp. Address (dynamic) addr of your shellcode to unprotect &Virtual. Protect Craft lp. Address Craft dw. Size 29
ROPing Windows: An Example Exploit (pre-Win 8) Shellcode Padding/NOPS 7. Change value of ESP back to where pointer to Virtual. Protect is, then ret Gadgets to run shellcode (not shown) 6. Gadget to overwrite placeholder for Param 4 5. Gadget to overwrite placeholder for Param 3 with value 4. Gadget to overwrite placeholder for Param 2 with value 3. Gadget to overwrite placeholder for Param 1 with value (Pointer to shellcode = saved ESP + offset) 1. Stack Pivot esp • lp. Address placeholder: base addr to pages to change • dw. Size placeholder: size of the region in bytes • fl. New. Protect placeholder: EXECUTE_READWRITE • fl. Protect: A ptr to a variable for prev. arg Pointer to Virtual. Protect (static) and space for params: 2. gadgets to get stack pointer and save it to a register (push %esp; pop %eax; ret) & jump below the parameters (add esp, offset; ret) From https: //www. corelan. be/index. php/2010/06/16/exploit-writing-tutorial-part-10 -chaining-dep-with-rop-the-rubikstm-cube/ 30
Stack Pivots Pointing esp to controlled data Fact: Functions often access arguments with respect to esp Defn: A stack pivot redirects esp at attackercontrolled data Example: Attacker controls heap data pointed to be ESI. One stack pivot may be: xchg esi, esp; ret Now esp points to the attacker-controlled data. 31
Other References Thorough introduction: https: //www. corelan. be/index. php/2010/06 /16/exploit-writing-tutorial-part-10 -chaining -dep-with-rop-the-rubikstm-cube/ Adopting to Win 8: http: //vulnfactory. org/blog/2011/09/21/def eating-windows-8 -rop-mitigation/ 32
Disassembling Code 33
Recall: Execution Model Fetch, decode, execute Code EIP Processor Stack Heap read and write Process Memory 34
Disassembly Address user@box: ~/l 2$ objdump -d. /file. . . Disassemble 0000 <even_sum>: 0: 55 push %ebp 1: 89 e 5 mov %esp, %ebp 3: 83 ec 10 sub $0 x 10, %esp 6: 8 b 45 0 c mov 0 xc(%ebp), %eax 9: 03 45 08 add 0 x 8(%ebp), %eax c: 03 45 10 add 0 x 10(%ebp), %eax f: 89 45 fc mov %eax, 0 xfffffffc(%ebp) 12: 8 b 45 fc mov 0 xfffffffc(%ebp), %eax 15: 83 e 0 01 and $0 x 1, %eax 18: 84 c 0 test %al, %al 1 a: 74 03 je 1 f <even_sum+0 x 1 f> 1 c: ff 45 fc incl 0 xfffffffc(%ebp) 1 f: 8 b 45 fc mov 0 xfffffffc(%ebp), %eax 22: c 9 leave 23: c 3 ret Executable instructions
Linear-Sweep Disassembly Executable Instructions 0 x 55 0 x 89 0 xe 5 0 x 83 0 xec 0 x 10 . . . 0 xc 9 Disassembler EIP Algorithm: 1. Decode Instruction 2. Advance EIP by len push ebp 36
Linear-Sweep Disassembly Executable Instructions 0 x 55 0 x 89 0 xe 5 0 x 83 0 xec 0 x 10 . . . 0 xc 9 Disassembler EIP . . . push ebp mov %esp, %ebp 37
Linear-Sweep Disassembly Executable Instructions 0 x 55 0 x 89 0 xe 5 0 x 83 0 xec 0 x 10 Disassembler EIP Algorithm: 1. Decode Instruction 2. Advance EIP by len . . . 0 xc 9 Note we don’t follow jumps: we just increment by instruction length push ebp mov %esp, %ebp 38
Disassemble from any address push ebp mov %esp, %ebp 0 x 55 0 x 89 0 xe 5 0 x 83 0 xec 0 x 10 Normal Execution . . . 0 xc 9 Disassembler EIP It’s perfectly valid to start disassembling from any address. All byte sequences will have a unique disassembly 39
Recursive Descent • Follow jumps and returns instead of linear sweep • Undecidable: indirect jumps – Where does jmp *eax go? 40
ROP Programming Disassemble all sequences ending in ret 1. Disassemble code 2. Identify useful code sequences ending in ret as gadgets 3. Assemble gadgets into desired shellcode 41
ROP: Shacham et al. 1. Disassemble code 2. Identify useful code sequences as gadgets ending in ret 3. Assemble gadgets into desired shellcode Automatic Manual Then Q came along and automated 42
Questions? 43
- Slides: 43