Introduction to Return Oriented Programming in Information Security
130 likes | 227 Vues
Return-oriented programming (ROP) is a method to control the EIP flow in a program without traditional code injection. Learn about exploiting ROP and how to rewrite stack contents for control hijacking. Understand ROP principles and how to create code chunks for execution.
Introduction to Return Oriented Programming in Information Security
E N D
Presentation Transcript
Return Oriented Programming • Return oriented programming is a different way to control the flow of EIP in a program • Motivation: • Write or Execute: as a result of overflows, the first prevention technique is to make: • Executable memory segments read-only • Writeable memory segments Non-Executable. • Most slides in this presentation were taken as is from: • Return-oriented Programming: Exploitation without Code Injection • By Erik Buchanan, Ryan Roemer, Stefan Savage, HovavShachamfrom the University of California, San Diego • http://cseweb.ucsd.edu/~hovav/dist/blackhat08.pdf
Getting started • Need control of memory around %esp • Rewrite stack: • Buffer overflow on stack • Format string vuln to rewrite stack contents • Move stack: • Overwrite saved frame pointer on stack; on leave/ret, move %esp to area under attacker control • Overflow function pointer to a register spring for %esp: • set or modify %esp from an attacker-controlled register • then return
Schematic: return to libc • Control hijacking without executing code stack libc.so args ret-addr exec() sfp printf() local buf “/bin/sh”
Principals of ROP • Instruction pointer (%eip) determines which instruction • to fetch & execute • Once processor has executed the instruction, it • automatically increments %eip to next instruction • Control flow by changing value of %eip
ROP – Machine level • Stack pointer (%esp) determines which instruction • sequence to fetch & execute • Processor doesn’t automatically increment %esp; — but • the “ret” at end of each instruction sequence does
No-op equivalent • No-op instruction does nothing but advance %eip • Return-oriented equivalent: • point to return instruction • advances %esp • Useful in nop sled
Loading Immediates • Instructions can encode constants • Return-oriented equivalent: • Store on the stack; • Pop into register to use
Control flow • Ordinary programming: • (Conditionally) set %eip to new value • Return-oriented equivalent: • (Conditionally) set %esp to new value
Multiple instruction sequence • Sometimes more than one instruction sequence needed • to encode logical unit • Example: load from memory into register: • Load address of source word into %eax • Load memory at (%eax) into %ebx
Return to code chunk • Write complex shellcode by returning to relevant code chunks in memory where code that meets our needs exists. • All code must end with ret. (0xc3) • We can create loops by finding code that modifies the stack pointer. • We don’t have to maintain the original alignment of code
Code chunk example • moveax, 0x5dc3 • This is interpreted into: B8 5D C3 • POP EBP • RETN • This is interpreted into: • 5D C3 • We can use binary search to identify where the shellcode we want exists
Code chunks • We can find them in any of the libraries that are loaded in the binary • Any memory area that is executable is kosher. • We only need to find memory chunks that end in 0xc3 • We need to verify that everything is interpretable until the 0xc3 • The best way to find them, is to compile the commands we need into binary and search for them.