C'est quoi un buffer over flow ?

Publié le par k'

Dans l'articles précedent, on a parlé d'un buffer over flow mais beacoup de personne de personnes m'ont reproché a juste cause ne pas avoir expiqué ce que c'était donc je fais essayer de me ratrapper ici.
I°) Qu'est-ce qu'un buffer-overflow ?

   La traduction littérale suffit à expliquer le terme : c'est un dépassement du buffer, aussi appellé dépassement de mémoire tampon en français. Cela peut arriver très fréquemment. En effet, les langages de haut-niveau laissent au programmeur le soin de vérifier la non-corruption des données, entre autres de vérifier que les longueurs limites des tableaux ne peuvent en aucun cas être dépassées dans le programme. Concrètement, si le dépassement est petit, il va juste corrompre les variables qui suivent le buffer. S'il est un peu plus grand, il peut changer la valeur des deux pointeurs SFP et return address, causant bien souvent le crash du programme, puisque ces pointeurs sont par la suite dénués de sens (par exemple, si le pointeur EIP contient une adresse où il n'y a pas d'instruction valide, le programme s'interrompt avec le message d'erreur Segmentation Fault ou Illegal Instruction). Voici un exemple simple d'overflow :

      //exemple-overflow.c : Dépassement de mémoire tampon

      #include < stdio.h >

      void demander_nom() {
            char buffer_nom[20];

            printf("Entrez votre nom\n");
            scanf("%s",&buffer_nom);

            printf("Votre nom est %s\n",buffer_nom);
      }

      int main() {
            demander_nom();

            return 0; }

La fonction printf imprime à l'écran un texte et scanf stocke ce qui est entré au clavier dans la variable buffer_nom. Ces fonctions sont contenues dans la librairie C stdio.h, c'est pourquoi on a inclut cette librairie au début du programme. Le caractère '\n' est quand à lui le caractère de retour à la ligne. Voici maintenant des exemples d'éxécutions de ce programme :

      $ gcc exemple-overflow.c -o exemple-overflow
      $ ./exemple-overflow
      Entrez votre nom
      SeriousGamers1
      Votre nom est SeriousGamers1
      $ ./exemple-overflow
      Entrez votre nom
      AAAAAAAAAAAAAAAAAAAAAAA
      Votre nom est AAAAAAAAAAAAAAAAAAAAAAA
      $ ./exemple-overflow
      Entrez votre nom
      AAAAAAAAAAAAAAAAAAAAAAAA
      Votre nom est AAAAAAAAAAAAAAAAAAAAAAAA
      Instruction illégale
      $


Nous avons donc l'exemple classique où l'utilisateur fournit un nom, plus petit que 20 caractères et où tout se passe bien. Dans le second exemple, on fournit exactement 23 fois le caractère 'A'. Le tableau ayant une taille de 20 octets, toutes ses cases seront remplies de A, 3 caractères à placer plus le nul byte. Par conséquent, l'espace du tableau va être dépassé et le pointeur SFP va être réécrit, en l'occurence remplacé par 0x41414100 (le caractère 'A' s'écrivant 0x41 en hexadécimal). Nous avons donc un overflow, mais ici sans incidence sur la suite du programme, car le pointeur EBP n'a plus d'utilité après la fonction, même s'il devient 0x00414141 qui est une addresse sans signification, celà n'a pas d'effet.
Dans le troisième cas, on a fournit un caractère de plus, à savoir 24 caractères. On devine rapidement ce qui se passe : le SFP deviendra cette fois 0x41414141 et le return address 0x00563412. L'EIP va donc pointer vers 0x12345600 après le popping de demander_nom(), où il va trouver une instruction qui ne sera pas valide, d'où le crash du programme.
On s'en doute, l'exploitation des buffer-overflows va consister en l'exploitation de ce type de faille. Cet exemple est basé sur un overflow dans la pile. L'exploitation associée sera dénommée stack-based overflow et sera notre premier "BoF" (enfin !)

Publié dans Exploit

Pour être informé des derniers articles, inscrivez vous :

Commenter cet article