Format string attack

Un article de Haypo.

Retour aux articles de sécurité

Sommaire

[modifier] Introduction

Les failles de sécurité de type format string attack sont issues des fonctions du type printf (et tous ses dérivés comme vsprintf) qui sont mal utilisée. L'exemple le plus simple est :

#include <stdio.h>
#include <stdlib.h>
void main()
{
    char name[30];
    int i;
    name[0] = '\0'; // Lit une chaîne, initialise la chaîne à vide
    (void)fgets(name, sizeof(name), stdin); //  pour gêrer le cas où fgets échoue
    printf(name); // *** ICI ***
    exit(EXIT_SUCCESS);
}

L'erreur est que le premier argument des fonctions de type printf est une chaîne de caractère d'un type spécial car elle peut contienir des commandes comme "%s" (afficher une chaîne de caractère) ou "%d" (afficher un nombre), mais la liste est très longue !

Cette erreur peut être très dangeureuse, c'est ce que nous allons voir.

[modifier] Planter un programme

Pour faire un planter un programme, il suffit de demander d'afficher des chaînes de caractère. Comme le contenu de la pile est aléatoire, le programme voudra forcément afficher des données en dehors de son espace mémoire. Ce qui donne :

$ echo "%s%s%s%s%s%s%s%s%s" | ./exemple
Erreur de segmentation

[modifier] Afficher le contenu de la pile

$ echo '%08X - %08X - %08X - %08X - %08X - %08X - %08X\n' | ./exemple
0000001E - B7F590A0 - B7E8A57E - B7F57FF4

Tiens, apparement je suis limité à 4 ou 5 mots mémoire. Variante :

$ echo '%p - %p - %p - %p - %p - %p - %p - %p\n' | ./exemple
0x1e - 0xb7ef40a0 - 0xb7e2557e - 0xb7ef2ff4 - 0xb7ef1604 - 0xbf923398

Encore mieux : on peut indiquer l'index du nombre qu'on veut accéder :

$ echo '%2$p\n' | ./exemple
0xb7ef40a0

On retrouve bien notre 2ème mot mémoire.

[modifier] Ecrire dans la pile

Le format "%n" est un peu spécial car il stocke le nombre de caractère écrit par la fonction printf. Exemple :

 int      a;
 printf ("%10u%n", 42, &a);
 /* Ici : a=10 */
 printf ("%150u%n", 7350, &a);
 /* Et là ... a=150 !*/

Variations :

  • %n : Mot mémoire
  • %hn : "short" (16 bits)
  • %hhn : "char" (8 bits)

[modifier] Liens externes