250 likes | 400 Vues
This paper examines Return-Oriented Programming (ROP), a malicious technique leveraging existing code to perform arbitrary computations without injecting code. The authors discuss the mechanics of ROP on x86 architecture and present methods for identifying useful instruction sequences. They explore the implications of ROP for security, including the challenges of defending against this technique in various operating systems. By analyzing the nature of “good” and “bad” code, the work highlights the limitations of traditional code integrity measures and the potential for ROP across different hardware architectures.
E N D
The Geometry of Innocent Flesh on the Bone:Return-into-libc without Function Calls (on the x86)In Proceedings of the 14th ACM Conference on Computer and Communications Security, (CCS '07) Shacham (UC San Diego ) Presented by: WANG Zhi
Code and Behavior • Does “good” codes always do “good” behavior?
malicious code • Insert and execute malicious code
Preventing malicious code • Check the integrity of good codes in the system. • Isolate “bad” code that has been introduced into the system. (e.g., W-xor-X, antivirus scanner.)
W-xor-X model • Memory is either marked as writable or executable, but may not be both. • Widely deployed: Linux (via PaX patches); OpenBSD; Windows (since XP SP2); OS X (since 10.5); … • Hardware support: Intel “XD” bit, AMD “NX” bit • So it is very difficult to execute the inserted malicious codes.
Ordinary programming • 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 the value of %eip
Return-oriented programming • The “ret” instruction could transfers program control to a return address located on the top of the stack. • Return-oriented programming introduces no new instructions, just using carefully crafted stack to link existed code snippets together by ret instruction. • Return-oriented programming generates a new execution path based on existed “good” codes
Return-oriented programming • 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
Useful Instruction Sequences • Useful Instruction Sequence: For a instruction sequence to be potentially useful, it needs only end in a return instruction. • In the libc library there are sufficient useful instruction sequences. • An attacker who controls the stack will be able to make the victim program to undertake arbitrary computation.
Finding Useful sequences • Galileo Algorithm: • First, to identify the ret (c3 byte) locations • Second, to scan backwards from such locations. • Does the single byte immediately preceding represent a valid one-byte instruction. • Dose the two bytes immediately preceding represent a valid two-byte instruction or two valid one-byte instructions. • And so on, up to the maximum length
Instruction Sequence Challenges • Code sequences are difficult to use: • short; perform a small unit of work • no standard function prologue/epilogue • haphazard interface, not an ABI
Gadget design • Gadgets are built from found code sequences. • Gadgets are intermediate organizational unit and perform well-defined operations, such as: load-store operations arithmetic & logic operations control flow invoking system calls The set of gadgets is Turing complete, so return-oriented programming could construct arbitrary computations.
Arithmetic And Logic Simple add into %eax
Return-Oriented Shellcode • An application of return-oriented shellcode. • The shellcode invokes the execve system call to run a shell. This requires: • Setting the system call index in %eax; • Setting the path of the program to run in %ebx. • Setting the argument vector argv in %ecx. • Setting the environment vector envp in %edx.
Return-oriented Shellcode • In this case, the binary codes of shellcode given above : • 3e 78 03 03 07 7f 02 03 0b 0b 0b 0b 18 ff ff 4f • 30 7f 02 03 4f 37 05 03 bd ad 06 03 34 ff ff 4f • 07 7f 02 03 2c ff ff 4f 30 ff ff 4f 55 d7 08 03 • 34 ff ff 4f ad fb ca de 2f 62 69 6e 2f 73 68 00
Extension • Return-oriented programming has extended to the SPARC, Atmel AVR, PowerPC, Z80, and ARM processors. • Using return-like instructions such as indirect jump instructions: ”pop x; jmp *x”;
References • [CCS08] Buchanan et al.: When good instructions go bad: Generalizing return-oriented programming to RISC.CCS 2008 • [USENIX Securiy09] Hund et al.: Return-oriented rootkits: Bypassing kernel code integrity protection mechanisms
Conclusions • Code injection is not necessary for arbitrary exploitation. • Defenses that distinguish “good code” from “bad code” are useless. • Return-oriented programming likely possible on every architecture, not just x86.