mirror of
https://github.com/drwetter/testssl.sh.git
synced 2025-05-15 04:36:04 +02:00
Detect downgrade to plaintext for STARTTLS, IMAP
Some Cyrus IMAD if configured with SSL_CTX_set_cipher_list(context, "!TLSv1") and similar respond with a plaintext 'a002 NO Starttls negotiation failed" when a not-supported protocol is detected, see #1082. This PR fixes this by detecting (also) this downgrade. As a precaution It still issues a warning as this is seems a special configuration.
This commit is contained in:
parent
43ee837ec2
commit
987fbeda37
79
testssl.sh
79
testssl.sh
@ -4889,6 +4889,12 @@ run_protocols() {
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
3) pr_svrty_best "not offered (OK), "
|
||||
fileout "$jsonID" "OK" "not offered"
|
||||
add_tls_offered ssl3 no
|
||||
pr_warning "SSL downgraded to STARTTLS plaintext"; outln
|
||||
fileout "$jsonID" "WARN" "SSL downgraded to STARTTLS plaintext"
|
||||
;;
|
||||
4) out "likely "; pr_svrty_best "not offered (OK), "
|
||||
fileout "$jsonID" "OK" "not offered"
|
||||
add_tls_offered ssl3 no
|
||||
@ -4956,6 +4962,12 @@ run_protocols() {
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
3) out "not offered, "
|
||||
fileout "$jsonID" "OK" "not offered"
|
||||
add_tls_offered tls1 no
|
||||
pr_warning "TLS downgraded to STARTTLS plaintext"; outln
|
||||
fileout "$jsonID" "WARN" "TLS downgraded to STARTTLS plaintext"
|
||||
;;
|
||||
4) out "likely not offered, "
|
||||
fileout "$jsonID" "INFO" "likely not offered"
|
||||
add_tls_offered tls1 no
|
||||
@ -5027,6 +5039,12 @@ run_protocols() {
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
3) out "not offered, "
|
||||
fileout "$jsonID" "OK" "not offered"
|
||||
add_tls_offered tls1_1 no
|
||||
pr_warning "TLS downgraded to STARTTLS plaintext"; outln
|
||||
fileout "$jsonID" "WARN" "TLS downgraded to STARTTLS plaintext"
|
||||
;;
|
||||
4) out "likely not offered, "
|
||||
fileout "$jsonID" "INFO" "is not offered"
|
||||
add_tls_offered tls1_1 no
|
||||
@ -5109,17 +5127,23 @@ run_protocols() {
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
4) out "likely "; pr_svrty_medium "not offered, "
|
||||
3) out "not offered, "
|
||||
fileout "$jsonID" "OK" "not offered"
|
||||
add_tls_offered tls1_2 no
|
||||
pr_warning "TLS downgraded to STARTTLS plaintext"; outl
|
||||
fileout "$jsonID" "WARN" "TLS downgraded to STARTTLS plaintext"
|
||||
;;
|
||||
4) out "likely "; pr_svrty_medium "not offered, "
|
||||
fileout "$jsonID" "MEDIUM" "not offered"
|
||||
add_tls_offered tls1_2 no
|
||||
pr_warning "received 4xx/5xx after STARTTLS handshake"; outln "$debug_recomm"
|
||||
fileout "$jsonID" "WARN" "received 4xx/5xx after STARTTLS handshake${debug_recomm}"
|
||||
;;
|
||||
5) outln "$supported_no_ciph1" # protocol detected, but no cipher --> comes from run_prototest_openssl
|
||||
5) outln "$supported_no_ciph1" # protocol detected, but no cipher --> comes from run_prototest_openssl
|
||||
fileout "$jsonID" "INFO" "$supported_no_ciph1"
|
||||
add_tls_offered tls1_2 yes
|
||||
;;
|
||||
7) if "$using_sockets" ; then
|
||||
7) if "$using_sockets" ; then
|
||||
# can only happen in debug mode
|
||||
pr_warning "strange reply, maybe a client side problem with TLS 1.2"; outln "$debug_recomm"
|
||||
else
|
||||
@ -5277,6 +5301,12 @@ run_protocols() {
|
||||
fi
|
||||
add_tls_offered tls1_3 no
|
||||
;;
|
||||
3) out "not offered "
|
||||
fileout "$jsonID" "INFO" "not offered"
|
||||
add_tls_offered tls1_3 no
|
||||
pr_warning "TLS downgraded to STARTTLS plaintext"; outln
|
||||
fileout "$jsonID" "WARN" "TLS downgraded to STARTTLS plaintext"
|
||||
;;
|
||||
4) out "likely not offered, "
|
||||
fileout "$jsonID" "INFO" "not offered"
|
||||
add_tls_offered tls1_3 no
|
||||
@ -9164,13 +9194,16 @@ starttls_mysql_dialog() {
|
||||
}
|
||||
|
||||
# arg1: fd for socket -- which we don't use as it is a hassle and it is not clear whether it works under every bash version
|
||||
#
|
||||
# returns 6 if opening the socket caused a problem, 1 if STARTTLS handshake failed, 0: all ok
|
||||
fd_socket() {
|
||||
local jabber=""
|
||||
local proyxline=""
|
||||
local nodeip="$(tr -d '[]' <<< $NODEIP)" # sockets do not need the square brackets we have of IPv6 addresses
|
||||
# we just need do it here, that's all!
|
||||
[[ -t 5 ]] && echo "tty"
|
||||
if [[ -t 5 ]]; then
|
||||
pr_warning "$PROG_NAME: unable to open a socket because of a tty conflict"
|
||||
return 6
|
||||
fi
|
||||
if [[ -n "$PROXY" ]]; then
|
||||
# PROXYNODE works better than PROXYIP on modern versions of squid
|
||||
if ! exec 5<> /dev/tcp/${PROXYNODE}/${PROXYPORT}; then
|
||||
@ -9607,7 +9640,7 @@ get_dh_ephemeralkey() {
|
||||
# 3=SSLv2 supported (in $TEMPDIR/$NODEIP.sslv2_sockets.dd is reply for further processing
|
||||
# --> there could be checked whether ciphers e.g have been returned at all (or anything else)
|
||||
# 4=looks like an STARTTLS 5xx message
|
||||
# 6=socket coudln't be opened
|
||||
# 6=socket couldn't be opened
|
||||
# 7=strange reply we can't deal with
|
||||
parse_sslv2_serverhello() {
|
||||
local ret v2_hello_ascii v2_hello_initbyte v2_hello_length
|
||||
@ -10572,7 +10605,7 @@ parse_tls_serverhello() {
|
||||
fi
|
||||
for (( i=0; i<tls_hello_ascii_len; i=i+msg_len )); do
|
||||
if [[ $tls_hello_ascii_len-$i -lt 10 ]]; then
|
||||
if [[ "$process_full" == "all" ]]; then
|
||||
if [[ "$process_full" == all ]]; then
|
||||
# The entire server response should have been retrieved.
|
||||
debugme tmln_warning "Malformed message."
|
||||
[[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt
|
||||
@ -10604,13 +10637,19 @@ parse_tls_serverhello() {
|
||||
tmln_out
|
||||
fi
|
||||
|
||||
if "$do_starttls" && ( [[ $tls_content_type == 35 ]] || [[ $tls_content_type == 34 ]] ); then
|
||||
# STARTTLS handshake failed and server replied plaintext with a 5xx or 4xx
|
||||
[[ $DEBUG -ge 2 ]] && printf "%s\n" "$(hex2ascii "$tls_hello_ascii" 2>/dev/null)"
|
||||
[[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt
|
||||
return 4
|
||||
elif [[ $tls_content_type != "14" ]] && [[ $tls_content_type != "15" ]] && \
|
||||
[[ $tls_content_type != "16" ]] && [[ $tls_content_type != "17" ]]; then
|
||||
if "$do_starttls" ; then
|
||||
if [[ $tls_content_type == 35 ]] || [[ $tls_content_type == 34 ]]; then
|
||||
# STARTTLS handshake failed and server replied plaintext with a 5xx or 4xx
|
||||
[[ $DEBUG -ge 2 ]] && printf "%s\n" "400/500: $(hex2ascii "$tls_hello_ascii" 2>/dev/null)"
|
||||
[[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt
|
||||
return 4
|
||||
elif [[ "$tls_hello_ascii" =~ 6130303220 ]]; then
|
||||
[[ $DEBUG -ge 2 ]] && printf "%s\n" "probably IMAP plaintext reply \"$(hex2ascii "${tls_hello_ascii:0:32}" 2>/dev/null)\""
|
||||
[[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt
|
||||
return 3
|
||||
fi
|
||||
elif [[ $tls_content_type != 14 ]] && [[ $tls_content_type != 15 ]] && \
|
||||
[[ $tls_content_type != 16 ]] && [[ $tls_content_type != 17 ]]; then
|
||||
debugme tmln_warning "Content type other than alert, handshake, change cipher spec, or application data detected."
|
||||
[[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt
|
||||
return 8
|
||||
@ -10622,7 +10661,7 @@ parse_tls_serverhello() {
|
||||
DETECTED_TLS_VERSION=$tls_protocol
|
||||
|
||||
if [[ $msg_len -gt $tls_hello_ascii_len-$i ]]; then
|
||||
if [[ "$process_full" == "all" ]]; then
|
||||
if [[ "$process_full" == all ]]; then
|
||||
debugme tmln_warning "Malformed message."
|
||||
[[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt
|
||||
return 7
|
||||
@ -10642,7 +10681,7 @@ parse_tls_serverhello() {
|
||||
|
||||
# Now check the alert messages.
|
||||
tls_alert_ascii_len=${#tls_alert_ascii}
|
||||
if [[ "$process_full" == "all" ]] && [[ $tls_alert_ascii_len%4 -ne 0 ]]; then
|
||||
if [[ "$process_full" == all ]] && [[ $tls_alert_ascii_len%4 -ne 0 ]]; then
|
||||
debugme tmln_warning "Malformed message."
|
||||
[[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt
|
||||
return 1
|
||||
@ -10706,7 +10745,6 @@ parse_tls_serverhello() {
|
||||
i=$i+2
|
||||
msg_len=2*$(hex2dec "${tls_handshake_ascii:i:6}")
|
||||
i=$i+6
|
||||
|
||||
if [[ $DEBUG -ge 3 ]]; then
|
||||
tm_out " handshake type: 0x${tls_msg_type}"
|
||||
case $tls_msg_type in
|
||||
@ -11602,6 +11640,7 @@ parse_tls_serverhello() {
|
||||
|
||||
#arg1: list of ciphers suites or empty
|
||||
#arg2: "true" if full server response should be parsed.
|
||||
# return: 6: couldn't open socket, 0: OK, else: return value of parse_sslv2_serverhello()
|
||||
sslv2_sockets() {
|
||||
local ret
|
||||
local client_hello cipher_suites len_client_hello
|
||||
@ -12447,7 +12486,7 @@ tls_sockets() {
|
||||
# if the ephemeral key is needed (which comes last for TLS 1.2 and
|
||||
# below), then we need to check if response appears to be complete,
|
||||
# and if it isn't then try to get another packet from the server.
|
||||
if [[ "$process_full" == "all" ]] || [[ "$process_full" == "ephemeralkey" ]]; then
|
||||
if [[ "$process_full" == all ]] || [[ "$process_full" == ephemeralkey ]]; then
|
||||
hello_done=1; skip=true
|
||||
fi
|
||||
for (( 1 ; hello_done==1; 1 )); do
|
||||
@ -12473,7 +12512,6 @@ tls_sockets() {
|
||||
hello_done=0
|
||||
else
|
||||
tls_hello_ascii+="$next_packet"
|
||||
|
||||
if [[ $DEBUG -ge 1 ]]; then
|
||||
sock_reply_file3=$(mktemp $TEMPDIR/ddreply.XXXXXX) || return 7
|
||||
mv "$SOCK_REPLY_FILE" "$sock_reply_file3"
|
||||
@ -12535,6 +12573,9 @@ tls_sockets() {
|
||||
# determine the return value for higher level, so that they can tell what the result is
|
||||
if [[ $save -eq 1 ]] || [[ $lines -eq 1 ]]; then
|
||||
ret=1 # NOT available
|
||||
elif [[ $save -eq 3 ]]; then
|
||||
# only for IMAP currently 'a002 NO Starttls'
|
||||
ret=3
|
||||
elif [[ $save -eq 8 ]]; then
|
||||
# odd return, we just pass this from parse_tls_serverhello() back
|
||||
ret=8
|
||||
|
Loading…
x
Reference in New Issue
Block a user