[Hackvens 2023][Write Up – Pwn] TLV
Enoncé
Pour apprendre le C, j’ai décidé de créer ma propre structure de TLV. Un ami m’a dit de revoir les bases du langage…
nc 13.38.58.247 1337
Reconnaissance
Le binaire « chall » qui est fourni est un exécutable linux x86-64.
En termes de protections:
- Partial RELRO: La Global Offset Table (GOT) est réinscriptible.
- No canary: Pas de protections contre les buffers overflow
- NX: La stack n’est pas exécutable
- No PIE: Les adresses du programme seront fixes
Reverse
Deux fonctions semblent importantes ici:
- getFlag
- Main
La fonction appelle fopen sur le fichier « /home/ctf/flag.txt », en lit 0x32 (50) bytes, puis l’affiche. Il s’agira d’une fonction « win« , qui nous donnera le flag si on arrive à l’appeler.
La fonction main alloue une variable taille (nom arbitraire) en rbp-0xb de taille 0x15 (21). Cette dernière nous permettra de lire ce nombre de bytes dans un buffer en rbp-0x1f. Ensuite, le programme redemande les données dans le buffer avec cette taille.
La vulnérabilité
Entre 0x1f et 0xb, il y a 20 bytes. Ainsi, en écrivant au maximum, il est possible de réécraser la variable taille. On obtient un buffer overflow de taille 1, aussi appelé un un off-by-one.
On va donc envoyer 20 bytes de padding pour remplir le buffer, puis mettre une nouvelle taille. Dans mon programme, j’ai mis arbitrairement la valeur 0x7f. Ensuite, on va pouvoir écraser l’adresse de retour, qui se trouve juste après RBP (0x1f+8). On y écrira l’adresse de GetFlag pour l’obtenir.
Solve.py
from pwn import * r = remote('13.38.58.247', 1337) payload = b'\x7f'*0x15 r.send(payload) get_flag = 0x0040125b payload = b'a'*0x27+p64(get_flag) r.sendline(payload) r.interactive()
FLAG
HACKVENS{0fF_bY_0n3_2_0v3rfL0w}