From 4bcd0d3200d0916a08be9fcd285ff55f6066ddfc Mon Sep 17 00:00:00 2001 From: Frank Breedijk Date: Thu, 10 Dec 2015 10:44:03 +0100 Subject: [PATCH] First attempt to create a JSON file. Incomplete --- testssl.sh | 116 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 103 insertions(+), 13 deletions(-) diff --git a/testssl.sh b/testssl.sh index 4e5bd63..be18253 100755 --- a/testssl.sh +++ b/testssl.sh @@ -134,6 +134,7 @@ DEBUG=${DEBUG:-0} # 1.: the temp files won't be erased. # 4: display bytes sent via sockets, 5: display bytes received via sockets, 6: whole 9 yards WIDE=${WIDE:-false} # whether to display for some options the cipher or the table with hexcode/KX,Enc,strength etc. LOGFILE=${LOGILE-""} # logfile if used +JSONFILE="testssl.json" # jsonfile if used HAS_IPv6=${HAS_IPv6:-false} # if you have OPENSSL with IPv6 support AND IPv6 networking set it to yes and testssl.sh works! # tuning vars, can not be set by a cmd line switch @@ -213,6 +214,7 @@ GET_REQ11="" HEAD_REQ10="" readonly UA_STD="TLS tester from $SWURL" readonly UA_SNEAKY="Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0" +FIRST_FINDING=true # Is this the first finding we are outputting to file? # Devel stuff, see -q below TLS_LOW_BYTE="" @@ -405,6 +407,36 @@ set_color_functions() { fi } +open_json_file() { + if $do_json; then + echo "[" > $JSONFILE + fi +} + +close_json_file() { + if $do_json; then + echo "]" >> $JSONFILE + fi +} + +output_finding() { # ID, IP, PORT, SEVERITY, FINDING + if $do_json; then + if ! $FIRST_FINDING; then + echo "," >> $JSONFILE + fi + echo " + { + 'id' : '$1', + 'ip' : '$2', + 'port' : '$3', + 'severity' : '$4', + 'finding' : '$5' + }" >> $JSONFILE + fi + if $FIRST_FINDING; then + FIRST_FINDING=false + fi +} ###### helper function definitions ###### @@ -564,21 +596,26 @@ runs_HTTP() { case $SERVICE in HTTP) out " $SERVICE" + output_finding "service" "$NODEIP" "$PORT" "info" "Service detected: $SERVICE" ret=0 ;; IMAP|POP|SMTP|NNTP) out " $SERVICE, thus skipping HTTP specific checks" + output_finding "service" "$NODEIP" "$PORT" "info" "Service detected: $SERVICE, thus skipping HTTP specific checks" ret=0 ;; *) if $CLIENT_AUTH; then out "certificate based authentication => skipping all HTTP checks" echo "certificate based authentication => skipping all HTTP checks" >$TMPFILE + output_finding "client_auth" "$NODEIP" "$PORT" "warn" "certificate based authentication => skipping all HTTP checks" else out " Couldn't determine what's running on port $PORT" if $ASSUMING_HTTP; then SERVICE=HTTP out " -- ASSUMING_HTTP set though" + output_finding "service" "$NODEIP" "$PORT" "warn" "Couldn't determine service, --ASSUMING_HTTP set" ret=0 else out ", assuming no HTTP service => skipping all HTTP checks" + output_finding "service" "$NODEIP" "$PORT" "warn" "Couldn't determine service, skipping all HTTP checks" ret=1 fi fi @@ -643,16 +680,49 @@ run_http_header() { out " $status_code$msg_thereafter" case $status_code in - 301|302|307|308) out ", redirecting to \"$(grep -a '^Location' $HEADERFILE | sed 's/Location: //' | tr -d '\r\n')\"" ;; - 200) ;; - 206) out " -- WTF?" ;; - 400) pr_litemagenta " (Hint: better try another URL)" ;; - 401) grep -aq "^WWW-Authenticate" $HEADERFILE && out " "; strip_lf "$(grep -a "^WWW-Authenticate" $HEADERFILE)" + 301|302|307|308) + redirect = $(grep -a '^Location' $HEADERFILE | sed 's/Location: //' | tr -d '\r\n') + out ", redirecting to \"$redirect\"" + output_finding "status_code" "$NODEIP" "$PORT" "info" \ + "Testing HTTP header response @ \"$URL_PATH\", $status_code$msg_thereafter, redirecting to \"$redirect\"" + ;; + 200) + output_finding "status_code" "$NODEIP" "$PORT" "info" \ + "Testing HTTP header response @ \"$URL_PATH\", $status_code$msg_thereafter" + ;; + 206) + out " -- WTF?" + output_finding "status_code" "$NODEIP" "$PORT" "info" \ + "Testing HTTP header response @ \"$URL_PATH\", $status_code$msg_thereafter -- WTF?" + ;; + 400) + pr_litemagenta " (Hint: better try another URL)" + output_finding "status_code" "$NODEIP" "$PORT" "info" \ + "Testing HTTP header response @ \"$URL_PATH\", $status_code$msg_thereafter (Hint: better try another URL)" + ;; + 401) + grep -aq "^WWW-Authenticate" $HEADERFILE && out " "; strip_lf "$(grep -a "^WWW-Authenticate" $HEADERFILE)" + output_finding "status_code" "$NODEIP" "$PORT" "info" \ + "Testing HTTP header response @ \"$URL_PATH\", $status_code$msg_thereafter $(grep -a "^WWW-Authenticate" $HEADERFILE)" + ;; + 403) + output_finding "status_code" "$NODEIP" "$PORT" "info" \ + "Testing HTTP header response @ \"$URL_PATH\", $status_code$msg_thereafter" + ;; + 404) + out " (Hint: supply a path which doesn't give a \"$status_code$msg_thereafter\")" + output_finding "status_code" "$NODEIP" "$PORT" "info" \ + "Testing HTTP header response @ \"$URL_PATH\", $status_code$msg_thereafter (Hint: supply a path which doesn't give a \"$status_code$msg_thereafter\")" + ;; + 405) + output_finding "status_code" "$NODEIP" "$PORT" "info" \ + "Testing HTTP header response @ \"$URL_PATH\", $status_code$msg_thereafter" + ;; + *) + pr_litemagenta ". Oh, didn't expect a $status_code$msg_thereafter" + output_finding "status_code" "$NODEIP" "$PORT" "info" \ + "Testing HTTP header response @ \"$URL_PATH\", $status_code$msg_thereafter. Oh, didn't expect a $status_code$msg_thereafter" ;; - 403) ;; - 404) out " (Hint: supply a path which doesn't give a \"$status_code$msg_thereafter\")" ;; - 405) ;; - *) pr_litemagenta ". Oh, didn't expect a $status_code$msg_thereafter";; esac outln @@ -668,6 +738,7 @@ detect_ipv4() { local result local first=true local spaces=" " + local count if [[ ! -s $HEADERFILE ]]; then run_http_header "$1" || return 3 @@ -676,7 +747,8 @@ detect_ipv4() { # remove pagespeed header as it is mistakenly identified as ipv4 address https://github.com/drwetter/testssl.sh/issues/158 # also facebook has a CSP rule for 127.0.0.1 if egrep -vi "pagespeed|page-speed|Content-Security-Policy" $HEADERFILE | grep -iqE "$ipv4address"; then - pr_bold " IPv4 address in header " + pr_bold " IPv4 address in header " + count=0 while read line; do result="$(grep -E "$ipv4address" <<< "$line")" result=$(strip_lf "$result") @@ -689,7 +761,9 @@ detect_ipv4() { fi pr_litered "$result" outln "\n$spaces$your_ip_msg" + output_finding "ip_in_header_$count" "$NODEIP" "$PORT" "NOT OK" "IPv4 address in header $result $your_ip_msg" fi + count=$count+1 done < $HEADERFILE fi } @@ -717,8 +791,10 @@ run_http_date() { # process was killed, so we need to add an error: [[ $HAD_SLEPT -ne 0 ]] && difftime="$difftime (± 1.5)" out "$difftime sec from localtime"; + output_finding "http_clock_skew" "$NODEIP" "$PORT" "INFO" "HTTP clock skew $difftime sec from localtime" else out "Got no HTTP time, maybe try different URL?"; + output_finding "http_clock_skew" "$NODEIP" "$PORT" "INFO" "HTTP clock skew not measured. Got no HTTP time, maybe try different URL?" fi debugme out ", epoch: $HTTP_TIME" fi @@ -4114,7 +4190,7 @@ Need HTML output? Just pipe through "aha" (Ansi HTML Adapter: github.com/theZiz/ EOF exit $1 } - +#' Do not break syntax highlighting in Sublime maketempf() { TEMPDIR=$(mktemp -d /tmp/ssltester.XXXXXX) || exit -6 @@ -4910,6 +4986,7 @@ initialize_globals() { do_mx_all_ips=false do_mass_testing=false do_logging=false + do_json=false do_pfs=false do_protocols=false do_rc4=false @@ -5213,7 +5290,16 @@ parse_cmd_line() { LOGFILE=$(parse_opt_equal_sign "$1" "$2") [[ $? -eq 0 ]] && shift do_logging=true - ;; + ;; + --json) + do_json=true + ;; # DEFINITION of JSONFILE is not arg specified via ENV or automagically in parse_hn_ports() + # following does the same but we can specify a log location additionally + --jsonfile=*) + JSONFILE=$(parse_opt_equal_sign "$1" "$2") + [[ $? -eq 0 ]] && shift + do_json=true + ;; --openssl|--openssl=*) OPENSSL=$(parse_opt_equal_sign "$1" "$2") [[ $? -eq 0 ]] && shift @@ -5278,6 +5364,7 @@ reset_hostdepended_vars() { OPTIMAL_PROTO="" } + lets_roll() { local ret @@ -5355,8 +5442,9 @@ maketempf mybanner check_proxy openssl_age +open_json_file -# TODO: it's ugly to have those two vars here --> main() +# TODO: it is ugly to have those two vars here --> main() ret=0 ip="" @@ -5400,6 +5488,8 @@ else fi fi +close_json_file + exit $?