Ghost (Vulnérabilité)
Ghost est une faille de sécurité basée sur un dépassement de mémoire tampon causé par les fonctions « gethostbyname » , « gethostbyname2 », « gethostbyaddr » des librairies glibC 2.2 et celles antérieures à la version 2.18 de Linux. Cette faille permet à un attaquant d’exécuter, en fonction du contexte, du code arbitraire et ainsi de prendre le contrôle du système. Elle concerne à la fois les serveurs, les routeurs ou encore les NAS utilisant Linux.
Historique
La première apparition de ce type de faille dans glibc remonte à 2000 et avait été corrigée le , entre les versions 2.17 et 2.18 de glibc[1] - [2]. Toutefois, le risque pour la sécurité des systèmes ayant été sous-évalué, l’essentiel des distributions Linux stables bénéficiant d'un support n’ont pas aussitôt appliqué de correction à leur librairie. La raison avancée par les éditeurs est celle d’un problème de compatibilité[1].
Ghost a été découvert par la société Qualys, fournisseur d’information de sécurité, en . Avant de divulguer la faille officiellement le , Qualys a signalé le problème aux éditeurs de distributions Linux, qui ont rapidement mis au point des correctifs. Des mises à jour sont notamment disponibles pour Debian, Ubuntu et Red Hat[3]. Compte tenu du nombre d’applications basées sur glibc, Ghost est depuis le considéré comme une vulnérabilité sévère qui doit être corrigée immédiatement. La vulnérabilité Ghost est aujourd’hui classifiée par la NCAS[note 1] américaine à la valeur 10, c’est-à-dire au niveau haut, et porte la référence CVE-2015-0235[4].
Sévérité CVSS (version 2.0)
Score: 10.0 |
Metriques CVSS
Vecteur d'accès: Exploitable par le réseau |
Principe
Ghost exploite une faille logée dans la libraire GNU/Linux nommée glibC. Cette dernière, intégrée dans toutes les distributions de Linux, permet de gérer les appels système de bas niveau, telles l’allocation d’espace mémoire, l’ouverture des fichiers, etc. La vulnérabilité est basée sur un dépassement de mémoire tampon dans les fonctions « gethostbyname » ou « gethostbyaddr » impliquées dans le mécanisme de résolution de nom DNS. Ces fonctions sont appelées par les applications Linux pour gérer les connexions Internet, à l’image des serveurs de messagerie par exemple.
La fonction « gethostbyname() » renvoie une structure de type hostent pour l'hôte « name ». La chaîne « name » est soit un nom d'hôte, soit une adresse IPv4 en notation pointée standard, soit une adresse IPv6 avec la notation points-virgules et points[5]. La fonction gethostbyaddr() renvoie une structure du type hostent pour l'hôte d'adresse « addr ». Les types d'adresse valides sont IPv4 ou IPv6[5]. L’objectif du dépassement de tampon est la mise en échec de la fonction en écrivant dans sa zone zone mémoire temporaire(buffer) plus de données qu’elle ne peut en contenir, afin d’écraser son code et de lui substituer du code malveillant.
- Le dépassement de tampon
Lors de l’appel de la fonction, le programme empile le pointeur d’instruction (@EIP[note 2]) dans la pile. Ceci afin d’avoir l’adresse de retour après l’exécution de la fonction et ainsi enchainer vers l’instruction suivante. Par ailleurs, l’appel de la fonction va généralement créer sa propre pile dans la pile pour simplifier sa gestion d’adressage. Elle va alors empiler l’adresse absolue de la base de la pile (@EBP[note 3]) et affecter la valeur du pointeur de la pile (@ESP[note 4]) à celle de la base(@EBP[note 3] pour la fonction). Ainsi, au dépilement après l’exécution de la fonction, l’adresse absolue de la base sera réaffectée et la pile réinitialisée[6].
Il faut savoir toutefois que l’allocation de la mémoire temporaire se décompose en deux parties :
- Le tas[note 5] qui correspond à la zone mémoire réservée temporairement pour le code, et les variables globales. Le tas se situe dans la partie d’adressage basse.
- La pile[note 6] qui correspond à la zone mémoire réservée dans les cadres d’appel à des fonctions (ou procédures), et les variables d’environnement. La pile se situe dans la partie d’adressage haute.
La grande différence entre ces deux zones est le sens d’empilement : il est croissant pour le tas, et décroissant pour la pile. Pour la pile, la première adresse empilée possède la valeur la plus grande, et la dernière adresse empilée possède la valeur la plus faible. Comme le sens de lecture de la mémoire reste dans le sens croissant, un dépassement de tampon dans la pile permet alors l’écrasement des registres contenant EBP et EIP. Par ce principe, un pirate peut remplacer la valeur d’EIP par une adresse pointant vers du code malveillant logé dans la zone tampon utilisée. Néanmoins, cela demande au pirate de connaitre l’adresse exacte de la pile pour assurer le saut d’adresse utilise à l’exécution de son code arbitraire[7].
- Ghost dans les faits
Les fonctions gethostbyname() et gethostbyaddr() provoquent le débordement de tampon lors de l’appelle à une autre fonction __nss_hostname_digits_dots()[8]. Celle-ci est appelée pour vérifier l’hôte ‘name’. Cette fonction contient en fait une erreur de code dans le calcul de la taille de son buffer si ‘name’ est une adresse IP[2].
En effet, son buffer est fixé à une taille size_needed ne considérant que trois entités de registre mémoire : host_addr, h_addr_ptrs et name. Toutefois , la fonction charge dans le buffer quatre entités de registre mémoire : host_addr, h_addr_ptrs , name et h_alias_ptr. C’est dans ce cas que le buffer peut s’avérer trop petit pour contenir un hôte 'name' très grand et ayant la forme d’une adresse IP « a.b.c.d », « a.b.c », « a.b », ou « a ».
Impact
Pour le mois de [9], les logiciels identifiés vulnérables sont :
- Clockdiff,
- Procmail (au travers des fonctionnalités comsat/biff),
- Point-to-Point Protocol daemon (en),
- Exim (lorsque les options « helo_verify_hosts » et « helo_try_verify_hosts » sont activées, ce qui n'est pas le cas par défaut),
- L’interpréteur PHP.
À noter aussi que les sites qui utilisent Wordpress (système de gestion de contenu CMS) pourraient être vulnérables avec la page « xmlrpc.php » par défaut qui utilise la fonctionnalité de notification « pingback ».
À ce titre, les distributions suivantes sont identifiées comme vulnérables :
OS | Distributions | Versions |
---|---|---|
Linux | Red Hat Enterprise | 5.x, 6.x et 7.x |
Linux | CentOS | 5.x, 6.x & 7.x |
Linux | Ubuntu | 10.04, 12.04 LTS |
Linux | Debian | 7.x |
Linux | Fedora | 19 et ultérieurs |
Linux | SUSE | 11 et ultérieurs |
Linux | Arch Linux avec Gblic | inférieure ou égale à 2.18-1 |
Linux | Mint | 13.0 |
Depuis 2013, ce type de vulnérabilité, désignée "A9 - Utilisation de composants avec des vulnérabilités connues", est entré dans le top10 d'OWASP (Open Web Application Security Project)[10]. Cela s’explique par le fait que les développements utilisent de plus en plus des composants. Par conséquent, l’usage de composants vulnérables est lui aussi de plus en plus risqué.
POC
Plusieurs preuves de concept sont publiées :
- Pour PHP, la commande suivante permet de vérifier si la vulnérabilité existe en rapportant un message d’erreur
php -r '$e="0";for($i=0;$i<2500;$i++){$e="0$e";gethostbyname($e); }'
- Pour Wordpress, la méthode « pingback » est à désactiver car elle emploie « gethostbyname »[11].
Pour vérifier si son système est concerné par la vulnérabilité Ghost, il est d’abord nécessaire de connaitre sa version de glibc grâce à la commande suivante : ldd –version
L'éditeur en sécurité Qualys propose un outillage pour tester son système rapidement[12]. Pour tester la faille, il utilise une détection de tampon par méthode du canari. Le code:
- fixe la taille de deux registres contigus de type struct.
- affecte un pointeur de buffer dans le premier registre.
- affecte une chaine de caractères CANARY dans le deuxième registre.
- calcule la taille maximale d’une variable name relative à la taille du premier registre.
- affecte à cette variable des ‘0’ et la termine par ‘\0’ pour qu’elle ait l’aspect d’une adresse IP,
- utilise la variable name, et le pointeur de buffer en argument à la fonction gethostbyname_r().
- teste si le contenu du deuxième registre contient toujours la chaine de caractère ‘CANARY’. Si les chaines sont différentes, le système est considéré vulnérable.
Exploit
À la date de publication de cet article, seul l’exploit fourni par Qualys est disponible au public, mais il ne provoque seulement qu’un déni de service[13]. En effet, aucun code d'exploitation n'est encore proposé pour prendre le contrôle d'un système à distance. Qualys a annoncé disposer d'un outil permettant de prendre le contrôle d'un serveur Exim à distance. Cependant, ce code ne sera publié que lorsque Qualys estimera que la majorité des systèmes exposés sur Internet seront corrigés[1].
- L'exploit Exim
Le serveur de messagerie Exim est exploitable à distance si configuré pour effectuer des contrôles de sécurité supplémentaires sur les commandes de salutation HELO et EHLO (helo_verify) envoyés par l’expéditeur de courrier[14] - [15].
Premièrement, la méthode d'exploit consiste à réaliser un débordement de tampon dans le tas de gethostbyname et écraser partiellement le champ du prochain bloc contigu de mémoire avec une taille légèrement plus grande (3 octets).
Cela entraine une allocation mémoire qui est agrandi artificiellement. Ce bloc de mémoire est géré par Malloc de GlibC et chevauche un autre bloc mémoire qui est géré par l’allocateur mémoire interne à Exim.
Dans ce bloc agrandi, la technique va être d’allouer partiellement un morceau de mémoire pour y écrire du code arbitraire et écraser le début du contenu du bloc mémoire d’Exim. Cela amène alors dans une primitive où il est possible d’écrire n’importe quoi n’importe où, car on peut contrôler à la fois le pointeur de la prochaine zone mémoire retourné par l’allocateur d’Exim et les données qui lui sont affectées (une chaine de caractère terminée par un null, l’argument d’une commande SMTP qu’on envoie à Exim).
Par conséquent, la primitive est utilisée pour aller écraser la configuration de l’environnement d’exécution (runtime) d’Exim qui est mis en cache dans le tas. Le but est d’écraser plus précisément la liste des contrôles d’accès (ACLs) d’Exim et de pouvoir exécuter des commandes arbitraires grâce à des extensions d’Exim telle ${run<command> <args<}}
.
Le succès de cet exploit dépend d'un élément d’information important: l'adresse de l'environnement d’exécution de la configuration d'Exim dans le tas.
Palliatifs
Tous les éditeurs Linux ont publié un correctif :
Les constructeurs de matériels comme les NAS[note 7] ou les routeurs utilisant une version de Linux impactées publient progressivement des patchs[16] - [17].
Il est important de noter que les fonctions « gethostbyname() » et « gethostbyaddr() » sont obsolètes. Les applications devraient plutôt utiliser les fonctions « getaddrinfo() » et « getnameinfo() » à la place et ainsi éviter la vulnérabilité. Le conseil majeur pour se prémunir de Ghost est d’appliquer le plus rapidement possible les patchs fournis par les éditeurs.
Un complément de protection de l'OS contre les débordements de tampon à l’aide de l’ensemble de patch Grsecurity pour Linux peut être utile, mais il ne protègera que la pile et pas le tas. En effet, Grsecurity[18] rend la région mémoire utilisée par la pile non exécutable. Ceci empêche du code malveillant inséré dans la pile d’être exécuté par un pirate. Il propose aussi la randomisation de l’espace d’adressage (ASLR) qui permet de placer aléatoirement les zones de données dans la mémoire virtuelle.
Notes et références
Notes
- NCAS pour National Cyber Awareness System qui pourrait être traduit par Système National de Cyber-sensibilisation.
- EIP pour Instruction Pointer. Le registre EIP contient l’offset de la prochaine instruction à exécuter.
- EBP pour Frame Base Pointer. Ce registre sert à pointer sur une donnée dans la pile.
- ESP pour Stack Pointer. Ce registre 32 bits contient le déplacement pour atteindre le sommet de la pile.
- tas: heap en anglais.
- Pile: stack en anglais.
- NAS pour Network Access Server qui pourrait être traduit par Serveur d'accès réseau.
Références
- (en) amolsarwate, « The GHOST Vulnerability », sur Qualys Community, (consulté le )
- (en) Qualys Security Advisory, « Qualys Security Advisory CVE-2015-0235 », sur Openwall,
- (en) « Technical analysis of Qualys' GHOST », sur lcamtuf's blog, .
- (en) US-CERT/NIST, « Vulnerability Summary for CVE-2015-0235 », sur National Vulnerability Database, .
- « Manuel du programmeur Linux », sur linux-france.org
- Piromsopa 2006, p. 454
- Fu 2012, p. 87
- (en) « Vulnerability Note VU#967332 », sur CERT,
- (en) Marc-Alexandre Montpas, « Critical “GHOST” Vulnerability Released », sur SecuryBlog,
- (en) « Open Web Application Security Project », sur owasp,
- (en) Ryan Barnett, « GHOST gethostbyname() heap overflow in glibc », sur Trustwave,
- (en) Nixcraft, « How To Patch and Protect Linux Server Against the Glibc GHOST Vulnerability », sur Nixcraft, .
- (en) « Exim ESMTP GHOST Denial Of Service », sur packetstormsecurity,
- (en) Qualys Security Advisory, « Qualys Exploit Exim », sur Qualys,
- (en) Exim, « Exim », sur Exim,
- « Faille Ghost : Synology met en ligne le correctif pour le DSM 5.1 », sur nextinpact,
- « Faille Ghost : les NAS QNAP ne sont pas épargnés, un correctif arrive », sur nextinpact,
- (en) « Grsecurity », sur Grsecurity,
Bibliographie
- (en) Krerk Piromsopa et Richard J. Enbody, « Buffer-Overflow Protection: The Theory », Electro/information Technology, 2006 IEEE International Conference on, , p. 454-458 (ISBN 0-7803-9592-1, DOI 10.1109/EIT.2006.252128)
- (en) Desheng Fu et Feiyue Shi, « Buffer Overflow Exploit and Defensive Techniques », Multimedia Information Networking and Security (MINES), 2012 Fourth International Conference on, Nanjing, , p. 87-90 (ISBN 978-1-4673-3093-0, DOI 10.1109/MINES.2012.81)