From a511da4ce8fdd2e658530f48a661fae8f58a6a8c Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Tue, 8 Sep 2020 12:37:50 +0200 Subject: [PATCH 1/5] New feature: winshock This commit implements a detection of Winshock from 2014 (aka MS14-066, CVE-2014-6321). It does that by analyzing * the ciphers supported -- MS' rollup patch introduced new GCM ciphers * AND grabbing the server banner which should match IIS 8.0 oder IIS 8.5 Admittedly this is not a strong detection. But it worked in the cases I tested (no RDP yet). The other known method remotely testing for it against IIS is using a patched openssl binary (see https://github.com/drwetter/testssl.sh/issues/331#issuecomment-211534954) -- the diff "jules" (hi) provided a while back. That seems to stem from securitysift albeit his decription was not complete and he didn't provide a PoC (I've seen also polarssl + a little bit of python here: https://vimeo.com/112089813 The catch is securitysift's method, is not as trivial to implement and it dosses the sass.exe process, see: http://www.securitysift.com/exploiting-ms14-066-cve-2014-6321-aka-winshock/. * Todo: man page This commit also removes -BB from the help. We haven't settled yet finally where we go with short options for the cmd line for vulnerabilities. One is for sure though: Using one letter uppercase doesn't scale. As winshock can be executed with --WS and --winshock --BB brings that in line. For now also -BB works (as -WS) but it isn't advertised anymore. --- testssl.sh | 121 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 113 insertions(+), 8 deletions(-) diff --git a/testssl.sh b/testssl.sh index 8e67768..cd3a5da 100755 --- a/testssl.sh +++ b/testssl.sh @@ -17416,6 +17416,102 @@ run_beast(){ return 0 } +# This is a quick test for Winshock, MS14-066, a vulnerability in the TLS stack of Microsoft which +# leads to RCE. See https://support.microsoft.com/en-us/help/2992611/ms14-066-vulnerability-in-schannel-could-allow-remote-code-execution-n +# and http://www.securitysift.com/exploiting-ms14-066-cve-2014-6321-aka-winshock for exploiting. +# What we do here is giving a hint, as with the Rollup patch MS introduced later is to supply the additional ciphers +# TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 TLS_RSA_WITH_AES_256_GCM_SHA384 TLS_RSA_WITH_AES_128_GCM_SHA256 +# = DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES128-GCM-SHA256 AES256-GCM-SHA384 AES128-GCM-SHA256. +# We check for those (in sockets only to avoid overhead) and for port 443 we also grab the server banner to be more sure. +# This vulnerability affected all SChannel services -- most notably RDP (port 3398 normally -- but other than +# +run_winshock() { + local ws_ciphers_hex='00,9F, 00,9D, 00,9E, 00,9C' + local -i sclient_success=0 + local is_iis8=true + local server_banner="" + local cve="CVE-2014-6321" + local cwe="CWE-94" + local hint="" + local jsonID="winshock" + + if [[ $VULN_COUNT -le $VULN_THRESHLD ]]; then + outln + pr_headlineln " Testing for winshock vulnerability " + outln + fi + pr_bold " Winshock"; out " ($cve), experimental " + + if [[ "$(has_server_protocol "tls1_3")" -eq 0 ]] ; then + # There's no MS server supporting TLS 1.3. Winshock was way back in time + prln_svrty_best "not vulnerable (OK)" + fileout "$jsonID" "OK" "not vulnerable, TLS 1.3 only" "$cve" "$cwe" + return 0 + fi + + # Next we weed out is whether we run HTTP or RDP (on standard port) + if [[ $SERVICE != HTTP ]] && [[ $PORT != 3389 ]]; then + prln_svrty_best "not vulnerable (OK) - no HTTP or RDP" + fileout "$jsonID" "OK" "not vulnerable - no HTTP or RDP" "$cve" "$cwe" + return 0 + fi + + # Now we have RDP and HTTP left + tls_sockets "01" "${ws_ciphers_hex}, 00,ff" + sclient_success=$? + [[ "$sclient_success" -eq 2 ]] && sclient_success=0 + if [[ $sclient_success -eq 0 ]]; then + # has rollup ciphers + prln_svrty_best "not vulnerable (OK)" + fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" + return 0 + elif [[ $sclient_success -ne 1 ]]; then + prln_warning "check failed, connect problem" + fileout "$jsonID" "WARN" "check failed, connect problem" "$cve" "$cwe" + return 1 + fi + + if [[ $SERVICE != HTTP ]] && [[ $PORT == 3389 ]]; then + # We take a guess here. + out "probably " + pr_svrty_critical "vulnerable (NOT ok)" + outln " - check patches locally to confirm" + fileout "${jsonID}" "CRITICAL" "probably vulnerable (NOT OK). Check patches locally to confirm" + fi + + # Now we have potentially vulnerable HTTP servers left where we garb the server banner. + # First choice for that is the HTTP header # file which we retrieved in a default run. + # From the service detection we also should have a header though as a fall back. + if [[ -s $HEADERFILE ]]; then + server_banner="$(grep -Eai '^Server:' $HEADERFILE)" + elif [[ -s "$TEMPDIR/$NODEIP.service_detection.txt" ]]; then + server_banner="$(grep -Eai '^Server:' "$TEMPDIR/$NODEIP.service_detection.txt")" + else + # We can't use run_http_header here as it messes up the screen. We could automatically + # run it when --winshock is requested though but this should suffice here. + prln_warning "check failed, rerun with cmd line option--header " + fileout "$jsonID" "WARN" "check failed, connect problem" "$cve" "$cwe" + return 1 + fi + if [[ $server_banner =~ Microsoft-IIS\/8.5 ]]; then + # Windows 2012 R2 is less likely than Windows 2012 + out "probably " + pr_svrty_critical "vulnerable (NOT ok)" + outln " - check patches locally to confirm" + fileout "${jsonID}" "CRITICAL" "probably vulnerable (NOT OK). Check patches locally to confirm" + elif [[ $server_banner =~ Microsoft-IIS\/8.0 ]]; then + out "likely " + pr_svrty_critical "VULNERABLE (NOT ok)" + outln " - check patches locally to confirm" + fileout "${jsonID}" "CRITICAL" "likely vulnerable (NOT OK). Check patches locally to confirm" + else + pr_svrty_best "not vulnerable (OK)" + outln " - doesn't seem to be IIS 8.x" + fileout "$jsonID" "OK" "not vulnerable - doesn't seem to be IIS 8.x" "$cve" "$cwe" + fi + return 0 +} + # https://web.archive.org/web/20200324101422/http://www.isg.rhul.ac.uk/tls/Lucky13.html # Paper: https://doi.org/10.1109/SP.2013.42 @@ -18855,7 +18951,7 @@ single check as ("$PROG_NAME URI" does everything except -E and -g): -H, --heartbleed tests for Heartbleed vulnerability -I, --ccs, --ccs-injection tests for CCS injection vulnerability -T, --ticketbleed tests for Ticketbleed vulnerability in BigIP loadbalancers - -BB, --robot tests for Return of Bleichenbacher's Oracle Threat (ROBOT) vulnerability + --BB, --robot tests for Return of Bleichenbacher's Oracle Threat (ROBOT) vulnerability -R, --renegotiation tests for renegotiation vulnerabilities -C, --compression, --crime tests for CRIME vulnerability (TLS compression issue) -B, --breach tests for BREACH vulnerability (HTTP compression issue) @@ -18864,6 +18960,7 @@ single check as ("$PROG_NAME URI" does everything except -E and -g): -W, --sweet32 tests 64 bit block ciphers (3DES, RC2 and IDEA): SWEET32 vulnerability -A, --beast tests for BEAST vulnerability -L, --lucky13 tests for LUCKY13 + --WS, --winshock tests for winshock vulnerability -F, --freak tests for FREAK vulnerability -J, --logjam tests for LOGJAM vulnerability -D, --drown tests for DROWN vulnerability @@ -21170,6 +21267,7 @@ initialize_globals() { do_fs=false do_protocols=false do_rc4=false + do_winshock=false do_grease=false do_renego=false do_cipherlists=false @@ -21207,6 +21305,7 @@ set_scanning_defaults() { do_header=true do_fs=true do_rc4=true + do_winshock=false do_protocols=true do_renego=true do_cipherlists=true @@ -21215,9 +21314,9 @@ set_scanning_defaults() { do_tls_fallback_scsv=true do_client_simulation=true if "$OFFENSIVE"; then - VULN_COUNT=16 + VULN_COUNT=17 else - VULN_COUNT=12 + VULN_COUNT=13 fi do_rating=true } @@ -21229,7 +21328,7 @@ count_do_variables() { for gbl in do_allciphers do_vulnerabilities do_beast do_lucky13 do_breach do_ccs_injection do_ticketbleed do_cipher_per_proto do_crime \ do_freak do_logjam do_drown do_header do_heartbleed do_mx_all_ips do_fs do_protocols do_rc4 do_grease do_robot do_renego \ - do_cipherlists do_server_defaults do_server_preference do_ssl_poodle do_tls_fallback_scsv \ + do_cipherlists do_server_defaults do_server_preference do_ssl_poodle do_tls_fallback_scsv do_winshock \ do_sweet32 do_client_simulation do_cipher_match do_tls_sockets do_mass_testing do_display_only do_rating; do "${!gbl}" && let true_nr++ done @@ -21242,7 +21341,7 @@ debug_globals() { for gbl in do_allciphers do_vulnerabilities do_beast do_lucky13 do_breach do_ccs_injection do_ticketbleed do_cipher_per_proto do_crime \ do_freak do_logjam do_drown do_header do_heartbleed do_mx_all_ips do_fs do_protocols do_rc4 do_grease do_robot do_renego \ - do_cipherlists do_server_defaults do_server_preference do_ssl_poodle do_tls_fallback_scsv \ + do_cipherlists do_server_defaults do_server_preference do_ssl_poodle do_tls_fallback_scsv do_winshock \ do_sweet32 do_client_simulation do_cipher_match do_tls_sockets do_mass_testing do_display_only do_rating; do printf "%-22s = %s\n" $gbl "${!gbl}" done @@ -21448,11 +21547,12 @@ parse_cmd_line() { do_logjam=true do_beast=true do_lucky13=true + do_winshock=true do_rc4=true if "$OFFENSIVE"; then - VULN_COUNT=16 + VULN_COUNT=17 else - VULN_COUNT=12 + VULN_COUNT=13 fi ;; --ids-friendly) @@ -21470,7 +21570,7 @@ parse_cmd_line() { do_ticketbleed=true let "VULN_COUNT++" ;; - -BB|--robot) + -BB|--BB|--robot) do_robot=true ;; -R|--renegotiation) @@ -21518,6 +21618,10 @@ parse_cmd_line() { do_lucky13=true let "VULN_COUNT++" ;; + -WS|--WS|--winshock) + do_winshock=true + let "VULN_COUNT++" + ;; -4|--rc4|--appelbaum) do_rc4=true let "VULN_COUNT++" @@ -22024,6 +22128,7 @@ lets_roll() { "$do_logjam" && { run_logjam; ret=$(($? + ret)); stopwatch run_logjam; } "$do_beast" && { run_beast; ret=$(($? + ret)); stopwatch run_beast; } "$do_lucky13" && { run_lucky13; ret=$(($? + ret)); stopwatch run_lucky13; } + "$do_winshock" && { run_winshock; ret=$(($? + ret)); stopwatch run_winshock; } "$do_rc4" && { run_rc4; ret=$(($? + ret)); stopwatch run_rc4; } fileout_section_header $section_number true && ((section_number++)) From a1a0605082463e14fa9d4f76844d42eebe04709e Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Tue, 8 Sep 2020 13:42:33 +0200 Subject: [PATCH 2/5] add winshock --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6cf5c47..e096737 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ * Percent output char problem fixed * Several display/output fixes * BREACH check: list all compression methods and add brotli +* test for winshock vulnerability * Security fix: DNS input * Don't use external pwd anymore * STARTTLS: XMPP server support From fe7b51a3e2847a62c64d2d89a62a216ac7b9a76e Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Tue, 8 Sep 2020 13:42:50 +0200 Subject: [PATCH 3/5] remove hint in winshock --- testssl.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index cd3a5da..3221630 100755 --- a/testssl.sh +++ b/testssl.sh @@ -17432,7 +17432,6 @@ run_winshock() { local server_banner="" local cve="CVE-2014-6321" local cwe="CWE-94" - local hint="" local jsonID="winshock" if [[ $VULN_COUNT -le $VULN_THRESHLD ]]; then From 1f8e65104cfce068441428e73ce51c355b910405 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Tue, 8 Sep 2020 22:08:05 +0200 Subject: [PATCH 4/5] Add winshock to documentation --- doc/testssl.1 | 3 +++ doc/testssl.1.html | 2 ++ doc/testssl.1.md | 2 ++ 3 files changed, 7 insertions(+) diff --git a/doc/testssl.1 b/doc/testssl.1 index 916b5b7..66ac0ac 100644 --- a/doc/testssl.1 +++ b/doc/testssl.1 @@ -385,6 +385,9 @@ Security headers (X\-Frame\-Options, X\-XSS\-Protection, Expect\-CT,\.\.\. , CSP \fB\-L, \-\-lucky13\fR Checks for LUCKY13 vulnerability\. It checks for the presence of CBC ciphers in TLS versions 1\.0 \- 1\.2\. . .P +\fB\-WS, \-\-winshock\fR Checks for Winshock vulnerability\. It tests for absence of GCM ciphers which were introduced in the fix and correlates that with the server banner\. +. +.P \fB\-4, \-\-rc4, \-\-appelbaum\fR Checks which RC4 stream ciphers are being offered\. . .SS "OUTPUT OPTIONS" diff --git a/doc/testssl.1.html b/doc/testssl.1.html index 484eef6..c299029 100644 --- a/doc/testssl.1.html +++ b/doc/testssl.1.html @@ -340,6 +340,8 @@ Also for multiple server certificates are being checked for as well as for the c

-L, --lucky13 Checks for LUCKY13 vulnerability. It checks for the presence of CBC ciphers in TLS versions 1.0 - 1.2.

+

-WS, --winshock Checks for Winshock vulnerability. It tests for absence of GCM ciphers which were introduced in the fix and correlates that with the server banner.

+

-4, --rc4, --appelbaum Checks which RC4 stream ciphers are being offered.

OUTPUT OPTIONS

diff --git a/doc/testssl.1.md b/doc/testssl.1.md index 4e21868..73341d3 100644 --- a/doc/testssl.1.md +++ b/doc/testssl.1.md @@ -254,6 +254,8 @@ Also for multiple server certificates are being checked for as well as for the c `-L, --lucky13` Checks for LUCKY13 vulnerability. It checks for the presence of CBC ciphers in TLS versions 1.0 - 1.2. +`-WS, --winshock` Checks for Winshock vulnerability. It tests for absence of GCM ciphers which were introduced in the fix and correlates that with the server banner. + `-4, --rc4, --appelbaum` Checks which RC4 stream ciphers are being offered. From 0e54075a6a3babae8d5adaa9122540a6e3bee2e8 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Tue, 8 Sep 2020 22:09:57 +0200 Subject: [PATCH 5/5] Reverse double dash option for vulnerabilities (cmd line) --- testssl.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/testssl.sh b/testssl.sh index 3221630..be0c734 100755 --- a/testssl.sh +++ b/testssl.sh @@ -18950,7 +18950,7 @@ single check as ("$PROG_NAME URI" does everything except -E and -g): -H, --heartbleed tests for Heartbleed vulnerability -I, --ccs, --ccs-injection tests for CCS injection vulnerability -T, --ticketbleed tests for Ticketbleed vulnerability in BigIP loadbalancers - --BB, --robot tests for Return of Bleichenbacher's Oracle Threat (ROBOT) vulnerability + -BB, --robot tests for Return of Bleichenbacher's Oracle Threat (ROBOT) vulnerability -R, --renegotiation tests for renegotiation vulnerabilities -C, --compression, --crime tests for CRIME vulnerability (TLS compression issue) -B, --breach tests for BREACH vulnerability (HTTP compression issue) @@ -18959,7 +18959,7 @@ single check as ("$PROG_NAME URI" does everything except -E and -g): -W, --sweet32 tests 64 bit block ciphers (3DES, RC2 and IDEA): SWEET32 vulnerability -A, --beast tests for BEAST vulnerability -L, --lucky13 tests for LUCKY13 - --WS, --winshock tests for winshock vulnerability + -WS, --winshock tests for winshock vulnerability -F, --freak tests for FREAK vulnerability -J, --logjam tests for LOGJAM vulnerability -D, --drown tests for DROWN vulnerability @@ -21569,7 +21569,7 @@ parse_cmd_line() { do_ticketbleed=true let "VULN_COUNT++" ;; - -BB|--BB|--robot) + -BB|--robot) do_robot=true ;; -R|--renegotiation) @@ -21617,7 +21617,7 @@ parse_cmd_line() { do_lucky13=true let "VULN_COUNT++" ;; - -WS|--WS|--winshock) + -WS|--winshock) do_winshock=true let "VULN_COUNT++" ;;