Skip to content

Commit 6e72c9b

Browse files
authored
Merge pull request #2646 from testssl/fix_feature2098
Feature: Detection STARTTLS throtteling via code 421/SMTP
2 parents abd0170 + 4b92810 commit 6e72c9b

2 files changed

Lines changed: 28 additions & 9 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@
2222
* BREACH check: list all compression methods and add brotli
2323
* Test for old winshock vulnerability
2424
* Test for STARTTLS injection vulnerabilities (SMTP, POP3, IMAP)
25-
* STARTTLS: XMPP server support, plus new set of OpenSSL-bad binaries
25+
* STARTTLS: XMPP server support, plus a new set of OpenSSL-bad binaries
26+
* STARTTLS sieve support, plus again a new set of OpenSSL-bad binaries
2627
* Several code improvements to STARTTLS, also better detection when no STARTTLS is offered
28+
* Detect throtteling via STARTTLS smtp
2729
* Renegotiation checks more reliable against different servers
2830
* STARTTLS on active directory service support
2931
* Security fixes: DNS and other input from servers
@@ -41,13 +43,13 @@
4143
* Added --user-agent argument to support using a custom User Agent
4244
* Added --overwrite argument to support overwriting output files without warning
4345
* Headerflag X-XSS-Protection is now labeled as INFO
46+
* Search for more HTTP security headers on the server
4447
* Strict parser for HSTS
4548
* DNS via proxy improvements
4649
* Client simulation runs in wide mode which is even better readable
4750
* Added --reqheader to support custom headers in HTTP requests
48-
* Search for more HTTP security headers on the server
4951
* Test for support for RFC 8879 certificate compression
50-
* Deprecating --fast and --ssl-native (warning but still av)
52+
* Deprecating --fast and --ssl-native (warning only but still av)
5153
* Compatible to GNU grep 3.8
5254
* Don't use external pwd command anymore
5355
* Doesn't hang anymore when there's no local resolver

testssl.sh

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6121,7 +6121,7 @@ listciphers() {
61216121
[[ "$TLS13_OSSL_CIPHERS" =~ $cipher ]] && tls13_supported_ciphers+=":$cipher"
61226122
done
61236123
tls13_ciphers="${tls13_supported_ciphers:1}"
6124-
6124+
61256125
"$HAS_SECLEVEL" && [[ -n "$ciphers" ]] && ciphers="@SECLEVEL=0:$1"
61266126
! "$HAS_TLS1" && options="${options//-tls1 /}"
61276127
if "$HAS_CIPHERSUITES"; then
@@ -11466,6 +11466,7 @@ starttls_full_read(){
1146611466
local end_pattern="$2"
1146711467
local starttls_regex="$3" # optional: pattern we search for in the server's response
1146811468
local debug_str="$4" # optional
11469+
local problem_pattern="$5" # optional: used currently only for 421 code
1146911470
local starttls_read_data=()
1147011471
local one_line=""
1147111472
local ret=0
@@ -11486,14 +11487,21 @@ starttls_full_read(){
1148611487
while read -r -t $STARTTLS_SLEEP one_line; ret=$?; (exit $ret); do
1148711488
debugme tmln_out "S: ${one_line}"
1148811489
if [[ $DEBUG -ge 5 ]]; then
11489-
echo "end_pattern/cont_pattern: ${end_pattern} / ${cont_pattern}"
11490+
echo "end / cont problem pattern: ${end_pattern} / ${cont_pattern} / ${problem_pattern}"
1149011491
fi
1149111492
if [[ -n "$starttls_regex" ]]; then
1149211493
if [[ ${one_line} =~ $starttls_regex ]]; then
1149311494
debugme tmln_out "${debugpad} ${one_line} "
1149411495
# We don't exit here as the buffer is not empty. So we continue reading but save the status:
1149511496
ret_found=0
1149611497
fi
11498+
elif [[ -n "$problem_pattern" ]]; then
11499+
if [[ ${one_line} =~ ${problem_pattern} ]]; then
11500+
debugme echo "=== matches ${problem_pattern} ==="
11501+
IFS="${oldIFS}"
11502+
ret_found=4
11503+
break
11504+
fi
1149711505
fi
1149811506
starttls_read_data+=("${one_line}")
1149911507
if [[ ${one_line} =~ ${end_pattern} ]]; then
@@ -11542,6 +11550,7 @@ starttls_smtp_dialog() {
1154211550
local greet_str="EHLO testssl.sh"
1154311551
local proto="smtp"
1154411552
local reSTARTTLS='^250[ -]STARTTLS'
11553+
local reToofast='^421 ' # 421 4.7.0 .* Error: too many connections, see #2098
1154511554
local starttls="STARTTLS"
1154611555
local -i ret=0
1154711556

@@ -11553,13 +11562,14 @@ starttls_smtp_dialog() {
1155311562
fi
1155411563
debugme echo "=== starting $proto STARTTLS dialog ==="
1155511564

11556-
starttls_full_read '^220-' '^220 ' '' "received server greeting" &&
11565+
starttls_full_read '^220-' '^220 ' '' "received server greeting" "${reToofast}" &&
1155711566
starttls_just_send "$greet_str" "sent $greet_str" &&
1155811567
starttls_full_read '^250-' '^250 ' "${reSTARTTLS}" "received server capabilities and checked STARTTLS availability" &&
1155911568
starttls_just_send "$starttls" "initiated STARTTLS" &&
1156011569
starttls_full_read '^220-' '^220 ' '' "received ack for STARTTLS"
1156111570
ret=$?
1156211571
debugme echo "=== finished $proto STARTTLS dialog with ${ret} ==="
11572+
# ret will be 4 if $reToofast matches
1156311573
return $ret
1156411574
}
1156511575

@@ -11781,9 +11791,13 @@ starttls_telnet_dialog() {
1178111791
return $ret
1178211792
}
1178311793

11784-
# arg1: fd for socket -- which we don't use yes as it is a hassle (not clear whether it works under every bash version)
11794+
# arg1: fd for socket (which we don't use yet. It's a hassle, not clear whether it works under every bash version
1178511795
# arg2: optional: for STARTTLS additional command to be injected
11786-
# returns 6 if opening the socket caused a problem, 1 if STARTTLS handshake failed, 0: all ok
11796+
# return values:
11797+
# 0: all ok
11798+
# 1: STARTTLS handshake failed
11799+
# 4: throtteling on STARTTLS level encountered
11800+
# 6: if opening the socket caused a problem
1178711801
#
1178811802
fd_socket() {
1178911803
local fd="$1"
@@ -11902,6 +11916,9 @@ fd_socket() {
1190211916
case $ret in
1190311917
0) return 0 ;;
1190411918
3) fatal "No STARTTLS found in handshake" $ERR_CONNECT ;;
11919+
4) ((NR_STARTTLS_FAIL++))
11920+
connectivity_problem $NR_STARTTLS_FAIL $MAX_STARTTLS_FAIL "Throtteling detected (STARTTLS server msg 421)" "repeated STARTTLS problems due to throtteling, giving up"
11921+
return 4 ;;
1190511922
*) if [[ $ret -eq 2 ]] && [[ -n "$payload" ]]; then
1190611923
# We don't want this handling for STARTTLS injection
1190711924
return 0
@@ -24119,7 +24136,7 @@ parse_cmd_line() {
2411924136
--mtls|--mtls=*)
2412024137
MTLS="$(parse_opt_equal_sign "$1" "$2")"
2412124138
[[ $? -eq 0 ]] && shift
24122-
;;
24139+
;;
2412324140
--connect-timeout|--connect-timeout=*)
2412424141
CONNECT_TIMEOUT="$(parse_opt_equal_sign "$1" "$2")"
2412524142
[[ $? -eq 0 ]] && shift

0 commit comments

Comments
 (0)