From 50d2ef18ca236331c77f767d72ee3a2eb60ac954 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Wed, 10 Aug 2016 16:14:32 -0400 Subject: [PATCH 1/6] Replace sockread() with sockread_serverhello() This PR is in response to issue #352, where it was noted that Bash does not support binary data in strings. I replaced all calls to `sockread()` with calls to `sockread_serverhello()`, and then, since is now used everywhere and not just to read ServerHello messages, I renamed `sockread_serverhello()` to `sockread()`. I tested the revised code against several servers, including one that is vulnerable to CCS and Heartbleed, and got the same results as with the current code (although the hexdumps displayed in debug mode differ). One concern I have is the code in `run_ccs_injection()`. The current code is: ``` byte6=$(echo "$SOCKREPLY" | "${HEXDUMPPLAIN[@]}" | sed 's/^..........//') lines=$(echo "$SOCKREPLY" | "${HEXDUMP[@]}" | count_lines ) debugme echo "lines: $lines, byte6: $byte6" if [[ "$byte6" == "0a" ]] || [[ "$lines" -gt 1 ]]; then pr_done_best "not vulnerable (OK)" ... ``` I revised this to: ``` if [[ -s "$SOCK_REPLY_FILE" ]]; then byte6=$(hexdump -ve '1/1 "%.2x"' "$SOCK_REPLY_FILE" | sed 's/^..........//') lines=$(hexdump -ve '16/1 "%02x " " \n"' "$SOCK_REPLY_FILE" | count_lines ) debugme echo "lines: $lines, byte6: $byte6" fi rm "$SOCK_REPLY_FILE" if [[ "$byte6" == "0a" ]] || [[ "$lines" -gt 1 ]]; then ... ``` In the revised code `byte6` is initialized to `0a` so that the response is `not vulnerable (OK)` if `$SOCK_REPLY_FILE` is empty. This has worked okay since for all of the servers that I tested that weren't vulnerable `$SOCK_REPLY_FILE` was empty. Since I haven't seen any other examples, I don't understand why check for vulnerability was written the way it was. So, I'm a bit concerned that the test in the revised code may produce incorrect results now that `hexdump -ve '1/1 "%.2x"' "$SOCK_REPLY_FILE"` is an accurate hexdump of the reply. --- testssl.sh | 66 ++++++++++++++++++++++-------------------------------- 1 file changed, 27 insertions(+), 39 deletions(-) diff --git a/testssl.sh b/testssl.sh index 1d91590..f318ee6 100755 --- a/testssl.sh +++ b/testssl.sh @@ -199,7 +199,6 @@ TLS_EXTENSIONS="" GOST_STATUS_PROBLEM=false DETECTED_TLS_VERSION="" PATTERN2SHOW="" -SOCKREPLY="" SOCK_REPLY_FILE="" HEXC="" NW_STR="" @@ -251,11 +250,6 @@ FIRST_FINDING=true # Is this the first finding we are outpu TLS_LOW_BYTE="" HEX_CIPHER="" - # The various hexdump commands we need to replace xxd (BSD compatibility) -HEXDUMPVIEW=(hexdump -C) # This is used in verbose mode to see what's going on -HEXDUMP=(hexdump -ve '16/1 "%02x " " \n"') # This is used to analyze the reply -HEXDUMPPLAIN=(hexdump -ve '1/1 "%.2x"') # Replaces both xxd -p and tr -cd '[:print:]' - ###### some hexbytes for bash network sockets follow ###### @@ -1467,23 +1461,6 @@ socksend() { sleep $2 } - -#FIXME: This is only for HB and CCS, others use still sockread_serverhello() -sockread() { - local -i ret=0 - local ddreply - - [[ "x$2" == "x" ]] && maxsleep=$MAX_WAITSOCK || maxsleep=$2 - - ddreply=$(mktemp $TEMPDIR/ddreply.XXXXXX) || return 7 - dd bs=$1 of=$ddreply count=1 <&5 2>/dev/null & - wait_kill $! $maxsleep - ret=$? - SOCKREPLY=$(cat $ddreply 2>/dev/null) - rm $ddreply - return $ret -} - #FIXME: fill the following two: openssl2rfc() { : @@ -1992,7 +1969,7 @@ client_simulation_sockets() { printf -- "$data" >&5 2>/dev/null & sleep $USLEEP_SND - sockread_serverhello 32768 + sockread 32768 TLS_NOW=$(LC_ALL=C date "+%s") debugme outln "reading server hello..." if [[ "$DEBUG" -ge 4 ]]; then @@ -5257,8 +5234,7 @@ socksend_sslv2_clienthello() { sleep $USLEEP_SND } -# for SSLv2 to TLS 1.2: -sockread_serverhello() { +sockread() { [[ -z "$2" ]] && maxsleep=$MAX_WAITSOCK || maxsleep=$2 SOCK_REPLY_FILE=$(mktemp $TEMPDIR/ddreply.XXXXXX) || return 7 @@ -5613,7 +5589,7 @@ sslv2_sockets() { debugme outln "sending client hello... " socksend_sslv2_clienthello "$SSLv2_CLIENT_HELLO" - sockread_serverhello 32768 + sockread 32768 debugme outln "reading server hello... " if [[ "$DEBUG" -ge 4 ]]; then hexdump -C "$SOCK_REPLY_FILE" | head -6 @@ -5900,7 +5876,7 @@ tls_sockets() { # if sending didn't succeed we don't bother if [[ $ret -eq 0 ]]; then - sockread_serverhello 32768 + sockread 32768 TLS_NOW=$(LC_ALL=C date "+%s") debugme outln "reading server hello..." if [[ "$DEBUG" -ge 4 ]]; then @@ -5946,6 +5922,9 @@ tls_sockets() { # mainly adapted from https://gist.github.com/takeshixx/10107280 run_heartbleed(){ + local tls_proto_offered tls_hexcode heartbleed_payload client_hello + local -i retval ret lines_returned + [[ $VULN_COUNT -le $VULN_THRESHLD ]] && outln && pr_headlineln " Testing for heartbleed vulnerability " && outln pr_bold " Heartbleed"; out " (CVE-2014-0160) " @@ -6029,10 +6008,11 @@ run_heartbleed(){ debugme outln "\nreading server hello" sockread 32768 if [[ $DEBUG -ge 4 ]]; then - echo "$SOCKREPLY" | "${HEXDUMPVIEW[@]}" | head -20 + hexdump -C "$SOCK_REPLY_FILE" | head -20 outln "[...]" outln "\nsending payload with TLS version $tls_hexcode:" fi + rm "$SOCK_REPLY_FILE" socksend "$heartbleed_payload" 1 sockread 16384 $HEARTBLEED_MAX_WAITSOCK @@ -6040,11 +6020,12 @@ run_heartbleed(){ if [[ $DEBUG -ge 3 ]]; then outln "\nheartbleed reply: " - echo "$SOCKREPLY" | "${HEXDUMPVIEW[@]}" + hexdump -C "$SOCK_REPLY_FILE" | head -20 outln fi - lines_returned=$(echo "$SOCKREPLY" | "${HEXDUMP[@]}" | wc -l | sed 's/ //g') + lines_returned=$(hexdump -ve '16/1 "%02x " " \n"' "$SOCK_REPLY_FILE" | wc -l | sed 's/ //g') + rm "$SOCK_REPLY_FILE" if [[ $lines_returned -gt 1 ]]; then pr_svrty_critical "VULNERABLE (NOT ok)" if [[ $retval -eq 3 ]]; then @@ -6078,6 +6059,9 @@ ok_ids(){ #FIXME: At a certain point heartbleed and ccs needs to be changed and make use of code2network using a file, then tls_sockets run_ccs_injection(){ + local tls_proto_offered tls_hexcode ccs_message client_hello byte6="0a" + local -i retval ret lines + # 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 [[ $VULN_COUNT -le $VULN_THRESHLD ]] && outln && pr_headlineln " Testing for CCS injection vulnerability " && outln @@ -6139,23 +6123,25 @@ run_ccs_injection(){ debugme outln "\nreading server hello" sockread 32768 if [[ $DEBUG -ge 4 ]]; then - echo "$SOCKREPLY" | "${HEXDUMPVIEW[@]}" | head -20 + hexdump -C "$SOCK_REPLY_FILE" | head -20 outln "[...]" outln "\npayload #1 with TLS version $tls_hexcode:" fi + rm "$SOCK_REPLY_FILE" # ... and then send the a change cipher spec message socksend "$ccs_message" 1 || ok_ids sockread 2048 $CCS_MAX_WAITSOCK if [[ $DEBUG -ge 3 ]]; then outln "\n1st reply: " - out "$SOCKREPLY" | "${HEXDUMPVIEW[@]}" | head -20 + hexdump -C "$SOCK_REPLY_FILE" | head -20 # ok: 15 | 0301 | 02 | 02 | 0a # ALERT | TLS 1.0 | Length=2 | Unexpected Message (0a) # or just timed out outln outln "payload #2 with TLS version $tls_hexcode:" fi + rm "$SOCK_REPLY_FILE" socksend "$ccs_message" 2 || ok_ids sockread 2048 $CCS_MAX_WAITSOCK @@ -6163,17 +6149,19 @@ run_ccs_injection(){ if [[ $DEBUG -ge 3 ]]; then outln "\n2nd reply: " - printf -- "$SOCKREPLY" | "${HEXDUMPVIEW[@]}" + printf -- "$(hexdump -C "$SOCK_REPLY_FILE")" # not ok: 15 | 0301 | 02 | 02 | 15 # ALERT | TLS 1.0 | Length=2 | Decryption failed (21) # ok: 0a or nothing: ==> RST outln fi - byte6=$(echo "$SOCKREPLY" | "${HEXDUMPPLAIN[@]}" | sed 's/^..........//') - lines=$(echo "$SOCKREPLY" | "${HEXDUMP[@]}" | count_lines ) - debugme echo "lines: $lines, byte6: $byte6" - + if [[ -s "$SOCK_REPLY_FILE" ]]; then + byte6=$(hexdump -ve '1/1 "%.2x"' "$SOCK_REPLY_FILE" | sed 's/^..........//') + lines=$(hexdump -ve '16/1 "%02x " " \n"' "$SOCK_REPLY_FILE" | count_lines ) + debugme echo "lines: $lines, byte6: $byte6" + fi + rm "$SOCK_REPLY_FILE" if [[ "$byte6" == "0a" ]] || [[ "$lines" -gt 1 ]]; then pr_done_best "not vulnerable (OK)" if [[ $retval -eq 3 ]]; then @@ -6654,7 +6642,7 @@ run_drown() { fd_socket 5 || return 6 debugme outln "sending client hello... " socksend_sslv2_clienthello "$SSLv2_CLIENT_HELLO" - sockread_serverhello 32768 + sockread 32768 debugme outln "reading server hello... " if [[ "$DEBUG" -ge 4 ]]; then hexdump -C "$SOCK_REPLY_FILE" | head -6 From 2abf6fc7c754cbfda56a5728b110e3af940b3d94 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Mon, 29 Aug 2016 10:14:21 -0400 Subject: [PATCH 2/6] Fix merge --- testssl.sh | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/testssl.sh b/testssl.sh index 84f6447..3568f50 100755 --- a/testssl.sh +++ b/testssl.sh @@ -6646,16 +6646,7 @@ run_drown() { fi # if we want to use OPENSSL: check for < openssl 1.0.2g, openssl 1.0.1s if native openssl pr_bold " DROWN"; out " (2016-0800, CVE-2016-0703) " - fd_socket 5 || return 6 - debugme outln "sending client hello... " - socksend_sslv2_clienthello "$SSLv2_CLIENT_HELLO" - sockread 32768 - debugme outln "reading server hello... " - if [[ "$DEBUG" -ge 4 ]]; then - hexdump -C "$SOCK_REPLY_FILE" | head -6 - outln - fi - parse_sslv2_serverhello "$SOCK_REPLY_FILE" + sslv2_sockets case $? in 7) # strange reply, couldn't convert the cipher spec length to a hex number From 9bcf232f0f239a4059e80b406af352ec2104902f Mon Sep 17 00:00:00 2001 From: David Cooper Date: Mon, 29 Aug 2016 14:10:16 -0400 Subject: [PATCH 3/6] Check for empty byte6 --- testssl.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testssl.sh b/testssl.sh index e2219e7..035e37c 100755 --- a/testssl.sh +++ b/testssl.sh @@ -6066,7 +6066,7 @@ ok_ids(){ #FIXME: At a certain point heartbleed and ccs needs to be changed and make use of code2network using a file, then tls_sockets run_ccs_injection(){ - local tls_proto_offered tls_hexcode ccs_message client_hello byte6="0a" + local tls_proto_offered tls_hexcode ccs_message client_hello byte6="" local -i retval ret lines # see https://www.openssl.org/news/secadv_20140605.txt @@ -6169,7 +6169,7 @@ run_ccs_injection(){ debugme echo "lines: $lines, byte6: $byte6" fi rm "$SOCK_REPLY_FILE" - if [[ "$byte6" == "0a" ]] || [[ "$lines" -gt 1 ]]; then + if [[ "$byte6" == "" ]] || [[ "$lines" -gt 1 ]]; then pr_done_best "not vulnerable (OK)" if [[ $retval -eq 3 ]]; then fileout "ccs" "OK" "CCS (CVE-2014-0224): not vulnerable (OK) (timed out)" From 1b548cee108814a38841ea0d0ae056cf44e34750 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Tue, 30 Aug 2016 11:38:43 -0400 Subject: [PATCH 4/6] Follow https://github.com/Tripwire/OpenSSL-CCS-Inject-Test Attempt to rewrite `run_ccs_injection()` to follow the logic from https://github.com/Tripwire/OpenSSL-CCS-Inject-Test. --- testssl.sh | 87 +++++++++++++++++++++++++++++------------------------- 1 file changed, 47 insertions(+), 40 deletions(-) diff --git a/testssl.sh b/testssl.sh index 035e37c..98d652e 100755 --- a/testssl.sh +++ b/testssl.sh @@ -6066,8 +6066,9 @@ ok_ids(){ #FIXME: At a certain point heartbleed and ccs needs to be changed and make use of code2network using a file, then tls_sockets run_ccs_injection(){ - local tls_proto_offered tls_hexcode ccs_message client_hello byte6="" - local -i retval ret lines + local tls_proto_offered tls_hexcode ccs_message close_message client_hello + local reply="" + local -i retval ret # 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 @@ -6089,6 +6090,7 @@ run_ccs_injection(){ #FIXME: for SSLv3 only we need to set tls_hexcode and the record layer TLS version correctly esac ccs_message=", x14, $tls_hexcode ,x00, x01, x01" + close_message=", x15, $tls_hexcode ,x00, x02, x01, x00" client_hello=" # TLS header (5 bytes) @@ -6136,58 +6138,63 @@ run_ccs_injection(){ fi rm "$SOCK_REPLY_FILE" -# ... and then send the a change cipher spec message +# ... and then send a change cipher spec message socksend "$ccs_message" 1 || ok_ids sockread 2048 $CCS_MAX_WAITSOCK if [[ $DEBUG -ge 3 ]]; then - outln "\n1st reply: " - hexdump -C "$SOCK_REPLY_FILE" | head -20 -# ok: 15 | 0301 | 02 | 02 | 0a -# ALERT | TLS 1.0 | Length=2 | Unexpected Message (0a) -# or just timed out - outln - outln "payload #2 with TLS version $tls_hexcode:" - fi - rm "$SOCK_REPLY_FILE" - - socksend "$ccs_message" 2 || ok_ids - sockread 2048 $CCS_MAX_WAITSOCK - retval=$? - - if [[ $DEBUG -ge 3 ]]; then - outln "\n2nd reply: " - printf -- "$(hexdump -C "$SOCK_REPLY_FILE")" -# not ok: 15 | 0301 | 02 | 02 | 15 -# ALERT | TLS 1.0 | Length=2 | Decryption failed (21) -# ok: 0a or nothing: ==> RST + if [[ $retval -eq 3 ]]; then + outln "\n1st reply: (timed out)" + else + outln "\n1st reply: " + hexdump -C "$SOCK_REPLY_FILE" | head -20 + fi outln fi if [[ -s "$SOCK_REPLY_FILE" ]]; then - byte6=$(hexdump -ve '1/1 "%.2x"' "$SOCK_REPLY_FILE" | sed 's/^..........//') - lines=$(hexdump -ve '16/1 "%02x " " \n"' "$SOCK_REPLY_FILE" | count_lines ) - debugme echo "lines: $lines, byte6: $byte6" + reply=$(hexdump -ve '1/1 "%.2x"' "$SOCK_REPLY_FILE") fi - rm "$SOCK_REPLY_FILE" - if [[ "$byte6" == "" ]] || [[ "$lines" -gt 1 ]]; then +# if the server responded with a fatal alert, then it is not vulnerable + if [[ "$reply" =~ 15030[0-9]000202[0-9a0f][0-9a-f] ]]; then pr_done_best "not vulnerable (OK)" - if [[ $retval -eq 3 ]]; then - fileout "ccs" "OK" "CCS (CVE-2014-0224): not vulnerable (OK) (timed out)" - else - fileout "ccs" "OK" "CCS (CVE-2014-0224): not vulnerable (OK)" - fi + fileout "ccs" "OK" "CCS (CVE-2014-0224): not vulnerable (OK)" ret=0 else - pr_svrty_critical "VULNERABLE (NOT ok)" - if [[ $retval -eq 3 ]]; then - fileout "ccs" "NOT ok" "CCS (CVE-2014-0224): VULNERABLE (NOT ok) (timed out)" - else - fileout "ccs" "NOT ok" "CCS (CVE-2014-0224): VULNERABLE (NOT ok)" + if [[ $DEBUG -ge 3 ]]; then + outln "payload #2 with TLS version $tls_hexcode:" fi - ret=1 + rm "$SOCK_REPLY_FILE" + + # Send a close notify warning message + socksend "$close_message" 2 || ok_ids + sockread 2048 $CCS_MAX_WAITSOCK + retval=$? + + if [[ $DEBUG -ge 3 ]]; then + outln "\n2nd reply: " + printf -- "$(hexdump -C "$SOCK_REPLY_FILE")" + outln + fi + + # if the server sends a non-empty response to the close notify, + # then it may be vulnerable. + if [[ ! -s "$SOCK_REPLY_FILE" ]]; then + pr_done_best "not vulnerable (OK)" + if [[ $retval -eq 3 ]]; then + fileout "ccs" "OK" "CCS (CVE-2014-0224): not vulnerable (OK) (timed out)" + else + fileout "ccs" "OK" "CCS (CVE-2014-0224): not vulnerable (OK)" + fi + ret=0 + else + pr_svrty_critical "VULNERABLE (NOT ok)" + fileout "ccs" "NOT ok" "CCS (CVE-2014-0224): VULNERABLE (NOT ok)" + ret=1 + fi + [[ $retval -eq 3 ]] && out " (timed out)" fi - [[ $retval -eq 3 ]] && out " (timed out)" outln + rm "$SOCK_REPLY_FILE" close_socket tmpfile_handle $FUNCNAME.txt From a2f968d4adb7506ccbfd61efd0ae10e0cdfb996f Mon Sep 17 00:00:00 2001 From: David Cooper Date: Wed, 31 Aug 2016 17:03:50 -0400 Subject: [PATCH 5/6] Undo changed behavior for CCS --- testssl.sh | 112 ++++++++++++++++++++++++++--------------------------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/testssl.sh b/testssl.sh index 2cb27f9..98a4e11 100755 --- a/testssl.sh +++ b/testssl.sh @@ -251,6 +251,10 @@ FIRST_FINDING=true # Is this the first finding we are outpu TLS_LOW_BYTE="" HEX_CIPHER="" + # The various hexdump commands we need to replace xxd (BSD compatibility) +HEXDUMP=(hexdump -ve '16/1 "%02x " " \n"') # This is used to analyze the reply +HEXDUMPPLAIN=(hexdump -ve '1/1 "%.2x"') # Replaces both xxd -p and tr -cd '[:print:]' + ###### some hexbytes for bash network sockets follow ###### @@ -1970,7 +1974,7 @@ client_simulation_sockets() { printf -- "$data" >&5 2>/dev/null & sleep $USLEEP_SND - sockread 32768 + sockread_serverhello 32768 TLS_NOW=$(LC_ALL=C date "+%s") debugme outln "reading server hello..." if [[ "$DEBUG" -ge 4 ]]; then @@ -5288,7 +5292,8 @@ socksend_sslv2_clienthello() { sleep $USLEEP_SND } -sockread() { +# for SSLv2 to TLS 1.2: +sockread_serverhello() { [[ -z "$2" ]] && maxsleep=$MAX_WAITSOCK || maxsleep=$2 SOCK_REPLY_FILE=$(mktemp $TEMPDIR/ddreply.XXXXXX) || return 7 @@ -5643,7 +5648,7 @@ sslv2_sockets() { debugme outln "sending client hello... " socksend_sslv2_clienthello "$SSLv2_CLIENT_HELLO" - sockread 32768 + sockread_serverhello 32768 debugme outln "reading server hello... " if [[ "$DEBUG" -ge 4 ]]; then hexdump -C "$SOCK_REPLY_FILE" | head -6 @@ -5894,7 +5899,7 @@ tls_sockets() { # if sending didn't succeed we don't bother if [[ $ret -eq 0 ]]; then - sockread 32768 + sockread_serverhello 32768 TLS_NOW=$(LC_ALL=C date "+%s") debugme outln "reading server hello..." if [[ "$DEBUG" -ge 4 ]]; then @@ -5941,7 +5946,7 @@ tls_sockets() { # mainly adapted from https://gist.github.com/takeshixx/10107280 run_heartbleed(){ local tls_proto_offered tls_hexcode heartbleed_payload client_hello - local -i retval ret lines_returned + local -i retval ret lines_returned bytes_returned [[ $VULN_COUNT -le $VULN_THRESHLD ]] && outln && pr_headlineln " Testing for heartbleed vulnerability " && outln pr_bold " Heartbleed"; out " (CVE-2014-0160) " @@ -6024,7 +6029,7 @@ run_heartbleed(){ socksend "$client_hello" 1 debugme outln "\nreading server hello" - sockread 32768 + sockread_serverhello 32768 if [[ $DEBUG -ge 4 ]]; then hexdump -C "$SOCK_REPLY_FILE" | head -20 outln "[...]" @@ -6033,12 +6038,14 @@ run_heartbleed(){ rm "$SOCK_REPLY_FILE" socksend "$heartbleed_payload" 1 - sockread 16384 $HEARTBLEED_MAX_WAITSOCK + sockread_serverhello 16384 $HEARTBLEED_MAX_WAITSOCK retval=$? if [[ $DEBUG -ge 3 ]]; then outln "\nheartbleed reply: " hexdump -C "$SOCK_REPLY_FILE" | head -20 + bytes_returned="$(wc -c "$SOCK_REPLY_FILE" | awk '{ print $1 }')" + [[ $bytes_returned -gt 160 ]] && outln "[...]" outln fi @@ -6077,9 +6084,8 @@ ok_ids(){ #FIXME: At a certain point heartbleed and ccs needs to be changed and make use of code2network using a file, then tls_sockets run_ccs_injection(){ - local tls_proto_offered tls_hexcode ccs_message close_message client_hello - local reply="" - local -i retval ret + local tls_proto_offered tls_hexcode ccs_message client_hello byte6 sockreply + local -i retval ret lines # 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 @@ -6101,7 +6107,6 @@ run_ccs_injection(){ #FIXME: for SSLv3 only we need to set tls_hexcode and the record layer TLS version correctly esac ccs_message=", x14, $tls_hexcode ,x00, x01, x01" - close_message=", x15, $tls_hexcode ,x00, x02, x01, x00" client_hello=" # TLS header (5 bytes) @@ -6141,7 +6146,7 @@ run_ccs_injection(){ socksend "$client_hello" 1 debugme outln "\nreading server hello" - sockread 32768 + sockread_serverhello 32768 if [[ $DEBUG -ge 4 ]]; then hexdump -C "$SOCK_REPLY_FILE" | head -20 outln "[...]" @@ -6149,63 +6154,58 @@ run_ccs_injection(){ fi rm "$SOCK_REPLY_FILE" -# ... and then send a change cipher spec message +# ... and then send the a change cipher spec message socksend "$ccs_message" 1 || ok_ids - sockread 2048 $CCS_MAX_WAITSOCK + sockread_serverhello 2048 $CCS_MAX_WAITSOCK if [[ $DEBUG -ge 3 ]]; then - if [[ $retval -eq 3 ]]; then - outln "\n1st reply: (timed out)" - else - outln "\n1st reply: " - hexdump -C "$SOCK_REPLY_FILE" | head -20 - fi + outln "\n1st reply: " + hexdump -C "$SOCK_REPLY_FILE" | head -20 +# ok: 15 | 0301 | 02 | 02 | 0a +# ALERT | TLS 1.0 | Length=2 | Unexpected Message (0a) +# or just timed out + outln + outln "payload #2 with TLS version $tls_hexcode:" + fi + rm "$SOCK_REPLY_FILE" + + socksend "$ccs_message" 2 || ok_ids + sockread_serverhello 2048 $CCS_MAX_WAITSOCK + retval=$? + + if [[ $DEBUG -ge 3 ]]; then + outln "\n2nd reply: " + printf -- "$(hexdump -C "$SOCK_REPLY_FILE")" +# not ok: 15 | 0301 | 02 | 02 | 15 +# ALERT | TLS 1.0 | Length=2 | Decryption failed (21) +# ok: 0a or nothing: ==> RST outln fi + sockreply=$(cat "$SOCK_REPLY_FILE" 2>/dev/null) + rm "$SOCK_REPLY_FILE" - if [[ -s "$SOCK_REPLY_FILE" ]]; then - reply=$(hexdump -ve '1/1 "%.2x"' "$SOCK_REPLY_FILE") - fi -# if the server responded with a fatal alert, then it is not vulnerable - if [[ "$reply" =~ 15030[0-9]000202[0-9a0f][0-9a-f] ]]; then + byte6=$(echo "$sockreply" | "${HEXDUMPPLAIN[@]}" | sed 's/^..........//') + lines=$(echo "$sockreply" | "${HEXDUMP[@]}" | count_lines ) + debugme echo "lines: $lines, byte6: $byte6" + + if [[ "$byte6" == "0a" ]] || [[ "$lines" -gt 1 ]]; then pr_done_best "not vulnerable (OK)" - fileout "ccs" "OK" "CCS (CVE-2014-0224): not vulnerable (OK)" + if [[ $retval -eq 3 ]]; then + fileout "ccs" "OK" "CCS (CVE-2014-0224): not vulnerable (OK) (timed out)" + else + fileout "ccs" "OK" "CCS (CVE-2014-0224): not vulnerable (OK)" + fi ret=0 else - if [[ $DEBUG -ge 3 ]]; then - outln "payload #2 with TLS version $tls_hexcode:" - fi - rm "$SOCK_REPLY_FILE" - - # Send a close notify warning message - socksend "$close_message" 2 || ok_ids - sockread 2048 $CCS_MAX_WAITSOCK - retval=$? - - if [[ $DEBUG -ge 3 ]]; then - outln "\n2nd reply: " - printf -- "$(hexdump -C "$SOCK_REPLY_FILE")" - outln - fi - - # if the server sends a non-empty response to the close notify, - # then it may be vulnerable. - if [[ ! -s "$SOCK_REPLY_FILE" ]]; then - pr_done_best "not vulnerable (OK)" - if [[ $retval -eq 3 ]]; then - fileout "ccs" "OK" "CCS (CVE-2014-0224): not vulnerable (OK) (timed out)" - else - fileout "ccs" "OK" "CCS (CVE-2014-0224): not vulnerable (OK)" - fi - ret=0 + pr_svrty_critical "VULNERABLE (NOT ok)" + if [[ $retval -eq 3 ]]; then + fileout "ccs" "NOT ok" "CCS (CVE-2014-0224): VULNERABLE (NOT ok) (timed out)" else - pr_svrty_critical "VULNERABLE (NOT ok)" fileout "ccs" "NOT ok" "CCS (CVE-2014-0224): VULNERABLE (NOT ok)" - ret=1 fi - [[ $retval -eq 3 ]] && out " (timed out)" + ret=1 fi + [[ $retval -eq 3 ]] && out " (timed out)" outln - rm "$SOCK_REPLY_FILE" close_socket tmpfile_handle $FUNCNAME.txt From 9ef0d1f4ea8e1b3f7f465c07af28c2c7dfae79ee Mon Sep 17 00:00:00 2001 From: David Cooper Date: Wed, 31 Aug 2016 17:07:53 -0400 Subject: [PATCH 6/6] 20 lines is 320 bytes, not 160 --- testssl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index 98a4e11..5bd5c72 100755 --- a/testssl.sh +++ b/testssl.sh @@ -6045,7 +6045,7 @@ run_heartbleed(){ outln "\nheartbleed reply: " hexdump -C "$SOCK_REPLY_FILE" | head -20 bytes_returned="$(wc -c "$SOCK_REPLY_FILE" | awk '{ print $1 }')" - [[ $bytes_returned -gt 160 ]] && outln "[...]" + [[ $bytes_returned -gt 320 ]] && outln "[...]" outln fi