**Return-oriented programming** bezeichnet eine gewiefte IT-Angriffstechnik, die im Prinzip eine Verallgemeinerung von *return-to-libc*-Attacken ist, welche wiederum zu den *stack buffer overflow exploits* gehören.
Wem das alles nichts sagt - keine Angst: Im Vortrag werden zunächst die Grundlagen von Puffer-Überläufen und deren Angriffspotential erläutert und einige historische Beispiele aufgezeigt, bevor schrittweise die Brücke zu **ROP** geschlagen wird. Zum Abschluss werden kurz einige Abwehrmaßnahmen vorgestellt und im Hinblick auf Umsetzbarkeit und Wirkungsgrad bewertet.
So die Demo-Götter es wollen, wird live u.A. ein Beispiel-Programm mithilfe von **ROP**-Tools gecrackt.
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Return oriented programming
1. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
Return-oriented programming
Sebastian Neuser
Hackspace Siegen
May 8, 2014
Return-oriented programming Sebastian Neuser
2. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
1 Introduction
What is return-oriented programming?
Before we begin...
Examples
History
2 Return-oriented programming in a nutshell
x86 crash course
Stack buffer overflow
Gadgets
Return-oriented programming Sebastian Neuser
3. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
3 Demonstration
ROPgadget – a ROP compiler
Stupid vulnerable program
Showtime!
4 Countermeasures
ASLR and PIE
Stack canaries and shadow stacks
CFI and ROPdefender
5 Conclusion
Return-oriented programming Sebastian Neuser
4. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
1 Introduction
What is return-oriented programming?
Before we begin...
Examples
History
2 Return-oriented programming in a nutshell
3 Demonstration
4 Countermeasures
5 Conclusion
Return-oriented programming Sebastian Neuser
5. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
What is return-oriented programming?
Buffer overflow vulnerabilities
simple example:
• fixed size character buffer
• program reads a string from the keyboard and copies it to the
buffer without bounds checking
• number of input characters > buffer size ; buffer overflow
• variables on the stack are overwritten – possibly including the
current function’s return address
• best case scenario: SIGSEGV
Return-oriented programming Sebastian Neuser
6. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
What is return-oriented programming?
Return-oriented programming
• generalization of return-to-libc exploitation
• attacker uses buffer overflow-vulnerability or something similar
to inject return addresses into the stack
• return-to-libc-exploits chain together calls to library
functions (libc in most cases)
• return-oriented exploits jump a few instructions before a
function’s ret to perform small operations
By carefully chaining together such jumps, an attacker can perform
arbitrary computations!
Return-oriented programming Sebastian Neuser
7. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
What is return-oriented programming?
Why care?
• 45% of all recorded security vulnerabilities in Ubuntu:
; buffer overflow vulnerabilities
• buffer overflow exploits have been implemented in numerous
malicious programs across different platforms
• Return-oriented programming:
• probably the most advanced buffer overflow exploitation
technique so far
• developed and refined over decades
Return-oriented programming Sebastian Neuser
8. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
Before we begin...
Terms of service
• Although I don’t intend to, unfortunately I tend to
• become overzealous,
• talk too fast and
• speak with a slur.
; Please insult me, if I do!
• By sitting here and listening to the talk, you agree that
• you will not use the knowledge provided here to harm anyone,
• I am not responsible for anything you break while messing
around with the techniques I present,
• vim is the name of the one true editor,
• proprietary software is inherently evil.
• Feel free to ask questions at any time.
Return-oriented programming Sebastian Neuser
9. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
Before we begin...
Stack diagrams
Stack diagrams are depicted from the stack’s top to bottom:
pointers addresses values
stack top 0xbf8c73c0:
0xbf8c73c4:
0xbf8c73c8:
0x1337c0de
0xdeadc0de
0xdeadbeef
Return-oriented programming Sebastian Neuser
10. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
Before we begin...
Platform
Examples and demo compiled and tested with
• gcc version 4.7.2
• gdb version 7.4.1
• 32 bit Debian GNU/Linux 7.1
; instruction set architecture: IA-32
• Intel Core 2 Duo P7450
Return-oriented programming Sebastian Neuser
11. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
Examples
Computer worms
• The Morris worm aka. ”Great Worm”
• utilized a buffer overflow-vulnerability in the fingerd program
on Unix systems
• rendered infected systems unusable within 90 minutes
• The Slammer worm
• used buffer overflow-vulnerabilities in Microsoft’s ”SQL Server
2000” and ”Desktop Engine 2000”
• infected roughly 75000 servers in approximately 30 minutes
• caused network overloads on a great scale
• The Sasser worm
• exploited a vulnerability in Microsoft’s LSASS
• caused systems to shut down
Return-oriented programming Sebastian Neuser
12. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
History
Timeline of buffer overflow exploits
1988 Morris worm
1996 Aleph One: ”Smashing The Stack For Fun And Profit”
1997 Solar Designer: return-to-libc basics
1998 Solar Designer: security patch for the Linux kernel
2000 PaX: Implementation of W⊕X
2001 Nergal: function chaining with return-to-libc
2007 Hovav Shacham: ”Return-into-libc without function calls”
; return-oriented programming
since more and more proof, that return-oriented programming is a
real threat
Return-oriented programming Sebastian Neuser
13. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
1 Introduction
2 Return-oriented programming in a nutshell
x86 crash course
Stack buffer overflow
Gadgets
3 Demonstration
4 Countermeasures
5 Conclusion
Return-oriented programming Sebastian Neuser
14. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
x86 crash course
Register set
%eax holds the return value of a function call.
%ebx holds a pointer to some data.
%ecx is used for counters in string- and loop instructions.
%edx holds a I/O pointers.
%esi is the source pointer in some instructions.
%edi is the destination pointer in some instructions.
%ebp is the stack frame- or base pointer.
%esp is the stack pointer.
%eip is the instruction pointer.
%eflags is the status and control register.
Return-oriented programming Sebastian Neuser
15. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
x86 crash course
Instruction set
mov %esp, %ebp Copies the stack pointer %esp to the base
pointer %ebp.
push %ebp Updates the stack pointer %esp and writes
the value of %ebp to the new top of the stack.
pop %ebp Reads the value at the top of the stack – the
memory location that %esp points to, writes
it into %ebp and discards the value from the
stack by adjusting %esp.
call func Pushes the return address, which is the ad-
dress of the next instruction (%eip+5) onto
the stack and jumps to the instruction la-
beled by ”func:”.
ret Pops the return address from the top of the
stack and writes it into %eip.
Return-oriented programming Sebastian Neuser
16. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
x86 crash course
The stack
• data section in a process’ address space
• contains local variables and buffers
• arguments to function calls and return addresses are also
implemented using the stack
• x86-family of CPUs:
• stack grows from higher to lower memory addresses
• memory is addressed byte-wise
; push decrements %esp by 4, pop increments %esp by 4
Return-oriented programming Sebastian Neuser
17. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
x86 crash course
Function calls – cdecl
• parameters are pushed to the stack in reverse order
• call pushes the address of the next instruction onto the stack
• function prologue (enter):
• save the base pointer %ebp
• copy %esp to %ebp for base pointer addressing
• decrement %esp to allocate stack memory for local variables
• function epilogue (leave):
• discard local variables by copying %ebp to %esp
• restore %ebp by popping it from the stack
• ret pops the return address off the stack and jumps to it
Return-oriented programming Sebastian Neuser
18. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
x86 crash course
Function calls – stack diagram
%esp
%ebp
0xbf8c73d0:
0xbf8c73d4:
local var 0
saved %ebp
Return-oriented programming Sebastian Neuser
19. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
x86 crash course
Function calls – stack diagram
%esp
%ebp
0xbf8c73cc:
0xbf8c73d0:
0xbf8c73d4:
parameter 2
local var 0
saved %ebp
Return-oriented programming Sebastian Neuser
20. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
x86 crash course
Function calls – stack diagram
%esp
%ebp
0xbf8c73c8:
0xbf8c73cc:
0xbf8c73d0:
0xbf8c73d4:
parameter 1
parameter 2
local var 0
saved %ebp
Return-oriented programming Sebastian Neuser
21. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
x86 crash course
Function calls – stack diagram
%esp
%ebp
0xbf8c73c4:
0xbf8c73c8:
0xbf8c73cc:
0xbf8c73d0:
0xbf8c73d4:
parameter 0
parameter 1
parameter 2
local var 0
saved %ebp
Return-oriented programming Sebastian Neuser
22. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
x86 crash course
Function calls – stack diagram
%esp
%ebp
0xbf8c73c0:
0xbf8c73c4:
0xbf8c73c8:
0xbf8c73cc:
0xbf8c73d0:
0xbf8c73d4:
return addr
parameter 0
parameter 1
parameter 2
local var 0
saved %ebp
Return-oriented programming Sebastian Neuser
23. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
x86 crash course
Function calls – stack diagram
%esp
%ebp
0xbf8c73bc:
0xbf8c73c0:
0xbf8c73c4:
0xbf8c73c8:
0xbf8c73cc:
0xbf8c73d0:
0xbf8c73d4:
saved %ebp
return addr
parameter 0
parameter 1
parameter 2
local var 0
saved %ebp
Return-oriented programming Sebastian Neuser
24. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
x86 crash course
Function calls – stack diagram
%esp,%ebp 0xbf8c73bc:
0xbf8c73c0:
0xbf8c73c4:
0xbf8c73c8:
0xbf8c73cc:
0xbf8c73d0:
0xbf8c73d4:
saved %ebp
return addr
parameter 0
parameter 1
parameter 2
local var 0
saved %ebp
Return-oriented programming Sebastian Neuser
25. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
x86 crash course
Function calls – stack diagram
%esp
%ebp
0xbf8c73b4:
0xbf8c73b8:
0xbf8c73bc:
0xbf8c73c0:
0xbf8c73c4:
0xbf8c73c8:
0xbf8c73cc:
0xbf8c73d0:
0xbf8c73d4:
local var 1
local var 0
saved %ebp
return addr
parameter 0
parameter 1
parameter 2
local var 0
saved %ebp
Return-oriented programming Sebastian Neuser
26. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
Stack buffer overflow
Before...
%esp
%ebp
0xbffff8b4:
0xbffff8b8:
0xbffff8bc:
...
0xbffff93c:
0xbffff940:
0xbffff944:
buffer[0]
buffer[1]
. . .
local var 1
local var 0
saved %ebp
return addr
Return-oriented programming Sebastian Neuser
27. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
Stack buffer overflow
Meanwhile...
%esp
%ebp
0xbffff8b4:
0xbffff8b8:
0xbffff8bc:
...
0xbffff93c:
0xbffff940:
0xbffff944:
buffer[0]
buffer[1]
. . .
local var 1
local var 0
saved %ebp
return addr
Return-oriented programming Sebastian Neuser
28. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
Stack buffer overflow
Meanwhile...
%esp
%ebp
0xbffff8b4:
0xbffff8b8:
0xbffff8bc:
...
0xbffff93c:
0xbffff940:
0xbffff944:
buffer[0]
buffer[1]
. . .
local var 1
local var 0
saved %ebp
return addr
Return-oriented programming Sebastian Neuser
29. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
Stack buffer overflow
Meanwhile...
%esp
%ebp
0xbffff8b4:
0xbffff8b8:
0xbffff8bc:
...
0xbffff93c:
0xbffff940:
0xbffff944:
buffer[0]
buffer[1]
. . .
local var 1
local var 0
saved %ebp
return addr
Return-oriented programming Sebastian Neuser
30. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
Stack buffer overflow
Meanwhile...
%esp
%ebp
0xbffff8b4:
0xbffff8b8:
0xbffff8bc:
...
0xbffff93c:
0xbffff940:
0xbffff944:
buffer[0]
buffer[1]
. . .
local var 1
local var 0
saved %ebp
return addr
Return-oriented programming Sebastian Neuser
31. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
Stack buffer overflow
Boom!
%esp
%ebp
0xbffff8b4:
0xbffff8b8:
0xbffff8bc:
...
0xbffff93c:
0xbffff940:
0xbffff944:
buffer[0]
buffer[1]
. . .
local var 1
local var 0
saved %ebp
return addr
Return-oriented programming Sebastian Neuser
32. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
Gadgets
What is a gadget?
• attacker searches for short instruction sequences that perform
small tasks and end with ret
; for example poping some values into registers
• gadget: combination of one or more addresses of short
instruction sequences and the values that they should pop off
the stack
• payload: chain of gadgets
Return-oriented programming Sebastian Neuser
33. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
Gadgets
A very simple gadget
ret addr
. . .
{prev gadg}
0x0000002a
{next gadg}
. . .
pop %eax
ret
Return-oriented programming Sebastian Neuser
34. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
1 Introduction
2 Return-oriented programming in a nutshell
3 Demonstration
ROPgadget – a ROP compiler
Stupid vulnerable program
Showtime!
4 Countermeasures
5 Conclusion
Return-oriented programming Sebastian Neuser
35. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
ROPgadget – a ROP compiler
ROPgadget
• finds and lists gadgets that are available in a specified binary
• constructs shellcode, a payload that opens a network socket
or user-specified opcodes
• prints out python commands that can be embedded in a
payload generation script
• searches and prints out addresses of instructions/opcodes and
strings in a binary
Return-oriented programming Sebastian Neuser
36. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
Stupid vulnerable program
log.h
1 //// io.c ////
2
3 // Appends the buffer to the log-file specified by the path
4 void append_log(char* buffer, char* path);
5
6 // Reads an input string to the buffer until EOF is read
7 void read_string_till_eof(char* buffer);
8
9
10
11 //// util.c ////
12
13 // Checks the program arguments
14 void check_args(int count, char* vector[]);
15
16 // Returns a string that describes the current timestamp
17 char* get_time_string(void);
Return-oriented programming Sebastian Neuser
40. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
Showtime!
The fun part...
”For a moment, nothing happened.
Then, after a second or so, nothing continued to happen.”
- Douglas Adams, The Hitchhiker’s Guide to the Galaxy
Return-oriented programming Sebastian Neuser
41. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
1 Introduction
2 Return-oriented programming in a nutshell
3 Demonstration
4 Countermeasures
ASLR and PIE
Stack canaries and shadow stacks
CFI and ROPdefender
5 Conclusion
Return-oriented programming Sebastian Neuser
42. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
ASLR and PIE
ASLR and PIE
• Address Space Layout Randomization
• Position Independent Executable
• take effect at load and link time during program startup
• in the PaX implementation, the addresses of the following
segments are randomized:
• .text-segment of the binary (; executable code)
• dynamically linked libraries
• the stack
• the heap
• libraries in themselves are not randomized
; randomization can be overcome by brute-force attacks
and/or through information leakage
Return-oriented programming Sebastian Neuser
43. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
Stack canaries and shadow stacks
Stack canaries – Explanation
• canary word: word between local variables of a function and
the return address
• during function prologue: canary word is placed on the stack
and backed up in a different location
• during function epilogue: canary word is verified through
comparison with the stored value
• word has changed (; the canary is dead )
; program is terminated with a warning message
• Example: StackGuard
Return-oriented programming Sebastian Neuser
44. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
Stack canaries and shadow stacks
Stack canaries – Diagram
%esp
%ebp
0xbf9358bc:
...
0xbf935924:
0xbf935928:
0xbf93592c:
buffer
. . .
canary
saved %ebp
return addr
Return-oriented programming Sebastian Neuser
45. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
Stack canaries and shadow stacks
Shadow stacks
• TRUSS: maintains shadow stack, which stores return
addresses
• function prologue: modified to push the correct return address
onto the shadow stack
• epilogue: compares return addresses
• mismatch ; program termination and error signal
Return-oriented programming Sebastian Neuser
46. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
CFI and ROPdefender
Control Flow Integrity
• control flow graph maps all function calls
• function prologues and epilogues are modified at runtime
• targets of call and ret instructions are correlated with the
anticipated control flow in the graph
• opcodes do not match ; program is aborted
• significant computational overhead with a factor typically in
the range of [1.5, 3.5]
Return-oriented programming Sebastian Neuser
47. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
CFI and ROPdefender
ROPdefender
• ROPdefender also maintains a shadow stack
• capable of detecting unintended instruction sequences
• return address of every call instruction is pushed onto the
shadow stack
• every ret instruction: comparison of the destination address
to the top of the shadow stack
• program is aborted if the addresses do not match
• computational overhead similar to CFI
Return-oriented programming Sebastian Neuser
48. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
1 Introduction
2 Return-oriented programming in a nutshell
3 Demonstration
4 Countermeasures
5 Conclusion
Return-oriented programming Sebastian Neuser
49. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
Summary
• long evolution from direct code injection to ROP
• applicable to many popular architectures
• quite complex technique
• relatively recent ; few effective countermeasures
• frameworks for automation of payload generation
• ; serious threat!
• But: It’s fun!
Return-oriented programming Sebastian Neuser
50. Introduction Return-oriented programming in a nutshell Demonstration Countermeasures Conclusion
Thanks for your attention.
Questions?
Return-oriented programming Sebastian Neuser