Tuesday, July 27, 2010

SSL Testing Tool ssltest.pl

Update: I have just updated this tool to version 0.1.1 to resolve a minor bug (thanks Gitsnik) and a few cosmetic issues.

I have used a number of different tools to check cipher support on SSL Servers, including SSLDigger, sslthing, CryptonarkOpenssl and even a few web based solutions.  Each tool has its good and bad points, but recently when trying to confirm that a particular badly behaved reverse proxy was compliant with DSD ISM crypto standards I ran into some problems.  The reverse proxy I was attempting to test was not correctly responding to or closing SSLv2 and TLSv1 sessions, causing a number of the tools that I commonly use to freeze up.

Cryptonark was able to run against the proxy without freezing up, due to its ability to timeout sessions, but it still wasn't providing the right results due to the fact that it only tests SSLv2 and TLSv1, but not SSLv3 - the only protocol that happened to work on this particular system.  The tool is written in Perl however, so I consequently decided to quickly modify it to test SSLv3 as well.

But what started off as a quick modification, soon turned into a complete rewrite, as I rapidly came up with a list of additional features I wanted in addition to the SSLv3 support - optional verbose output (such as listing unsupported ciphers, plus connection attempts), colour highlighting for DSD ISM compliance as well as PCI-DSS, control over timeout settings, the ability to individually test protocols, more detail in the explanatory text for each cipher, greppable compliance status for each cipher, etc.  I have essentially reused the essential design concepts of the Cryptonark tool (including colour coding output, use of IO::Socket::SSL to make SSL connections, documenting supported ciphers within the tool, checking supported ciphers against a compliance standard), but have completely rewritten the code from scratch to clean it up, reduce repetition and dependence on additional perl modules, and ease implementation of the new features.

So now the tool is complete, it includes all those additional features I wanted, and it works very nicely against that badly behaving reverse proxy that started this whole thing.

I have decided to make the tool available here, first of all so I can easily get to a copy when needed, and also just in case anyone else finds it useful.  Until I can think of something better, I'm releasing this under the imaginative name of ssltest.pl - so called because the tool is used to test ssl.

Here is a listing of the help:
lupin@lion:~$ ssltest.pl
ssltest 0.1.1
grey-corner.blogspot.com

Tests the provided SSL host to determine supported SSL protocols and ciphers.
Originally based on Cryptonark by Chris Mahns.

USAGE:

/home/lupin/bin/ssltest.pl [options] host port
/home/lupin/bin/ssltest.pl [--pci|--ssl2|--ssl3|--tls1] --list


OPTIONS:

        -v|--verbose    Verbosity level. Use once to also list tested
                        ciphers that are not enabled on the target host.
                        Use twice to also show when host connection
                        attempts are made.

        -r|--ssl2       Performs cipher tests for the sslv2 protocol.
                        Default is all protocols (ssl2, ssl3, tls1).

        -s|--ssl3       Performs cipher tests for the sslv3 protocol.
                        Default is all protocols (ssl2, ssl3, tls1).

        -t|--tls1       Performs cipher tests for the tlsv1 protocol.
                        Default is all protocols (ssl2, ssl3, tls1).

        -x|--timeout    Sets timeout value in seconds for connections.
                        Default 4.  Lower value for hosts that may not
                        properly close connections when an unsupported
                        protocol request is attempted.  Raise value for
                        slow links/hosts.

        -i|--ism        Marks enabled ciphers that are compliant with the
                        DSD ISMs standards for in-transit protection of
                        IN-CONFIDENCE information (ISM Sep 2009).  Default
                        compliance standard used (as opposed to PCI).

        -p|--pci        Marks enabled ciphers that are compliant with
                        PCI-DSS standards.  Provided as an alternate
                        compliance standard to the DSD ISM.

        -g|--grep       Outputs in a semicolon ";" separated greppable
                        format, adds text for compliance status.  Use
                        when you need to write output to a text file and
                        you want compliance status to be included in
                        text format instead of just being repressnted by
                        terminal colour.

        -l|--list       Lists ciphers checked by this tool and exits,
                        with output colour coded to indicate compliance
                        status with the selected standard (pci or ism).
                        Host and port values do not need to be provided
                        when using this option, as no host connection is
                        made.  Purely informational, so you can see what
                        ciphers are tested for, and which are deemed to be
                        compliant with the various standards.


If one or more protocol/s (SSLV2, SSLV3, TLSV1) are not specifically enabled,
tests for all protocols will be performed.  If you know that a host does not
support certain protocols (or does not properly close connection attempts made
using particular protocols) you can only include tests for the protocols you
are interested in to speed up the test.  If no compliance standard is
specifically enabled, or if more than one standard is enabled, the default
is to use the DSD ISM.


EXAMPLES:

/home/lupin/bin/ssltest.pl -vvrsi test.example.com 443

Performs testing on host test.example.com port 443, using the sslv3 protocol
(-s), and sslv2 protocol (-r), matches responses against the cipher
requirements in the ISM (-i) and provides double verbose output (-vv) where
ciphers unsupported by the destination host and connection attempts are printed
to screen.

/home/lupin/bin/ssltest.pl --list

Provides a list of all ciphers supported by the tool, colour coded to indicate
which ones are considered to be compliant with the ISM.  Add the --pci switch
to colour code listed ciphers for PCI compliance instead, or supply the --ssl2,
--ssl3 or --tls1 switches to only list ciphers appropriate to those protocols.

Here is the tool in action, performing a test of the SSL ciphers supported by www.google.com

lupin@lion:~$ ssltest.pl www.google.com 443
Checking for Supported SSLv2 Ciphers on www.google.com:443...
Checking for Supported SSLv3 Ciphers on www.google.com:443...
   DES-CBC3-SHA, 3DES 168 bits, RSA Authentication, SHA1 MAC, RSA Key Exchange
   AES128-SHA, AES 128 bits, RSA Authentication, SHA1 MAC, RSA Key Exchange
   AES256-SHA, AES 256 bits, RSA Authentication, SHA1 MAC, RSA Key Exchange
   RC4-MD5, RC4 128 bits, RSA Authentication, MD5 MAC, RSA Key Exchange
   RC4-SHA, RC4 128 bits, RSA Authentication, SHA1 MAC, RSA Key Exchange
Checking for Supported TLSv1 Ciphers on www.google.com:443...
   DES-CBC3-SHA, 3DES 168 bits, RSA Authentication, SHA1 MAC, RSA Key Exchange
   AES128-SHA, AES 128 bits, RSA Authentication, SHA1 MAC, RSA Key Exchange
   AES256-SHA, AES 256 bits, RSA Authentication, SHA1 MAC, RSA Key Exchange
   RC4-MD5, RC4 128 bits, RSA Authentication, MD5 MAC, RSA Key Exchange
   RC4-SHA, RC4 128 bits, RSA Authentication, SHA1 MAC, RSA Key Exchange

I have reproduced above the colour coding the tool uses, a really helpful feature "borrowed" from Cryptonark, showing which ciphers are considered to be supported under the DSD ISM.  You can see from the above output that no SSlv2 ciphers are supported, and that some ciphers are coloured green, indicating that they are compliant with the selected standard of the ISM, and others are coloured red, indicating they are not.

Some ideas I have for the next revision of this tool are to have it verify that the hostname matches the common name on the certificate, to confirm the certificate has not expired, and possibly also to verify that the certificate is signed by a trusted certificate authority and has not been revoked.

You can download version 0.1 of the tool from here (this link will always point to the newest version of the tool):

Let me know if you try this tool out and find it useful.

14 comments:

  1. Nice! Can I ask, what is the difference cipher-wise between PCI and DSD ISM? PCI seemed to only be worried about null, weak, and anonymous plus slv2.

    ReplyDelete
  2. Thanks for your comments Chris, much appreciated

    I have essentially used the same standard for PCI compliance checking as found in Cryptonark, which I assume you are quite familiar with.

    The DSD ISM outlines the crypto use requirements for the Australian Government. Basically there are restrictions on protocol (SSL3 or TLS1 only), ciphers (3DES and AES only), hash algorithms (SHA-1 only), and digitial signature verification (DSA (specified in FIPS 186-DSS) or RSA). Following this standard makes the crypto sufficient for use in providing transit encryption for IN-CONFIDENCE data, anything above this requires use of EPL approved products.

    So obviously the DSD ISM is much more proscriptive when it comes to cipher choice... ;)

    You can download a copy of the ISM from the link above if you're really interested, as it spells it all out in excruciating detail. Makes for kind of dry reading if you dont have to know it though.

    If you have a read of the code you will the ISM checks dont explicitly look for all of the things mentioned above, but the end result for the list of allowed choices results in matching ISM requirements.

    ReplyDelete
  3. Thanks again. You know, I purposefully left out the ssl3 tests because openssl used the same ciphers to test with sslv3 and tlsv1, so it seemed redundant to use both. i do like your protocol options though. I may just "accidentally" pilfer them! :)

    There have been quite a few updates to openssl since I first wrote it. As soon as I can finish scratching this groovy programming language itch, I think some cryptonark re-work and updating is in order.

    ReplyDelete
  4. Chris

    Yes for most well behaving SSL enabled devices seperate SSlv3 support would be redundant. I only bothered to write this at all because of this one type of device I had to test that only supports SSLv3 connections - and what's more it's only SSLv3 connections from particular versions of OpenSSL.

    Unfortunately, I am also having to continually re-test this device at the moment while it's being configured in multiple environments to be ISM compliant, so a tool that supported SSLv3 was essential. I have also got this to run on a Windows machine, useful for when I am working in areas where I don't have easy access to a Linux box. It's a bit messy though, because the Windows command shell does not support terminal colours (and has some other issues too), so I will tidy this up and release a new "Windows supported" version soon.

    Feel free to pilfer away - I guess its only fair considering that my tool was heavily "inspired" by cryptonark ;)

    ReplyDelete
  5. The tool returns false positive results with the sites which support weak ciphers, however just to display a user friendly error message that one need to update a browser.

    Please consider such cases. Here is an example:
    72.246.88.47 443.

    ReplyDelete
  6. Anton

    Yes, I see what you mean. In theory thats fixable by making the script make a https request over the established SSL session and checking the response. The only difficulty is determining when the response contains such a warning - Im not aware of any well defined standards in this area.

    I'll give this a bit of thought to determine how it can best be implemented. Thanks for the input.

    ReplyDelete
  7. A new version of the tool has been released which will hopefully resolve this issue.

    See here for more information:
    http://grey-corner.blogspot.com/2010/11/version-03-of-ssl-testing-tool.html

    ReplyDelete
  8. Hi Lupin was doing some research on current online testing tools, getting supported ssl protocols from the server is a good idea. but there is so many things to test :)

    what i have so far you can see at www.ssltest.net it mostly looks for common installation errors, debian bug, information, etc.

    ReplyDelete
  9. Sole

    Interesting. Don't think I have seen any of these that test for the Debian bug yet. Certificate name matching, expiry and certificate chain testing are things I have on the to-do list for ssltest.pl...

    ReplyDelete
  10. Hi Lupin,

    I have also started a new ssl test project, that might be of interest to you. not being the test of the server, but testing clients compatibility with ssl certificates. this results in a comparison chart showing what clients are reported working/not working with different SSL's.

    You can try the test on www.ssltest.net/compare/
    and see the results so far (still under development!) on www.ssltest.net/compare/sar.php

    Basicly the project has started from my own curiosity and trying to figure out exactly what clients and especially mobile phones that work with what ssl certificates.

    ReplyDelete
  11. Oh and a quick question, would you mind if i use your script to add its output to the server ssl test client?

    ReplyDelete
  12. Sole

    Yes, its fine if you use the script for that. I'd appreciate a link back to here in the output if you do so, but thats not mandatory.

    ReplyDelete
  13. lupin ... I am forced to go through a local proxy to access the internet. Is there a quick way i could modify the source to support going through a proxy first? If so, I would be glad to do the mod myself and then send the source to you for your publishing back to the cmmunity.

    ReplyDelete
  14. Matt

    Probably not a quick way, no.

    Something like this shows one way of connecting via a proxy server using the CONNECT method, which is what you would need to use.

    http://www.nntp.perl.org/group/perl.libwww/2010/02/msg7377.html

    But then you need to work out how to actually perform the SSL socket creation using IO::Socket::SSL because this is what I am using to actually allow the ciphers for the connection to be specified.

    It may be that the method described in that link is completely unsuitable for use with IO::Socket::SSL, and the proxy connection code may need to be coded on top of something like IO::Socket::INET...

    In short, I cant think of a quick/easy way to do this off the top of my head...

    ReplyDelete