Return-oriented Programming:
Exploitation without Code Injection
Erik Buchanan, Ryan Roemer, Stefan Savage, Hovav Shacham
University of California, San Diego
Bad code versus bad behavior
Bad code versus bad behavior
“Bad”
Bad
behavior
“Good”
Good
behavior
Attacker
d
code
Application
d
code
Problem: this implication is
false!
The Return-oriented programming thesis
The Return oriented programming thesis
any sufficiently large program codebase
any sufficiently large program codebase
arbitrary attacker computation and behavior,
arbitrary attacker computation and behavior,
without code injection
(in the absence of control-flow integrity)
Security systems endangered:
Security systems endangered:
W-xor-X aka DEP
Linux OpenBSD Windows XP SP2 MacOS X
Linux, OpenBSD, Windows XP SP2, MacOS X
Hardware support: AMD NX bit, Intel XD bit
p
Trusted computing
g
Code signing: Xbox
Binary hashing: Tripwire, etc.
… and others
Return-into-libc and W^X
W-xor-X
W xor X
Industry response to code injection exploits
Marks all writeable locations in a process’ address
Marks all writeable locations in a process address
space as nonexecutable
Deployment: Linux (via PaX patches); OpenBSD;
p y
;
Windows (since XP SP2); OS X (since 10.5); …
); p
(
p
Hardware support: Intel “XD” bit, AMD “NX” bit
(and many RISC processors)
Return-into-libc
Return into libc
Divert control flow of exploited program into libc code
system() printf()
system(), printf(), …
No code injection required
Perception of return-into-libc: limited, easy to defeat
Attacker cannot execute arbitrary code
Attacker relies on contents of libc — remove system()?
We show: this perception is false.
The Return-oriented programming thesis:
return-into-libc special case
return into libc special case
attacker control of stack
attacker control of stack
arbitrary attacker computation and behavior
arbitrary attacker computation and behavior
via return-into-libc techniques
(given any sufficiently large codebase to draw on)