How do I use "openssl s_client" to test for (absence of) SSLv3 support?
In order to mitigate the "Poodle" vulnerability, I'd like to disable SSLv3 support in my (in this case, TLS, rather than HTTPS) server. How can I use
openssl s_client
to verify that I've done this?OpenSSL s_client
To check if you have disabled the SSLv3 support, then run the following
openssl s_client -connect example.com:443 -ssl3
which should produce something like
3073927320:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:1258:SSL alert number 40 3073927320:error:1409E0E5:SSL routines:SSL3_WRITE_BYTES:ssl handshake failure:s3_pkt.c:596:
meaning SSLv3 is disabled on the server. Otherwise the connection will established successfully.
Nmap
Alternatively, you can use nmap to scan server for supported version:
# nmap --script ssl-enum-ciphers example.com Starting Nmap 6.47 ( http://nmap.org ) at 2014-10-15 03:19 PDT Nmap scan report for example.com (203.0.113.100) Host is up (0.090s latency). rDNS record for 203.0.113.100: edge.example.com Not shown: 997 filtered ports PORT STATE SERVICE 80/tcp open http 443/tcp open https | ssl-enum-ciphers: | **SSLv3: No supported ciphers found** | TLSv1.0:
The openssl command works; I can't get the nmap script to work, though.
Ah. Non-default port. Use `--script +ssl-enum-ciphers`, per http://stackoverflow.com/a/17175548/8446.
What is the output of your nmap command ?
@RogerLipscombe Right, so what's not working there? SSLv3 is not listed, so it's not supported.
It's working fine; I solved it. I'm using a non-standard port, so I have to prefix the script name with '+' to force it to run.
See also this answer to know how to interpret the openssl output: https://security.stackexchange.com/a/169738/60157
On a side note you can use
nmap
with ssl-enum-ciphers script as followsnmap --script ssl-enum-ciphers -p 443 example.com
You will get a response like this.
PORT STATE SERVICE 443/tcp open https | ssl-enum-ciphers: | SSLv3: | ciphers: | TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA - strong | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - strong | TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - strong | TLS_RSA_WITH_RC4_128_MD5 - strong | TLS_RSA_WITH_RC4_128_SHA - strong | compressors: | NULL | TLSv1.0: | ciphers: | TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA - strong | TLS_RSA_WITH_RC4_128_MD5 - strong | TLS_RSA_WITH_RC4_128_SHA - strong | compressors: | NULL | TLSv1.1: | ciphers: | TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA - strong | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - strong | compressors: | NULL | TLSv1.2: | ciphers: | TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA - strong | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - strong | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - strong | compressors: | NULL |_ least strength: strong
As you can see it lists all the supported versions of ssl/tls as well as the cipher suites
I created this test for the availability of the SSLv3 protocol. There is probably a better way to search for a string that also shows that CBC ciphers are in use, but most people just seem to want to know if SSLv3 is available at all.
A few things to note:
- Written for the bash on Mac OS X so can't say for sure it will work everywhere
- Uses gtimeout vs. timeout since Mac is weird about those core utils
- allexternal.txt is a file with one hostname or IP per line
script:
for ip in `awk '{print $1}' < allexternal.txt`; do if gtimeout 30 openssl s_client -connect $ip:443 -ssl3 | grep -q 'Protocol : SSLv3' ; then echo $ip SSLv3 detected >> sslv3output; else echo $ip SSLv3 NOT detected >> sslv3output; fi; done
Apologies for the formatting, wasn't sure how to have grave accents show up as literal instead of making it into a code block.
Thanks for sharing, but can I suggest you use echo 'QUIT' so you don't have to install gtimeout. The second line should read... if echo 'QUIT' | openssl s_client -connect $ip:443 -ssl3 | grep -q 'Protocol : SSLv3' ; then
Using "Protocol : SSLv3" also seems to be dubious. Per this page: http://security.stackexchange.com/a/71459/51963, "Cipher : 0000" may be a better string to search for.
If just SSLv3 is disabled, you can also force
openssl s_client
to use only TLS:openssl s_client -connect exmaple.com:443 -tls1
For TLS 1.0 and above, you should use the `-servername` option too. In enlists SNI.
This does not verify that ssl3 is disable, it just tells to use TLS 1
It's worth noting that the -ssl3 option in OpenSSL now has to be enabled at compile time. If you're running on pre-compiled binaries then the option may not be available. See this issue: https://github.com/openssl/openssl/issues/6801
An alternative tool is testssl.sh. This checks for protocols, ciphers and selected vulnerabilities: https://github.com/drwetter/testssl.sh
License under CC-BY-SA with attribution
Content dated before 6/26/2020 9:53 AM
Roger Lipscombe 6 years ago
The openssl command works; I can't get the nmap script to work, though.