BOF win()

Catégorie: Pwn Difficulté: - Flag: Flag: CTFREI{b0f_t0_w1n}

Challenge

Description


Voici ma fonction win() qui te donnes un shell, seras-tu capable de la call ? :D

Connexion: nc intro.ctfrei.fr 7005

Solution

Comme dans les challenges précédents, on va dépenser le buffer prévu pour écraser les variables suivantes, sauf que là, on va aller encore plus loin pour atteindre les valeurs utilisées par les registres EBP et EIP. Ce dernier contient l'adresse de la prochaine exécution, en modifiant cette adresse, on peut donc modifier le flux d'exécution du binaire.

On nous donne le code directement compilé. De là, si sur le serveur la randomisation des adresses mémoire (appelée ASLR) est désactivée, on peut regarder de notre côté l'adresse de la fonction que l'on souhaite exécuter et utiliser le Buffer Overflow pour mettre son adresse dans EIP pour qu'elle soit ensuite appelée.

Commençons par récupérer son adresse, pour ça on peut lancer avec gdb le binaire et lister les fonctions avec info functions, son adresse est 0x08049254 :

Maintenant, il faut savoir à quel point il faut remplir le buffer pour mettre cette valeur à la bonne place dans la mémoire. Le plus simple, c'est de regarder avec GDB en testant, donc ici j'ai envoyé 0x44 fois le caractère "a" (la taille du buffer) suivis de "AAAABBBBCCCCDDDD" (pour pouvoir différencier où vont ces valeurs)

On voit que EIP contient "CCCC", c'est-à-dire que pour mettre notre adresse dans EIP, il faut envoyer avant nos 0x44 * "a" + "AAAA" + "BBBB", c'est-à-dire0x44 + 4 + 4 = 76 caractères. On n'oublie pas de mettre l'adresse en Little Endian.

from pwn import remote, context

context.log_level = 'error'    
client = remote('intro.ctfrei.fr', 7005)

filler =    b'A' * 76
win_address = 0x08049254.to_bytes(4, 'little')
payload = filler  + win_address

client.sendlineafter(b'prends ton shell: ', payload)
print(client.recvlines(2)[1].decode())
# Flag: CTFREI{b0f_t0_w1n}

Dernière mise à jour

Cet article vous a-t-il été utile ?