• Aucun résultat trouvé

Débordements de tampon

Dans le document Sécurité Sécurité (Page 113-118)

Si vous consultez un site de publication de listes de vulnérabilités, par exemple celui de Security Focus1, vous verrez apparaître avec une fréquence étonnante la phrase «A buffer overflow allows remote attackers to execute arbitrary code...» (« Un

1. Cf.http://www.securityfocus.org/

débordement de tampon permet à un agresseur à distance d’exécuter un code ar-bitraire... »), c’est-à-dire que cet agresseur est en mesure de prendre le contrôle de l’ordinateur affecté et d’en faire n’importe quoi, ce qui représente la gravité maximale pour un incident de sécurité.

De quoi s’agit-il ? D’une maladie fréquente qui fait l’objet d’une entrée dans Wiki-pédia2et de nombreux articles détaillés, celui-ci3parmi beaucoup d’autres. Nous commencerons par en exposer un cas particulier très significatif, qui a le mérite de bien faire comprendre le principe du mécanisme, puis le cas général.

Mais il convient d’abord de préciser ce que l’on entend par tampon (buffer) : ce terme désigne en général une zone de mémoire utilisée par le système d’exploita-tion pour stocker temporairement des données en provenance du (ou en partance vers le) monde extérieur. Plus généralement il s’agira ici d’une zone de mémoire utilisée par un programme pour y manipuler un texte, au sens le plus général.

Attaques par débordement sur la pile

La revue Communications of the Association for Computer Machinerya récemment publié un article[71]qui décrit en détail un cas particulier d’attaque par déborde-ment de tampon, celui qui survient sur lapiledu programme.

Le principe en est le suivant : un programme en cours d’exécution note dans un coin (comme sur un post-it) l’adresse à laquelle revenir quand il aura fini son travail (la notion d’adresse est précisée plus bas). L’attaquant cherchera à modifier cette adresse de retour pour la remplacer par celle d’un programme malveillant installé par ses soins.

Le « coin » où cette adresse de retour est notée se situe dans une zone nommée pile d’exécution du programme. Une pile est une structure de données, une façon d’organiser un ensemble de données, telle que la dernière donnée introduite sera la première à être obtenue, on parle d’organisation LIFO, commelast in, first out, comme pour une pile d’assiettes, où la première à prendre sera celle du dessus, qui a été déposée la dernière. Pour extraire les données de la pile, on utilise un pointeur; un pointeur est une donnée dont la valeur est un moyen d’accès à la valeur d’une autre donnée ; par exemple la valeur du pointeur peut être le numéro

2. Cf.http://fr.wikipedia.org/wiki/Buffer_overflow

3. Cf.http://c2.com/cgi/wiki?CeeLanguageAndBufferOverflows

de la case mémoire où se trouve la valeur de la donnée pointée par lui, autrement dit ce que l’on appelle habituellement sonadresse. Lepointeur de pile (stack pointer) est une donnée qui contient l’adresse du dernier élément empilé, ou en d’autres termes l’adresse du sommet de la pile.

Un programme est généralement constitué de plusieurs sous-programmes ; à chaque sous-programme correspondent des données locales : les valeurs des pa-ramètres transmis lors de l’appel du sous-programme, des variables locales dont la durée de vie est limitée à la période d’activité de ce sous-programme, et sur-tout l’adresse de retour vers le programme appelant, c’est-à-dire l’adresse de l’ins-truction qui devra être exécutée à la fin du sous-programme. L’ensemble de ces données locales constitue le bloc d’activation (activation record)4 de cet appel au sous-programme, aussi appelécadre de pile (stack frame).

La pile d’exécution d’un programme est une pile de blocs d’activation. Lors d’un appel à un sous-programme, le bloc d’activation (ou cadre de pile) correspon-dant est créé et stocké sur la pile du programme. Lorsque le sous-programme se termine, ce cadre de pile est détruit et le pointeur de pile pointe vers le cadre précédent, qui est celui du programme appelant.

On observe qu’une telle organisation en pile autorise que soient présents en mé-moire à un instant donné les blocs d’activation de plusieurs appels emboîtés au même sous-programme, ce qui est indispensable pour les programmes récursifs, qui s’appellent eux-mêmes ; ainsi chaque instance du sous-programme possède son propre bloc d’activation, avec ses variables locales et ses arguments, sans in-terférence avec les autres instances. La figure 5.2 représente la pile d’un processus Unix ; on notera qu’elle croît à l’envers, son sommet est vers le bas (vers les adresses de plus faibles valeurs) ; letasest une autre région de la mémoire du programme, où sont allouées les zones nécessaires à des données de plus grande taille, tels les tableaux.

Un débordement de tampon sur la pile consistera à altérer de façon fautive mais soigneusement calculée, dans un programme légitime, une variable locale de type chaîne de caractères, de façon que l’adresse de retour soit écrasée par l’adresse du

4. Les auteurs de langue française traduisent souventactivation recordparenregistrement d’acti-vation, qui me semble moins approprié quebloc d’activation.

Figure 5.2 La pile d’un processus Unix

code malicieux placé là par le pirate ; ainsi ce sera ce code qui s’exécutera à la fin de l’exécution du sous-programme.

ALTERNATIVE Faire croître la pile vers le haut ?

Christian Queinnec me fait observer la chose suivante : cette possibilité d’écraser l’adresse de retour d’un programme par un débordement de tampon résulte uniquement du choix des concepteurs d’Unix (imités par de nombreux suiveurs) de faire croître la pile vers le bas ; si les blocs d’activation s’empilaient dans l’autre sens, les débordements de tampons écraseraient sans doute des choses, mais pas l’adresse de retour. Il y a bien sûr des raisons à ce choix de conception : faire croître la pile et le tas en sens inverse simplifie l’utilisation de la mémoire, procéder autrement poserait d’autres problèmes, mais devant l’abondance des failles qui reposent sur ce dispositif, on devrait au moins se poser la question.

L’article des CACM cite quelques attaques réussies par débordement de tampon sur la pile, et énumère plusieurs remèdes de nature à les prévenir :

1. les développeurs du projetOpenBSDpassent en revue le code de l’ensemble de leur système pour y repérer les séquences d’instructions affectées par une telle vulnérabilité, et ajouter des contrôles de nature à vérifier la longueur des chaînes de caractères concernées ; ils ont créé, pour les aider dans ce travail de bénédictin, des logiciels qui automatisent une partie des opérations ; 2. il existe des logiciels ou des bibliothèques de sous-programmes qui

instru-mentent le compilateur de façon qu’il insère automatiquement des contrôles adéquats dans le programme compilé :

StackGuard place dans la pile un marqueur spécial, et détecte grâce à lui toute altération anormale de l’adresse de retour,

StackShield modifie le comportement du compilateur gcc de façon à ce qu’il insère dans le programme compilé des séquences d’instructions des-tinées à maintenir une copie de secours de la pile des adresses de retour, et à détecter ainsi toute altération anormale de la pile du processus,

RAD est une modification du compilateur gccqui insère au début et à la fin des appels de fonctions des instructions qui recopient la pile des adresses de retour, un peu commeStackShield;

3. il existe également un projet baptiséSmashGuard qui se propose d’implan-ter les opérations destinées à protéger la pile contre les débordements de tampons dans le matériel, par la modification des instructions d’appel et de retour de fonction, ce qui éviterait d’une part de modifier ou de recompi-ler d’innombrables logiciels, d’autre part de détériorer les performances des systèmes en voulant les rendre plus sûrs.

CULTURE gcc

gccest le compilateur de base du projet GNU. Un compilateur est un programme qui traduit le texte d’un programme vers un langage de plus bas niveau, souvent le langage machine de l’ordinateur sur lequel on souhaite que le programme s’exécute. Initialement conçu pour le langage C,gccsert désormais à traduire d’autres langages, tels que C++, Ada ou Java. C’est un logiciel libre.

Dans le document Sécurité Sécurité (Page 113-118)