From ed4d29e0c5a4c0500ab78fcb294c78089cccc0b3 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Thu, 3 Nov 2016 10:49:27 -0400 Subject: [PATCH 01/11] Allow caller to provide extra extensions to tls_sockets() This PR allows the caller to provide additional extensions to `tls_sockets()` to be included in the ClientHello. If the caller provides an extension that would have already been included in the ClientHello, then the caller's value for the extension is used rather than the default value. --- testssl.sh | 106 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 73 insertions(+), 33 deletions(-) diff --git a/testssl.sh b/testssl.sh index b5368b6..d1b0146 100755 --- a/testssl.sh +++ b/testssl.sh @@ -6196,6 +6196,7 @@ sslv2_sockets() { # ARG1: TLS version low byte (00: SSLv3, 01: TLS 1.0, 02: TLS 1.1, 03: TLS 1.2) # ARG2: CIPHER_SUITES string +# ARG3: (optional) additional request extensions socksend_tls_clienthello() { local tls_low_byte="$1" local tls_word_reclayer="03, 01" # the first TLS version number is the record layer and always 0301 -- except: SSLv3 @@ -6208,10 +6209,12 @@ socksend_tls_clienthello() { local len_client_hello_word len_all_word local ecc_cipher_suite_found=false local extension_signature_algorithms extension_heartbeat - local extension_session_ticket extension_next_protocol extensions_ecc extension_padding + local extension_session_ticket extension_next_protocol extension_padding + local extension_supported_groups="" extension_supported_point_formats="" + local extra_extensions extra_extensions_list="" - code2network "$2" # convert CIPHER_SUITES - cipher_suites="$NW_STR" # we don't have the leading \x here so string length is two byte less, see next + code2network "$(echo "$2" | tr 'A-Z' 'a-z')" # convert CIPHER_SUITES + cipher_suites="$NW_STR" # we don't have the leading \x here so string length is two byte less, see next len_ciph_suites_byte=$(echo ${#cipher_suites}) let "len_ciph_suites_byte += 2" @@ -6240,7 +6243,7 @@ socksend_tls_clienthello() { elif [[ "$part2" -ge "0x5c" ]] && [[ "$part2" -le "0x63" ]]; then ecc_cipher_suite_found=true && break elif [[ "$part2" -ge "0x70" ]] && [[ "$part2" -le "0x79" ]]; then - ecc_cipher_suite_found=true && break + ecc_cipher_suite_found=true && break elif [[ "$part2" -ge "0x86" ]] && [[ "$part2" -le "0x8d" ]]; then ecc_cipher_suite_found=true && break elif [[ "$part2" -ge "0x9a" ]] && [[ "$part2" -le "0x9b" ]]; then @@ -6287,43 +6290,79 @@ socksend_tls_clienthello() { extension_next_protocol=" 33, 74, 00, 00" - # Supported Elliptic Curves Extension and Supported Point Formats Extension. - extensions_ecc=" - 00, 0a, # Type: Supported Elliptic Curves , see RFC 4492 - 00, 3e, 00, 3c, # lengths - 00, 0e, 00, 0d, 00, 19, 00, 1c, 00, 1e, 00, 0b, 00, 0c, 00, 1b, - 00, 18, 00, 09, 00, 0a, 00, 1a, 00, 16, 00, 17, 00, 1d, 00, 08, - 00, 06, 00, 07, 00, 14, 00, 15, 00, 04, 00, 05, 00, 12, 00, 13, - 00, 01, 00, 02, 00, 03, 00, 0f, 00, 10, 00, 11, - 00, 0b, # Type: Supported Point Formats , see RFC 4492 - 00, 02, # len - 01, 00" - - all_extensions=" - $extension_heartbeat - ,$extension_session_ticket - ,$extension_next_protocol" + if "$ecc_cipher_suite_found"; then + # Supported Groups Extension + extension_supported_groups=" + 00, 0a, # Type: Supported Elliptic Curves , see RFC 4492 + 00, 3e, 00, 3c, # lengths + 00, 0e, 00, 0d, 00, 19, 00, 1c, 00, 1e, 00, 0b, 00, 0c, 00, 1b, + 00, 18, 00, 09, 00, 0a, 00, 1a, 00, 16, 00, 17, 00, 1d, 00, 08, + 00, 06, 00, 07, 00, 14, 00, 15, 00, 04, 00, 05, 00, 12, 00, 13, + 00, 01, 00, 02, 00, 03, 00, 0f, 00, 10, 00, 11" + # Supported Point Formats Extension + extension_supported_point_formats=" + 00, 0b, # Type: Supported Point Formats , see RFC 4492 + 00, 02, # len + 01, 00" + fi - if [[ -n "$SNI" ]]; then - all_extensions="$all_extensions - ,00, 00 # extension server_name + # Each extension should appear in the ClientHello at most once. So, + # find out what extensions were provided as an argument and only use + # the provided values for those extensions. + extra_extensions="$(echo "$3" | tr 'A-Z' 'a-z')" + code2network "$extra_extensions" + len_all=${#extra_extensions} + for (( i=0; i < len_all; i=i+16+4*0x$len_extension_hex )); do + part2=$i+4 + extra_extensions_list+=" ${NW_STR:i:2}${NW_STR:part2:2} " + j=$i+8 + part2=$j+4 + len_extension_hex="${NW_STR:j:2}${NW_STR:part2:2}" + done + + if [[ -n "$SNI" ]] && [[ ! "$extra_extensions_list" =~ " 0000 " ]]; then + all_extensions=" + 00, 00 # extension server_name ,00, $len_sni_ext # length SNI EXT ,00, $len_sni_listlen # server_name list_length ,00 # server_name type (hostname) ,00, $len_servername_hex # server_name length. We assume len(hostname) < FF - 9 ,$servername_hexstr" # server_name target fi + if [[ ! "$extra_extensions_list" =~ " 000f " ]]; then + [[ -n "$all_extensions" ]] && all_extensions+="," + all_extensions+="$extension_heartbeat" + fi + if [[ ! "$extra_extensions_list" =~ " 0023 " ]]; then + [[ -n "$all_extensions" ]] && all_extensions+="," + all_extensions+="$extension_session_ticket" + fi + + # If the ClientHello will include the ALPN extension, then don't include the NPN extension. + if [[ ! "$extra_extensions_list" =~ " 3374 " ]] && [[ ! "$extra_extensions_list" =~ " 0010 " ]]; then + [[ -n "$all_extensions" ]] && all_extensions+="," + all_extensions+="$extension_next_protocol" + fi # RFC 5246 says that clients MUST NOT offer the signature algorithms # extension if they are offering TLS versions prior to 1.2. - if [[ "0x$tls_low_byte" -ge "0x03" ]]; then - all_extensions="$all_extensions - ,$extension_signature_algorithms" + if [[ "0x$tls_low_byte" -ge "0x03" ]] && [[ ! "$extra_extensions_list" =~ " 000d " ]]; then + [[ -n "$all_extensions" ]] && all_extensions+="," + all_extensions+="$extension_signature_algorithms" fi - if $ecc_cipher_suite_found; then - all_extensions="$all_extensions - ,$extensions_ecc" + if [[ -n "$extension_supported_groups" ]] && [[ ! "$extra_extensions_list" =~ " 000a " ]]; then + [[ -n "$all_extensions" ]] && all_extensions+="," + all_extensions+="$extension_supported_groups" + fi + if [[ -n "$extension_supported_point_formats" ]] && [[ ! "$extra_extensions_list" =~ " 000b " ]]; then + [[ -n "$all_extensions" ]] && all_extensions+="," + all_extensions+="$extension_supported_point_formats" + fi + + if [[ -n "$extra_extensions" ]]; then + [[ -n "$all_extensions" ]] && all_extensions+="," + all_extensions+="$extra_extensions" fi code2network "$all_extensions" # convert extensions @@ -6336,11 +6375,11 @@ socksend_tls_clienthello() { # If the length of the Client Hello would be between 256 and 511 bytes, # then add a padding extension (see RFC 7685) len_all=$((0x$len_ciph_suites + 0x2b + 0x$len_extension_hex + 0x2)) - if [[ $len_all -ge 256 ]] && [[ $len_all -le 511 ]]; then + if [[ $len_all -ge 256 ]] && [[ $len_all -le 511 ]] && [[ ! "$extra_extensions_list" =~ " 0015 " ]]; then if [[ $len_all -gt 508 ]]; then - len_padding_extension=0 + len_padding_extension=0 else - len_padding_extension=$((508 - 0x$len_ciph_suites - 0x2b - 0x$len_extension_hex - 0x2)) + len_padding_extension=$((508 - 0x$len_ciph_suites - 0x2b - 0x$len_extension_hex - 0x2)) fi len_padding_extension_hex=$(printf "%02x\n" $len_padding_extension) len2twobytes "$len_padding_extension_hex" @@ -6413,6 +6452,7 @@ socksend_tls_clienthello() { # arg2: (optional) list of cipher suites # arg3: (optional): "all" - process full response (including Certificate and certificate_status handshake messages) # "ephemeralkey" - extract the server's ephemeral key (if any) +# arg4: (optional) additional request extensions tls_sockets() { local -i ret=0 local -i save=0 @@ -6435,7 +6475,7 @@ tls_sockets() { fi debugme echo "sending client hello..." - socksend_tls_clienthello "$tls_low_byte" "$cipher_list_2send" + socksend_tls_clienthello "$tls_low_byte" "$cipher_list_2send" "$4" ret=$? # 6 means opening socket didn't succeed, e.g. timeout # if sending didn't succeed we don't bother From 765b1bdf5dc85e90efb6b864635d401bd94ba45f Mon Sep 17 00:00:00 2001 From: David Cooper Date: Fri, 4 Nov 2016 11:51:34 -0400 Subject: [PATCH 02/11] Use ephemeral public key in client simulations This PR makes similar changes to `run_client_simulation()` as were made to `tls_sockets()`, so that `run_client_simulation()` retrieves the entire server response, even if it is split across multiple packets, and it has `parse_tls_serverhello()` extract information about the server's ephemeral public key, if present. The PR also changes `run_client_simulation()` to use information about the ephemeral public key. It includes the length of the public key in the output and, if it is a DH public key, checks that the size is within the acceptable range (`${minDhBits[i]} <= dh_bits <= ${maxDhBits[i]}`). --- testssl.sh | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 66 insertions(+), 5 deletions(-) diff --git a/testssl.sh b/testssl.sh index d1ba2b3..9c739ee 100755 --- a/testssl.sh +++ b/testssl.sh @@ -2348,7 +2348,8 @@ client_simulation_sockets() { local -i save=0 local lines clienthello data="" local cipher_list_2send - local tls_hello_ascii + local sock_reply_file2 sock_reply_file3 + local tls_hello_ascii next_packet hello_done=0 if [[ "${1:0:4}" == "1603" ]]; then clienthello="$(create_client_simulation_tls_clienthello "$1")" @@ -2357,7 +2358,7 @@ client_simulation_sockets() { fi len=${#clienthello} for (( i=0; i < len; i=i+2 )); do - data+=", ${clienthello:i:2}" + data+=", ${clienthello:i:2}" done debugme echo "sending client hello..." code2network "${data}" @@ -2373,15 +2374,58 @@ client_simulation_sockets() { tls_hello_ascii=$(hexdump -v -e '16/1 "%02X"' "$SOCK_REPLY_FILE") tls_hello_ascii="${tls_hello_ascii%%[!0-9A-F]*}" + check_tls_serverhellodone "$tls_hello_ascii" + hello_done=$? + + for(( 1 ; hello_done==1; 1 )); do + sock_reply_file2=$(mktemp $TEMPDIR/ddreply.XXXXXX) || return 7 + mv "$SOCK_REPLY_FILE" "$sock_reply_file2" + + debugme echo "requesting more server hello data..." + socksend "" $USLEEP_SND + sockread_serverhello 32768 + + next_packet=$(hexdump -v -e '16/1 "%02X"' "$SOCK_REPLY_FILE") + next_packet="${next_packet%%[!0-9A-F]*}" + if [[ ${#next_packet} -eq 0 ]]; then + # This shouldn't be necessary. However, it protects against + # getting into an infinite loop if the server has nothing + # left to send and check_tls_serverhellodone doesn't + # correctly catch it. + mv "$sock_reply_file2" "$SOCK_REPLY_FILE" + hello_done=0 + else + tls_hello_ascii+="$next_packet" + + sock_reply_file3=$(mktemp $TEMPDIR/ddreply.XXXXXX) || return 7 + mv "$SOCK_REPLY_FILE" "$sock_reply_file3" + mv "$sock_reply_file2" "$SOCK_REPLY_FILE" + cat "$sock_reply_file3" >> "$SOCK_REPLY_FILE" + rm "$sock_reply_file3" + + check_tls_serverhellodone "$tls_hello_ascii" + hello_done=$? + fi + done + debugme outln "reading server hello..." if [[ "$DEBUG" -ge 4 ]]; then hexdump -C $SOCK_REPLY_FILE | head -6 echo fi - parse_tls_serverhello "$tls_hello_ascii" + parse_tls_serverhello "$tls_hello_ascii" "ephemeralkey" save=$? + if [[ $save -eq 0 ]]; then + debugme echo "sending close_notify..." + if [[ "$DETECTED_TLS_VERSION" == "0300" ]]; then + socksend ",x15, x03, x00, x00, x02, x02, x00" 0 + else + socksend ",x15, x03, x01, x00, x02, x02, x00" 0 + fi + fi + # see https://secure.wand.net.nz/trac/libprotoident/wiki/SSL lines=$(count_lines "$(hexdump -C "$SOCK_REPLY_FILE" 2>$ERRFILE)") debugme out " (returned $lines lines) " @@ -2421,7 +2465,7 @@ run_client_simulation() { local minEcdsaBits=() local requiresSha2=() local i=0 - local name tls proto cipher + local name tls proto cipher temp what_dh bits has_dh_bits local using_sockets=true if "$SSL_NATIVE" || [[ -n "$STARTTLS" ]]; then @@ -3183,6 +3227,18 @@ run_client_simulation() { sclient_connect_successful $? $TMPFILE sclient_success=$? fi + if [[ $sclient_success -eq 0 ]]; then + # If an ephemeral DH key was used, check that the number of bits is within range. + temp=$(awk -F': ' '/^Server Temp Key/ { print $2 }' "$TMPFILE") # extract line + what_dh=$(awk -F',' '{ print $1 }' <<< $temp) + bits=$(awk -F',' '{ print $3 }' <<< $temp) + grep -q bits <<< $bits || bits=$(awk -F',' '{ print $2 }' <<< $temp) + bits=$(tr -d ' bits' <<< $bits) + if [[ "$what_dh" == "DH" ]]; then + [[ ${minDhBits[i]} -ne -1 ]] && [[ $bits -lt ${minDhBits[i]} ]] && sclient_success=1 + [[ ${maxDhBits[i]} -ne -1 ]] && [[ $bits -gt ${maxDhBits[i]} ]] && sclient_success=1 + fi + fi if [[ $sclient_success -ne 0 ]]; then outln "No connection" fileout "client_${short[i]}" "INFO" "$(strip_spaces "${names[i]}") client simulation: No connection" @@ -3217,7 +3273,12 @@ run_client_simulation() { #FiXME: awk cipher=$(grep -wa Cipher $TMPFILE | egrep -avw "New|is" | sed -e 's/ //g' -e 's/^Cipher://') "$using_sockets" && [[ -n "${handshakebytes[i]}" ]] && cipher="$(rfc2openssl "$cipher")" - outln "$proto $cipher" + out "$proto $cipher" + "$using_sockets" && [[ -n "${handshakebytes[i]}" ]] && has_dh_bits=$HAS_DH_BITS && HAS_DH_BITS=true + "$HAS_DH_BITS" && read_dhbits_from_file $TMPFILE + "$using_sockets" && [[ -n "${handshakebytes[i]}" ]] && HAS_DH_BITS=$has_dh_bits + [[ ":${ROBUST_PFS_CIPHERS}:" =~ ":${cipher}:" ]] && out ", " && pr_done_good "FS" + outln if [[ -n "${warning[i]}" ]]; then out " " outln "${warning[i]}" From d698005313a9e79017c50392fbff483048386eb7 Mon Sep 17 00:00:00 2001 From: Dirk Date: Sat, 5 Nov 2016 12:26:18 +0100 Subject: [PATCH 03/11] tolower --- testssl.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/testssl.sh b/testssl.sh index b4101a1..a8749f0 100755 --- a/testssl.sh +++ b/testssl.sh @@ -558,9 +558,13 @@ trim_trailing_space() { echo "${1%%*( )}" } -toupper() { - echo -n "$1" | tr 'a-z' 'A-Z' -} +if [[ $(uname) == "Linux" ]] ; then + toupper() { echo -n "${1^^}" ; } + tolower() { echo -n "${1,,}" ; } +else + toupper() { echo -n "$1" | tr 'a-z' 'A-Z'; } + tolower() { echo -n "$1" | tr 'A-Z' 'a-z' ; } +fi is_number() { [[ "$1" =~ ^[1-9][0-9]*$ ]] && \ @@ -1543,7 +1547,7 @@ normalize_ciphercode() { HEXC="$part1$part2$part3" fi #TODO: we should just echo this and avoid the global var HEXC - HEXC=$(echo $HEXC | tr 'A-Z' 'a-z' | sed 's/0x/x/') #tolower + strip leading 0 + HEXC=$(tolower "$HEXC"| sed 's/0x/x/') # strip leading 0 return 0 } From 4e40ab53abae41ad4e93dd66f0b499d380ce20c9 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Sat, 5 Nov 2016 12:35:16 +0100 Subject: [PATCH 04/11] Update Readme.md --- Readme.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Readme.md b/Readme.md index 6e63b16..fdfb96e 100644 --- a/Readme.md +++ b/Readme.md @@ -28,9 +28,8 @@ cryptographic flaws. #### Status -_ _Here in the master branch you find the stable version 2.8rc2 of the software, it -superseds 2.6. Version 2.8 is currently being finalized_ . The 2.9dev branch is the developement --- with new features and maybe some bugs. For the stable version and **a +_ _Here in the 2.9dev branch you find the development version of the software +-- with new features and maybe some bugs. For the stable version and **a more thorough description of the command line options** please see [testssl.sh](https://testssl.sh/ "Go to the site with the stable version and more documentation") or https://github.com/drwetter/testssl.sh/wiki/Usage-Documentation. @@ -48,10 +47,10 @@ exchanges. Update notification here or @ [twitter](https://twitter.com/drwetter). -#### [Features in 2.9dev](Readme.md#devel) +#### Features in [2.9dev](Readme.md#devel) * Support of supplying timeout value for ``openssl connect`` * TLS 1.2 protocol check via socket -* Further TLS socket improvements (Handshake) +* Further TLS socket improvements (Handshake parsing, robustness) #### Planned in 2.9dev From b3967f1ed20d6798de7a1da8c745cf520f373471 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Sat, 5 Nov 2016 12:39:05 +0100 Subject: [PATCH 05/11] Update Readme.md --- Readme.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index fdfb96e..df1b06c 100644 --- a/Readme.md +++ b/Readme.md @@ -28,7 +28,7 @@ cryptographic flaws. #### Status -_ _Here in the 2.9dev branch you find the development version of the software +Here in the _2.9dev branch you find the development version_ of the software -- with new features and maybe some bugs. For the stable version and **a more thorough description of the command line options** please see [testssl.sh](https://testssl.sh/ "Go to the site with the stable version @@ -48,9 +48,11 @@ exchanges. Update notification here or @ [twitter](https://twitter.com/drwetter). #### Features in [2.9dev](Readme.md#devel) -* Support of supplying timeout value for ``openssl connect`` +* Support of supplying timeout value for ``openssl connect`` -- useful for batch/mass scanning * TLS 1.2 protocol check via socket * Further TLS socket improvements (Handshake parsing, robustness) +* non-flat JSON support +* in file output (CSV, JSON flat, JSON non-flat) support of a minimum severity level (only above supplied level there will be output) #### Planned in 2.9dev From 41e862b3ea6e77b3b01368c60297ace505c63324 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Sat, 5 Nov 2016 12:41:05 +0100 Subject: [PATCH 06/11] Update Readme.md --- Readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index df1b06c..bf8ba46 100644 --- a/Readme.md +++ b/Readme.md @@ -47,7 +47,7 @@ exchanges. Update notification here or @ [twitter](https://twitter.com/drwetter). -#### Features in [2.9dev](Readme.md#devel) +#### Features implemented in [2.9dev](Readme.md#devel) * Support of supplying timeout value for ``openssl connect`` -- useful for batch/mass scanning * TLS 1.2 protocol check via socket * Further TLS socket improvements (Handshake parsing, robustness) @@ -55,7 +55,7 @@ Update notification here or @ [twitter](https://twitter.com/drwetter). * in file output (CSV, JSON flat, JSON non-flat) support of a minimum severity level (only above supplied level there will be output) -#### Planned in 2.9dev +#### Features planned in 2.9dev https://github.com/drwetter/testssl.sh/issues?q=is%3Aopen+is%3Aissue+milestone%3A2.9dev From dc871030b215ce2b750a135d069b5b0c1a1fb1c2 Mon Sep 17 00:00:00 2001 From: Dirk Date: Sat, 5 Nov 2016 13:43:55 +0100 Subject: [PATCH 07/11] reordered help --- testssl.sh | 69 +++++++++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/testssl.sh b/testssl.sh index adbf660..7886243 100755 --- a/testssl.sh +++ b/testssl.sh @@ -8212,17 +8212,34 @@ check_bsd_mount() { help() { cat << EOF -$PROG_NAME + "$PROG_NAME URI" or "$PROG_NAME " or "$PROG_NAME URI" + + +"$PROG_NAME URI", where URI is: + + URI host|host:port|URL|URL:port port 443 is default, URL can only contain HTTPS protocol) + +"$PROG_NAME ", where is: -h, --help what you're looking at -b, --banner displays banner + version of $PROG_NAME -v, --version same as previous -V, --local pretty print all local ciphers - -V, --local which local ciphers with are available? - (if pattern not a number: word match) + -V, --local which local ciphers with are available? If pattern is not a number: word match -$PROG_NAME URI ("$PROG_NAME URI" does everything except -E) + pattern is always an ignore case word pattern of cipher hexcode or any other string in the name, kx or bits + +"$PROG_NAME URI", where is: + + -t, --starttls does a default run against a STARTTLS enabled (latter two require supplied openssl) + --xmpphost for STARTTLS enabled XMPP it supplies the XML stream to-'' domain -- sometimes needed + --mx tests MX records from high to low priority (STARTTLS, port 25) + --file mass testing option: Reads command lines from , one line per instance. + Comments via # allowed, EOF signals end of . Implicitly turns on "--warnings batch" + +single check as ("$PROG_NAME URI" does everything except -E): -e, --each-cipher checks each local cipher remotely -E, --cipher-per-proto checks those per protocol -f, --ciphers checks common cipher suites @@ -8236,7 +8253,7 @@ $PROG_NAME URI ("$PROG_NAME URI" does everything except -E) -c, --client-simulation test client simulations, see which client negotiates with cipher and protocol -H, --header, --headers tests HSTS, HPKP, server/app banner, security headers, cookie, reverse proxy, IPv4 address - -U, --vulnerable tests all vulnerabilities + -U, --vulnerable tests all (of the following) vulnerabilities (if applicable) -B, --heartbleed tests for heartbleed vulnerability -I, --ccs, --ccs-injection tests for CCS injection vulnerability -R, --renegotiation tests for renegotiation vulnerabilities @@ -8251,29 +8268,16 @@ $PROG_NAME URI ("$PROG_NAME URI" does everything except -E) -s, --pfs, --fs, --nsa checks (perfect) forward secrecy settings -4, --rc4, --appelbaum which RC4 ciphers are being offered? -special invocations: - -t, --starttls does a default run against a STARTTLS enabled - --xmpphost for STARTTLS enabled XMPP it supplies the XML stream to-'' domain -- sometimes needed - --mx tests MX records from high to low priority (STARTTLS, port 25) - --ip a) tests the supplied v4 or v6 address instead of resolving host(s) in URI - b) arg "one" means: just test the first DNS returns (useful for multiple IPs) - -n, --nodns do not try any DNS lookup - --file mass testing option: Reads command lines from , one line per instance. - Comments via # allowed, EOF signals end of . Implicitly turns on "--warnings batch" - -partly mandatory parameters: - URI host|host:port|URL|URL:port (port 443 is assumed unless otherwise specified) - pattern an ignore case word pattern of cipher hexcode or any other string in the name, kx or bits - protocol is one of the STARTTLS protocols ftp,smtp,pop3,imap,xmpp,telnet,ldap - (for the latter two you need e.g. the supplied openssl) - -tuning options (can also be preset via environment variables): +tuning / connect options (most also can be preset via environment variables): --bugs enables the "-bugs" option of s_client, needed e.g. for some buggy F5s --assume-http if protocol check fails it assumes HTTP protocol and enforces HTTP checks --ssl-native fallback to checks with OpenSSL where sockets are normally used --openssl use this openssl binary (default: look in \$PATH, \$RUN_DIR of $PROG_NAME) --proxy : connect via the specified HTTP proxy -6 use also IPv6. Works only with supporting OpenSSL version and IPv6 connectivity + --ip a) tests the supplied v4 or v6 address instead of resolving host(s) in URI + b) arg "one" means: just test the first DNS returns (useful for multiple IPs) + -n, --nodns do not try any DNS lookup --sneaky leave less traces in target logs: user agent, referer output options (can also be preset via environment variables): @@ -8290,22 +8294,23 @@ output options (can also be preset via environment variables): file output options (can also be preset via environment variables): --log, --logging logs stdout to in current working directory --logfile logs stdout to if file is a dir or to specified log file - --json additional output of findings to JSON file in cwd - --jsonfile additional output to JSON and output JSON to the specified file - --json-pretty additional pretty structed output of findings to JSON file in cwd - --jsonfile-pretty additional pretty structed output to JSON and output JSON to the specified file - --csv additional output of findings to CSV file in cwd - --csvfile set output to CSV and output CSV to the specified file + --json additional output of findings to flat JSON file in cwd + --jsonfile additional output to the specified flat JSON file + --json-pretty additional pretty structured output of findings to JSON file in cwd + --jsonfile-pretty additional pretty structured output as JSON to the specified file + --csv additional output of findings to CSV file in cwd + --csvfile additional output as CSV to the specified file + --severity severities with lower level will be filtered for CSV+JSON, possible values --append if or exists rather append then overwrite - --severity severities with lower level will be filtered -All options requiring a value can also be called with '=' e.g. testssl.sh -t=smtp --wide --openssl=/usr/bin/openssl . - is always the last parameter. +Options requiring a value can also be called with '=' e.g. testssl.sh -t=smtp --wide --openssl=/usr/bin/openssl . +URI always needs to be the last parameter. Need HTML output? Just pipe through "aha" (ANSI HTML Adapter: github.com/theZiz/aha) like - "$PROG_NAME | aha >output.html" + "$PROG_NAME | aha >output.html" or use -log* and convert later + EOF #' Fix syntax highlight on sublime exit $1 From 711e460cae064daab1d1cdf39a56c07c37ad01ca Mon Sep 17 00:00:00 2001 From: Dirk Date: Sun, 6 Nov 2016 20:39:56 +0100 Subject: [PATCH 08/11] minor polish --- testssl.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/testssl.sh b/testssl.sh index 1475efa..16d82ef 100755 --- a/testssl.sh +++ b/testssl.sh @@ -6599,7 +6599,7 @@ socksend_tls_clienthello() { local extension_supported_groups="" extension_supported_point_formats="" local extra_extensions extra_extensions_list="" - code2network "$(echo "$2" | tr 'A-Z' 'a-z')" # convert CIPHER_SUITES + code2network "$(tolower "$2")" # convert CIPHER_SUITES cipher_suites="$NW_STR" # we don't have the leading \x here so string length is two byte less, see next len_ciph_suites_byte=$(echo ${#cipher_suites}) @@ -8444,8 +8444,9 @@ EOF $OPENSSL ciphers -V 'ALL:COMPLEMENTOFALL' &>$TEMPDIR/all_local_ciphers.txt fi # see also $TEMPDIR/s_client_has.txt from find_openssl_binary - CIPHERS_BY_STRENGTH_FILE=$(mktemp $TEMPDIR/ciphers_by_strength.XXXXXX) + +-#FIXME: better externally: separation of code and data cat >$CIPHERS_BY_STRENGTH_FILE << EOF 0xCC,0x14 - ECDHE-ECDSA-CHACHA20-POLY1305 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256_OLD TLSv1.2 Kx=ECDH Au=ECDSA Enc=ChaCha20(256) Mac=AEAD 0xCC,0x13 - ECDHE-RSA-CHACHA20-POLY1305 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD TLSv1.2 Kx=ECDH Au=RSA Enc=ChaCha20(256) Mac=AEAD From f5f3218e69216c75ec76714c875c3ada6247fb1e Mon Sep 17 00:00:00 2001 From: Dirk Date: Sun, 6 Nov 2016 21:12:57 +0100 Subject: [PATCH 09/11] update --- testssl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index f289624..05ddf13 100755 --- a/testssl.sh +++ b/testssl.sh @@ -8507,7 +8507,7 @@ EOF # see also $TEMPDIR/s_client_has.txt from find_openssl_binary CIPHERS_BY_STRENGTH_FILE=$(mktemp $TEMPDIR/ciphers_by_strength.XXXXXX) --#FIXME: better externally: separation of code and data +#FIXME: better externally: separation of code and data cat >$CIPHERS_BY_STRENGTH_FILE << EOF 0xCC,0x14 - ECDHE-ECDSA-CHACHA20-POLY1305 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256_OLD TLSv1.2 Kx=ECDH Au=ECDSA Enc=ChaCha20(256) Mac=AEAD 0xCC,0x13 - ECDHE-RSA-CHACHA20-POLY1305 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD TLSv1.2 Kx=ECDH Au=RSA Enc=ChaCha20(256) Mac=AEAD From db64ea6d6109aec26cf8ccd078ea9453aebbcac1 Mon Sep 17 00:00:00 2001 From: Dirk Date: Sun, 6 Nov 2016 22:43:42 +0100 Subject: [PATCH 10/11] add more test info to #503 --- testssl.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/testssl.sh b/testssl.sh index 05ddf13..dcd0844 100755 --- a/testssl.sh +++ b/testssl.sh @@ -505,10 +505,13 @@ strip_quote() { fileout_pretty_json_header() { START_TIME=$(date +%s) - echo -e " \"host\" : \"$NODE\", + echo -e " \"Invocation\" : \"$PROG_NAME $CMDLINE\", + \"at\" : \"$HNAME:$OPENSSL_LOCATION\", + \"version\" : \"$VERSION ${GIT_REL_SHORT:-$CVS_REL_SHORT} from $REL_DATE\" + \"openssl\" : \"$OSSL_VER\" from \"$OSSL_BUILD_DATE\" + \"target host\" : \"$NODE\", \"port\" : \"$PORT\", \"startTime\" : \"$START_TIME\", - \"version\" : \"$VERSION\", \"scanResult\" : { " } From a153b71598f3bb120ff8c69441baaaf2d3e9d520 Mon Sep 17 00:00:00 2001 From: Dirk Date: Sun, 6 Nov 2016 23:00:55 +0100 Subject: [PATCH 11/11] fixing same openssl cipher names, see #379 --- testssl.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testssl.sh b/testssl.sh index dcd0844..b9a5a4d 100755 --- a/testssl.sh +++ b/testssl.sh @@ -8512,9 +8512,9 @@ EOF #FIXME: better externally: separation of code and data cat >$CIPHERS_BY_STRENGTH_FILE << EOF - 0xCC,0x14 - ECDHE-ECDSA-CHACHA20-POLY1305 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256_OLD TLSv1.2 Kx=ECDH Au=ECDSA Enc=ChaCha20(256) Mac=AEAD - 0xCC,0x13 - ECDHE-RSA-CHACHA20-POLY1305 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD TLSv1.2 Kx=ECDH Au=RSA Enc=ChaCha20(256) Mac=AEAD - 0xCC,0x15 - DHE-RSA-CHACHA20-POLY1305 TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD TLSv1.2 Kx=DH Au=RSA Enc=ChaCha20(256) Mac=AEAD + 0xCC,0x14 - ECDHE-ECDSA-CHACHA20-POLY1305-OLD TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256_OLD TLSv1.2 Kx=ECDH Au=ECDSA Enc=ChaCha20(256) Mac=AEAD + 0xCC,0x13 - ECDHE-RSA-CHACHA20-POLY1305-OLD TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD TLSv1.2 Kx=ECDH Au=RSA Enc=ChaCha20(256) Mac=AEAD + 0xCC,0x15 - DHE-RSA-CHACHA20-POLY1305-OLD TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD TLSv1.2 Kx=DH Au=RSA Enc=ChaCha20(256) Mac=AEAD 0xC0,0x30 - ECDHE-RSA-AES256-GCM-SHA384 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD 0xC0,0x2C - ECDHE-ECDSA-AES256-GCM-SHA384 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD 0xC0,0x28 - ECDHE-RSA-AES256-SHA384 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA384