* NEW: protocol check SSLv2 in bash sockets per default (HTTP)
(fallback to openssl with SSL_NATIVE=1)
This commit is contained in:
parent
b2e8e0175a
commit
89012a7a42
207
testssl.sh
207
testssl.sh
|
@ -44,8 +44,6 @@ SWCONTACT="dirk aet testssl dot sh"
|
|||
|
||||
|
||||
# following variables make use of $ENV, e.g. OPENSSL=<myprivate_path_to_openssl> ./testssl.sh <host>
|
||||
CAPATH="${CAPATH:-/etc/ssl/certs/}" # Does nothing yet. FC has only a CA bundle per default, ==> openssl version -d
|
||||
ECHO="/usr/bin/printf --" # works under Linux, BSD, MacOS.
|
||||
COLOR=${COLOR:-2} # 2: Full color, 1: b/w+positioning, 0: no ESC at all
|
||||
SHOW_LOC_CIPH=${SHOW_LOC_CIPH:-0} # determines whether the client side ciphers are displayed at all (makes no sense normally)
|
||||
VERBERR=${VERBERR:-1} # 0 means to be more verbose (some like the errors to be dispayed so that one can tell better
|
||||
|
@ -53,11 +51,15 @@ VERBERR=${VERBERR:-1} # 0 means to be more verbose (some like the errors to b
|
|||
LOCERR=${LOCERR:-0} # displays the local error
|
||||
SHOW_EACH_C=${SHOW_EACH_C:-0} # where individual ciphers are tested show just the positively ones tested
|
||||
SNEAKY=${SNEAKY:-1} # if zero: the referer and useragent we leave while checking the http header is just usual
|
||||
HEADER_MAXSLEEP=${HEADER_MAXSLEEP:-3} # we wait this long before killing the process to retrieve a service banner / http header
|
||||
SSL_NATIVE=${SSL_NATIVE:-0} # we do per default bash sockets!
|
||||
#FIXME: consequently we should mute the initial openssl s_client -connect as they cause a 400 (nginx, apache)
|
||||
|
||||
#FIXME: still to be filled with (more) sense:
|
||||
DEBUG=${DEBUG:-0} # if 1 the temp files won't be erased. 2: list more what's going on (formerly: eq VERBOSE=1), 3: slight hexdumps
|
||||
# and other info, 4: the whole nine yards of output
|
||||
|
||||
CAPATH="${CAPATH:-/etc/ssl/certs/}" # Does nothing yet. FC has only a CA bundle per default, ==> openssl version -d
|
||||
HSTS_MIN=180 # >180 days is ok for HSTS
|
||||
HPKP_MIN=30 # >=30 days should be ok for HPKP_MIN, practical hints?
|
||||
MAX_WAITSOCK=10 # waiting at max 10 seconds for socket reply
|
||||
|
@ -66,6 +68,9 @@ DAYS2WARN1=60 # days to warn before cert expires, threshold 1
|
|||
DAYS2WARN2=30 # days to warn before cert expires, threshold 2
|
||||
|
||||
# more global vars, here just declared
|
||||
ECHO="/usr/bin/printf --" # works under Linux, BSD, MacOS.
|
||||
NPN_PROTOs="spdy/4a2,spdy/3,spdy/3.1,spdy/2,spdy/1,http/1.1"
|
||||
RUN_DIR=`dirname $0`
|
||||
TEMPDIR=""
|
||||
TLS_PROTO_OFFERED=""
|
||||
SOCKREPLY=""
|
||||
|
@ -80,10 +85,7 @@ OSSL_VER_APPENDIX="none"
|
|||
NODEIP=""
|
||||
IPS=""
|
||||
SERVICE="" # is the server running an HTTP server, SMTP, POP or IMAP?
|
||||
HEADER_MAXSLEEP=${HEADER_MAXSLEEP:-3} # we wait this long before killing the process to retrieve a service banner / http header
|
||||
|
||||
NPN_PROTOs="spdy/4a2,spdy/3,spdy/3.1,spdy/2,spdy/1,http/1.1"
|
||||
RUN_DIR=`dirname $0`
|
||||
BLA=""
|
||||
|
||||
|
||||
|
@ -188,7 +190,7 @@ pr_brown() {
|
|||
pr_off
|
||||
}
|
||||
|
||||
pr_yellowln() { pr_yellowln "$1"; outln; }
|
||||
pr_yellowln() { pr_yellow "$1"; outln; }
|
||||
pr_yellow() {
|
||||
[[ "$COLOR" -eq 2 ]] && out "\033[1;33m$1 " || out "$1 "
|
||||
pr_off
|
||||
|
@ -238,7 +240,7 @@ ok(){
|
|||
case $1 in
|
||||
7) pr_brownln "not offered" ;; # 7 0
|
||||
6) pr_literedln "offered (NOT ok)" ;; # 6 0
|
||||
5) pr_litered "supported but couldn't detect a cipher"; outln "(check manually)" ;; # 5 5
|
||||
5) pr_litered "supported but couldn't detect a cipher"; outln "(may need debugging)" ;; # 5 5
|
||||
4) pr_litegreenln "offered (OK)" ;; # 4 0
|
||||
3) pr_brownln "offered" ;; # 3 0
|
||||
2) outln "offered" ;; # 2 0
|
||||
|
@ -849,13 +851,17 @@ runprotocols() {
|
|||
pr_blue "--> Testing Protocols"; outln "\n"
|
||||
# e.g. ubuntu's 12.04 openssl binary + soon others don't want sslv2 anymore: bugs.launchpad.net/ubuntu/+source/openssl/+bug/955675
|
||||
|
||||
testprotohelper "-ssl2" " SSLv2 "
|
||||
case $? in
|
||||
0) ok 1 1 ;; # pr_red
|
||||
5) ok 5 5 ;; # protocol ok, but no cipher
|
||||
1) ok 0 1 ;; # pr_green "not offered (ok)"
|
||||
7) ;; # no local support
|
||||
esac
|
||||
if [ $SSL_NATIVE -eq 1 ] || [ "$SERVICE" != "HTTP" ]; then
|
||||
testprotohelper "-ssl2" " SSLv2 "
|
||||
case $? in
|
||||
0) ok 1 1 ;; # pr_red
|
||||
5) ok 5 5 ;; # protocol ok, but no cipher
|
||||
1) ok 0 1 ;; # pr_green "not offered (ok)"
|
||||
7) ;; # no local support
|
||||
esac
|
||||
else
|
||||
sslv2_sockets
|
||||
fi
|
||||
|
||||
testprotohelper "-ssl3" " SSLv3 "
|
||||
case $? in
|
||||
|
@ -963,7 +969,7 @@ server_preference() {
|
|||
*CBC*) pr_brown "$default_cipher" ;; #FIXME BEAST: We miss some CBC ciphers here, need to work w/ a list
|
||||
*GCM*) pr_green "$default_cipher" ;; # best ones
|
||||
*CHACHA20*) pr_green "$default_cipher" ;; # best ones
|
||||
ECDHE*AES*) pr_yellow "$default_cipher" ;; # it's CBC. so lucky13
|
||||
ECDHE*AES*) pr_yellow "$default_cipher" ;; # it's CBC. --> lucky13
|
||||
*) out "$default_cipher" ;;
|
||||
esac
|
||||
outln "$remark4default_cipher"
|
||||
|
@ -1210,7 +1216,7 @@ pfs() {
|
|||
if [ $ret -ne 0 ] || [ `grep -c "BEGIN CERTIFICATE" $TMPFILE` -eq 0 ]; then
|
||||
pr_brown "No PFS available"
|
||||
else
|
||||
pr_litegreenln "PFS seems generally available. Now testing specific ciphers ...";
|
||||
pr_litegreenln "PFS is generally offered. Now testing specific ciphers ...";
|
||||
outln "(it depends on the browser/client whether one of them will be used)\n"
|
||||
noone=0
|
||||
neat_header
|
||||
|
@ -1255,7 +1261,7 @@ rc4() {
|
|||
[ $SHOW_LOC_CIPH = "1" ] && echo "local ciphers available for testing RC4:" && echo `cat $TMPFILE`
|
||||
$OPENSSL s_client -cipher `$OPENSSL ciphers RC4` $STARTTLS -connect $NODEIP:$PORT $SNI &>/dev/null </dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
pr_literedln "\nRC4 is broken. It seems generally available. Now testing specific ciphers...";
|
||||
pr_literedln "\nRC4 is broken and is offered! Now testing specific ciphers...";
|
||||
outln "(for legacy support e.g. IE6 rather consider x13 or x0a)\n"
|
||||
bad=1
|
||||
neat_header
|
||||
|
@ -1370,10 +1376,164 @@ close_socket(){
|
|||
return 0
|
||||
}
|
||||
|
||||
## old network code ^^^^^^
|
||||
|
||||
|
||||
### new funcs for network follow
|
||||
|
||||
socksend_clienthello() {
|
||||
code2network "$SSLv2_CLIENT_HELLO"
|
||||
data=`echo $NW_STR`
|
||||
[[ "$DEBUG" -ge 3 ]] && echo "\"$data\""
|
||||
printf -- "$data" >&5 2>/dev/null &
|
||||
sleep $USLEEP_SND
|
||||
}
|
||||
|
||||
sockread_serverhello() {
|
||||
[[ "x$2" = "x" ]] && maxsleep=$MAX_WAITSOCK || maxsleep=$2
|
||||
ret=0
|
||||
|
||||
SOCK_REPLY_FILE=`mktemp /tmp/ddreply.XXXXXX` || exit 7
|
||||
dd bs=$1 of=$SOCK_REPLY_FILE count=1 <&5 2>/dev/null &
|
||||
pid=$!
|
||||
|
||||
while true; do
|
||||
if ! ps ax | grep -v grep | grep -q $pid; then
|
||||
break # didn't reach maxsleep yet
|
||||
kill $pid >&2 2>/dev/null
|
||||
fi
|
||||
sleep $USLEEP_REC
|
||||
maxsleep=$(($maxsleep - 1))
|
||||
[[ $maxsleep -le 0 ]] && break
|
||||
done
|
||||
|
||||
if ps ax | grep -v grep | grep -q $pid; then
|
||||
# time's up and dd is still alive --> timeout
|
||||
kill $pid >&2 2>/dev/null
|
||||
wait $pid 2>/dev/null
|
||||
ret=3 # means killed
|
||||
fi
|
||||
|
||||
return $ret
|
||||
}
|
||||
|
||||
display_sslv2serverhello() {
|
||||
# server hello: in hex representation, see below
|
||||
# byte 1+2: length of server hello 0123
|
||||
# 3: 04=Handshake message, server hello 45
|
||||
# 4: session id hit or not (boolean: 00=false, this 67
|
||||
# is the normal case)
|
||||
# 5: certificate type, 01 = x509 89
|
||||
# 6+7 version (00 02 = SSLv2) 10-13
|
||||
# 8+9 certificate length 14-17
|
||||
# 10+11 cipher spec length 17-20
|
||||
# 12+13 connection id length
|
||||
# [certificate length] ==> certificate
|
||||
# [cipher spec length] ==> ciphers GOOD: HERE ARE ALL CIPHERS ALREADY!
|
||||
|
||||
v2_hello_ascii=`hexdump -v -e '16/1 "%02X"' $1`
|
||||
[[ "$DEBUG" -ge 4 ]] && echo $v2_hello_ascii # one line without any blanks
|
||||
[[ -z $v2_hello_ascii ]] && return 0 # no server hello received
|
||||
|
||||
# now scrape two bytes out of the reply per byte
|
||||
v2_hello_initbyte="${v2_hello_ascii:0:1}" # normally this belongs to the next, should be 8!
|
||||
v2_hello_length="${v2_hello_ascii:1:3}" # + 0x8000 see above
|
||||
v2_hello_handshake="${v2_hello_ascii:4:2}"
|
||||
v2_hello_cert_length="${v2_hello_ascii:14:4}"
|
||||
v2_hello_cipherspec_length="${v2_hello_ascii:18:4}"
|
||||
V2_HELLO_CIPHERSPEC_LENGTH=`printf "%d\n" "0x$v2_hello_cipherspec_length"`
|
||||
|
||||
if [[ $v2_hello_initbyte != "8" ]] || [[ $v2_hello_handshake != "04" ]]; then
|
||||
[[ $DEBUG -ge 2 ]] && echo "$v2_hello_initbyte / $v2_hello_handshake"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ $DEBUG -ge 3 ]]; then
|
||||
echo "SSLv2 server hello length: 0x0$v2_hello_length"
|
||||
echo "SSLv2 certificate length: 0x$v2_hello_cert_length"
|
||||
echo "SSLv2 cipher spec length: 0x$v2_hello_cipherspec_length"
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
# helper function for protocol checks
|
||||
# arg1: formatted string here in the code
|
||||
code2network() {
|
||||
NW_STR=`echo "$1" | sed -e 's/,/\\\x/g' | sed -e 's/# .*$//g' -e 's/ //g' -e '/^$/d' | tr -d '\n' | tr -d '\t'`
|
||||
}
|
||||
|
||||
|
||||
sslv2_sockets() {
|
||||
V2_HELLO_CIPHERSPEC_LENGTH=0 # initialize
|
||||
USLEEP_REC=${USLEEP_REC:-0.2}
|
||||
USLEEP_SND=${USLEEP_SND:-0.1} # 1 second wait until otherwise specified
|
||||
SOCK_REPLY_FILE="" # we do this with a file here. At a certain point heartbleed and ccs needs to be changed and make use of code2network
|
||||
NW_STR=""
|
||||
|
||||
out " SSLv2 ";
|
||||
|
||||
# SSLV2 chello:
|
||||
SSLv2_CLIENT_HELLO="
|
||||
,80,34 # length (here: 52)
|
||||
,01 # Client Hello
|
||||
,00,02 # SSLv2
|
||||
,00,1b # cipher spec length (here: 27 )
|
||||
,00,00 # session ID length
|
||||
,00,10 # challenge length
|
||||
,05,00,80 # 1st cipher 9 cipher specs, only classical V2 ciphers are used here, see http://max.euston.net/d/tip_sslciphers.html
|
||||
,03,00,80 # 2nd there are v3 in v2!!! : https://tools.ietf.org/html/rfc6101#appendix-E
|
||||
,01,00,80 # 3rd Cipher specifications introduced in version 3.0 can be included in version 2.0 client hello messages using
|
||||
,07,00,c0 # 4th the syntax below. [..] # V2CipherSpec (see Version 3.0 name) = { 0x00, CipherSuite }; !!!!
|
||||
,08,00,80 # 5th
|
||||
,06,00,40 # 6th
|
||||
,04,00,80 # 7th
|
||||
,02,00,80 # 8th
|
||||
,00,00,00 # 9th
|
||||
,29,22,be,b3,5a,01,8b,04,fe,5f,80,03,a0,13,eb,c4" # Challenge
|
||||
|
||||
fd_socket 5 || return 6
|
||||
|
||||
[[ "$DEBUG" -ge 2 ]] && out "sending client hello... "
|
||||
socksend_clienthello
|
||||
|
||||
sockread_serverhello 32768 0
|
||||
[[ "$DEBUG" -ge 2 ]] && out "reading server hello... "
|
||||
if [[ "$DEBUG" -eq 3 ]]; then
|
||||
hexdump -C $SOCK_REPLY_FILE | head -6
|
||||
outln
|
||||
fi
|
||||
|
||||
display_sslv2serverhello "$SOCK_REPLY_FILE"
|
||||
|
||||
# see https://secure.wand.net.nz/trac/libprotoident/wiki/SSL
|
||||
lines=`cat "$SOCK_REPLY_FILE" 2>/dev/null | hexdump -C | wc -l`
|
||||
[[ "$DEBUG" -ge 2 ]] && out " ($lines lines) "
|
||||
|
||||
if [[ "$lines" -gt 1 ]] ;then
|
||||
ciphers_detected=$(($V2_HELLO_CIPHERSPEC_LENGTH / 3 ))
|
||||
if [ 0 -eq $ciphers_detected ] ; then
|
||||
pr_litered "supported but couldn't detect a cipher"; outln "(may need debugging)"
|
||||
else
|
||||
pr_red "offered (NOT ok)"; outln " -- $ciphers_detected ciphers"
|
||||
fi
|
||||
ret=1
|
||||
else
|
||||
pr_greenln "not offered (OK)"
|
||||
ret=0
|
||||
fi
|
||||
pr_off
|
||||
|
||||
close_socket
|
||||
TMPFILE=$SOCK_REPLY_FILE
|
||||
tmpfile_handle $FUNCNAME.dd
|
||||
return $ret
|
||||
}
|
||||
|
||||
|
||||
|
||||
ok_ids(){
|
||||
echo
|
||||
tput pr_bold; tput setaf 2; echo "ok -- something resetted our ccs packets"; tput sgr0
|
||||
echo
|
||||
greenln "\n ok -- something resetted our ccs packets"
|
||||
return 0
|
||||
}
|
||||
|
||||
|
@ -1465,7 +1625,7 @@ ccs_injection(){
|
|||
|
||||
if [ "$reply_sanitized" == "0a" ] || [ "$lines" -gt 1 ] ; then
|
||||
pr_green "not vulnerable (OK)"
|
||||
ret=1
|
||||
ret=0
|
||||
else
|
||||
pr_red "VULNERABLE"
|
||||
ret=1
|
||||
|
@ -1714,11 +1874,10 @@ beast(){
|
|||
local -i ret=0
|
||||
local spaces=" "
|
||||
#in a nutshell: don't use CBC Ciphers in SSLv3 TLSv1.0
|
||||
#
|
||||
|
||||
pr_bold " BEAST"; out " (CVE-2011-3389) "
|
||||
|
||||
# 2) test handfull of common CBC ciphers
|
||||
#set -x
|
||||
for proto in ssl3 tls1; do
|
||||
$OPENSSL s_client -"$proto" $STARTTLS -connect $NODEIP:$PORT $SNI >$TMPFILE 2>/dev/null </dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
|
@ -2389,6 +2548,6 @@ case "$1" in
|
|||
exit $ret ;;
|
||||
esac
|
||||
|
||||
# $Id: testssl.sh,v 1.174 2015/01/29 08:33:33 dirkw Exp $
|
||||
# $Id: testssl.sh,v 1.175 2015/01/29 09:46:15 dirkw Exp $
|
||||
# vim:ts=5:sw=5
|
||||
|
||||
|
|
Loading…
Reference in New Issue