La sécurité informatique et internet au service des entreprises
Accueil | Produits & Services | Boutique | Documentation | Partenaires | Références | A propos | Contact | Flux RSS Recherche 
 

Services en sécurité informatique : appliances audits formations
SecuriteInfo.com AntiPub
SecuriteInfo.com Appliance de sécurité
Prestations d'Audits : audit intrusif, de vulnérabilités, ...
Recouvrement de mot de passe
Formations
Le grand livre de Securiteinfo.com sécurité informatique et internet
Le grand livre de Securiteinfo.com sécurité informatique et internet
Tout notre savoir faire en 299 pages. Commandez le maintenant !
Initiation a la sécurité informatique
Qu'est-ce que le piratage informatique ?
Introduction à la sécurité informatique
Sécurisation de vos données informatiques : Quels enjeux pour votre entreprise ?
Principes de sécurité informatique et évolution du marché
Initiation à la cryptographie
Principaux types d'attaque
Open Source et sécurité
Modélisation de la sécurité informatique
Le Compartemented Mode Workstation
Le modèle "Bell La Padula"
La méthode FEROS
Classes de Fonctionnalité
Les contrats de licence et la Sécurité Informatique
Laboratoire et expérimentations en sécurité informatique
LibClamAV Warning : RAR code not compiled-in
myServer 0.7
TrackMania DoS
Pablo FTP 1.77
CuteNews 1.3
myServer 0.4.3
Pablo Baby Web Server 1.51
Téléchargement
Ebooks
WinSSLMiM
WinTCPKill
WinDNSSpoof
ICMP Shell Detect
Domino Hash Breaker
Les buffers overflow


Qu'est-ce que c'est ?

Un buffer overflow est une attaque très efficace et assez compliquée à réaliser. Elle vise à exploiter une faille, une faiblesse dans une application (type browser, logiciel de mail, etc...) pour executer un code arbitraire qui compromettra la cible (acquisition des droits administrateur, etc...).



En bref

Le fonctionnement gébéral d'un buffer overflow est de faire crasher un programme en écrivant dans un buffer plus de données qu'il ne peut en contenir (un buffer est un zone mémoire temporaire utilisée par une application), dans le but d'écraser des parties du code de l'application et d'injecter des données utiles pour exploiter le crash de l'application.

Cela permet donc en résumé d'exécuter du code arbitraire sur la machine où tourne l'application vulnérable.

L'intérêt de ce type d'attaque est qu'il ne nécessite pas -le plus souvent- d'accès au système, ou dans le cas contraire, un accès restreint suffit. Il s'agit donc d'une attaque redoutable. D'un autre côté, il reste difficile à mettre en oeuvre car il requiert des connaissances avancées en programmation; de plus, bien que les nouvelles failles soient largement publiées sur le web, les codes ne sont pas ou peu portables. Une attaque par buffer overflow signifie en général que l'on a affaire à des attaquants doués plutôt qu'à des "script kiddies".



Technique

Le problème réside dans le fait que l'application crashe plutôt que de gérer l'accès illégal à la mémoire qui a été fait. Elle essaye en fait d'accéder (lire, exécuter) à des données qui ne lui appartiennent pas puisque le buffer overflow a décalé la portion de mémoire utile à l'application, ce qui a pour effet (très rapidement) de la faire planter.


D'un point de vue plus technique, la pile (stack en anglais) est une partie de la mémoire utilisée par l'application pour stocker ses variables locales. Nous allons utiliser l'exemple d'une architecture intel (32 bits). Lors d'un appel à une sous-routine, le programme empile (push) le pointeur d'instruction (EIP) sur la stack et saute au code de la sous-routine pour l'exécuter. Après l'exécution, le programme dépile (pop) le pointer d'instruction et retourne juste après l'endroit où a été appelée la sous-routine, grâce à la valeur d'EIP. En effet, comme EIP pointe toujours vers l'instruction suivante, lors de l'appel de la sous-routine il pointait déjà vers l'instruction suivante, autrement dit l'instruction à exécuter après la sous-routine (= adresse de retour).


D'autre part, lors de l'appel de la sous-routine, celle-ci va dans la majorité des cas créer sa propre pile dans la pile (pour éviter de gérer des adresses compliquées). Pour cela elle va empiler la valeur de la base de la pile (EBP) et affecter la valeur du pointeur de pile (ESP) à celle de la base (EBP).




  • ESP est le pointeur du sommet de la pile.

  • EBP est le pointeur de la base de la pile.

  • EIP est le pointeur de la prochaine instruction à exécuter. Il pointe donc toujours une exécution en avance.



En résumé, on sauvegarde la valeur originale de la base et on décale le tout ensuite. Lors du retour de la sous-routine, on dépile EBP et réaffecte sa valeur originale pour restaurer la pile initiale.


Voici pour le déroulement "normal" des opérations. Un point intéressant à citer est le fait que dans notre architecture, les zones mémoires allouées dans la stack se remplissent dans le sens croissant des adresses (de 0..0H à F..FH) ce qui semble logique. Par contre, l'empilement sur la stack s'éffectue dans le sens décroissant! C'est-à-dire que l'ESB originale est l'adresse la plus grande et que le sommet est 0..0H. De là naît la possibilité d'écraser des données vitales et d'avoir un buffer overflow.
En effet, si notre buffer se trouve dans la pile d'une sous-routine et si nous le remplissons jusqu'à déborder sa taille allouée, nous allons écrire par-dessus les données qui se trouvent à la fin du buffer, c'est-à-dire les adresses qui ont été empilées précédement : EBP, EIP... Une fois la routine terminée, le programme va dépiler EIP et sauter à cette adresse pour poursuivre son exécution. Le but est donc d'écraser EIP avec une adresse différente que nous pourrons utiliser pour accéder à une partie de code qui nous appartient. (par exemple le contenu du buffer)
Un problème à ce stade est de connaitre l'adresse exacte de la stack (surtout sous Windows) pour pouvoir sauter dedans. On utilise généralement des astuces propres à chaque système (librairies, etc..) qui vont permettre -indirectement- d'atteindre notre stack et d'exécuter notre code. Cela nécessite un débogage intensif qui n'est pas à la portée de tout le monde...



Solutions

  • Lors du développement : propreté du source (utiliser malloc/free le plus possible, utiliser les fonctions n comme strncpy pour vérifier les limites...), utilisation de librairies de développement spécialisée contre les buffers overflow (Libsafe d'Avayalabs)

  • Utiliser un langage n'autorisant pas ce type d'attaques : Java, Cyclone (qui est issu du C).

  • Utiliser des logiciels spécialisés dans la vérification de code source, comme par exemple Qaudit ou Flawfinder. Article français sur Flawfinder

  • Auditer le programme compilé à l'aide d'outils tels que BFBTester. Article français sur BFBTester

  • Appliquer le plus rapidement possible les patches fournis par les développeurs.

  • Fiabiliser l'OS pour qu'il ne soit pas vulnérable aux debordement de buffer, par exemple : grsecurity pour Linux.




SoGoodToBe
04 Juin 2001
Cybercriminalité : le piratage politique
Que faire lors d'une attaque ?
Cybercriminalité : Comment porter plainte ?
La cryptographie à algorithmes symétriques
Les mots de passe à usage unique (OTP : One Time Password)
Le chiffrement AES
Les fonctions de hachage
Attaques et faiblesses du SSL : Secure Socket Layer
Le tunneling
IPSec
Choisir un mot de passe robuste
Les firewalls
Les antivirus gratuits en ligne et professionnels
La biométrie : L'informatique au service de l'authentification des personnes
Sécurité des réseaux Wifi et Wardriving
Les enjeux sécuritaires de la 3G
Les sauvegardes : enjeux et choix des supports
Les différents types de malwares
Comment les malwares se cachent parmis vos fichiers
Chevaux de Troie (ou Trojans) expliqués
Fonctionnement des Key Loggers (enregistreurs de touches)
Découverte des Espiogiciels (Spywares)
La collecte d'information grâce au Social Engeeriering
Explication du fonctionnement des emails de Spam Images
IP Spoofing
DNS Spoofing
Buffer Overflow
Deni de Service Distribué (DDoS)
Challenges de hacking