From 8627ba518fd87d1e80849650ad92228a2dbc4f43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Fust=C3=A9?= Date: Fri, 1 Mar 2024 21:17:56 +0100 Subject: [PATCH] Kill the heuristic an count the real number of renegociations The heuristic is too fragile and timing dependant. - As for the initial TLS negociation, wait for the result of the renegociation request before sending the next one. - Remove the result ratio calculation and message as we now reach the timeout in case of exponential backoff or connection hang. This commit depend on the fix of the timeout, broken by the zombi fix. --- testssl.sh | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/testssl.sh b/testssl.sh index 398eb7b..1c27f09 100755 --- a/testssl.sh +++ b/testssl.sh @@ -16981,6 +16981,8 @@ run_renego() { local jsonID="" local ssl_reneg_attempts=$SSL_RENEG_ATTEMPTS local ssl_reneg_wait=$SSL_RENEG_WAIT + local pid watcher + local tmp_result loop_reneg # In cases where there's no default host configured we need SNI here as openssl then would return otherwise an error and the test will fail "$HAS_TLS13" && [[ -z "$proto" ]] && proto="-no_tls1_3" @@ -17108,26 +17110,28 @@ run_renego() { # If we dont wait for the session to be established on slow server, we will try to re-negotiate # too early losing all the attempts before the session establishment as OpenSSL will not buffer them # (only the first will be till the establishement of the session). - (while [[ $(grep -ac '^SSL-Session:' $TMPFILE) -ne 1 ]]; do sleep 1; done; \ - for ((i=0; i < ssl_reneg_attempts; i++ )); do echo R; sleep $ssl_reneg_wait; done) | \ + (while [[ $(grep -ac '^SSL-Session:' $TMPFILE) -ne 1 ]]; do sleep $ssl_reneg_wait; done; \ + for ((i=0; i < ssl_reneg_attempts; i++ )); do echo R; sleep $ssl_reneg_wait; \ + while [[ $(grep -ac '^RENEGOTIATING' $ERRFILE) -ne $(($i+3)) ]] && [[ ! -f $TEMPDIR/was_killed ]]; \ + do sleep $ssl_reneg_wait; done; \ + done) | \ $OPENSSL s_client $(s_client_options "$proto $legacycmd $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>>$ERRFILE & pid=$! ( sleep $(($ssl_reneg_attempts*3)) && kill $pid && touch $TEMPDIR/was_killed ) >&2 2>/dev/null & watcher=$! # Trick to get the return value of the openssl command, output redirection and a timeout. Yes, some target hang/block after some tries. - wait $pid && pkill -HUP -P $watcher + wait $pid tmp_result=$? + pkill -HUP -P $watcher wait $watcher # If we are here, we have done two successful renegotiation (-2) and do the loop loop_reneg=$(($(grep -ac '^RENEGOTIATING' $ERRFILE )-2)) if [[ -f $TEMPDIR/was_killed ]]; then - tmp_result=3 + tmp_result=2 + sleep $ssl_reneg_wait # let the while loop see the watchdog file + sleep $ssl_reneg_wait # and + sleep $ssl_reneg_wait # avoid float arithmetic rm -f $TEMPDIR/was_killed - else - # If we got less than 2/3 successful attempts during the loop with 1s pause, we are in presence of exponential backoff. - if [[ $tmp_result -eq 0 ]] && [[ $loop_reneg -le $(($ssl_reneg_attempts*2/3)) ]]; then - tmp_result=2 - fi fi case $tmp_result in 0) pr_svrty_high "VULNERABLE (NOT ok)"; outln ", DoS threat ($ssl_reneg_attempts attempts)" @@ -17137,10 +17141,6 @@ run_renego() { fileout "$jsonID" "OK" "not vulnerable, mitigated" "$cve" "$cwe" ;; 2) pr_svrty_good "not vulnerable (OK)"; \ - outln " -- mitigated ($loop_reneg successful reneg within ${ssl_reneg_attempts} in ${ssl_reneg_attempts}x${ssl_reneg_wait}s)" - fileout "$jsonID" "OK" "not vulnerable, mitigated" "$cve" "$cwe" - ;; - 3) pr_svrty_good "not vulnerable (OK)"; \ outln " -- mitigated ($loop_reneg successful reneg within ${ssl_reneg_attempts} in $((${ssl_reneg_attempts}*3))s(timeout))" fileout "$jsonID" "OK" "not vulnerable, mitigated" "$cve" "$cwe" ;;