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 follows

    nmap --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