From aa5d4917cfc04f5fb2f6b57c3726237cca6735b9 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Mon, 3 Feb 2025 14:21:10 -0800 Subject: [PATCH] Enhance ticketbleed testing Some versions of OpenSSL/LibreSSL do not support TLS 1.1 and earlier, either because they do not support the protocol (e.g, `$OEPNSSL s_client -tls1` results in a "unknown option" error) or because the cryptography needed to support these protocol versions (e.g., MD5/SHA1) is not available. Given the limitations of some versions of $OPENSSL, this commit enhances ticketbleed testing in two ways. First, it performs the testing using the newest (non-TLS 1.3) version supported by the server, so that TLS 1 and TLS 1.1 aren't used unless TLS 1.2 is not supported. Second, it adds tests for whether the protocol version to be used is supported by $OPENSSL and for whether connection attempts were successful, rather than assuming connection attempts succeed. --- testssl.sh | 51 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/testssl.sh b/testssl.sh index 038fd72..9a6a339 100755 --- a/testssl.sh +++ b/testssl.sh @@ -16907,25 +16907,11 @@ run_ccs_injection(){ return $ret } -sub_session_ticket_tls() { - local tls_proto="$1" - local sessticket_tls="" - #FIXME: we likely have done this already before (either @ run_server_defaults() or at least the output - # from a previous handshake) --> would save 1x connect. We have TLS_TICKET but not yet the ticket itself #FIXME - #ATTENTION: we DO NOT use SNI here as we assume ticketbleed is a vulnerability of the TLS stack. If we'd do SNI here, we'd also need - # it in the ClientHello of run_ticketbleed() otherwise the ticket will be different and the whole thing won't work! - # - sessticket_tls="$($OPENSSL s_client $(s_client_options "$BUGS $tls_proto $PROXY $SNI -connect $NODEIP:$PORT") $ERRFILE | awk '/TLS session ticket:/,/^$/' | awk '!/TLS session ticket/')" - sessticket_tls="$(sed -e 's/^.* - /x/g' -e 's/ .*$//g' <<< "$sessticket_tls" | tr '\n' ',')" - sed -e 's/ /,x/g' -e 's/-/,x/g' <<< "$sessticket_tls" - -} - # see https://blog.filippo.io/finding-ticketbleed/ | https://filippo.io/ticketbleed/ run_ticketbleed() { local tls_hexcode tls_proto="" - local session_tckt_tls="" + local sessticket_tls="" session_tckt_tls="" local -i len_ch=300 # fixed len of prepared clienthello below local sid="x00,x0B,xAD,xC0,xDE,x00," # some arbitrary bytes local len_sid="$(( ${#sid} / 4))" @@ -16961,17 +16947,23 @@ run_ticketbleed() { return 0 fi - if [[ 0 -eq $(has_server_protocol tls1) ]]; then - tls_hexcode="x03, x01"; tls_proto="-tls1" + if [[ 0 -eq $(has_server_protocol tls1_2) ]]; then + tls_hexcode="x03, x03"; tls_proto="-tls1_2" elif [[ 0 -eq $(has_server_protocol tls1_1) ]]; then tls_hexcode="x03, x02"; tls_proto="-tls1_1" - elif [[ 0 -eq $(has_server_protocol tls1_2) ]]; then - tls_hexcode="x03, x03"; tls_proto="-tls1_2" + elif [[ 0 -eq $(has_server_protocol tls1) ]]; then + tls_hexcode="x03, x01"; tls_proto="-tls1" elif [[ 0 -eq $(has_server_protocol ssl3) ]]; then tls_hexcode="x03, x00"; tls_proto="-ssl3" else # no protocol for some reason defined, determine TLS versions offered with a new handshake "$HAS_TLS13" && tls_proto="-no_tls1_3" $OPENSSL s_client $(s_client_options "$STARTTLS $BUGS $tls_proto -connect $NODEIP:$PORT $PROXY") >$TMPFILE 2>$ERRFILE would save 1x connect. We have TLS_TICKET but not yet the ticket itself #FIXME + #ATTENTION: we DO NOT use SNI here as we assume ticketbleed is a vulnerability of the TLS stack. If we'd do SNI here, we'd also need + # it in the ClientHello of run_ticketbleed() otherwise the ticket will be different and the whole thing won't work! + # + $OPENSSL s_client $(s_client_options "$BUGS $tls_proto $PROXY $SNI -connect $NODEIP:$PORT") $TMPFILE 2>$ERRFILE + sclient_connect_successful $? "$TMPFILE" + if [[ $? -ne 0 ]]; then + prln_warning "$OPENSSL unable to connect to $NODEIP:$PORT when testing for ticketbleed." + fileout "$jsonID" "WARN" "$OPENSSL unable to connect to $NODEIP:$PORT when testing for ticketbleed." + return 1 + fi + sessticket_tls="$(awk '/TLS session ticket:/,/^$/' "$TMPFILE" | awk '!/TLS session ticket/')" + sessticket_tls="$(sed -e 's/^.* - /x/g' -e 's/ .*$//g' <<< "$sessticket_tls" | tr '\n' ',')" + session_tckt_tls="$(sed -e 's/ /,x/g' -e 's/-/,x/g' <<< "$sessticket_tls")" if [[ "$session_tckt_tls" == "," ]]; then pr_svrty_best "not vulnerable (OK)" outln ", no session tickets"