Je me suis retrouvé l'autre jour avec une alerte de sonde de détection d'intrusion, laquelle me signalait qu'une potentielle exploitation de la faille Heartbleed avait eu lieu sur un serveur web. L'autre détail que j'avais au niveau de l'alerte : le protocole utilisé pour cette exploitation était SSL v3.
N'ayant pas la main sur la machine, je n'avais pour seule option que de vérifier côté client si le serveur utilise ce protocole. Sur l'instant, j'ai pensé à utiliser OpenSSL, qui dispose d'options pour se connecter à un serveur en utilisant certains protocoles. Cela donne pour mon cas, l'exemple et le résultat suivant :
$ openssl s_client -connect blog.anotherhomepage.org:443 -ssl3 CONNECTED(00000006) 140187574654788:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:/usr/src/crypto/external/bsd/openssl/dist/ssl/s3_pkt.c:1304:SSL alert number 40 140187574654788:error:1409E0E5:SSL routines:SSL3_WRITE_BYTES:ssl handshake failure:/usr/src/crypto/external/bsd/openssl/dist/ssl/s3_pkt.c:637: --- no peer certificate available --- No client certificate CA names sent --- SSL handshake has read 7 bytes and written 0 bytes --- New, (NONE), Cipher is (NONE) Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE SSL-Session: Protocol : SSLv3 Cipher : 0000 Session-ID: Session-ID-ctx: Master-Key: Key-Arg : None PSK identity: None PSK identity hint: None SRP username: None Start Time: 1485895043 Timeout : 7200 (sec) Verify return code: 0 (ok) ---
Alors bon, je sais pas trop vous, mais pour moi, ce n'est pas très évident que le serveur ne prend pas en charge SSL v3. Il y a quand même écrit "CONNECTED" au début, avant de me sortir "handshake failure". Néanmoins, la mission est remplie, et on peut vérifier plusieurs protocoles via les options suivantes d'OpenSSL :
* -ssl2 ; * -ssl3 ; * -tls1_2 ; * -tls1_1 ; * -tls1 ; * -dtls1.
Peu satisfait de la solution, j'ai continué mon voyage dans les moteurs de recherche, avant de tomber sur une question similaire, disposant de la première solution, mais d'une autre visiblement plus lisible, utilisant le célèbre Nmap. Elle consiste à tirer parti d'une fonctionnalité assez intéressante du célèbre scanneur de ports, à savoir la disponibilité d'un langage de script permettant d'obtenir des détails supplémentaires lors d'un scan de port. Parmi les scripts disponibles, certains ont même pour but de mener des attaques par bruteforce. Là, il n'est pas question d'attaque, mais simplement d'énumération des ciphers disponibles. Comme plus haut, voici un exemple accompagné d'un résultat :
Starting Nmap 7.40 ( https://nmap.org ) at 2017-02-19 09:30 CET Nmap scan report for blog.anotherhomepage.org (163.172.46.128) Host is up (0.0012s latency). rDNS record for 163.172.46.128: vhost2.anotherhomepage.org PORT STATE SERVICE 443/tcp open https | ssl-enum-ciphers: | TLSv1.0: | ciphers: | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A | TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A | TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 4096) - A | TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 4096) - A | compressors: | NULL | cipher preference: server | warnings: | Key exchange (secp256r1) of lower strength than certificate key | TLSv1.1: | ciphers: | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A | TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A | TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 4096) - A | TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 4096) - A | compressors: | NULL | cipher preference: server | warnings: | Key exchange (secp256r1) of lower strength than certificate key | TLSv1.2: | ciphers: | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A | TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A | TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 4096) - A | TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 4096) - A | compressors: | NULL | cipher preference: server | warnings: | Key exchange (secp256r1) of lower strength than certificate key | TLSv1.2: | ciphers: | TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A | TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A | TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (dh 4096) - A | TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (dh 4096) - A | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (secp256r1) - A | TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (secp256r1) - A | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A | TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A | TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (dh 4096) - A | TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 4096) - A | TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (dh 4096) - A | TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 4096) - A | compressors: | NULL | cipher preference: server | warnings: | Key exchange (secp256r1) of lower strength than certificate key |_ least strength: A Nmap done: 1 IP address (1 host up) scanned in 10.06 seconds
On remarquera, dans mon exemple, l'absence de SSLv3.
Et pour l'alerte de mon IDS ? Et bien comme dans mon exemple, SSLv3 n'est pas apparu dans mes résultats, ce qui m'a permis de conclure au faux-positif.
Un dernier détail : au moment de l'écriture de ce billet, NSE n'est pas activé par défaut dans pkgsrc, et pour NetBSD, son activation empêche de compiler Nmap.
Des remarques, des propositions d'améliorations ? Les commentaires sont là pour ça !