Thursday, April 09, 2009

SSL Audit

SSL is not a panacea. Thus, it is important to learn how to audit a SSL/TLS host effectively. This is a compilation of various articles on how to audit a weak SSL host.

Attempt to connect to target (in this case google.com) with SSLv2:
~# openssl s_client -no_tls1 -no_ssl3 -connect www.google.com:443
Check the output if it works. You can also do this with NMAP (with NSE script):
~# nmap -n -p443 -v --script=sslv2 -iL target.list -oG https.gnmap
Next, we will need to parse the NMAP output and dump the all the X.509 certificates with OpenSSL tool:
~# gawk "/https/{print $0}" https.gnmap > https-ip.txt
~# ./get-cert-info.sh https-ip.txt
Below is the "get-cert-info.sh":
#!/bin/bash
# You will need OpenSSL for this script to work

processLine(){
# Use OpenSSl to download the cert and extract the right info
# from it witht he X509 utility e.o.
line="$@" # get all args
IP=$(echo "$line" | cut -d" " -f1)
TARGETDOM=$(echo "$line" | cut -d" " -f2)
HOST="$TARGETDOM:443"
# Connect to HOST, defer errors to /dev/null,
# send standard output to RAWCERT variable
RAWCERT=$(openssl s_client -connect ${HOST} 2>/dev/null)
# Obtain encoded certificate from RAWCERT
CERTTEXT=$(echo "$RAWCERT" | /
sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p')
# Process certificate for the different variables
SIGALG=$(echo "$CERTTEXT" | /
openssl x509 -noout -text | /
grep -m 1 "Signature Algo" | cut -d: -f2)
SUBJECT=$(echo "$CERTTEXT" | /
openssl x509 -noout -subject | sed -e 's/subject= //')
ISSUER=$(echo "$CERTTEXT" | /
openssl x509 -noout -issuer | sed -e 's/issuer= //')
START=$(echo "$CERTTEXT" | /
openssl x509 -noout -startdate | cut -d= -f2)
END=$(echo "$CERTTEXT" | /
openssl x509 -noout -enddate | cut -d= -f2)
SERIAL=$(echo "$CERTTEXT" | /
openssl x509 -noout -serial | cut -d= -f2)

#Clean-up dates
START=$(echo "$START" | sed -e 's/GMT//')
START=$(echo "$START" | cut -d" " -f1,2,4)
STARTDAY=$(echo "$START" | cut -d" " -f2)
STARTMONTH=$(echo "$START" | cut -d" " -f1)
STARTYEAR=$(echo "$START" | cut -d" " -f3)
START=$STARTDAY\/$STARTMONTH\/$STARTYEAR

END=$(echo "$END" | sed -e 's/GMT//')
END=$(echo "$END" | cut -d" " -f1,2,4)
ENDDAY=$(echo "$END" | cut -d" " -f2)
ENDMONTH=$(echo "$END" | cut -d" " -f1)
ENDYEAR=$(echo "$END" | cut -d" " -f3)
END=$STARTDAY\/$STARTMONTH\/$STARTYEAR

# Output in CSV format
echo $IP, $TARGETDOM, $SIGALG, $SUBJECT,/
$ISSUER, $START, $END, $SERIAL
}

### File line loop ###
# Store file name
FILE=""

# Make sure we get file name as command line argument
FILE=${1?"No file name specified"}
# Check that file exists and is readable
[ ! -f $FILE ] && { echo "$FILE: does not exist"; exit 1; }
[ ! -r $FILE ] && { echo "$FILE: cannot be read"; exit 2; }

#Open file for reading
exec 3< $FILE

#Process file line by line
while read -u 3 line
do
# use $line variable to process line
# in processLine() function
processLine $line
done

# Close file after reading
exec 3<&-

exit 0

Related links: