Merge pull request #2951 from testssl/fixAndImprove_opossum_check_2950

Fix and improve Opossum check
This commit is contained in:
Dirk Wetter
2025-11-21 15:11:07 +01:00
committed by GitHub

View File

@@ -1939,26 +1939,25 @@ http_head() {
} }
# does a simple http head via printf with no proxy, only used by run_opossum() # does a simple http head via printf with no proxy, only used by run_opossum()
# arg1: URL # arg1: extra http header
# arg2: extra http header
# #
# return codes: # return codes:
# 0: all fine (response header is returned as string) # 0: all fine (response header is returned as string)
# 1: server didn't respond within HEADER_MAXSLEEP # 1: server didn't respond within HEADER_MAXSLEEP
# 3: server didn't respond within HEADER_MAXSLEEP and PROXY was defined # 3: server didn't respond within HEADER_MAXSLEEP and PROXY was defined
# #
# return http header as string
#
http_head_printf() { http_head_printf() {
local request_header="$2" local node="$NODE"
local path="$URL_PATH"
local extra_header="$1"
local useragent="$UA_STD" local useragent="$UA_STD"
local tmpfile=$TEMPDIR/$NODE.$NODEIP.http_head_printf.log local tmpfile=$TEMPDIR/$NODE.$NODEIP.http_head_printf.log
local errfile=$TEMPDIR/$NODE.$NODEIP.http_head_printf-err.log local errfile=$TEMPDIR/$NODE.$NODEIP.http_head_printf-err.log
local -i ret=0 local -i ret=0
local proto="" foo="" node="" query=""
[[ $DEBUG -eq 0 ]] && errfile=/dev/null [[ $DEBUG -eq 0 ]] && errfile=/dev/null
IFS=/ read -r proto foo node query <<< "$1"
node=${node%:*}
# $node works here good as it connects via IPv6 first, then IPv4. # $node works here good as it connects via IPv6 first, then IPv4.
# This is a subshell, so fd 8 is not inherited # This is a subshell, so fd 8 is not inherited
bash -c "exec 8<>/dev/tcp/$node/80" 2>/dev/null & bash -c "exec 8<>/dev/tcp/$node/80" 2>/dev/null &
@@ -1969,14 +1968,16 @@ http_head_printf() {
bash -c "exec 8<>/dev/tcp/$node/80" 2>/dev/null bash -c "exec 8<>/dev/tcp/$node/80" 2>/dev/null
if [[ $? -eq 0 ]]; then if [[ $? -eq 0 ]]; then
exec 33<>/dev/tcp/$node/80 exec 33<>/dev/tcp/$node/80
# not killed --> socket open. Now we connect to the virtual host "$node" safe_echo "HEAD ${path} HTTP/1.1\r\nUser-Agent: ${useragent}\r\nHost: ${node}\r\nAccept: */*\r\n${extra_header}\r\n\r\n" >&33 2>$errfile
printf -- "%b" "HEAD ${proto}//${node}/${query} HTTP/1.1\r\nUser-Agent: ${useragent}\r\nHost: ${node}\r\n${request_header}\r\nAccept: */*\r\n\r\n\r\n" >&33 2>$errfile
ret=0 ret=0
if [[ $DEBUG -eq 0 ]] ; then touch $tmpfile
cat <&33 # This doesn't block
else while IFS= read -r line <&33; do
cat <&33 >$tmpfile safe_echo "$line" >>$tmpfile
cat $tmpfile done
cat $tmpfile
if [[ $DEBUG -ge 2 ]]; then
cat $tmpfile >&2
fi fi
else else
if [[ -n "$PROXY" ]]; then if [[ -n "$PROXY" ]]; then
@@ -8055,9 +8056,9 @@ determine_trust() {
fi fi
fileout "${jsonID}${json_postfix}" "CRITICAL" "failed $code. $addtl_warning" fileout "${jsonID}${json_postfix}" "CRITICAL" "failed $code. $addtl_warning"
if [[ "$code" =~ "chain incomplete" ]]; then if [[ "$code" =~ "chain incomplete" ]]; then
set_grade_cap "B" "Issues with chain of trust $code" set_grade_cap "B" "Issues with chain of trust $code"
else else
set_grade_cap "T" "Issues with chain of trust $code" set_grade_cap "T" "Issues with chain of trust $code"
fi fi
else else
# alt least one ok and other(s) not ==> display the culprit store(s) # alt least one ok and other(s) not ==> display the culprit store(s)
@@ -17860,6 +17861,8 @@ run_ticketbleed() {
} }
# https://opossum-attack.com/, TLS Upgrade via old RFC 2817 # https://opossum-attack.com/, TLS Upgrade via old RFC 2817
# TL;DR: curl -vi -I -H "Upgrade: TLS/1.0" <FQDN> --> returns "Upgrade: TLS/1.0"?
# We might be better off with cURL but sockets are sometimes better
# #
run_opossum() { run_opossum() {
local cve='CVE-2025-49812' local cve='CVE-2025-49812'
@@ -17881,8 +17884,7 @@ run_opossum() {
fi fi
case $service in case $service in
HTTP) HTTP)
uri=${URI/https:\/\//} response=$(http_head_printf 'Upgrade: TLS/1.0')
response=$(http_head_printf http://${uri} 'Upgrade: TLS/1.0\r\n\r\nClose\r\n')
# In any case we use $response but we handle the return codes # In any case we use $response but we handle the return codes
# 0: connection was fine, 1 or 3: no http connection # 0: connection was fine, 1 or 3: no http connection
ret=$? ret=$?
@@ -17904,6 +17906,7 @@ run_opossum() {
fi fi
fi fi
;; ;;
IMAP|FTP|POP3|SMTP|LMTP|NNTP) IMAP|FTP|POP3|SMTP|LMTP|NNTP)
outln "(implemented currently for HTTP only)" outln "(implemented currently for HTTP only)"
fileout "$jsonID" "INFO" "not yet implemented" "$cve" "$cwe" fileout "$jsonID" "INFO" "not yet implemented" "$cve" "$cwe"