Key Dates
Project Groups
ret
instruction which already exist as executable code within each binary or library. These gadgets may be used for binary exploitation and to subvert vulnerable executables.When the addresses of many ROP Gadgets are written into a buffer we have formed a ROP Chain. If an attacker can move the stack pointer into this ROP Chain then control can be completely transferred to the attacker.
Most executables contain enough gadgets to write a turing-complete ROP Chain. For those that don’t, one can always use dynamic libraries contained in the same address-space (such as libc
) once we know their addresses.
The beauty of using ROP Gadgets is that no new executable code needs to be written anywhere - an attacker may achieve their objective using only the code that already exists in the program. Source: github.com/Ben-Lichtman/ropr
Hi confused! I’m a diagram
0xFFFF +-----------+
| |
| |
| |
| |
| |
| |
|== RET ==|
| | \
| | |
| | | Current function
Start of ----> | | |
buffer | | /
0x0000 +-----------+
Ultimately we want to use gadgets that form some desired shellcode e.g. call to /bin/sh
execve("/bin/sh", NULL, NULL)
eax = 0xb (execve syscall) # mov eax, 0xb
ebx = bin_sh_address # ...
ecx = 0 # xor ecx, ecx
edx = 0 # xor edx, edx
syscall # int 0x80
inc ...
mov ...
add ...
sub ...
pop ...
pop
Your ROP exploit doesn’t need to comprised of just addresses. We can pass values (NB: encoded correctly) and pop
them off!
i.e. Set EAX to 13
gdgt{mov eax, 13}
gdgt{xor eax, eax} + gdgt{inc eax}
…gdgt{pop eax} + p32(0xd)
pop ...
+ value
... |
payload += gdgt{pop ebx; ret;} |
payload += p32(0xAABBCCDD) | payload += ...
... | ...
# ebx = 0xAABBCCDD | #
push esp
If you need to get the address of the stack position… find a gadget that pushes esp, and pops it
push esp; pop ...
Note: Generally both of these instructions need to be in the same gadget
We can also add addresses in our ROP chain.
i.e found a call to
system
? Use that!
payload += p32(0x804aabb) # some system() function address
payload += p32(addr_to_binsh)
0xFFFF +-----------------+
| | # esp+4 ^ when popped
| addr_to_binsh | # esp
| 0x804aabb | # esp-4 v when pushed
| ^-------- buffer start
0x0000 +-----------------+
What if a program doesn’t have enough gadgets?
A:
Find a better program
Use gadgets in dependent libraries
A: Uninstall, give up, cry, sleep
libc
provides functions used by most programs!
i.e basically literally any C function
puts, printf, gets, etc…
libc
versionYou can set the base address of an ELF in pwntools!
<ELF>.address = base_address
libc = ELF("libc_version.so")
libc.address = printf_leak - l.symbols['printf']
...
payload += p32(l.symbols['system']) # Offset adjusted!
Note: Also works for the program base
Note
Don’t forget about ASLR / PIE
roproproproproproproprop