Skip to content

Instantly share code, notes, and snippets.

@thikade
Last active March 26, 2023 18:46
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save thikade/209187b2990fd49544b8d76fd51a5248 to your computer and use it in GitHub Desktop.
Save thikade/209187b2990fd49544b8d76fd51a5248 to your computer and use it in GitHub Desktop.
SSL/TLS Debugging tools & cheatsheet

Test connection to server and display certificates etc

  • Test TLS connection to HOST:PORT only using tls 1.2, giving a compact status summary:
    openssl s_client -connect HOST:PORT -tls1_2 -brief

  • Test TLS connection to HOST:PORT only using tls 1.1 and more verbose output on handshake states: openssl s_client -connect HOST:PORT -tls1_1 -state

    Alternatives:

    • -tls1 Just use TLSv1
    • -tls1_1 Just use TLSv1.1
    • -tls1_2 Just use TLSv1.2
    • -tls1_3 Just use TLSv1.3
    • -no_ssl3 Just disable SSLv3
    • -no_tls1 Just disable TLSv1
    • -no_tls1_1 Just disable TLSv1.1
    • -no_tls1_2 Just disable TLSv1.2
    • -no_tls1_3 Just disable TLSv1.3
  • Show all ciphers of cipher-suite HIGH:
    openssl ciphers HIGH

  • Test TLS connection to HOST:PORT using a specific cipher:
    openssl s_client -connect HOST:PORT -cipher ECDHE-ECDSA-AES128-SHA256

Links

#!/usr/bin/env bash
# credits & source:
# https://superuser.com/questions/109213/how-do-i-list-the-ssl-tls-cipher-suites-a-particular-website-offers
# OpenSSL requires the port number.
SERVER=$1
DELAY=1
ciphers=$(openssl ciphers 'ALL:eNULL' | sed -e 's/:/ /g')
echo Obtaining cipher list from $(openssl version).
for cipher in ${ciphers[@]}
do
echo -n Testing $cipher...
result=$(echo -n | openssl s_client -cipher "$cipher" -connect $SERVER 2>&1)
if [[ "$result" =~ ":error:" ]] ; then
error=$(echo -n $result | cut -d':' -f6)
echo NO \($error\)
else
if [[ "$result" =~ "Cipher is ${cipher}" || "$result" =~ "Cipher :" ]] ; then
echo YES
else
echo UNKNOWN RESPONSE
echo $result
fi
fi
sleep $DELAY
done
#!/usr/bin/env bash
#
#### Source: http://www.taddong.com/tools/TLSSLed_v1.3.sh
#
#
# Tool:
# TLSSLed.sh
#
# Description:
# Script to extract the most relevant security details from a
# target SSL/TLS HTTPS implementation by using sslscan & openssl.
#
# URL:
# http://www.taddong.com/en/lab.html#TLSSLED
#
# Author:
# Raul Siles (raul _AT_ taddong _DOT_ com)
# Taddong SL (www.taddong.com)
#
# Date: 2013-01-31
# Version: 1.3
#
#
# /**************************************************************************
# * Copyright 2011-2013 by Taddong SL (Raul Siles) *
# * *
# * This program is free software; you can redistribute it and/or modify *
# * it under the terms of the GNU General Public License as published by *
# * the Free Software Foundation; either version 3 of the License, or *
# * (at your option) any later version. *
# * *
# * This program is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU General Public License for more details. *
# * *
# * You should have received a copy of the GNU General Public License *
# * along with this program. If not, see <http://www.gnu.org/licenses/>. *
# * *
# **************************************************************************/
#
#
# - TODO:
# - Add a new command line argument to define the specific URL to test in
# the target server. E.g. $ ./TLSSLed.sh HOSTNAME_or_IP-ADDRESS PORT [URL]"
#
# By default the URL should be "/".
# This check should use HTTP/1.1 (instead of 1.0) and a valid Host header.
# (Right now this only applies to the HTTP header tests at the end)
#
#
# - New in version 1.3:
# - All file output goes to a single directory (same filenames as in
# previous versions) instead of to the working local directory.
# - Change in the date format used for log files:
# From: 2011-12-30_105055 - To: 20111230-105055
# - Test if SSL/TLS renegotiation is enabled (NEW check) and if the target
# service supports secure renegotiation (already in previous versions).
# If secure renegotiation is not supported, we must check renegotiation
# by usin legacy renegotiation (two new log files are used).
# - New test to check for legacy renegotiation even when secure
# renegotiation is supported, just in case the target service supports
# both.
# - Test if client certificate authentication is required by the target
# service. If so, identify the number of CAs accepted and save the
# list of CAs to a file.
# - New test to check for HTTP headers using HTTP/1.0 (previous
# versions) as well as HTTP/1.1 and a valid Host header. New log
# files created for this.
# - New error handling code for the initial SSL/TLS verification.
# - Optimizations in the openssl delays (sleep timers).
# - New DELAY variable to control sleep timers (by default 3 seconds -
# it was 5 before).
# - New output indentation.
# - New output code set for findings: - (negative), + (positive), . (info),
# * (group of checks) or ! (error/warning).
# - LOGFILE changed to SSLSCANLOGFILE & ERRFILE changed to SSLSCANERRFILE.
# - RENEGLEGACY???FILE(s) included in the final listing and removal
# process.
# - Several changes to the output messages for the different findings.
# - Duplication of "Prefered Server Cipher" output message removed.
# - New check to test for RC4 in the prefered chiper(s) regarding BEAST.
# - Use of openssl "-prexit" option for some weird target scenarios (CSA).
# - Added the date and time at the beggining of the output.
#
# - New in version 1.2:
# - Mac OS X support: sed regex switch changed - by [ anonymous ].
# - Test if target service speaks SSL/TLS - by Abraham Aranguren (AA).
# For performance reasons, this test has been merged with the SSL/TLS
# renegotiation test.
# - Optimizations by removing cat usage in grepping for findings - by AA.
# - New initial tests to check for the tool prerequisites: openssl &
# sslscan.
# - Test for TLS v1.1 and v1.2 support (CVE-2011-3389 aka BEAST).
# The tests also include checking for SSLv3 and TLSv1 support.
# - Log files names changed from host:port to host_port and ":" removed
# from the time portion of the date command, to be able to copy them
# to Windows based file systems:
# (In Windows ":" is not allowed in a filename, while "_" is).
#
# - New in version 1.1:
# - Cert public key length, subject, issuer, and validiy period.
# - Test HTTP(S) secure headers: Strict-Transport-Security (STS), and
# cookies with and without the secure flag.
# - NOTE: openssl output is now saved to files too.
#
# - Current SSL/TLS tests: (version 1.0)
# SSLv2, NULL cipher, weak ciphers -key length-, strong ciphers -AES-,
# MD5 signed cert, and SSL/TLS renegotiation.
#
#
# Requires:
# - sslscan
# https://sourceforge.net/projects/sslscan/
# - openssl
# http://www.openssl.org
#
# Credits for ideas and feedback:
# - Version 1.0 based on ssl_test.sh by Aung Khant, http://yehg.net.
# - Abraham Aranguren (AA) - http://securityconscious.blogspot.com (in v1.2)
#
# New output codeset (between square brackets) for the findings:
# [-] Negative finding (insecure)
# [+] Positive finding (secure)
# [.] Informational finding
# [*] Group of checks
# [!] Error or warning message
# Variables
# Version
VERSION=1.3
# Manage sleep time for openssl connections (in seconds)
DELAY=3
# DATE (pre v1.3):
# DATE=$(date +%F_%R:%S | sed 's/://g')
# DATE (post v1.3+):
DATE=$(date +%Y%m%d-%H%M%S)
# Some SSL/TLS target services require some extra options to work:
# E.g. -prexit: Print out info even when the SSL/TLS connection fails.
# http://www.openssl.org/docs/apps/s_client.html
# For some scenarios where client certificates are required.
OPENSSLOPTIONS="-prexit"
# Default openssl protocol: By default this variable is empty so that the
# protocol is automatically selected by the openssl version available:
OPENSSLPROTOCOLVERSION=""
# The default backward compatible protocol version in case of errors: TLS1
BACKWARDPROTOCOL="false"
OPENSSLBACKWARDPROTOCOLVERSION="-tls1"
#
# See NOTE (openssl protocol version glitches) below.
#
# openssl 1.x might require the "-tls1" or "-ssl3" openssl command line
# arguments on some target sites, as openssl 1.x uses TLS protocol version
# 1.2 by default in the Client Hello message, and if not supported by the
# target server, it never sends the Server Hello message back.
#
# *** SECURITY DISCLAIMER ***
# This script does not filter the input for certain commands, hence it
# might be vulnerable to local input command manipulation, such as in uname.
# *** SECURITY DISCLAIMER ***
# Functions ()
reviewlogfiles () {
echo
echo "[.] Review the files within the output directory for more info."
echo " [.] Output directory: $DIRECTORY ..."
echo
}
# Function to initially test if the target service speaks SSL/TLS
test_if_service_speaks_SSLTLS () {
(echo R; sleep $DELAY) | \
openssl s_client $OPENSSLPROTOCOLVERSION -connect $HOST:$PORT \
$OPENSSLOPTIONS > $DIRECTORY/$RENEGLOGFILE 2> $DIRECTORY/$RENEGERRFILE &
pid=$!
sleep $DELAY
SSL_HANDSHAKE_LINES=$(cat $DIRECTORY/$RENEGLOGFILE | wc -l)
#
# NOTE: openssl protocol version glitches
#
# This check does not work with openssl 1.0.1-dev on some target sites,
# and it requires the "-tls1" or "-ssl3" openssl command line arguments;
# here, and in all openssl instances within this script.
#
# The reason is openssl 1.0.1-dev uses TLS protocol version 1.2 in the
# Client Hello message, and the server never sends the Server Hello
# message. The otput simply shows:
# CONNECTED
#
# If the -tls1_1 switch is used in these target services, they properly
# reply back with a "wrong version number" message.
#
# v1.3: Added new code to accommodate this scenario:
# If (-lt 5) but CONNECTED, then use the -tls1 (backward protocol
# version) switch in all openssl executions...
# ... or (select the right option based on the openssl version, but this
# might change): if openssl 1.0.1-dev or +, use -tls1...
#
# There is a specific case where the target service can refuse the
# connection but the port still speaks SSL/TLS. In that case the error
# log contains the following messages, although the handshake log is >
# than 5 lines:
# connect: Connection refused
# connect:errno=22
#
ERR_SSL=$(cat $DIRECTORY/$RENEGERRFILE)
if grep -q "connect: Connection refused" <<<$ERR_SSL; then
# Target service speaks SSL/TLS but refuses the connection
echo
echo "[!] ERROR: The target service $HOST:$PORT might speak SSL/TLS"
echo " but refuses the connection."
reviewlogfiles
exit
fi
if [ $SSL_HANDSHAKE_LINES -lt 5 ] ; then
# SSL handshake failed - Non SSL/TLS service or error:
# - If the target service does not speak SSL/TLS, openssl does not
# terminate, so kill it.
# - However, if the target speaks SSL/TLS but the connection fails
# (e.g. "sslv3 alert bad certificate") then the connection
# finishes.
kill -s SIGINT ${pid} 2>/dev/null
# Check if it failed because of an error or lack of SSL/TLS support
#ERR_SSL=$(cat $DIRECTORY/$RENEGERRFILE)
if grep -q "ssl handshake failure" <<<$ERR_SSL; then
echo
echo "[!] ERROR: The target service $HOST:$PORT speaks SSL/TLS"
echo " but returned an error: ssl handshake failure."
echo " E.g. Client certificate mandatory?"
elif [ $BACKWARDPROTOCOL == "true" ]; then
echo
echo "[!] ERROR: The target service $HOST:$PORT does not seem"
echo " to speak SSL/TLS even when using the SSL/TLS backward"
echo " protocol version: $OPENSSLPROTOCOLVERSION"
elif grep -q "CONNECTED" <<<$ERR_SSL; then
# The local openssl tool tried by default a protocol version not
# supported by the target server. Switching back to a more
# conservative protocol version (OPENSSLBACKWARDPROTOCOLVERSION).
OPENSSLPROTOCOLVERSION=$OPENSSLBACKWARDPROTOCOLVERSION
# Set we already tried a backward option
BACKWARDPROTOCOL="true"
echo
echo "[.] WARNING: Trying connection again with SSL/TLS protocol version:"
echo " $OPENSSLPROTOCOLVERSION"
#echo
mv $DIRECTORY/$RENEGLOGFILE $DIRECTORY/$RENEGLOGFILE.1st-try
mv $DIRECTORY/$RENEGERRFILE $DIRECTORY/$RENEGERRFILE.1st-try
# Repeat initial test with a potentially different
# $OPENSSLPROTOCOLVERSION
test_if_service_speaks_SSLTLS
else
echo
echo "[!] ERROR: The target service $HOST:$PORT does not seem"
echo " to speak SSL/TLS or it is not reachable!!"
fi
reviewlogfiles
exit
else
# Specific case where server returns "reason(1000)" cause it requires a
# client certificate, and SSLv3 was used by default. Force it to switch
# to the OPENSLLBACKWARDPROTOCOLVERSION and try again:
# Error:
# 3073591496:error:140773E8:SSL routines:SSL23_GET_SERVER_HELLO:\
# reason(1000):s23_clnt.c:724:
# Another error: (!= openssl version)
# 13531:error:14094412:SSL routines:SSL3_READ_BYTES:sslv3 alert bad certificate:s3_pkt.c:1093:SSL alert number 42
if grep -q "SSL23_GET_SERVER_HELLO:reason(1000)\|sslv3 alert bad certificate" <<<$ERR_SSL; then
echo
echo "[!] ERROR: The target service $HOST:$PORT speaks SSL/TLS"
echo " but returned an error."
echo " Check the output and try manually other SSL/TLS versions."
echo " E.g. Client certificate mandatory?"
reviewlogfiles
exit
else
# SSL handshake succeded - Continue...
# VERBOSE
echo " [.] The target service $HOST:$PORT seems to speak SSL/TLS..."
echo
echo " [.] Using SSL/TLS protocol version: $OPENSSLPROTOCOLVERSION"
echo " (empty means I'm using the default openssl protocol version(s))"
echo
fi
fi
}
# MAIN:
# v1.2:
# Mac OS X (Darwin) support:
# sed regexes in Linux use the -r switch, while in non-GNU systems (like
# Mac OS X) they use the -E switch.
#SED_ARG_REGEX=-r
#if [ "$(uname)" == "Darwin" ] ; then
# SED_ARG_REGEX=-E
#fi
#
# Used for the old check below required to remove terminal output formatting
echo ------------------------------------------------------
echo " TLSSLed - ($VERSION) based on sslscan and openssl"
echo " by Raul Siles (www.taddong.com)"
echo ------------------------------------------------------
if [ -z `which openssl` ] ;then echo; echo "[!] ERROR: openssl command not found!"; echo; exit; fi
if [ -z `which sslscan` ] ;then echo; echo "[!] ERROR: sslscan command not found!"; echo; exit; fi
OPENSSLVERSION=$(openssl version)
#SSLSCANVERSION=$(sslscan --version | grep version | \
#sed ${SED_ARG_REGEX} "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g")
# v1.3:
# Works with the old sslscan 1.8.2 and the new 1.8.3rc3 fork
SSLSCANVERSION=$(sslscan --version | grep version | \
sed "s/^.*sslscan/sslscan/")
echo " openssl version: $OPENSSLVERSION"
echo " $SSLSCANVERSION"
echo ------------------------------------------------------
echo " Date: $DATE"
echo ------------------------------------------------------
echo
if [ $# -ne 2 ]; then
echo "[!] Usage: $0 <hostname or IP_address> <port>"
echo
exit
fi
HOST=$1
PORT=$2
echo "[*] Analyzing SSL/TLS on $HOST:$PORT ..."
# Run sslcan once, store the results to a log file and
# analyze that file for all the different tests:
TARGET=$HOST\_$PORT
DIRECTORY=TLSSLed\_$VERSION\_$TARGET\_$DATE
SSLSCANLOGFILE=sslscan\_$TARGET\_$DATE.log
SSLSCANERRFILE=sslscan\_$TARGET\_$DATE.err
# Same idea for openssl - save results to files and analyze
# them to verify different tests:
RENEGLOGFILE=openssl\_RENEG\_$TARGET\_$DATE.log
RENEGERRFILE=openssl\_RENEG\_$TARGET\_$DATE.err
RENEGLEGACYLOGFILE=openssl\_RENEG\_LEGACY\_$TARGET\_$DATE.log
RENEGLEGACYERRFILE=openssl\_RENEG\_LEGACY\_$TARGET\_$DATE.err
HEADLOGFILE=openssl\_HEAD\_$TARGET\_$DATE.log
HEADERRFILE=openssl\_HEAD\_$TARGET\_$DATE.err
HEAD1LOGFILE=openssl\_HEAD\_1.0\_$TARGET\_$DATE.log
HEAD1ERRFILE=openssl\_HEAD\_1.0\_$TARGET\_$DATE.err
CASFILE=CAs-client-cert\_$TARGET\_$DATE.txt
# Just in case...
if [ -z "$DIRECTORY" ]; then
echo
echo "[!] ERROR: Output directory is not defined! Aborting execution!"
echo
exit
fi
# VERBOSE
echo " [.] Output directory: $DIRECTORY ..."
if [ -d "$DIRECTORY" ]; then
echo
echo "[!] ERROR: Output directory already exist! Aborting execution!"
echo
exit
fi
echo
mkdir -p $DIRECTORY
# Check if the target service speaks SSL/TLS (& check renegotiation)
echo "[*] Checking if the target service speaks SSL/TLS..."
test_if_service_speaks_SSLTLS
# This initial check is required because sslscan works pretty slow & badly
# on non-SSL/TLS services, such as HTTP (without S):
echo "[*] Running sslscan on $HOST:$PORT ..."
sslscan $HOST:$PORT > $DIRECTORY/$SSLSCANLOGFILE \
2> $DIRECTORY/$SSLSCANERRFILE
echo
echo " [-] Testing for SSLv2 ..."
grep "Accepted SSLv2" $DIRECTORY/$SSLSCANLOGFILE
echo
echo " [-] Testing for the NULL cipher ..."
grep "NULL" $DIRECTORY/$SSLSCANLOGFILE | grep Accepted
echo
echo " [-] Testing for weak ciphers (based on key length - 40 or 56 bits) ..."
grep " 40 bits" $DIRECTORY/$SSLSCANLOGFILE | grep Accepted
grep " 56 bits" $DIRECTORY/$SSLSCANLOGFILE | grep Accepted
echo
echo " [+] Testing for strong ciphers (based on AES) ..."
grep "AES" $DIRECTORY/$SSLSCANLOGFILE | grep Accepted
echo
echo " [-] Testing for MD5 signed certificate ..."
#cat $DIRECTORY/$SSLSCANLOGFILE | grep -E 'MD5WithRSAEncryption|md5WithRSAEncryption'
grep -i 'MD5WithRSAEncryption' $DIRECTORY/$SSLSCANLOGFILE
echo
echo " [.] Testing for the certificate public key length ..."
grep -i 'RSA Public Key' $DIRECTORY/$SSLSCANLOGFILE
echo
echo " [.] Testing for the certificate subject ..."
grep -i 'Subject:' $DIRECTORY/$SSLSCANLOGFILE
echo
echo " [.] Testing for the certificate CA issuer ..."
grep -i 'Issuer:' $DIRECTORY/$SSLSCANLOGFILE
echo
echo " [.] Testing for the certificate validity period ..."
NOW=$(date -u)
echo " Today: $NOW"
grep -i 'Not valid' $DIRECTORY/$SSLSCANLOGFILE
echo
echo " [.] Checking preferred server ciphers ..."
# v1.1:
# cat $DIRECTORY/$SSLSCANLOGFILE | sed '/Prefered Server Cipher(s):/,/^$/!d' | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"
#
PREFERED_CIPHERS=$(cat $DIRECTORY/$SSLSCANLOGFILE | \
sed '/Prefered Server Cipher(s):/,/^$/!d' | \
sed ${SED_ARG_REGEX} "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g" | \
grep -v "Prefered Server Cipher" | grep -v "^$")
echo "$PREFERED_CIPHERS"
# Extra empty line above removed with the last grep
#
# SSL/TLS RENEGOTIATION TESTS:
# -----------------------------
#
# Before testing for client initiated renegotiation, we need to check if
# we must use the secure (RFC5746) or the insecure (legacy) mode.
#
# Renegotiation details will go to stderr (2>).
#
# If $OPENSSLVERSION is updated (0.9.8m+) it supports RFC5746 and will print
# the details based on the analysis of the new RI extension:
# - Secure Renegotiation IS NOT supported
# - Secure Renegotiation IS supported
#
# Command executed initially to check if target service supports SSL/TLS:
#
# (echo R; sleep $DELAY) | openssl s_client $OPENSSLPROTOCOLVERSION -connect $HOST:$PORT > \
# $DIRECTORY/$RENEGLOGFILE 2> $DIRECTORY/$RENEGERRFILE
#
# v1.3:
# First of all, check if secure renegotiation is supported. Based on the
# results, check if client initiated renegotiation is enabled by using
# openssl defaults (secure) or the use the "-legacy_renegotiation" flag
# (insecure).
#
# It is important to differentiate between having client initiated
# renegotiation enabled, and having support for secure renegotiation.
# There are four possible options or combinations.
#
# If secure renegotiation is NOT supported, we need to use the legacy flag
# to test for SSL/TLS legacy renegotiation. If it IS supported, the default
# command (initially executed) works fine.
#
# Additionally, even if secure renegotiation IS supported, we can check if
# the target service also accepts insecure renegotiations (legacy).
# Therefore, in any case we test for SSL/TLS renegotiation using the legacy
# mode.
#
# The text can appear two times, hence we use "uniq":
SECURE_RENEG=$(grep -E "Secure Renegotiation IS" $DIRECTORY/$RENEGLOGFILE | \
uniq)
echo
echo "[*] Testing for SSL/TLS renegotiation MitM vuln. (CVE-2009-3555) ..."
echo
echo " [+] Testing for secure renegotiation support (RFC 5746) ..."
echo " $SECURE_RENEG"
# Check for SSL/TLS renegotiation using legacy mode in any case
LEGACY_RENEG="-legacy_renegotiation"
(echo R; sleep $DELAY) | \
openssl s_client $LEGACY_RENEG $OPENSSLPROTOCOLVERSION -connect $HOST:$PORT \
> $DIRECTORY/$RENEGLEGACYLOGFILE 2> $DIRECTORY/$RENEGLEGACYERRFILE
echo
echo "[*] Testing for SSL/TLS renegotiation DoS vuln. (CVE-2011-1473) ..."
echo
if grep -q NOT <<<$SECURE_RENEG; then
# Secure renegotiation IS NOT supported: show legacy mode results
SECURE_RENEG_STATE="No"
ERR_RENEG=$(cat $DIRECTORY/$RENEGLEGACYERRFILE)
echo " [.] Testing for client initiated (CI) SSL/TLS renegotiation (insecure)..."
else
# Secure renegotiation IS supported: RFC5746
# The default option in openssl (assuming 0.9.8m+) is not to use any
# special flag, that is, use secure renegotiation by default
SECURE_RENEG_STATE="Yes"
ERR_RENEG=$(cat $DIRECTORY/$RENEGERRFILE)
echo " [.] Testing for client initiated (CI) SSL/TLS renegotiation (secure)..."
fi
# - If SSL/TLS renegotiation is enabled you will get:
# ...
# verify return:0
# DONE
#
# The DONE message is on the error output, not on the standard output, and
# only when the "echo R & sleep" method is used (not in interactive mode).
if grep -q DONE <<<$ERR_RENEG; then
echo " (CI) SSL/TLS renegotiation IS enabled"
# Client certificate might be required:
elif grep -q "sslv3 alert bad certificate" <<<$ERR_RENEG; then
echo " UNKNOWN: Client certificate might be required (sslv3 alert bad certificate)"
# Client certificate might be required:
# "sslv3 alert unexpected message" in openssl-1.0.1-dev
elif grep -q "sslv3 alert unexpected message" <<<$ERR_RENEG; then
echo " UNKNOWN: Client certificate might be required (sslv3 alert unexpected message)"
# Different error behaviors when reneg. is not enabled:
elif grep -q "no renegotiation" <<<$ERR_RENEG; then
echo " (CI) SSL/TLS renegotiation IS NOT enabled (no renegotiation)"
elif grep -q "ssl handshake failure" <<<$ERR_RENEG; then
echo " (CI) SSL/TLS renegotiation IS NOT enabled (ssl handshake failure)"
else
echo " UNKNOWN"
fi
# Additionally, if secure renegotiation is supported, check if it still
# allows renegotiation using legacy mode (insecure):
if [ "$SECURE_RENEG_STATE" == "Yes" ]; then
echo
echo " [.] Testing for client initiated (CI) SSL/TLS renegotiation (insecure)..."
ERR_RENEG=$(cat $DIRECTORY/$RENEGLEGACYERRFILE)
# REPEAT:
if grep -q DONE <<<$ERR_RENEG; then
echo " (CI) SSL/TLS renegotiation IS enabled"
# Client certificate might be required:
elif grep -q "sslv3 alert bad certificate" <<<$ERR_RENEG; then
echo " UNKNOWN: Client certificate might be required (sslv3 alert bad certificate)"
# Client certificate might be required:
# "sslv3 alert unexpected message" in openssl-1.0.1-dev
elif grep -q "sslv3 alert unexpected message" <<<$ERR_RENEG; then
echo " UNKNOWN: Client certificate might be required (sslv3 alert unexpected message)"
# Different error behaviors when reneg. is not enabled:
elif grep -q "no renegotiation" <<<$ERR_RENEG; then
echo " (CI) SSL/TLS renegotiation IS NOT enabled (no renegotiation)"
elif grep -q "ssl handshake failure" <<<$ERR_RENEG; then
echo " (CI) SSL/TLS renegotiation IS NOT enabled (ssl handshake failure)"
else
echo " UNKNOWN"
fi
fi
# Check if client certificate autentication is required by the target
# service.
#
# NOTE: If client certificate authentication is being requested, it would be
# possible to test for it using a client digital certificate using openssl:
# $ openssl s_client $OPENSSLPROTOCOLVERSION -connect www.example.com:443 \
# -cert client.pem -key client.key
#
LOG_RENEG=$(cat $DIRECTORY/$RENEGLOGFILE)
echo
echo "[*] Testing for client authentication using digital certificates ..."
echo
if grep -q "Acceptable client certificate CA names" <<<$LOG_RENEG; then
echo " SSL/TLS client certificate authentication IS required"
# Check the list and number of accepted CAs
# Save CAs list to file
# The LOG_RENEG variable does not have the original break lines to parse
# the output properly, so read the file again
cat $DIRECTORY/$RENEGLOGFILE | \
sed '/Acceptable client certificate CA names/,/^---$/!d' | \
grep -v "\-\-\-" | grep -v "Acceptable client certificate CA names" | \
grep -v "^$" > $DIRECTORY/$CASFILE
# Number of CAs
CAS=$(cat $DIRECTORY/$CASFILE | wc -l)
echo " The target service accepts $CAS Certification Authorities (CAs)"
elif grep -q "No client certificate CA names sent" <<<$LOG_RENEG; then
echo " SSL/TLS client certificate authentication IS NOT required"
else
echo " UNKNOWN"
fi
echo
echo "[*] Testing for TLS v1.1 and v1.2 (CVE-2011-3389 vuln. aka BEAST) ..."
# Test for SSLv3 and TLSv1 support first (from sslscan)
echo
echo " [-] Testing for SSLv3 and TLSv1 support ..."
grep "Accepted SSLv3" $DIRECTORY/$SSLSCANLOGFILE
grep "Accepted TLSv1" $DIRECTORY/$SSLSCANLOGFILE
# Test for RC4 in the list of prefered ciphers (from sslscan previously)
echo
echo " [+] Testing for RC4 in the prefered cipher(s) list ..."
echo "$PREFERED_CIPHERS" | grep "RC4"
#
# Connection details go to stderr (2>) and, in this case, to a variable:
#
# If $OPENSSLVERSION is updated (version >= 1.0.1-stable) it supports
# TLS v1.1 & v1.2, if not, the openssl help is displayed in the command
# output.
#
OUTPUT_TLS1_1=$((echo Q; sleep $DELAY) | \
openssl s_client -tls1_1 -connect $HOST:$PORT 2>&1)
OUTPUT_TLS1_2=$((echo Q; sleep $DELAY) | \
openssl s_client -tls1_2 -connect $HOST:$PORT 2>&1)
# if "DONE": TLS v1.x supported
# else if "wrong version number": TLS v1.x not supported
# else if "unknown option": OpenSSL does not support TLS v1.1 or v1.2
echo
echo " [.] Testing for TLS v1.1 support ..."
if grep -q DONE <<<$OUTPUT_TLS1_1; then
echo " TLS v1.1 IS supported"
elif grep -q "wrong version number" <<<$OUTPUT_TLS1_1; then
echo " TLS v1.1 IS NOT supported"
elif grep -q "ssl handshake failure" <<<$OUTPUT_TLS1_1; then
echo " TLS v1.1 IS NOT supported (ssl handshake failure)"
elif grep -q "unknown option" <<<$OUTPUT_TLS1_1; then
echo " The local openssl version does NOT support TLS v1.1"
else
echo " UNKNOWN"
fi
echo
echo " [.] Testing for TLS v1.2 support ..."
if grep -q DONE <<<$OUTPUT_TLS1_2; then
echo " TLS v1.2 IS supported"
elif grep -q "wrong version number" <<<$OUTPUT_TLS1_2; then
echo " TLS v1.2 IS NOT supported"
elif grep -q "ssl handshake failure" <<<$OUTPUT_TLS1_2; then
echo " TLS v1.2 IS NOT supported (ssl handshake failure)"
elif grep -q "unknown option" <<<$OUTPUT_TLS1_2; then
echo " The local openssl version does NOT support TLS v1.2"
else
echo " UNKNOWN"
fi
echo
echo "[*] Testing for HTTPS (SSL/TLS) security headers using HTTP/1.0 ..."
(echo -e "HEAD / HTTP/1.0\n\n"; sleep $DELAY) | \
openssl s_client $OPENSSLPROTOCOLVERSION -connect $HOST:$PORT \
> $DIRECTORY/$HEAD1LOGFILE 2> $DIRECTORY/$HEAD1ERRFILE
echo
echo " [+] Testing for HTTP Strict-Transport-Security (HSTS) header ..."
grep -i 'Strict-Transport-Security' $DIRECTORY/$HEAD1LOGFILE
echo
echo " [+] Testing for cookies with the secure flag ..."
grep -i 'Set-Cookie' $DIRECTORY/$HEAD1LOGFILE | grep -i 'secure'
echo
echo " [-] Testing for cookies without the secure flag ..."
grep -i 'Set-Cookie' $DIRECTORY/$HEAD1LOGFILE | grep -v -i 'secure'
echo
echo "[*] Testing for HTTPS (SSL/TLS) security headers using HTTP/1.1 & Host ..."
(echo -e "HEAD / HTTP/1.1\nHost: $HOST\n\n"; sleep $DELAY) | \
openssl s_client $OPENSSLPROTOCOLVERSION -connect $HOST:$PORT \
> $DIRECTORY/$HEADLOGFILE 2> $DIRECTORY/$HEADERRFILE
echo
echo " [+] Testing for HTTP Strict-Transport-Security (HSTS) header ..."
grep -i 'Strict-Transport-Security' $DIRECTORY/$HEADLOGFILE
echo
echo " [+] Testing for cookies with the secure flag ..."
grep -i 'Set-Cookie' $DIRECTORY/$HEADLOGFILE | grep -i 'secure'
echo
echo " [-] Testing for cookies without the secure flag ..."
grep -i 'Set-Cookie' $DIRECTORY/$HEADLOGFILE | grep -v -i 'secure'
echo
echo "[*] New files created:"
echo " [.] Output directory: $DIRECTORY ..."
echo
# Moved to bottom:
#ls -l $DIRECTORY/$SSLSCANLOGFILE
#ls -l $DIRECTORY/$RENEGLOGFILE
#ls -l $DIRECTORY/$RENEGLEGACYLOGFILE
#ls -l $DIRECTORY/$HEAD1LOGFILE
#ls -l $DIRECTORY/$HEADLOGFILE
# Delete all empty error files:
# $ find . -size 0 -name '*.err' -delete
# This could potentially delete other .err zero-size files not created by
# TLSSLed.
if [ ! -s "$DIRECTORY/$SSLSCANERRFILE" ]; then
# SSLscan error file is empty
rm "$DIRECTORY/$SSLSCANERRFILE"
fi
if [ ! -s "$DIRECTORY/$RENEGERRFILE" ]; then
# Renegotiation error file is empty
rm "$DIRECTORY/$RENEGERRFILE"
fi
if [ ! -s "$DIRECTORY/$RENEGLEGACYERRFILE" ]; then
# Legacy renegotiation error file is empty
rm "$DIRECTORY/$RENEGLEGACYERRFILE"
fi
if [ ! -s "$DIRECTORY/$HEAD1ERRFILE" ]; then
# Openssl HEAD 1.0 error file is empty
rm "$DIRECTORY/$HEAD1ERRFILE"
fi
if [ ! -s "$DIRECTORY/$HEADERRFILE" ]; then
# Openssl HEAD 1.1 error file is empty
rm "$DIRECTORY/$HEADERRFILE"
fi
ls $DIRECTORY
echo
echo [*] done
echo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment