Nous allons ici aborder 2 outils extrêmement pratiques pour FreeBSD permettant d'empêcher les attaques de type buffer overflow consistant à dépasser une mémoire tampon statique pour écrire un code original exécuté avec les droits du programme dont dépend ce buffer. Nous disposons de libparanoia et du gcc protector patch.

libparanoia est une librairie qui intercepte les appels à des fonctions présumées sensibles et les remplace par des fonctions similaires en tous points et fonctionnalités, à la seule différence que ces fonctions sont modifiées pour empêcher toutes tentatives de corruption de la stack mémoire ce qui permet de nous prévenir des failles de type stack overflow ou return-into-libc très documentées et largment répandues ces dernières années. Les fonctions ANSI C présumées sensibles sont strcpy, strcat, gets, sprintf et scanf qui sont connues pour être souvent exploitées à des fins illégitimes. Le problème essentiel vient du fait que le langage C n'inclut aucunes techniques natives de vérification lorsque nous manipulons des variables dans une mémoire tampon permettant à l'occasion d'écrire dans cette mémoire afin d'y faire exécuter diverses commandes pouvant entraîner jusqu'à la compromission du compte root. L'idée de base de libparanoia est de ne jamais exécuter de nouvelles instructions suite à ces fonctions si la stack a été modifié. On preferera alors tuer le processus ou appeler une fonction d'exit. La méthode peut paraître brutale mais ceci suppose une corruption de la mémoire tampon de ce programme et dans ce contexte entraver un instant le bon déroulement d'un programme ou d'un unique processus parait bien moins grave que de risquer la comprimission complète du système. Nous installons libparanoia depuis le port tree à /usr/ports/security/libparanoia. Nous vous recommendons ensuite d'exécuter le script copy-to-libc qui permet de patcher directement la libc FreeBSD quelqu'en soit la version.

huyhuy# ./copy-to-libc

Le GCC Protector Patch consiste en une série de vérification effectuée directement par le GNU Compiler Collection lors de la compilation de programmes. Il tire une partie de ses techniques du travail effectué pour le patch StackGuard pour Immunix OS, une distribution Slackware GNU/Linux renforcée par une série de patchs de sécurité. Ainsi, il utilise une guard variable inserée juste après le précédent frame pointer. Ainsi elle protège les arguments, l'adresse de retour et le précédent frame pointer. Il est par ailleurs supérieur dans la pile à un tableau ou une string. La valeur de cette variable est aléatoire ainsi un attaquant ne peut pas la calculer pour la contourner. Par ailleurs, le GCC protector patch introduit un modèle de fonction sûre (Safety Protection Model) avec quelques limitations d'usage de la pile.

                    |------------------------|
                    |       arguments        |
                    |------------------------|
                    |     return adress      |
                    |------------------------|
                    | previous frame pointer |
                    |------------------------|
                    |         guard          |
                    |------------------------|
                    |        arrays          |
                    |------------------------|
                    |     local variables    |
                    |------------------------|

Suivant ce modèle, les données en mémoire en dehors d'une fonction ne peuvent pas être endommagées lorsque la fonction retourne et les attaques sur les pointeurs en dehors ou au sein de la fonction ne passeront pas dû aux limitations d'usage de la pile. Toutes ces protections se heurtent bien sûr aux limitations du langage C, par exemple on ne peut protéger un pointeur faisant parti d'une structure contenant également un tableau puisque le réagencement est interdit. Ou encore, l'utilisation des options d'optimisation de GCC peut entraîner la non utilisation des protections du patch. Cependant, le GCC Protector Patch reste une option intéressante dans la lutte contre les attaques par stack overflow. Pour l'installer et construire FreeBSD avec cette protection, nous devons d'abord patcher GCC puis le construire indépendemment du système.

huyhuy# cd /usr
huyhuy# patch -p1 < protector.patch

huyhuy# cd /usr/src/gnu/lib/libgcc
huyhuy# make depend && make all install clean

huyhuy# cd /usr/src/gnu/usr.bin/cc
huyhuy# make depend && make all install clean

Puis avant d'effectuer les opérations de recompilation de FreeBSD, nous définissons la variable d'environnement CFLAGS indiquant les options à passer au compilateur

huyhuy# setenv CFLAGS=-O -pipe -fstack-protector

A noter que l'options -fstack-protector et son opposé -fnostack-protector passées à GCC permettent d'activer ou non la protection du patch. Nous mettons maintenant la libc à jour.

huyhuy# cd /usr/src/lib/libc
huyhuy# make depend && make all install clean

Et nous n'avons plus qu'à recompiler le monde ! Ce patch est valable depuis FreeBSD 4.3 et fonctionne avec les versions de GCC 2.95.2, 2.95.3 et 3.0. Plus d'informations à http://www.trl.ibm.com/projects/security/ssp/. Des problèmes peuvent apparaîtres à la compilation de programmes comme Xfree (comme d'hab') n'utilisant pas la varibale d'environnement CFLAGS.

– eberkut

freebsd/stack_smashing.txt · Last modified: 2010/01/12 13:29 (external edit)