From 888f4f9c5a2ac1f8bcbd05526c22cd1e705a5722 Mon Sep 17 00:00:00 2001 From: Dirk Date: Tue, 27 Oct 2020 22:36:42 +0100 Subject: [PATCH 1/3] Fix run_freak() when sslv2 server hello is empty This fixes #1754 by avoiding further strings operations if the socket reply is empty as bash 5.1 seems to have a problem with that. The fix is done in sslv2_sockets() . Also sslv2 is not being used in run_freak() if known not to be supported. --- testssl.sh | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/testssl.sh b/testssl.sh index ec03c1a..3bea2dc 100755 --- a/testssl.sh +++ b/testssl.sh @@ -14274,19 +14274,18 @@ parse_tls13_new_session_ticket() { # 1,4,6,7: see return value of parse_sslv2_serverhello() sslv2_sockets() { local ret - local client_hello cipher_suites len_client_hello + local cipher_suites="$1" + local client_hello len_client_hello local len_ciph_suites_byte len_ciph_suites local server_hello sock_reply_file2 local -i response_len server_hello_len local parse_complete=false - # this could be empty so swe use '==' + # this could be empty so we use '==' if [[ "$2" == true ]]; then parse_complete=true fi - if [[ -n "$1" ]]; then - cipher_suites="$1" - else + if [[ -z "$cipher_suites" ]]; then cipher_suites=" 05,00,80, # 1st cipher 9 cipher specs, only classical V2 ciphers are used here, see FIXME below 03,00,80, # 2nd there are v3 in v2!!! : https://tools.ietf.org/html/rfc6101#appendix-E @@ -14330,22 +14329,24 @@ sslv2_sockets() { sockread_serverhello 32768 if "$parse_complete"; then - server_hello=$(hexdump -v -e '16/1 "%02X"' "$SOCK_REPLY_FILE") - server_hello_len=2+$(hex2dec "${server_hello:1:3}") - response_len=$(wc -c "$SOCK_REPLY_FILE" | awk '{ print $1 }') - for (( 1; response_len < server_hello_len; 1 )); do - sock_reply_file2=${SOCK_REPLY_FILE}.2 - mv "$SOCK_REPLY_FILE" "$sock_reply_file2" - - debugme echo -n "requesting more server hello data... " - socksend "" $USLEEP_SND - sockread_serverhello 32768 - - [[ ! -s "$SOCK_REPLY_FILE" ]] && break - cat "$SOCK_REPLY_FILE" >> "$sock_reply_file2" - mv "$sock_reply_file2" "$SOCK_REPLY_FILE" + if [[ -s "$SOCK_REPLY_FILE" ]]; then + server_hello=$(hexdump -v -e '16/1 "%02X"' "$SOCK_REPLY_FILE") + server_hello_len=2 + $(hex2dec "${server_hello:1:3}") response_len=$(wc -c "$SOCK_REPLY_FILE" | awk '{ print $1 }') - done + for (( 1; response_len < server_hello_len; 1 )); do + sock_reply_file2=${SOCK_REPLY_FILE}.2 + mv "$SOCK_REPLY_FILE" "$sock_reply_file2" + + debugme echo -n "requesting more server hello data... " + socksend "" $USLEEP_SND + sockread_serverhello 32768 + + [[ ! -s "$SOCK_REPLY_FILE" ]] && break + cat "$SOCK_REPLY_FILE" >> "$sock_reply_file2" + mv "$sock_reply_file2" "$SOCK_REPLY_FILE" + response_len=$(wc -c "$SOCK_REPLY_FILE" | awk '{ print $1 }') + done + fi fi debugme echo "reading server hello... " if [[ "$DEBUG" -ge 4 ]]; then @@ -16823,7 +16824,6 @@ run_freak() { else nr_supported_ciphers=$(count_ciphers $(actually_supported_osslciphers $exportrsa_cipher_list)) fi - #echo "========= ${PIPESTATUS[*]} case $nr_supported_ciphers in 0) prln_local_problem "$OPENSSL doesn't have any EXPORT RSA ciphers configured" @@ -16841,7 +16841,9 @@ run_freak() { tls_sockets "03" "$exportrsa_tls_cipher_list_hex, 00,ff" sclient_success=$? [[ $sclient_success -eq 2 ]] && sclient_success=0 - if [[ $sclient_success -ne 0 ]]; then + + # TLS handshake failed with ciphers above. Now we check SSLv2 -- unless we know it's not available + if [[ $sclient_success -ne 0 ]] && [[ $(has_server_protocol ssl2) -ne 1 ]]; then sslv2_sockets "$exportrsa_ssl2_cipher_list_hex" "true" if [[ $? -eq 3 ]] && [[ "$V2_HELLO_CIPHERSPEC_LENGTH" -ne 0 ]]; then exportrsa_ssl2_cipher_list_hex="$(strip_spaces "${exportrsa_ssl2_cipher_list_hex//,/}")" From 3cd1273439595603100e199422e03aa83c5fd862 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Wed, 28 Oct 2020 09:52:10 +0100 Subject: [PATCH 2/3] Address complaint by Travis Despite the fact google doesn't support RC4 ciphers, testssl.sh called sslv2_sockets(). Google answered with a >= TLS alert. Building a sum then failed then in sslv2_sockets(). This fixes sslv2_sockets() and introduces count_chars() as a helper function (tested also under old FreeBSD to make sure it works under MacOSX). --- testssl.sh | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/testssl.sh b/testssl.sh index 3bea2dc..9b00b6a 100755 --- a/testssl.sh +++ b/testssl.sh @@ -803,6 +803,10 @@ count_ciphers() { echo $(wc -w <<< "${1//:/ }") } +count_chars() { + echo $(wc -c <<< "$1") +} + newline_to_spaces() { tr '\n' ' ' <<< "$1" | sed 's/ $//' } @@ -14331,8 +14335,8 @@ sslv2_sockets() { if "$parse_complete"; then if [[ -s "$SOCK_REPLY_FILE" ]]; then server_hello=$(hexdump -v -e '16/1 "%02X"' "$SOCK_REPLY_FILE") - server_hello_len=2 + $(hex2dec "${server_hello:1:3}") - response_len=$(wc -c "$SOCK_REPLY_FILE" | awk '{ print $1 }') + server_hello_len=$((2 + $(hex2dec "${server_hello:1:3}") )) + response_len=$(count_chars "$SOCK_REPLY_FILE") for (( 1; response_len < server_hello_len; 1 )); do sock_reply_file2=${SOCK_REPLY_FILE}.2 mv "$SOCK_REPLY_FILE" "$sock_reply_file2" @@ -14344,7 +14348,7 @@ sslv2_sockets() { [[ ! -s "$SOCK_REPLY_FILE" ]] && break cat "$SOCK_REPLY_FILE" >> "$sock_reply_file2" mv "$sock_reply_file2" "$SOCK_REPLY_FILE" - response_len=$(wc -c "$SOCK_REPLY_FILE" | awk '{ print $1 }') + response_len=$(count_chars "$SOCK_REPLY_FILE") done fi fi @@ -14362,6 +14366,7 @@ sslv2_sockets() { return $ret } + # arg1: supported groups extension # arg2: "all" - process full response (including Certificate and certificate_status handshake messages) # "ephemeralkey" - extract the server's ephemeral key (if any) From faad7128a78f80359f8eefc9a4c987d702feb25c Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Wed, 28 Oct 2020 10:13:22 +0100 Subject: [PATCH 3/3] If we are sure we don't have sslv2 we don't need to test any RC4 SSLv2 ciphers --- testssl.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/testssl.sh b/testssl.sh index 9b00b6a..cea2094 100755 --- a/testssl.sh +++ b/testssl.sh @@ -17870,7 +17870,8 @@ run_rc4() { return 0 fi - # get a list of all the cipher suites to test + # Get a list of all the cipher suites to test. #FIXME: This is rather ineffective as RC4 ciphers won't change. + # We should instead build a fixed list here like @ other functions if "$using_sockets" || [[ $OSSL_VER_MAJOR -lt 1 ]]; then for (( i=0; i < TLS_NR_CIPHERS; i++ )); do if [[ "${TLS_CIPHER_RFC_NAME[i]}" =~ RC4 ]] && ( "$using_sockets" || "${TLS_CIPHER_OSSL_SUPPORTED[i]}" ); then @@ -17925,7 +17926,7 @@ run_rc4() { done < <($OPENSSL ciphers $OSSL_CIPHERS_S -V 'ALL:COMPLEMENTOFALL:@STRENGTH' 2>>$ERRFILE) fi - if "$using_sockets" && [[ -n "$sslv2_ciphers_hex" ]]; then + if "$using_sockets" && [[ -n "$sslv2_ciphers_hex" ]] && [[ $(has_server_protocol ssl2) -ne 1 ]]; then sslv2_sockets "${sslv2_ciphers_hex:2}" "true" if [[ $? -eq 3 ]] && [[ "$V2_HELLO_CIPHERSPEC_LENGTH" -ne 0 ]]; then supported_sslv2_ciphers="$(grep "Supported cipher: " "$TEMPDIR/$NODEIP.parse_sslv2_serverhello.txt")" @@ -17938,7 +17939,7 @@ run_rc4() { fi done fi - elif "$HAS_SSL2" && [[ -n "$sslv2_ciphers_ossl" ]]; then + elif "$HAS_SSL2" && [[ -n "$sslv2_ciphers_ossl" ]] && [[ $(has_server_protocol ssl2) -ne 1 ]]; then $OPENSSL s_client -cipher "${sslv2_ciphers_ossl:1}" $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY -ssl2 >$TMPFILE 2>$ERRFILE