Source : https://tryhackme.com/room/bof1

L’objectif de cette exercice est de modifier le fonctionnement normal du programme pour qu’il execute une fonction qu’il n’est pas censé pouvoir executer.

Apres s’être connecté en ssh à a machine, on trouve le code c du programme :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void special()
{
printf("this is the special function\\n");
printf("you did this, friend!\\n");
}
void normal()
{
printf("this is the normal function\\n");
}
void other()
{
printf("why is this here?");
}
int main(int argc, char **argv)
{
volatile int (*new_ptr) () = normal;
char buffer[14];
gets(buffer);
new_ptr();
}

Pour que les adresses mémoire soient cohérentes entre l’exécution normale et le débogueur, il est recommandé de désactiver certaines variables d’environnement dans GDB :

1
set exec-wrapper env -u LINES -u COLUMNS

Maintenant que GDB est préparé, on peut essayer de faire crasher le program. D’après le code source, la taille de buffer[] est de 14 donc on sait le nombre de caractere que l’on peut saisir avant le crash.

Si on ajoute un caractere on obtient alors :

Il ne faut pas oublier qu’en C, les chaines de caractes se termine par le byte null \0 donc en réalité notre chaine de 14 caracteres en fait 15 ce qui provoque l’overflow.

En testant 15 A, on voit que l’on peut modifier la valeur du registre EIP :

A correspond à \x41 en hexadécimale donc on voit qu’à partir du 15 A on peut controler ce qui est écrit en mémoire. Voyons jusqu’ou on peut aller :

Avec 20 A, on voit qu’on remplit entierement l’espace mémoire et qu’avec 21 A me programme nous redirige vers une autre instruction. On peut en déduire le nombre d’octes dont l’on dispose pour l’over flow en faisant 20 – 14 = 6 bytes

Ensuite, pour utiliser la fonction special(), on récupérer l’adresse à laquelle elle commence :

Ainsi, en utilisant cette adresse (que l’on convertie en little endian en inversant l’ordre des octets), on peut injecter cette adresse dans le registre EIP :