Faille

Il est parfois difficile de trouver un bon sujet d'article, je peux y passer des heures. Je pensais en voir trouvé un excellent, le sujet était « La vie des chiens chez les Inuits ». Mais on m'a dit, que le sujet était un peu trop polémique, et pas assez fédérateur. Qu'à cela ne tienne, un nouveau brainstorming avec moi-même. Puis... Bon dieu, mais c'est bien sûr...
L'Idée, le Sujet sans qui la sécurité informatique ne serait pas vraiment ce qu'elle est. LA vulnérabilité, LA faille... en deux mots, Buffer Overflow (ou dans la langue de Victor Hugo, le dépassement de tampon). « Bue feur oh vert flot, kezako ? ». Pas d'insultes, s'il vous plait... Ce n'est pas un bon sujet ? Tout logiciel passé ou à venir aura au moins une vulnérabilité de type buffer overflow, ceci est un axiome qui peut même se démontrer (c'est dire) vu la complexité grandissante des logiciels. Ceci est la conséquence directe de la non validation de la longueurs des tampons mémoires ou de la non vérification des données copiées dans ce tampon.

Un exemple simple
Char buf [100] ;
...
Buf [101] = 'dommage' ;

Dans ce cas, tout à fait correct pour le compilateur d'un point de vue syntaxe, on crée un débordement sur... on ne sait pas, une partie de la mémoire, qui peut entrainer un plantage du programme, et une possibilité (ceci est à définir) de prendre le contrôle de la machine entière. Pourtant, ce type d'erreur pourrait être aisée à annihiler, il est « facile » de contrôler les variables, il suffit d'avoir les bonnes pratiques de programmation. Plus « facile » à dire qu'à faire à en croire la pratique et la réalité.

Afin de mieux comprendre pourquoi ce dépassement peut être un problème, il faut se rappeler comment un système d'exploitation gère sa mémoire. Chaque programme a besoin de mémoire pour fonctionner, et en gros la mémoire est divisé en trois parties :
  • La mémoire fixée pour le programme qui contient le code lui-même, des données statiques
  • La file (heap) qui est utilisée pour stocker les données dynamiques
  • La pile utilisée pour passer des variables aux fonctions ou à d'autres programmes

Seulement voilà les deux dernières parties sont gérées dynamiquement, la file s'étend en commençant par les adresses basses, la pile fait exactement le contraire. Et ce qui peut arriver arrive, si l'on passe un argument trop gros à la pile, il sera traité, et ira donc dans la file, et débordera sur la mémoire allouée à la pile, dans ce cas, le pointeur de pile est modifié, donc l'adresse de retour est modifiée, donc fini le programme... L'attaque la plus simple se rapproche donc d'un deni de service du programme. Mais elle peut être plus ambitieuse, on peut positionner dans la pile une adresse de retour correspondant au petit programme malicieux qui permettra de prendre le contrôle. Je ne m'appesantirai pas sur la façon de faire, il existe sur Internet une littérature abondante sur ce sujet, par exemple « Smash the Stack for Fun and Profit que vous trouverez sur http://www.phrack.org) .

Il existe bien des méthodes à postériori pour essayer d'éviter cette plaie, comme des audits de code par exemple, ou une meilleure protection des systèmes grâce à des HIPS. Mais, il faut le répéter ce ne seront que des rustines, la seule méthode fiable est de sensibiliser à la sécurité les programmeurs, c'est-à-dire à l'amont de tout projet de développement. Afin qu'ils puissent contrôler tous les types d'entrée de variables du programme (soit par saisie directe, soit par passage de paramètre à la pile).

Nicolas Jacquey
Philippe Maltere

_