From 2176f29104b7e4cba68d23ddb6d6b58d9a2313b6 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Fri, 3 May 2019 16:16:30 +0200 Subject: [PATCH 01/22] Fix bug due to different naming scheme for curves ... which led to a false output in OpenSSL based handshake simulations. secp256r1 is prime256v1 secp192r1 is prime192v1 Also a few varaiables were added in debug output (environment.txt) --- testssl.sh | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/testssl.sh b/testssl.sh index 1bd9d25..b1cd7f2 100755 --- a/testssl.sh +++ b/testssl.sh @@ -1891,6 +1891,14 @@ s_client_options() { fi fi fi + + # OpenSSL's name for secp256r1 is prime256v1. So whenever we encounter this + # (e.g. client simulations) we replace it with the name which OpenSSL understands + # This shouldn't be needed. We have this here as a last resort + if [[ "$1" =~ " -curves " ]]; then + [[ "$1" =~ secp192r1 ]] && options="${options//secp192r1/prime192v1}" + [[ "$1" =~ secp256r1 ]] && options="${options//secp256r1/prime256v1}" + fi tm_out "$options" } @@ -4496,6 +4504,11 @@ run_client_simulation() { # "$OPENSSL s_client" will fail if the -curves option includes any unsupported curves. supported_curves="" for curve in $(colon_to_spaces "${curves[i]}"); do + # Attention! secp256r1 = prime256v1 and secp192r1 = prime192v1 + # We need to map two curves here as otherwise handshakes will go wrong if "-curves" are supplied + # https://github.com/openssl/openssl/blob/master/apps/ecparam.c#L221 + ./ssl/t1_lib.c + [[ "$curve" =~ secp256r1 ]] && curve="${curve//secp256r1/prime256v1}" + [[ "$curve" =~ secp192r1 ]] && curve="${curve//secp192r1/prime192v1}" [[ "$OSSL_SUPPORTED_CURVES" =~ " $curve " ]] && supported_curves+=":$curve" done curves[i]="" @@ -4541,6 +4554,15 @@ run_client_simulation() { if [[ "$proto" == TLSv1.2 ]] && ( ! "$using_sockets" || [[ -z "${handshakebytes[i]}" ]] ); then # OpenSSL reports TLS1.2 even if the connection is TLS1.1 or TLS1.0. Need to figure out which one it is... for tls in ${tlsvers[i]}; do + # If the handshake data includes TLS 1.3 we need to remove it, otherwise the + # simulation will fail with # 'Oops: openssl s_client connect problem' + # before/after trying another protocol. We only print a warning it in debug mode + # as otherwise we would need e.g. handle the curves in a similar fashion -- not + # to speak about ciphers + if [[ $tls =~ 1_3 ]] && ! "$HAS_TLS13"; then + debugme pr_local_problem "TLS 1.3 not supported, " + continue + fi options="$(s_client_options "$tls -cipher ${ciphers[i]} -ciphersuites "\'${ciphersuites[i]}\'" ${curves[i]} $STARTTLS $BUGS $PROXY -connect $NODEIP:$PORT ${sni[i]}")" debugme echo "$OPENSSL s_client $options $TMPFILE 2>$ERRFILE @@ -13990,7 +14012,7 @@ run_crime() { [[ $sclient_success -eq 0 ]] && cp "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" $TMPFILE fi else - [[ "$OSSL_VER" == "0.9.8"* ]] && addcmd="-no_ssl2" + [[ "$OSSL_VER" == 0.9.8* ]] && addcmd="-no_ssl2" "$HAS_TLS13" && [[ -z "$OPTIMAL_PROTO" ]] && addcmd+=" -no_tls1_3" $OPENSSL s_client $(s_client_options "$OPTIMAL_PROTO $BUGS -comp $addcmd $STARTTLS -connect $NODEIP:$PORT $PROXY $SNI") $TMPFILE sclient_connect_successful $? $TMPFILE @@ -16668,6 +16690,11 @@ HAS_NO_SSL2: $HAS_NO_SSL2 HAS_SPDY: $HAS_SPDY HAS_ALPN: $HAS_ALPN HAS_FALLBACK_SCSV: $HAS_FALLBACK_SCSV +HAS_COMP: $HAS_COMP +HAS_NO_COMP: $HAS_NO_COMP +HAS_CIPHERSUITES: $HAS_CIPHERSUITES +HAS_PKEY: $HAS_PKEY +HAS_PKUTIL: $HAS_PKUTIL HAS_PROXY: $HAS_PROXY HAS_XMPP: $HAS_XMPP HAS_POSTGRES: $HAS_POSTGRES @@ -16886,7 +16913,7 @@ ip_fatal() { return 0 } -# This gneric function outputs an error onto the screen and handles logging. +# This generic function outputs an error onto the screen and handles logging. # arg1: string to print / to write to file, arg2 (optional): additional hint to write # generic_nonfatal() { @@ -17947,6 +17974,7 @@ run_mx_all_ips() { # If run_mass_testing() is being used, then "$1" is "serial". If # run_mass_testing_parallel() is being used, then "$1" is "parallel XXXXXXXX" # where XXXXXXXX is the number of the test being run. +# create_mass_testing_cmdline() { local testing_type="$1" local cmd test_number @@ -18240,6 +18268,7 @@ run_mass_testing() { # appropriate, adds any JSON, CSV, and HTML output it has created to the # appropriate file. If the child process was stopped, then a message indicating # that is printed, but the incomplete results are not used. +# get_next_message_testing_parallel_result() { draw_line "=" $((TERM_WIDTH / 2)); outln; outln "${PARALLEL_TESTING_CMDLINE[NEXT_PARALLEL_TEST_TO_FINISH]}" From c38a1e689677a98ffba61fb6be279af2d0956e36 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Fri, 3 May 2019 16:24:57 +0200 Subject: [PATCH 02/22] Major imporvement to unit test for client simulations - we don't check the head line only but errors - don't use "pass" if you didn't run a test - add simulation for http too --- t/25_client_sims_starttls.t | 50 +++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/t/25_client_sims_starttls.t b/t/25_client_sims_starttls.t index 1d6245c..fa4cd9d 100755 --- a/t/25_client_sims_starttls.t +++ b/t/25_client_sims_starttls.t @@ -1,25 +1,55 @@ #!/usr/bin/env perl +# Just a functional test, whether there are any problems on the client side +# Probably we could also inspect the JSON for any problems for +# "id" : "scanProblem" +# "finding" : "Scan interrupted" + use strict; use Test::More; use Data::Dumper; use JSON; my $tests = 0; +my $check2run ="--client-simulation -q --ip=one --color 0"; unlink "tmp.json"; -pass("Running openssl based client simulations against smtp-relay.gmail.com:587"); $tests++; -my $opensslout = `./testssl.sh --client-simulation --ssl-native -t smtp --jsonfile tmp.json --color 0 smtp-relay.gmail.com:587`; -my $openssl = json('tmp.json'); -unlike($opensslout, qr/Running client simulations via sockets/, "Tests didn't run via sockets"); $tests++; - -pass("Running socket based client simulations against smtp-relay.gmail.com:587"); $tests++; -unlink "tmp.json"; -my $socketout = `./testssl.sh --client-simulation -t smtp --jsonfile tmp.json --color 0 smtp-relay.gmail.com:587`; +printf "\n%s\n", "Running socket based client simulations against google.com ..."; +# $tests++; +my $socketout = `./testssl.sh $check2run --jsonfile tmp.json google.com`; my $socket = json('tmp.json'); -like($socketout, qr/Running client simulations via sockets/, "Tests ran via sockets"); $tests++; +#FIXME: This comparison is maybe not sufficient yet: +unlike($socketout, qr/(e|E)rror|(f|F)atal/, ""); +$tests++; +unlink "tmp.json"; +printf "\n%s\n", "Running OpenSSL based client simulations against google.com ..."; +# $tests++; +my $opensslout = `./testssl.sh $check2run --ssl-native --jsonfile tmp.json google.com`; +my $openssl = json('tmp.json'); +#FIXME: This comparison is maybe sufficient yet: +unlike($opensslout, qr/(e|E)rror|(f|F)atal|Oops|s_client connect problem/, ""); +$tests++; + + +unlink "tmp.json"; +printf "\n%s\n", "STARTTLS: Running socket based client simulations against smtp-relay.gmail.com:587 ..."; +# $tests++; +my $socketout = `./testssl.sh $check2run --jsonfile tmp.json -t smtp smtp-relay.gmail.com:587`; +my $socket = json('tmp.json'); +unlike($socketout, qr/(e|E)rror|(f|F)atal/, ""); +$tests++; + + +unlink "tmp.json"; +printf "\n%s\n", "STARTTLS: Running OpenSSL based client simulations against smtp-relay.gmail.com:587 ..."; +# $tests++; +my $opensslout = `./testssl.sh --ssl-native $check2run --jsonfile tmp.json -t smtp smtp-relay.gmail.com:587`; +my $openssl = json('tmp.json'); +unlike($opensslout, qr/(e|E)rror|(f|F)atal|Oops|s_client connect problem/, ""); +$tests++; + #my $i = 0; #foreach my $o ( @$openssl ) { # my $s = $$socket[$i]; @@ -42,5 +72,3 @@ sub json($) { return from_json($file); } -# problem: 1-4 ok but of limited use: wy should we test whether runs really via sockets or openssl?? -# 5-n: no sense, we know sockets and ssl are diffferent why should we have a unit test comparing those??? From bdbc19449148ab6877103bb022a444a4cb5e70e8 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Fri, 3 May 2019 16:38:44 +0200 Subject: [PATCH 03/22] Beautify and simplify the code --- t/25_client_sims_starttls.t | 55 +++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/t/25_client_sims_starttls.t b/t/25_client_sims_starttls.t index fa4cd9d..c00c7e5 100755 --- a/t/25_client_sims_starttls.t +++ b/t/25_client_sims_starttls.t @@ -1,7 +1,7 @@ #!/usr/bin/env perl # Just a functional test, whether there are any problems on the client side -# Probably we could also inspect the JSON for any problems for +# Probably we could also inspect the JSON for any problems for # "id" : "scanProblem" # "finding" : "Scan interrupted" @@ -12,59 +12,54 @@ use JSON; my $tests = 0; my $check2run ="--client-simulation -q --ip=one --color 0"; +my $uri=""; +my $socketout=""; +my $opensslout=""; + +# $check2run="--jsonfile tmp.json $check2run"; + + +$uri="google.com"; unlink "tmp.json"; -printf "\n%s\n", "Running socket based client simulations against google.com ..."; -# $tests++; -my $socketout = `./testssl.sh $check2run --jsonfile tmp.json google.com`; -my $socket = json('tmp.json'); +printf "\n%s\n", "Client simulations unit test via sockets --> $uri ..."; +$socketout = `./testssl.sh $check2run $uri`; +# my $socket = json('tmp.json'); #FIXME: This comparison is maybe not sufficient yet: unlike($socketout, qr/(e|E)rror|(f|F)atal/, ""); $tests++; unlink "tmp.json"; -printf "\n%s\n", "Running OpenSSL based client simulations against google.com ..."; -# $tests++; -my $opensslout = `./testssl.sh $check2run --ssl-native --jsonfile tmp.json google.com`; -my $openssl = json('tmp.json'); +printf "\n%s\n", "Client simulations unit test via OpenSSL --> $uri ..."; +$opensslout = `./testssl.sh $check2run --ssl-native $uri`; +# my $openssl = json('tmp.json'); #FIXME: This comparison is maybe sufficient yet: unlike($opensslout, qr/(e|E)rror|(f|F)atal|Oops|s_client connect problem/, ""); $tests++; +$uri="smtp-relay.gmail.com:587"; + unlink "tmp.json"; -printf "\n%s\n", "STARTTLS: Running socket based client simulations against smtp-relay.gmail.com:587 ..."; -# $tests++; -my $socketout = `./testssl.sh $check2run --jsonfile tmp.json -t smtp smtp-relay.gmail.com:587`; -my $socket = json('tmp.json'); +printf "\n%s\n", "STARTTLS: Client simulations unit test via sockets --> $uri ..."; +$socketout = `./testssl.sh $check2run -t smtp $uri`; +# my $socket = json('tmp.json'); unlike($socketout, qr/(e|E)rror|(f|F)atal/, ""); $tests++; - unlink "tmp.json"; -printf "\n%s\n", "STARTTLS: Running OpenSSL based client simulations against smtp-relay.gmail.com:587 ..."; -# $tests++; -my $opensslout = `./testssl.sh --ssl-native $check2run --jsonfile tmp.json -t smtp smtp-relay.gmail.com:587`; -my $openssl = json('tmp.json'); +printf "\n%s\n", "STARTTLS: Client simulations unit test via OpenSSL --> $uri ..."; +$opensslout = `./testssl.sh --ssl-native $check2run -t smtp $uri`; +# my $openssl = json('tmp.json'); unlike($opensslout, qr/(e|E)rror|(f|F)atal|Oops|s_client connect problem/, ""); $tests++; -#my $i = 0; -#foreach my $o ( @$openssl ) { -# my $s = $$socket[$i]; -# if ( $o->{id} =~ /^client_/ ) { -# pass("Comparing $o->{id}"); $tests++; -# cmp_ok($o->{id}, "eq", $s->{id}, "Id's match"); $tests++; -# cmp_ok($o->{severity}, "eq", $s->{severity}, "Severities match"); $tests++; -# cmp_ok($o->{finding}, "eq", $s->{finding}, "Findings match"); $tests++; -# } -# $i++; -#} - done_testing($tests); unlink "tmp.json"; + + sub json($) { my $file = shift; $file = `cat $file`; From bb5450e3f5f83d9c560e5293c692a8d03d02523f Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Fri, 3 May 2019 18:55:28 +0200 Subject: [PATCH 04/22] Make STARTTLS + LDAP work again (via sockets) A couple of checks required sockets but e.g. LDAP via STARTTLS throwed an error (FIXME: LDAP+STARTTLS over sockets not supported yet) in fd_sockets(). This adds a temporary workaround so that those functions are bypassed and LDAP via STARTTLS can be used again. See also #1258 --- testssl.sh | 60 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 11 deletions(-) diff --git a/testssl.sh b/testssl.sh index b1cd7f2..4ae8eff 100755 --- a/testssl.sh +++ b/testssl.sh @@ -6795,6 +6795,12 @@ tls_time() { local jsonID="TLS_timestamp" pr_bold " TLS clock skew" ; out "$spaces" + + if ( [[ "$STARTTLS_PROTOCOL" =~ ldap ]] || [[ "$STARTTLS_PROTOCOL" =~ irc ]] ); then + prln_local_problem "STARTTLS/$STARTTLS_PROTOCOL and --ssl-native collide here" + return 1 + fi + TLS_DIFFTIME_SET=true # this is a switch whether we want to measure the remote TLS_TIME tls_sockets "01" "$TLS_CIPHER" # try first TLS 1.0 (most frequently used protocol) [[ -z "$TLS_TIME" ]] && tls_sockets "03" "$TLS12_CIPHER" # TLS 1.2 @@ -7101,7 +7107,10 @@ get_server_certificate() { extract_stapled_ocsp success=$? else - if [[ "$1" =~ "tls1_3_RSA" ]]; then + # For STARTTLS protcols not being implemented yet via sockets this is a bypass otherwise it won't be usable at all (e.g. LDAP) + if ( [[ "$STARTTLS" =~ ldap ]] || [[ "$STARTTLS" =~ irc ]] ); then + return 1 + elif [[ "$1" =~ "tls1_3_RSA" ]]; then tls_sockets "04" "$TLS13_CIPHER" "all" "00,12,00,00, 00,05,00,05,01,00,00,00,00, 00,0d,00,10,00,0e,08,04,08,05,08,06,04,01,05,01,06,01,02,01" elif [[ "$1" =~ "tls1_3_ECDSA" ]]; then tls_sockets "04" "$TLS13_CIPHER" "all" "00,12,00,00, 00,05,00,05,01,00,00,00,00, 00,0d,00,0a,00,08,04,03,05,03,06,03,02,03" @@ -9127,7 +9136,7 @@ run_pfs() { sigalg[nr_supported_ciphers]="" ossl_supported[nr_supported_ciphers]="${TLS_CIPHER_OSSL_SUPPORTED[i]}" hexcode[nr_supported_ciphers]="${hexc:2:2},${hexc:7:2}" - if [[ "${hexc:2:2}" == "00" ]]; then + if [[ "${hexc:2:2}" == 00 ]]; then normalized_hexcode[nr_supported_ciphers]="x${hexc:7:2}" else normalized_hexcode[nr_supported_ciphers]="x${hexc:2:2}${hexc:7:2}" @@ -9139,7 +9148,7 @@ run_pfs() { else while read -r hexc dash ciph[nr_supported_ciphers] sslvers kx[nr_supported_ciphers] auth enc[nr_supported_ciphers] mac export; do ciphers_found[nr_supported_ciphers]=false - if [[ "${hexc:2:2}" == "00" ]]; then + if [[ "${hexc:2:2}" == 00 ]]; then normalized_hexcode[nr_supported_ciphers]="x${hexc:7:2}" else normalized_hexcode[nr_supported_ciphers]="x${hexc:2:2}${hexc:7:2}" @@ -9909,6 +9918,7 @@ 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="" @@ -9982,7 +9992,7 @@ fd_socket() { fatal "FIXME: IRC+STARTTLS not yet supported" $ERR_NOSUPPORT ;; ldap|ldaps) # LDAP, https://tools.ietf.org/html/rfc2830, https://tools.ietf.org/html/rfc4511 - fatal "FIXME: LDAP+STARTTLS over sockets not yet supported (try \"--ssl-native\")" $ERR_NOSUPPORT + fatal "FIXME: LDAP+STARTTLS over sockets not supported yet (try \"--ssl-native\")" $ERR_NOSUPPORT ;; acap|acaps) # ACAP = Application Configuration Access Protocol, see https://tools.ietf.org/html/rfc2595 fatal "ACAP Easteregg: not implemented -- probably never will" $ERR_NOSUPPORT @@ -13313,12 +13323,10 @@ tls_sockets() { } -####### vulnerabilities follow ####### - -# general overview which browser "supports" which vulnerability: +####### Vulnerabilities follow ####### +# General overview which browser "supports" which vulnerability: # http://en.wikipedia.org/wiki/Transport_Layer_Security-SSL#Web_browsers - # mainly adapted from https://gist.github.com/takeshixx/10107280 # run_heartbleed(){ @@ -13335,6 +13343,11 @@ run_heartbleed(){ [[ $VULN_COUNT -le $VULN_THRESHLD ]] && outln && pr_headlineln " Testing for heartbleed vulnerability " && outln pr_bold " Heartbleed"; out " ($cve) " + if ( [[ "$STARTTLS_PROTOCOL" =~ ldap ]] || [[ "$STARTTLS_PROTOCOL" =~ irc ]] ); then + prln_local_problem "STARTTLS/$STARTTLS_PROTOCOL and --ssl-native collide here" + return 1 + fi + [[ -z "$TLS_EXTENSIONS" ]] && determine_tls_extensions if [[ ! "${TLS_EXTENSIONS}" =~ heartbeat ]]; then pr_svrty_best "not vulnerable (OK)" @@ -13389,8 +13402,8 @@ run_heartbleed(){ tmln_out fi - if [[ $lines_returned -gt 1 ]] && [[ "${tls_hello_ascii:0:4}" == "1803" ]]; then - if [[ "$STARTTLS_PROTOCOL" == "ftp" ]] || [[ "$STARTTLS_PROTOCOL" == "ftps" ]]; then + if [[ $lines_returned -gt 1 ]] && [[ "${tls_hello_ascii:0:4}" == 1803 ]]; then + if [[ "$STARTTLS_PROTOCOL" =~ ftp ]]; then # check possibility of weird vsftpd reply, see #426, despite "1803" seems very unlikely... if grep -q '500 OOPS' "$SOCK_REPLY_FILE" ; then append=", successful weeded out vsftpd false positive" @@ -13439,6 +13452,11 @@ run_ccs_injection(){ [[ $VULN_COUNT -le $VULN_THRESHLD ]] && outln && pr_headlineln " Testing for CCS injection vulnerability " && outln pr_bold " CCS"; out " ($cve) " + if ( [[ "$STARTTLS_PROTOCOL" =~ ldap ]] || [[ "$STARTTLS_PROTOCOL" =~ irc ]] ); then + prln_local_problem "STARTTLS/$STARTTLS_PROTOCOL and --ssl-native collide here" + return 1 + fi + if [[ 0 -eq $(has_server_protocol tls1) ]]; then tls_hexcode="x03, x01" elif [[ 0 -eq $(has_server_protocol tls1_1) ]]; then @@ -14879,7 +14897,17 @@ run_drown() { cert_fingerprint_sha2=${cert_fingerprint_sha2/SHA256 /} fi - sslv2_sockets + if ( [[ "$STARTTLS_PROTOCOL" =~ ldap ]] || [[ "$STARTTLS_PROTOCOL" =~ irc ]] ); then + prln_local_problem "STARTTLS/$STARTTLS_PROTOCOL and --ssl-native collide here" + return 1 + fi + + if [[ $(has_server_protocol ssl2) -ne 1 ]]; then + sslv2_sockets + else + [[ aaa == bbb ]] # provoke retrurn code=1 + fi + case $? in 7) # strange reply, couldn't convert the cipher spec length to a hex number pr_fixme "strange v2 reply " @@ -14891,6 +14919,7 @@ run_drown() { 3) # vulnerable, [[ -n "$cert_fingerprint_sha2" ]] test is not needed as we should have RSA certificate here lines=$(count_lines "$(hexdump -C "$TEMPDIR/$NODEIP.sslv2_sockets.dd" 2>/dev/null)") debugme tm_out " ($lines lines) " + add_tls_offered ssl2 yes if [[ "$lines" -gt 1 ]]; then nr_ciphers_detected=$((V2_HELLO_CIPHERSPEC_LENGTH / 3)) if [[ 0 -eq "$nr_ciphers_detected" ]]; then @@ -15928,6 +15957,11 @@ run_robot() { [[ $VULN_COUNT -le $VULN_THRESHLD ]] && outln && pr_headlineln " Testing for Return of Bleichenbacher's Oracle Threat (ROBOT) vulnerability " && outln pr_bold " ROBOT " + if ( [[ "$STARTTLS_PROTOCOL" =~ ldap ]] || [[ "$STARTTLS_PROTOCOL" =~ irc ]] ); then + prln_local_problem "STARTTLS/$STARTTLS_PROTOCOL and --ssl-native collide here" + return 1 + fi + if [[ ! "$HAS_PKUTIL" ]]; then prln_local_problem "Your $OPENSSL does not support the pkeyutl utility." fileout "$jsonID" "WARN" "$OPENSSL does not support the pkeyutl utility." "$cve" "$cwe" @@ -17777,6 +17811,10 @@ determine_sizelimitbug() { local overflow_cipher1='C0,86' local overflow_cipher2='C0,88' + # For STARTTLS protcols not being implemented yet via sockets this is a bypass otherwise it won't be usable at all (e.g. LDAP) + [[ "$STARTTLS" =~ ldap ]] && return 0 + [[ "$STARTTLS" =~ irc ]] && return 0 + debugme echo -n "${FUNCNAME[0]} starting at # of ciphers (excl. 00FF): " debugme 'echo "$test_ciphers" | tr ' ' '\n' | wc -l' # Only with TLS 1.2 offered at the server side it is possible to hit this bug, in practise. Thus From 2d719e5ebeb36005c56abb046e1428a91061ef5e Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Fri, 3 May 2019 19:25:37 +0200 Subject: [PATCH 05/22] Add cmdlines * t / --starttls irc/ircs (which will fail later for now) * --vulnerabilities : not yet the moment for renaming --- testssl.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testssl.sh b/testssl.sh index 4ae8eff..4aa9f2a 100755 --- a/testssl.sh +++ b/testssl.sh @@ -18705,8 +18705,8 @@ parse_cmd_line() { STARTTLS_PROTOCOL="$(parse_opt_equal_sign "$1" "$2")" [[ $? -eq 0 ]] && shift case $STARTTLS_PROTOCOL in - ftp|smtp|lmtp|pop3|imap|xmpp|telnet|ldap|nntp|postgres|mysql) ;; - ftps|smtps|lmtps|pop3s|imaps|xmpps|telnets|ldaps|nntps) ;; + ftp|smtp|lmtp|pop3|imap|xmpp|telnet|ldap|irc|nntp|postgres|mysql) ;; + ftps|smtps|lmtps|pop3s|imaps|xmpps|telnets|ldaps|ircs|nntps) ;; *) tmln_magenta "\nunrecognized STARTTLS protocol \"$1\", see help" 1>&2 help 1 ;; esac @@ -18739,7 +18739,7 @@ parse_cmd_line() { -c|--client-simulation) do_client_simulation=true ;; - -U|--vulnerable) + -U|--vulnerable|--vulnerabilities) do_vulnerabilities=true do_heartbleed="$OFFENSIVE" do_ccs_injection="$OFFENSIVE" From 2996d24176536492d02d6a834fcd2ae35d7efade Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Fri, 3 May 2019 19:27:31 +0200 Subject: [PATCH 06/22] Add several unit tests for STARTTLS protocols - SMTP via sockets+OpenSSL - POP3 via sockets+OpenSSL - IMAP via sockets+OpenSSL - XMPP via sockets+OpenSSL - FTP via sockets+OpenSSL - LDAP via OpenSSL - NNTPS via sockets+OpenSSL Open: IRC, LTMP, mysql, postgres This PR fixes #923. Partly it addresses #1254 --- t/25_starttls.t | 146 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100755 t/25_starttls.t diff --git a/t/25_starttls.t b/t/25_starttls.t new file mode 100755 index 0000000..7ca0f9c --- /dev/null +++ b/t/25_starttls.t @@ -0,0 +1,146 @@ +#!/usr/bin/env perl + +# Just a functional test, whether there are any problems on the client side +# Probably we could also inspect the JSON for any problems for +# "id" : "scanProblem" +# "finding" : "Scan interrupted" + +use strict; +use Test::More; +use Data::Dumper; +use JSON; + +my $tests = 0; +my $check2run_smtp="--protocols --standard --pfs --server-preference --headers --vulnerable --each-cipher -q --ip=one --color 0"; +my $check2run="-q --ip=one --color 0"; +my $uri=""; +my $socketout=""; +my $opensslout=""; + +# $check2run_smtp="--jsonfile tmp.json $check2run_smtp"; +# $check2run="--jsonfile tmp.json $check2run"; + +$uri="smtp-relay.gmail.com:587"; + +# we will have client simulations later, so we don't need to run everything again: +unlink "tmp.json"; +printf "\n%s\n", "STARTTLS SMTP unit test via sockets --> $uri ..."; +$socketout = `./testssl.sh $check2run_smtp -t smtp $uri`; +# my $socket = json('tmp.json'); +unlike($socketout, qr/(e|E)rror|(f|F)atal/, ""); +$tests++; + +unlink "tmp.json"; +printf "\n%s\n", "STARTTLS SMTP unit tests via OpenSSL --> $uri ..."; +$opensslout = `./testssl.sh --ssl-native $check2run_smtp -t smtp $uri`; +# my $openssl = json('tmp.json'); +unlike($opensslout, qr/(e|E)rror|(f|F)atal|Oops|s_client connect problem/, ""); +$tests++; + + +$uri="pop.gmx.net:110"; + +unlink "tmp.json"; +printf "\n%s\n", "STARTTLS POP3 unit tests via OpenSSL --> $uri ..."; +$socketout = `./testssl.sh $check2run -t pop3 $uri`; +# my $socket = json('tmp.json'); +unlike($socketout, qr/(e|E)rror|(f|F)atal/, ""); +$tests++; + +unlink "tmp.json"; +printf "\n%s\n", "STARTTLS POP3 unit tests via OpenSSL --> $uri ..."; +$opensslout = `./testssl.sh --ssl-native $check2run -t pop3 $uri`; +# my $openssl = json('tmp.json'); +unlike($opensslout, qr/(e|E)rror|(f|F)atal|Oops|s_client connect problem/, ""); +$tests++; + + +$uri="imap.gmx.net:143"; + +unlink "tmp.json"; +printf "\n%s\n", "STARTTLS IMAP unit tests via sockets --> $uri ..."; +my $socketout = `./testssl.sh $check2run -t imap $uri`; +# my $socket = json('tmp.json'); +unlike($socketout, qr/(e|E)rror|(f|F)atal/, ""); +$tests++; + +printf "\n%s\n", "STARTTLS IMAP unit tests via OpenSSL --> $uri ..."; +my $opensslout = `./testssl.sh --ssl-native $check2run -t imap $uri`; +# my $openssl = json('tmp.json'); +unlike($opensslout, qr/(e|E)rror|(f|F)atal|Oops|s_client connect problem/, ""); +$tests++; + + +$uri="jabber.org:5222"; + +unlink "tmp.json"; +printf "\n%s\n", "STARTTLS XMPP unit tests via sockets --> $uri ..."; +my $socketout = `./testssl.sh $check2run -t xmpp $uri`; +# my $socket = json('tmp.json'); +unlike($socketout, qr/(e|E)rror|(f|F)atal/, ""); +$tests++; + +printf "\n%s\n", "STARTTLS XMPP unit tests via OpenSSL --> $uri ..."; +my $opensslout = `./testssl.sh --ssl-native $check2run -t xmpp $uri`; +# my $openssl = json('tmp.json'); +unlike($opensslout, qr/(e|E)rror|(f|F)atal|Oops|s_client connect problem/, ""); +$tests++; + + +$uri="ldap.uni-rostock.de:21"; + +unlink "tmp.json"; +printf "\n%s\n", "STARTTLS FTP unit tests via sockets --> $uri ..."; +my $socketout = `./testssl.sh $check2run -t ftp $uri`; +# my $socket = json('tmp.json'); +unlike($socketout, qr/(e|E)rror|(f|F)atal/, ""); +$tests++; + +printf "\n%s\n", "STARTTLS FTP unit tests via OpenSSL --> $uri ..."; +my $opensslout = `./testssl.sh --ssl-native $check2run -t ftp $uri`; +# my $openssl = json('tmp.json'); +unlike($opensslout, qr/(e|E)rror|(f|F)atal|Oops|s_client connect problem/, ""); +$tests++; + + +# https://ldapwiki.com/wiki/Public%20LDAP%20Servers +$uri="ldap.telesec.de:389"; + +printf "\n%s\n", "STARTTLS LDAP unit tests via OpenSSL --> $uri ..."; +my $opensslout = `./testssl.sh --ssl-native $check2run -t ftp $uri`; +# my $openssl = json('tmp.json'); +unlike($opensslout, qr/(e|E)rror|(f|F)atal|Oops|s_client connect problem/, ""); +$tests++; + + +$uri="news.newsguy.com:119"; + +unlink "tmp.json"; +printf "\n%s\n", "STARTTLS NNTP unit tests via sockets --> $uri ..."; +my $socketout = `./testssl.sh $check2run -t nntp $uri`; +# my $socket = json('tmp.json'); +unlike($socketout, qr/(e|E)rror|(f|F)atal/, ""); +$tests++; + +printf "\n%s\n", "STARTTLS NNTP unit tests via OpenSSL --> $uri ..."; +my $opensslout = `./testssl.sh --ssl-native $check2run -t nntp $uri`; +# my $openssl = json('tmp.json'); +unlike($opensslout, qr/(e|E)rror|(f|F)atal|Oops|s_client connect problem/, ""); +$tests++; + + +# IRC: missing +# LTMP, mysql, postgres + + + +done_testing($tests); +unlink "tmp.json"; + +sub json($) { + my $file = shift; + $file = `cat $file`; + unlink $file; + return from_json($file); +} + From 1825a8ca3352d33f67244a68a5de50baa5ef7576 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Fri, 3 May 2019 19:32:25 +0200 Subject: [PATCH 07/22] Fix output for POP (STARTTLS unit test) --- t/25_starttls.t | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/t/25_starttls.t b/t/25_starttls.t index 7ca0f9c..aceeb0a 100755 --- a/t/25_starttls.t +++ b/t/25_starttls.t @@ -41,7 +41,7 @@ $tests++; $uri="pop.gmx.net:110"; unlink "tmp.json"; -printf "\n%s\n", "STARTTLS POP3 unit tests via OpenSSL --> $uri ..."; +printf "\n%s\n", "STARTTLS POP3 unit tests via sockets --> $uri ..."; $socketout = `./testssl.sh $check2run -t pop3 $uri`; # my $socket = json('tmp.json'); unlike($socketout, qr/(e|E)rror|(f|F)atal/, ""); From 72136437bbc26c3665e27014141ef8b2c8f1425d Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Fri, 3 May 2019 19:32:59 +0200 Subject: [PATCH 08/22] Proper file naming --- t/{25_client_sims_starttls.t => 26_client_simulation.t} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename t/{25_client_sims_starttls.t => 26_client_simulation.t} (100%) diff --git a/t/25_client_sims_starttls.t b/t/26_client_simulation.t similarity index 100% rename from t/25_client_sims_starttls.t rename to t/26_client_simulation.t From b60dbc0fa6b6896a28458608e8a4cb219139a071 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Fri, 3 May 2019 20:08:31 +0200 Subject: [PATCH 09/22] Code + Fix - Removed doubled declaration (my) - hopefully fix error in FTPs (should maybe think about changing the line in testssl.sh or filter here always) --- t/25_starttls.t | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/t/25_starttls.t b/t/25_starttls.t index aceeb0a..ba41078 100755 --- a/t/25_starttls.t +++ b/t/25_starttls.t @@ -5,6 +5,10 @@ # "id" : "scanProblem" # "finding" : "Scan interrupted" +# Catches: +# - This unit test takes very long +# - Hosts which match the regex patterns should be avoided + use strict; use Test::More; use Data::Dumper; @@ -59,13 +63,13 @@ $uri="imap.gmx.net:143"; unlink "tmp.json"; printf "\n%s\n", "STARTTLS IMAP unit tests via sockets --> $uri ..."; -my $socketout = `./testssl.sh $check2run -t imap $uri`; +$socketout = `./testssl.sh $check2run -t imap $uri`; # my $socket = json('tmp.json'); unlike($socketout, qr/(e|E)rror|(f|F)atal/, ""); $tests++; printf "\n%s\n", "STARTTLS IMAP unit tests via OpenSSL --> $uri ..."; -my $opensslout = `./testssl.sh --ssl-native $check2run -t imap $uri`; +$opensslout = `./testssl.sh --ssl-native $check2run -t imap $uri`; # my $openssl = json('tmp.json'); unlike($opensslout, qr/(e|E)rror|(f|F)atal|Oops|s_client connect problem/, ""); $tests++; @@ -75,13 +79,13 @@ $uri="jabber.org:5222"; unlink "tmp.json"; printf "\n%s\n", "STARTTLS XMPP unit tests via sockets --> $uri ..."; -my $socketout = `./testssl.sh $check2run -t xmpp $uri`; +$socketout = `./testssl.sh $check2run -t xmpp $uri`; # my $socket = json('tmp.json'); unlike($socketout, qr/(e|E)rror|(f|F)atal/, ""); $tests++; printf "\n%s\n", "STARTTLS XMPP unit tests via OpenSSL --> $uri ..."; -my $opensslout = `./testssl.sh --ssl-native $check2run -t xmpp $uri`; +$opensslout = `./testssl.sh --ssl-native $check2run -t xmpp $uri`; # my $openssl = json('tmp.json'); unlike($opensslout, qr/(e|E)rror|(f|F)atal|Oops|s_client connect problem/, ""); $tests++; @@ -91,13 +95,15 @@ $uri="ldap.uni-rostock.de:21"; unlink "tmp.json"; printf "\n%s\n", "STARTTLS FTP unit tests via sockets --> $uri ..."; -my $socketout = `./testssl.sh $check2run -t ftp $uri`; +$socketout = `./testssl.sh $check2run -t ftp $uri`; # my $socket = json('tmp.json'); +# OCSP stapling fails sometimes with: 'offered, error querying OCSP responder (ERROR: No Status found)' +$debughtml =~ s/ error querying OCSP responder .*\n//g; unlike($socketout, qr/(e|E)rror|(f|F)atal/, ""); $tests++; printf "\n%s\n", "STARTTLS FTP unit tests via OpenSSL --> $uri ..."; -my $opensslout = `./testssl.sh --ssl-native $check2run -t ftp $uri`; +$opensslout = `./testssl.sh --ssl-native $check2run -t ftp $uri`; # my $openssl = json('tmp.json'); unlike($opensslout, qr/(e|E)rror|(f|F)atal|Oops|s_client connect problem/, ""); $tests++; @@ -107,7 +113,7 @@ $tests++; $uri="ldap.telesec.de:389"; printf "\n%s\n", "STARTTLS LDAP unit tests via OpenSSL --> $uri ..."; -my $opensslout = `./testssl.sh --ssl-native $check2run -t ftp $uri`; +$opensslout = `./testssl.sh --ssl-native $check2run -t ftp $uri`; # my $openssl = json('tmp.json'); unlike($opensslout, qr/(e|E)rror|(f|F)atal|Oops|s_client connect problem/, ""); $tests++; @@ -117,13 +123,13 @@ $uri="news.newsguy.com:119"; unlink "tmp.json"; printf "\n%s\n", "STARTTLS NNTP unit tests via sockets --> $uri ..."; -my $socketout = `./testssl.sh $check2run -t nntp $uri`; +$socketout = `./testssl.sh $check2run -t nntp $uri`; # my $socket = json('tmp.json'); unlike($socketout, qr/(e|E)rror|(f|F)atal/, ""); $tests++; printf "\n%s\n", "STARTTLS NNTP unit tests via OpenSSL --> $uri ..."; -my $opensslout = `./testssl.sh --ssl-native $check2run -t nntp $uri`; +$opensslout = `./testssl.sh --ssl-native $check2run -t nntp $uri`; # my $openssl = json('tmp.json'); unlike($opensslout, qr/(e|E)rror|(f|F)atal|Oops|s_client connect problem/, ""); $tests++; From 92576545224a2b888b6c9fda82925b9e3885a172 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Fri, 3 May 2019 20:11:42 +0200 Subject: [PATCH 10/22] fix wrong variable --- t/25_starttls.t | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/t/25_starttls.t b/t/25_starttls.t index ba41078..32ed2c9 100755 --- a/t/25_starttls.t +++ b/t/25_starttls.t @@ -98,7 +98,7 @@ printf "\n%s\n", "STARTTLS FTP unit tests via sockets --> $uri ..."; $socketout = `./testssl.sh $check2run -t ftp $uri`; # my $socket = json('tmp.json'); # OCSP stapling fails sometimes with: 'offered, error querying OCSP responder (ERROR: No Status found)' -$debughtml =~ s/ error querying OCSP responder .*\n//g; +$socketout =~ s/ error querying OCSP responder .*\n//g; unlike($socketout, qr/(e|E)rror|(f|F)atal/, ""); $tests++; From de454402799c73f10bcdacb31dacfdaa80d197a2 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Fri, 3 May 2019 20:26:59 +0200 Subject: [PATCH 11/22] better use the right protocol when checking ldap --- t/25_starttls.t | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/t/25_starttls.t b/t/25_starttls.t index 32ed2c9..5d55d16 100755 --- a/t/25_starttls.t +++ b/t/25_starttls.t @@ -113,7 +113,7 @@ $tests++; $uri="ldap.telesec.de:389"; printf "\n%s\n", "STARTTLS LDAP unit tests via OpenSSL --> $uri ..."; -$opensslout = `./testssl.sh --ssl-native $check2run -t ftp $uri`; +$opensslout = `./testssl.sh --ssl-native $check2run -t ldap $uri`; # my $openssl = json('tmp.json'); unlike($opensslout, qr/(e|E)rror|(f|F)atal|Oops|s_client connect problem/, ""); $tests++; From dc64753085e32fffa03224979dfc0c42e6b28778 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Fri, 3 May 2019 20:46:06 +0200 Subject: [PATCH 12/22] Add error catcher also for --ssl-native + FTP --- t/25_starttls.t | 2 ++ 1 file changed, 2 insertions(+) diff --git a/t/25_starttls.t b/t/25_starttls.t index 5d55d16..90ccda9 100755 --- a/t/25_starttls.t +++ b/t/25_starttls.t @@ -105,6 +105,8 @@ $tests++; printf "\n%s\n", "STARTTLS FTP unit tests via OpenSSL --> $uri ..."; $opensslout = `./testssl.sh --ssl-native $check2run -t ftp $uri`; # my $openssl = json('tmp.json'); +# OCSP stapling fails sometimes with: 'offered, error querying OCSP responder (ERROR: No Status found)' +$opensslout =~ s/ error querying OCSP responder .*\n//g; unlike($opensslout, qr/(e|E)rror|(f|F)atal|Oops|s_client connect problem/, ""); $tests++; From 19e9137f7924525e74d3c2864736d469d9ac3794 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Sat, 4 May 2019 11:57:03 +0200 Subject: [PATCH 13/22] Add --vulnerabilities and LDAP constraints to documentation --- doc/testssl.1 | 4 ++-- doc/testssl.1.html | 4 ++-- doc/testssl.1.md | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/testssl.1 b/doc/testssl.1 index 5a4e485..4e74bcb 100644 --- a/doc/testssl.1 +++ b/doc/testssl.1 @@ -122,7 +122,7 @@ Please note that \fBfname\fR has to be in Unix format\. DOS carriage returns won \fB\-\-mode \fR\. Mass testing to be done serial (default) or parallel (\fB\-\-parallel\fR is shortcut for the latter, \fB\-\-serial\fR is the opposite option)\. Per default mass testing is being run in serial mode, i\.e\. one line after the other is processed and invoked\. The variable \fBMASS_TESTING_MODE\fR can be defined to be either equal \fBserial\fR or \fBparallel\fR\. . .SS "SPECIAL INVOCATIONS" -\fB\-t , \-\-starttls \fR does a default run against a STARTTLS enabled \fBprotocol\fR\. \fBprotocol\fR must be one of \fBftp\fR, \fBsmtp\fR, \fBpop3\fR, \fBimap\fR, \fBxmpp\fR, \fBtelnet\fR, \fBldap\fR, \fBlmtp\fR, \fBnntp\fR, \fBpostgres\fR, \fBmysql\fR\. For the latter four you need e\.g\. the supplied OpenSSL or OpenSSL version 1\.1\.1\. Please note: MongoDB doesn\'t offer a STARTTLS connection\. +\fB\-t , \-\-starttls \fR does a default run against a STARTTLS enabled \fBprotocol\fR\. \fBprotocol\fR must be one of \fBftp\fR, \fBsmtp\fR, \fBpop3\fR, \fBimap\fR, \fBxmpp\fR, \fBtelnet\fR, \fBldap\fR, \fBlirc\fR, \fBlmtp\fR, \fBnntp\fR, \fBpostgres\fR, \fBmysql\fR\. For the latter four you need e\.g\. the supplied OpenSSL or OpenSSL version 1\.1\.1\. Please note: MongoDB doesn\'t offer a STARTTLS connection, LDAP currently only works with \fB--ssl-native\fR \fBtelnet\fR and \fBirc\fR is WIP.\. . .P \fB\-\-xmpphost \fR is an additional option for STARTTLS enabled XMPP: It expects the jabber domain as a parameter\. This is only needed if the domain is different from the URI supplied\. @@ -323,7 +323,7 @@ Security headers (X\-Frame\-Options, X\-XSS\-Protection, Expect\-CT,\.\.\. , CSP \fB\-g, \-\-grease\fR checks several server implementation bugs like tolerance to size limitations and GREASE, see https://www\.ietf\.org/archive/id/draft\-ietf\-tls\-grease\-01\.txt \. This checks doesn\'t run per default\. . .SS "VULNERABILITIES" -\fB\-U, \-\-vulnerable\fR Just tests all (of the following) vulnerabilities\. The environment variable \fBVULN_THRESHLD\fR determines after which value a separate headline for each vulnerability is being displayed\. Default is \fB1\fR which means if you check for two vulnerabilities, only the general headline for vulnerabilities section is displayed \-\- in addition to the vulnerability and the result\. Otherwise each vulnerability or vulnerability section gets its own headline in addition to the output of the name of the vulnerabilty and test result\. A vulnerability section is comprised of more than one check, e\.g\. the renegotiation vulnerability check has two checks, so has Logjam\. +\fB\-U, \-\-vulnerable, \-\-vulnerablilities\fR Just tests all (of the following) vulnerabilities\. The environment variable \fBVULN_THRESHLD\fR determines after which value a separate headline for each vulnerability is being displayed\. Default is \fB1\fR which means if you check for two vulnerabilities, only the general headline for vulnerabilities section is displayed \-\- in addition to the vulnerability and the result\. Otherwise each vulnerability or vulnerability section gets its own headline in addition to the output of the name of the vulnerabilty and test result\. A vulnerability section is comprised of more than one check, e\.g\. the renegotiation vulnerability check has two checks, so has Logjam\. . .P \fB\-H, \-\-heartbleed\fR Checks for Heartbleed, a memory leakage in openssl\. Unless the server side doesn\'t support the heartbeat extension it is likely that this check runs into a timeout\. The seconds to wait for a reply can be adjusted with \fBHEARTBLEED_MAX_WAITSOCK\fR\. 8 is the default\. diff --git a/doc/testssl.1.html b/doc/testssl.1.html index 52bedbd..81c5765 100644 --- a/doc/testssl.1.html +++ b/doc/testssl.1.html @@ -180,7 +180,7 @@ host.example.com:631

SPECIAL INVOCATIONS

-

-t <protocol>, --starttls <protocol> does a default run against a STARTTLS enabled protocol. protocol must be one of ftp, smtp, pop3, imap, xmpp, telnet, ldap, lmtp, nntp, postgres, mysql. For the latter four you need e.g. the supplied OpenSSL or OpenSSL version 1.1.1. Please note: MongoDB doesn't offer a STARTTLS connection.

+

-t <protocol>, --starttls <protocol> does a default run against a STARTTLS enabled protocol. protocol must be one of ftp, smtp, pop3, imap, xmpp, telnet, ldap, irc, lmtp, nntp, postgres, mysql. For the latter four you need e.g. the supplied OpenSSL or OpenSSL version 1.1.1. Please note: MongoDB doesn't offer a STARTTLS connection. LDAP currently only works with `--ssl-native`. `telnet` and `irc` is WIP

--xmpphost <jabber_domain> is an additional option for STARTTLS enabled XMPP: It expects the jabber domain as a parameter. This is only needed if the domain is different from the URI supplied.

@@ -297,7 +297,7 @@ Also for multiple server certificates are being checked for as well as for the c

VULNERABILITIES

-

-U, --vulnerable Just tests all (of the following) vulnerabilities. The environment variable VULN_THRESHLD determines after which value a separate headline for each vulnerability is being displayed. Default is 1 which means if you check for two vulnerabilities, only the general headline for vulnerabilities section is displayed -- in addition to the vulnerability and the result. Otherwise each vulnerability or vulnerability section gets its own headline in addition to the output of the name of the vulnerabilty and test result. A vulnerability section is comprised of more than one check, e.g. the renegotiation vulnerability check has two checks, so has Logjam.

+

-U, --vulnerable, --vulnerabilities Just tests all (of the following) vulnerabilities. The environment variable VULN_THRESHLD determines after which value a separate headline for each vulnerability is being displayed. Default is 1 which means if you check for two vulnerabilities, only the general headline for vulnerabilities section is displayed -- in addition to the vulnerability and the result. Otherwise each vulnerability or vulnerability section gets its own headline in addition to the output of the name of the vulnerabilty and test result. A vulnerability section is comprised of more than one check, e.g. the renegotiation vulnerability check has two checks, so has Logjam.

-H, --heartbleed Checks for Heartbleed, a memory leakage in openssl. Unless the server side doesn't support the heartbeat extension it is likely that this check runs into a timeout. The seconds to wait for a reply can be adjusted with HEARTBLEED_MAX_WAITSOCK. 8 is the default.

diff --git a/doc/testssl.1.md b/doc/testssl.1.md index b216863..1b45a25 100644 --- a/doc/testssl.1.md +++ b/doc/testssl.1.md @@ -101,7 +101,7 @@ Please note that `fname` has to be in Unix format. DOS carriage returns won't be ### SPECIAL INVOCATIONS -`-t , --starttls ` does a default run against a STARTTLS enabled `protocol`. `protocol` must be one of `ftp`, `smtp`, `pop3`, `imap`, `xmpp`, `telnet`, `ldap`, `lmtp`, `nntp`, `postgres`, `mysql`. For the latter four you need e.g. the supplied OpenSSL or OpenSSL version 1.1.1. Please note: MongoDB doesn't offer a STARTTLS connection. +`-t , --starttls ` does a default run against a STARTTLS enabled `protocol`. `protocol` must be one of `ftp`, `smtp`, `pop3`, `imap`, `xmpp`, `telnet`, `ldap`, `irc`, `lmtp`, `nntp`, `postgres`, `mysql`. For the latter four you need e.g. the supplied OpenSSL or OpenSSL version 1.1.1. Please note: MongoDB doesn't offer a STARTTLS connection, LDAP currently only works with `--ssl-native`. `telnet` and `irc` is WIP. `--xmpphost ` is an additional option for STARTTLS enabled XMPP: It expects the jabber domain as a parameter. This is only needed if the domain is different from the URI supplied. @@ -210,7 +210,7 @@ Also for multiple server certificates are being checked for as well as for the c ### VULNERABILITIES -`-U, --vulnerable` Just tests all (of the following) vulnerabilities. The environment variable `VULN_THRESHLD` determines after which value a separate headline for each vulnerability is being displayed. Default is `1` which means if you check for two vulnerabilities, only the general headline for vulnerabilities section is displayed -- in addition to the vulnerability and the result. Otherwise each vulnerability or vulnerability section gets its own headline in addition to the output of the name of the vulnerabilty and test result. A vulnerability section is comprised of more than one check, e.g. the renegotiation vulnerability check has two checks, so has Logjam. +`-U, --vulnerable, --vulnerabilities` Just tests all (of the following) vulnerabilities. The environment variable `VULN_THRESHLD` determines after which value a separate headline for each vulnerability is being displayed. Default is `1` which means if you check for two vulnerabilities, only the general headline for vulnerabilities section is displayed -- in addition to the vulnerability and the result. Otherwise each vulnerability or vulnerability section gets its own headline in addition to the output of the name of the vulnerabilty and test result. A vulnerability section is comprised of more than one check, e.g. the renegotiation vulnerability check has two checks, so has Logjam. `-H, --heartbleed` Checks for Heartbleed, a memory leakage in openssl. Unless the server side doesn't support the heartbeat extension it is likely that this check runs into a timeout. The seconds to wait for a reply can be adjusted with `HEARTBLEED_MAX_WAITSOCK`. 8 is the default. From df88577ec4e5bb05893bb5ea7a76d1052d62cbd8 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Sat, 4 May 2019 13:51:20 +0200 Subject: [PATCH 14/22] Add basline test for IPv4 and IPv6 ... client simulations come later. One pattern for failed output added --- t/10_baseline_http.t | 72 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100755 t/10_baseline_http.t diff --git a/t/10_baseline_http.t b/t/10_baseline_http.t new file mode 100755 index 0000000..b2ba7f5 --- /dev/null +++ b/t/10_baseline_http.t @@ -0,0 +1,72 @@ +#!/usr/bin/env perl + +# Just a functional test, whether there are any problems on the client side +# Probably we could also inspect the JSON for any problems for +# "id" : "scanProblem" +# "finding" : "Scan interrupted" + +use strict; +use Test::More; +use Data::Dumper; +# use JSON; + +my $tests = 0; +my $check2run ="-p -s -P --pfs -S -h -U -q --ip=one --color 0"; +my $uri=""; +my $socketout=""; +my $opensslout=""; + +# $check2run="--jsonfile tmp.json $check2run"; + + +$uri="google.com"; + +unlink "tmp.json"; +printf "\n%s\n", "Baseline unit test IPv4 via sockets --> $uri ..."; +$socketout = `./testssl.sh $check2run $uri 2>&1`; +# my $socket = json('tmp.json'); +#FIXME: This comparison is maybe not sufficient yet: +unlike($socketout, qr/(e|E)rror|\.\/testssl\.sh: line |(f|F)atal/, ""); +$tests++; + + +unlink "tmp.json"; +printf "\n%s\n", "Baseline unit test IPv4 via OpenSSL --> $uri ..."; +$opensslout = `./testssl.sh $check2run --ssl-native $uri 2>&1`; +# my $openssl = json('tmp.json'); +# This happens with Google only, so we white list a pattern here: +$opensslout =~ s/testssl.*warning: command substitution: ignored null byte in input\n//g; +#FIXME: This comparison is maybe sufficient yet: +unlike($opensslout, qr/(e|E)rror|(f|F)atal|\.\/testssl\.sh: line |Oops|s_client connect problem/, ""); +$tests++; + + +$uri="ipv6.google.com"; + +unlink "tmp.json"; +printf "\n%s\n", "Baseline unit test IPv6 via sockets --> $uri ..."; +$socketout = `./testssl.sh $check2run -6 $uri 2>&1`; +# my $socket = json('tmp.json'); +unlike($socketout, qr/(e|E)rror|\.\/testssl\.sh: line |(f|F)atal/, ""); +$tests++; + +unlink "tmp.json"; +printf "\n%s\n", "Baseline unit test IPv6 via OpenSSL --> $uri ..."; +$opensslout = `./testssl.sh --ssl-native $check2run -6 $uri 2>&1`; +# my $openssl = json('tmp.json'); +$opensslout =~ s/testssl.*warning: command substitution: ignored null byte in input\n//g; +unlike($opensslout, qr/(e|E)rror|(f|F)atal|\.\/testssl\.sh: line |Oops|s_client connect problem/, ""); +$tests++; + +done_testing($tests); +unlink "tmp.json"; + + + +sub json($) { + my $file = shift; + $file = `cat $file`; + unlink $file; + return from_json($file); +} + From 50a83235fe18f389d8952a977bad930ddab386c4 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Sun, 5 May 2019 12:08:13 +0200 Subject: [PATCH 15/22] Renamed + testssl.net (IPv6) --- t/{10_baseline_http.t => 20_baseline_http.t} | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) rename t/{10_baseline_http.t => 20_baseline_http.t} (94%) diff --git a/t/10_baseline_http.t b/t/20_baseline_http.t similarity index 94% rename from t/10_baseline_http.t rename to t/20_baseline_http.t index b2ba7f5..2e8a430 100755 --- a/t/10_baseline_http.t +++ b/t/20_baseline_http.t @@ -25,7 +25,6 @@ unlink "tmp.json"; printf "\n%s\n", "Baseline unit test IPv4 via sockets --> $uri ..."; $socketout = `./testssl.sh $check2run $uri 2>&1`; # my $socket = json('tmp.json'); -#FIXME: This comparison is maybe not sufficient yet: unlike($socketout, qr/(e|E)rror|\.\/testssl\.sh: line |(f|F)atal/, ""); $tests++; @@ -36,12 +35,11 @@ $opensslout = `./testssl.sh $check2run --ssl-native $uri 2>&1`; # my $openssl = json('tmp.json'); # This happens with Google only, so we white list a pattern here: $opensslout =~ s/testssl.*warning: command substitution: ignored null byte in input\n//g; -#FIXME: This comparison is maybe sufficient yet: unlike($opensslout, qr/(e|E)rror|(f|F)atal|\.\/testssl\.sh: line |Oops|s_client connect problem/, ""); $tests++; -$uri="ipv6.google.com"; +$uri="testssl.net"; unlink "tmp.json"; printf "\n%s\n", "Baseline unit test IPv6 via sockets --> $uri ..."; From b9aee02978a32a99afdbecb0fb60083ec66976d9 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Sun, 5 May 2019 12:53:07 +0200 Subject: [PATCH 16/22] Split IPv6 + IPv4 ... and disable IPv6 test as it is NOT supported by Travis CI, see https://docs.travis-ci.com/user/reference/overview/#virtualisation-environment-vs-operating-system The *.disabled file should provide a start if it'll be available at some time or one can manage this in travis with a docker container, see https://github.com/travis-ci/travis-ci/issues/8891 --- ...aseline_http.t => 20_baseline_ipv4_http.t} | 16 ------ t/21_baseline_ipv6_http.t.DISABLED | 52 +++++++++++++++++++ 2 files changed, 52 insertions(+), 16 deletions(-) rename t/{20_baseline_http.t => 20_baseline_ipv4_http.t} (66%) create mode 100755 t/21_baseline_ipv6_http.t.DISABLED diff --git a/t/20_baseline_http.t b/t/20_baseline_ipv4_http.t similarity index 66% rename from t/20_baseline_http.t rename to t/20_baseline_ipv4_http.t index 2e8a430..4caf1b6 100755 --- a/t/20_baseline_http.t +++ b/t/20_baseline_ipv4_http.t @@ -39,22 +39,6 @@ unlike($opensslout, qr/(e|E)rror|(f|F)atal|\.\/testssl\.sh: line |Oops|s_client $tests++; -$uri="testssl.net"; - -unlink "tmp.json"; -printf "\n%s\n", "Baseline unit test IPv6 via sockets --> $uri ..."; -$socketout = `./testssl.sh $check2run -6 $uri 2>&1`; -# my $socket = json('tmp.json'); -unlike($socketout, qr/(e|E)rror|\.\/testssl\.sh: line |(f|F)atal/, ""); -$tests++; - -unlink "tmp.json"; -printf "\n%s\n", "Baseline unit test IPv6 via OpenSSL --> $uri ..."; -$opensslout = `./testssl.sh --ssl-native $check2run -6 $uri 2>&1`; -# my $openssl = json('tmp.json'); -$opensslout =~ s/testssl.*warning: command substitution: ignored null byte in input\n//g; -unlike($opensslout, qr/(e|E)rror|(f|F)atal|\.\/testssl\.sh: line |Oops|s_client connect problem/, ""); -$tests++; done_testing($tests); unlink "tmp.json"; diff --git a/t/21_baseline_ipv6_http.t.DISABLED b/t/21_baseline_ipv6_http.t.DISABLED new file mode 100755 index 0000000..d98fc90 --- /dev/null +++ b/t/21_baseline_ipv6_http.t.DISABLED @@ -0,0 +1,52 @@ +#!/usr/bin/env perl + +# disabled as IPv6 is not supported by Travis, see https://github.com/drwetter/testssl.sh/issues/1177 + +# Just a functional test, whether there are any problems on the client side +# Probably we could also inspect the JSON for any problems for +# "id" : "scanProblem" +# "finding" : "Scan interrupted" + +use strict; +use Test::More; +use Data::Dumper; +# use JSON; + +my $tests = 0; +my $check2run ="-p -s -P --pfs -S -h -U -q --ip=one --color 0"; +my $uri=""; +my $socketout=""; +my $opensslout=""; + +# $check2run="--jsonfile tmp.json $check2run"; + + +$uri="testssl.net"; + +unlink "tmp.json"; +printf "\n%s\n", "Baseline unit test IPv6 via sockets --> $uri ..."; +$socketout = `./testssl.sh $check2run -6 $uri 2>&1`; +# my $socket = json('tmp.json'); +unlike($socketout, qr/(e|E)rror|\.\/testssl\.sh: line |(f|F)atal/, ""); +$tests++; + +unlink "tmp.json"; +printf "\n%s\n", "Baseline unit test IPv6 via OpenSSL --> $uri ..."; +$opensslout = `./testssl.sh --ssl-native $check2run -6 $uri 2>&1`; +# my $openssl = json('tmp.json'); +$opensslout =~ s/testssl.*warning: command substitution: ignored null byte in input\n//g; +unlike($opensslout, qr/(e|E)rror|(f|F)atal|\.\/testssl\.sh: line |Oops|s_client connect problem/, ""); +$tests++; + +done_testing($tests); +unlink "tmp.json"; + + + +sub json($) { + my $file = shift; + $file = `cat $file`; + unlink $file; + return from_json($file); +} + From b63c389b54734c96068571ba740365c726f13489 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Sun, 5 May 2019 12:58:49 +0200 Subject: [PATCH 17/22] Renamed --- t/{26_client_simulation.t => 23_client_simulation.t} | 0 t/{25_starttls.t => 25_baseline_starttls.t} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename t/{26_client_simulation.t => 23_client_simulation.t} (100%) rename t/{25_starttls.t => 25_baseline_starttls.t} (100%) diff --git a/t/26_client_simulation.t b/t/23_client_simulation.t similarity index 100% rename from t/26_client_simulation.t rename to t/23_client_simulation.t diff --git a/t/25_starttls.t b/t/25_baseline_starttls.t similarity index 100% rename from t/25_starttls.t rename to t/25_baseline_starttls.t From 666e897623e7b18033fe418e9059a6a98d5dd733 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Sun, 5 May 2019 13:42:48 +0200 Subject: [PATCH 18/22] renamed --- t/{100_report_structure.t => 09_isJSON_severitylevel_valid.t} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename t/{100_report_structure.t => 09_isJSON_severitylevel_valid.t} (100%) mode change 100644 => 100755 diff --git a/t/100_report_structure.t b/t/09_isJSON_severitylevel_valid.t old mode 100644 new mode 100755 similarity index 100% rename from t/100_report_structure.t rename to t/09_isJSON_severitylevel_valid.t From c3ff9e85f9e3065d411647cd08d0fbf66be6ec62 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Sun, 5 May 2019 13:44:02 +0200 Subject: [PATCH 19/22] Rename file according to new scheme ... Readme.md --- t/{10_ca_hashes_up_to_date.t => 01_ca_hashes_up_to_date.t} | 0 t/{09_isJSON_valid.t => 07_isJSON_valid.t} | 0 t/{32_http.t => 08_isHTML_valid.t} | 0 t/{31_badssl.com.t => 51_badssl.com.t} | 0 t/{11_hpkp.t.tmpDISABLED => 59_hpkp.t.tmpDISABLED} | 0 t/Readme.md | 3 +++ 6 files changed, 3 insertions(+) rename t/{10_ca_hashes_up_to_date.t => 01_ca_hashes_up_to_date.t} (100%) rename t/{09_isJSON_valid.t => 07_isJSON_valid.t} (100%) rename t/{32_http.t => 08_isHTML_valid.t} (100%) rename t/{31_badssl.com.t => 51_badssl.com.t} (100%) rename t/{11_hpkp.t.tmpDISABLED => 59_hpkp.t.tmpDISABLED} (100%) create mode 100644 t/Readme.md diff --git a/t/10_ca_hashes_up_to_date.t b/t/01_ca_hashes_up_to_date.t similarity index 100% rename from t/10_ca_hashes_up_to_date.t rename to t/01_ca_hashes_up_to_date.t diff --git a/t/09_isJSON_valid.t b/t/07_isJSON_valid.t similarity index 100% rename from t/09_isJSON_valid.t rename to t/07_isJSON_valid.t diff --git a/t/32_http.t b/t/08_isHTML_valid.t similarity index 100% rename from t/32_http.t rename to t/08_isHTML_valid.t diff --git a/t/31_badssl.com.t b/t/51_badssl.com.t similarity index 100% rename from t/31_badssl.com.t rename to t/51_badssl.com.t diff --git a/t/11_hpkp.t.tmpDISABLED b/t/59_hpkp.t.tmpDISABLED similarity index 100% rename from t/11_hpkp.t.tmpDISABLED rename to t/59_hpkp.t.tmpDISABLED diff --git a/t/Readme.md b/t/Readme.md new file mode 100644 index 0000000..f85ae6e --- /dev/null +++ b/t/Readme.md @@ -0,0 +1,3 @@ +00-09: Is reporting ok +20-39: Do scans work fine (client side) +50-69: Are the results what I expect? (server side) From 3785e9d62259df84f38e5d6c1739ebc04747404c Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Sun, 5 May 2019 13:45:23 +0200 Subject: [PATCH 20/22] Proper formatting --- t/Readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/t/Readme.md b/t/Readme.md index f85ae6e..86a2170 100644 --- a/t/Readme.md +++ b/t/Readme.md @@ -1,3 +1,3 @@ -00-09: Is reporting ok -20-39: Do scans work fine (client side) -50-69: Are the results what I expect? (server side) +* 00-09: Is reporting ok +* 20-39: Do scans work fine (client side) +* 50-69: Are the results what I expect? (server side) From 62bd23a63271b46144a26faf32729a882822467c Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Sun, 5 May 2019 13:54:56 +0200 Subject: [PATCH 21/22] add headline+note --- t/Readme.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/t/Readme.md b/t/Readme.md index 86a2170..123b395 100644 --- a/t/Readme.md +++ b/t/Readme.md @@ -1,3 +1,7 @@ +### Naming scheme + * 00-09: Is reporting ok * 20-39: Do scans work fine (client side) * 50-69: Are the results what I expect? (server side) + +Please help to write Travis/CI tests! Documentation can be found [here](https://perldoc.perl.org/Test/More.html) and consulting the existing code (e.g. 20_baseline_ipv4_http.t) From 15df3316c1f83683f3d62184a47165dd38b974dd Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Sun, 5 May 2019 15:07:55 +0200 Subject: [PATCH 22/22] Formatting fixed --- doc/testssl.1 | 2 +- doc/testssl.1.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/testssl.1 b/doc/testssl.1 index 4e74bcb..89d925d 100644 --- a/doc/testssl.1 +++ b/doc/testssl.1 @@ -122,7 +122,7 @@ Please note that \fBfname\fR has to be in Unix format\. DOS carriage returns won \fB\-\-mode \fR\. Mass testing to be done serial (default) or parallel (\fB\-\-parallel\fR is shortcut for the latter, \fB\-\-serial\fR is the opposite option)\. Per default mass testing is being run in serial mode, i\.e\. one line after the other is processed and invoked\. The variable \fBMASS_TESTING_MODE\fR can be defined to be either equal \fBserial\fR or \fBparallel\fR\. . .SS "SPECIAL INVOCATIONS" -\fB\-t , \-\-starttls \fR does a default run against a STARTTLS enabled \fBprotocol\fR\. \fBprotocol\fR must be one of \fBftp\fR, \fBsmtp\fR, \fBpop3\fR, \fBimap\fR, \fBxmpp\fR, \fBtelnet\fR, \fBldap\fR, \fBlirc\fR, \fBlmtp\fR, \fBnntp\fR, \fBpostgres\fR, \fBmysql\fR\. For the latter four you need e\.g\. the supplied OpenSSL or OpenSSL version 1\.1\.1\. Please note: MongoDB doesn\'t offer a STARTTLS connection, LDAP currently only works with \fB--ssl-native\fR \fBtelnet\fR and \fBirc\fR is WIP.\. +\fB\-t , \-\-starttls \fR does a default run against a STARTTLS enabled \fBprotocol\fR\. \fBprotocol\fR must be one of \fBftp\fR, \fBsmtp\fR, \fBpop3\fR, \fBimap\fR, \fBxmpp\fR, \fBtelnet\fR, \fBldap\fR, \fBlirc\fR, \fBlmtp\fR, \fBnntp\fR, \fBpostgres\fR, \fBmysql\fR\. For the latter four you need e\.g\. the supplied OpenSSL or OpenSSL version 1\.1\.1\. Please note: MongoDB doesn\'t offer a STARTTLS connection, LDAP currently only works with \fB--ssl-native\fR\. \fBtelnet\fR and \fBirc\fR is WIP\. . .P \fB\-\-xmpphost \fR is an additional option for STARTTLS enabled XMPP: It expects the jabber domain as a parameter\. This is only needed if the domain is different from the URI supplied\. diff --git a/doc/testssl.1.html b/doc/testssl.1.html index 81c5765..e69974f 100644 --- a/doc/testssl.1.html +++ b/doc/testssl.1.html @@ -180,7 +180,7 @@ host.example.com:631

SPECIAL INVOCATIONS

-

-t <protocol>, --starttls <protocol> does a default run against a STARTTLS enabled protocol. protocol must be one of ftp, smtp, pop3, imap, xmpp, telnet, ldap, irc, lmtp, nntp, postgres, mysql. For the latter four you need e.g. the supplied OpenSSL or OpenSSL version 1.1.1. Please note: MongoDB doesn't offer a STARTTLS connection. LDAP currently only works with `--ssl-native`. `telnet` and `irc` is WIP

+

-t <protocol>, --starttls <protocol> does a default run against a STARTTLS enabled protocol. protocol must be one of ftp, smtp, pop3, imap, xmpp, telnet, ldap, irc, lmtp, nntp, postgres, mysql. For the latter four you need e.g. the supplied OpenSSL or OpenSSL version 1.1.1. Please note: MongoDB doesn't offer a STARTTLS connection. LDAP currently only works with --ssl-native. telnet and irc is WIP

--xmpphost <jabber_domain> is an additional option for STARTTLS enabled XMPP: It expects the jabber domain as a parameter. This is only needed if the domain is different from the URI supplied.