Heartbleed une faille de sécurité saignante !

Par:
fredericmazue

jeu, 10/04/2014 - 17:55

Cette faille a été baptisée Heartbleed, le coeur qui saigne, par jeu de mots avec Heartbeat, nom d'une extension au protocole SSL/TSL qui est vulnérable. La faille a été mise en évidence par des chercheurs en sécurité de codenomicon et des experts en sécurité de Google.

Il s'agit d'une faille très grave car elle réduit à néant la sécurité en laquelle vous aviez confiance à l'apparition du petit cadenas qui apparaît dans votre navigateur, à côté de l'URL du site que vous visitez. Très concrètement, alors que le protocole SSL/TLS permet normalement la protection des données échangées entre un navigateur et le serveur qui héberge un site, la faille permet au contraire de récupérer des noms d'utilisateurs et des mots de passe, des clés de certificats X.509, et bien sûr toutes sortes de données ultra sensibles généralement échangées à travers ce protocole, comme des numéros de cartes bancaires.

Ce n'est pas le protocole SSL/TLS qui est compromis, mais seulement son extension heartbeat qui permet de garder des connexions persistantes, plutôt que de les renégocier à chaque communication. Plus exactement, ce n'est pas cette extension elle-même qui pose problème, mais son implémentation dans la librairie open source OpenSSL, librairie utilisée par deux des principaux serveur web à savoir Apache et nginx.

Il s'agit d'un hélas trop classique problème de mauvaise allocation mémoire, comme on en voit beaucoup en langage C. Une structure de données HeartbeatMessage est ainsi définie :

struct {
  HeartbeatMessageType type;
  uint16 payload_length;
  opaque payload[HeartbeatMessage.payload_length];
  opaque padding[padding_length];
} HeartbeatMessage;

 

et allouée ainsi dans le code de la librairie :

buffer  = OPENSS_malloc(1 + 2 + payload + padding)

Le problème est qu'ici la valeur paylog n'est pas contrôlée. Or il se trouve que les paquets HeartbeatMessage voyagent entre le client et le serveur. Le client envoie un petit bout de sa mémoire  et le serveur lui renvoie normalement le paquet à l'identique.

Malheureusement comme la valeur de payload n'est pas contrôlée le client peut forcer des allocations mémoire jusqu'à 64 Ko (payload est codé sur 16 bits). Et comme la mémoire allouée n'est pas vidée de son contenu, le serveur retourne des paquets de 64ko de sa mémoire et donc retourne les données qui y résident.

En envoyant ainsi de multiples requêtes malicieuses, un client peut "pomper" une grande partie du contenu mémoire d'un serveur et ainsi voler les informations qui y résident en clair : mot de passe, n° de cartes bancaires, ou hash de ces valeurs, etc.

Un script Python sous forme de preuve de concept pour l'exploit de cette vulnérabilité est proposé ici : https://gist.github.com/mpdavis/10171593

Les spécialistes en sécurité qualifient cette faille d'une des plus grosse failles de sécurité qui a jamais touché Internet. La faille a été introduite en 2011 avec  l'arrivée de la version 1.0.1 de la librairie et elle s'est répandue au rythme de la mise  jour des systèmes.

Ne sont touchées que les version 1.0.1 à 1.0.1f de la librairie. La version 1.0.1g publiée le 7 avril dernier est un correctif du problème. Les version 1.0.0 et 0.98 ne sont pas touchées.

Que devez-vous faire en tant qu'administrateur système, si vous craignez que vos serveurs soient touchés ?

Vous devez d'abord vérifier la version de votre librairie openssl. Par exemple sur une distribution Debian Linux :

apt-cache policy openssl

openssl:
  Installé : 0.9.8o-4squeeze14
  Candidat : 0.9.8o-4squeeze14

 Table de version :
 *** 0.9.8o-4squeeze14 0

Ouf...

Si vous êtes touchés, vous devez mettre à jour votre librairie openssl. Vous devez le faire toutes affaires cessantes, car maintenant que la faille est connue de tous, nul doute que les hackers vont essayer son exploit sur quantités de serveurs, dans l'espoir de profiter de la négligence des administrateurs systèmes.

Puis vous devrez au minimum réinitialiser les mots de passe de vos utilisateurs.

Frédéric Mazué