An introduction to the
Return Oriented P rogramming
Tradi&onal
Stack
Overflow
NOP Sled Payload Saved EIP
Tradi&onal
Stack
Overflow
The simplest stack overflow exploit operates as
follows:
1. Send a payload with a NOP sled, shellcode, and a
pointer to the NOP sled
2. The pointer to the NOP sled overwrites the saved
return address and thereby takes over the stored
EIP
3. EIP now points to the machine code and the
program executes arbitrary code
Evalua&on
Pros
• Very
easy
to
trigger
• Simple
to
understand
• Being
able
to
inject
code
means
our
payloads
are
powerful
and
flexible
Cons
• Just
make
the
stack
non-‐executable
• Lots
of
problems
with
bad
characters,
buffer
sizes,
payload
detec&on,
etc.
Return-‐to-‐libc
Padding system() exit() “/bin/sh”
Return-‐to-‐libc
• Used primarily to streamline exploitation to
bypass mitigation and situational limitations
• We want to spawn a shell. Send a payload that
overwrites the saved EIP with the address of
system(), the address of exit(), and a pointer to
“/bin/sh”
• The system call will return directly to exit()
which will then shut down the program cleanly
Evalua&on
• Pros
▫ Does not need executable stack
▫ Also pretty easy to understand and implement
• Cons
▫ Relies on access to library functions
▫ Can only execute sequential instructions, no
branching or fancy stuff
▫ Can only use code in .text and loaded libraries
Mi&ga&on
against
these
classical
aLacks
v Address
Space
Layout
Randomiza&on
v No
eXecute
bit
v There
are
other
protec&ons
but
we
won't
describe
them
in
this
lecture
• ASCII
Armor
• FORTIFY_SOURCE
• Stack-‐smashing
protec2on
(SSP)
Address
Space
Layout
Randomiza&on
Map your Heap and Stack randomly
– At each execution, your Heap and Stack will be mapped at
different places
– It's the same for shared libraries and VDSO
So, now you cannot jump on an hardened address like in a
classical attack
Address
S pace
Layout
Randomization
-‐
E xample
Two executions of the same binary :
Address
Space
Layout
Randomiza&on
–
Linux
Internal
● Heap and Stack areas
mapped at a pseudo-
random place for each
execution
No
eXecute
bit
NX bit is a CPU feature
– On Intel CPU, it works only on x86_64 or with Physical
Address Extension (PAE) enable
Enabled, it raises an exception if the CPU tries to
execute something that doesn't have the NX bit set
The NX bit is located and setup in the Page Table
Entry
No
eXecute
bit
–
P aging
Internals
No
eXecute
bit
–
PTE
Internal
●
The last bit is the NX bit (exb)
– 0 = disabled
– 1 = enabled
ROP
Introduc&on
●
When Good Instructions Go Bad: Generalizing
Return-Oriented Programming to RISC [1] -
Buchanan, E.; Roemer, R.; Shacham, H.; Savage, S. (October 2008)
●
Return-Oriented Programming: Exploits Without
Code Injection [2] - Shacham, Hovav; Buchanan, Erik; Roemer,
Ryan; Savage, Stefan. Retrieved 2009-08-12.
ROP
defini&on
• Chain
gadgets
to
execute
malicious
code.
• A
gadget
is
a
suite
of
instruc&ons
which
end
by
the
branch
instruc&on
ret
(Intel)
or
the
equivalent
on
ARM.
– Intel examples: – ARM examples:
pop eax ; ret pop {r4, pc}
xor ebx, ebx ; ret str r1, [r0] ; bx lr
Objective: Use gadgets instead of classical shellcode
A
gadget
can
contain
other
gadgets
●
Because x86 instructions aren't aligned, a gadget can
contain another gadget.
f7c7070000000f9545c3 → test edi, 0x7 ; setnz byte ptr [rbp-0x3d] ; c7070000000f9545c3 → mov
dword ptr [rdi], 0xf000000 ; xchg ebp, eax ; ret
●
Doesn't work on RISC architectures like ARM, MIPS,
SPARC...
Why
use
the
ROP?
● Gadgets are mainly located on segments
without ASLR and on pages marked as
executables
–
It can bypass the ASLR
– It can bypass the NX bit
Road-‐map
a ttack
●
Find the needed Gadgets
●
S tore your gadge ts a ddres s e s on the s ta ck
– You must to overwrite the saved eip with the
address of your first gadget
CALL
and
RET
seman&cs
(Intel
x86)
● CALL semantic
ESP ← ESP – 4
[ESP] ← NEXT(EIP) ; sEIP
EIP ← OPERANDE
● RET semantic
TMP ← [ESP] ; get the sEIP
ESP ← ESP + 4 ; Align stack pointer
EIP ← TMP ; restore the sEIP
ALack
proce ss
o n
x86
●
Gadget1 is executed and returns
●
Gadget2 is executed and returns
●
Gadget3 is executed and returns
●
And so on until all instructions
that you want are executed
●
So, the real execution is:
ALack
process
on
ARM
●
This is exactly the same process but this time using this
kind of gadgets:
pop {r3, pc}
mov r0, r3 ; pop {r4, r5, r6, pc}
pop {r3, r4, r5, r6, r7, pc}
●
On ARM it's possible to pop a value directly in the
program counter register (pc)
How
can
we
find
gadgets?
●
Several ways to find gadgets
Old school method : objdump and grep
• Some
gadgets
will
be
not
found:
Objdump aligns
instruc&ons
• Make
your
own
tool
which
scans
an
executable
segment
• Use
an
exis&ng
tool
Tools
which
can
help
you
●
Rp++ by Axel Souchet [3]
●
Ropeme by Long Le Dinh [4]
●
Ropc by patkt [5]
●
Nrop by Aurelien wailly [6]
●
ROPgadget by Jonathan Salwan [7]
ROPgadget
tool
●
ROPgadget is :
ü A gadgets finder and “auto-roper”
ü Using Python
ü Using Capstone engine
ü Support PE, ELF, Mach-O formats
ü Support x86, x64, ARM, ARM64, PowerPC, SPARC and
MIPS architectures
ROPgadget
tool
–
Quick
example
● Dis play a vailable gadgets
ROPgadget tool – ROP chain
genera&on
in
5
s teps
●
Objec&ve
:
●
Step
1
-‐
Write-‐what-‐where
gadgets
–
Write
“/bin/sh”
in
memory
●
Step
2
-‐
Init
syscall
number
gadgets
–
Setup
execve
syscall
number
●
Step
3
-‐
Init
syscall
arguments
gadgets
–
Setup
execve
arguments
●
Step
4
-‐
Syscall
gadgets
–
Find
syscall
interrupt
●
Step
5
-‐
Build
the
ROP
chain
–
Build
the
python
payload
Step
1
Write-‐what-‐where
g adgets
Step
2
Init
syscall
number
gadgets
Step 3
Init
syscall
arguments
gadgets
S tep 4
S yscall gadget
Step
5
-‐
Build
the
ROP
chain
Mi&ga&on
against
the
ROP
aLack
●
Linux - Position-Independent Executable
– Applies the ASLR on the section .text
●
Can be bypassed on old specific 32bits-based Linux
distribution
– PIC (Position-Independent Code) is used for library
when a binary is compiled with PIE
●
On Windows, ASLR can include the section
.text
ASLR
–
Entropy
not
enough
on
certain
old
distribu&on
●
Tested on a ArchLinux 32 bits in 2011
– NX enable
–
ASLR enable
–
PIE enable
–
RELRO full
●
If you don't have enough gadgets :
– Choose yours in the libc Brute-force the
– base address
PIC/PIE
–
Entropy
not
enough
on
certain
old
distribu&on
●
Brute-force the base address
base_addr = 0xb770a000
p = "a" * 44
# execve /bin/sh generated by RopGadget p v3.3
p += pack("<I", base_addr + 0x000e07c1) # pop %edx | pop %ecx | pop %ebx | ret
p += pack("<I", 0x42424242) # padding
p += pack("<I", base_addr + 0x00178020) # @ .data
p += pack("<I", 0x42424242) # padding
p += pack("<I", base_addr + 0x00025baf) # pop %eax | ret
+= "/bin"
[...]
PIC/PIE
–
E ntropy
n ot
e nough
on
c ertain
old
d istribution
●
Wait for a few s e conds
$while true ; do ./main "$(./exploit.py)" ; done
Segmentation fau l t
Segmentation fau l t
Segmentation fau l t
Segmentation fau l t
Segmentation fault
[...]
Segmentation fau l t
Segmentation fau l t
Segmentation fau l t
Segmentation fau l t
Segmentation fau l t
Segmentation fau l t
Segmentation fault
sh$
ROP
variants
v Jump Oriented Programming [8]
v String Oriented Programmng [9]
v Blind Return Oriented Programming [10]
v Signal Return Oriented Programming [11]
Jump
Oriented
Programming
v Use
the
jump instruc&on
instead
of
the
ret one
v “The
aLack
relies
on
a
gadget
dispatcher
to
dispatch
and
execute
the
func&onal
gadgets”
v “The
“program
counter”
is
any
register
that
points
into
the
dispatch
table”
Jump
Oriented
Programming
String
Oriented
Programming
●
SOP uses a format string bug to get the control flow
●
SOP uses two scenario to get the control of the application
– Direct control flow redirect
●
Erase the return address on the stack
– Jump on a gadget which adjusts the stack frame to the attacker-controlled buffer
●
If the buffer is on the stack → we can use the ROP
●
If the buffer is on the heap → we cabn use the JOP
– Indirect control flow redirect
●
Erase a GOT entry
– Jump on a gadget (ROP scenario)
– Jump on a gadgets dispatcher (JOP scenario)
Blind
Return
Oriented
Programming
●
BROP deals with the ROP and “timing attack”
● Constraints:
–
The vulnerability must be a stack buffer overflow The
–
target binary (server) must restart after the crash
● Scan the memory byte-by-byte to find potential gadgets
– Try to execute the _write_ function/syscall to leak more
gadget from the .text section
Signal
Return
Oriented
Programming
●
Uses the SIGRETURN Linux signal to load
values from the stack to the registers
– Store the values on the stack then raise the
SIGRETURN syscall
●
Your registers will be initialized with the stack values
Open
Problems
&
Challenges
●
ROP chain mitigation
– Heuristic ROP detection
●
ROP chain generation via theorem solver
– Use a SAT/SMT solver to build a ROP chain
●
Gadgets finding via instruction semantics
– Looking for gadgets based on their semantics
●
LOAD/STORE, GET/PUT
Conclusion
• The
ROP
is
now
a
current
opera&on
and
it's
ac&vely
used
by
every
aLackers
• There
is
yet
a
lot
of
research
around
this
aLack
like:
ü ROP mitigation (heuristic, etc...)
ü ROP chain generation
ü Smart gadgets finding Etc...
References
[1]
h ttp://csewe b.ucsd.e du/~hovav/talks/blackhat08.html
[2]
h ttp://cseweb.ucsd.edu/~hovav/dist/sparc.pdf
[3]
h ttps://github.com/0vercl0k/rp
[4]
h ttp://ropshell.com/ropem e/
[5]
h ttps://github.com/pakt/ropc
[6]
h ttps://github.com/a wailly/nrop
[7]
h ttp://shell-‐storm.org/project/ROPgadget/
[8]
h ttps://www.comp.nus.edu.sg/~liangzk/papers/asiaccs11.pdf
[9]
h ttps://www.lst.inf.ethz.ch/research/publica&ons/PPREW _2013/PPREW _2013.pdf
[10]
h ttp://www.scs.stanford.e du/brop/bittau-‐brop.pdf
[11]
https://labs.portcullis.co.uk/blog/ohm-‐2013-‐review-‐of-‐returning-‐signals-‐for-‐fun-‐and-‐profit/
[12]
h ttp://shell-‐storm.org/repo/Notepad/ROP-‐c hain-‐genera&on-‐via-‐backtracking-‐and-‐state-‐machine.txt
Acknowledgements
These
slides
contain
material
by
Jonathan
Salwan
and
ScoL
Hand