- fix regression on missing rfc cipher names
- cosmetic stuff
This commit is contained in:
parent
d58f39d008
commit
ed38a365ae
91
testssl.sh
91
testssl.sh
|
@ -1,15 +1,11 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# bash is needed for some distros which use dash as /bin/sh and for tcp sockets which
|
||||
# this program uses a couple of times. Also some expressions are bashisms as I expect
|
||||
# them to be faster. Idea is to not overdo it though.
|
||||
|
||||
# testssl.sh is a program for spotting weak SSL encryption, ciphers, version and some
|
||||
# vulnerablities or features
|
||||
#
|
||||
# Devel version is availabe from https://github.com/drwetter/testssl.sh
|
||||
# Devel version is available from https://github.com/drwetter/testssl.sh
|
||||
# Stable version from https://testssl.sh
|
||||
# Please file bugs at github!
|
||||
# Please file bugs at github! https://github.com/drwetter/testssl.sh/issues
|
||||
|
||||
VERSION="2.5dev"
|
||||
SWURL="https://testssl.sh"
|
||||
|
@ -30,13 +26,19 @@ SWCONTACT="dirk aet testssl dot sh"
|
|||
# HISTORY: I know this shell script is still on its way to be nice and readable. ;-) It
|
||||
# all started with a few openssl commands around 2006. That's because openssl is a such a good
|
||||
# swiss army knife (see e.g. wiki.openssl.org/index.php/Command_Line_Utilities) that it was
|
||||
# difficult to resist wrapping # with some shell commandos around it. This is how everything started.
|
||||
# difficult to resist wrapping some shell commands around it, which I used for my pen tests.
|
||||
# This is how everything started.
|
||||
# Now it has grown up, it has bash socket support for some features which basically replacing
|
||||
# more and more functions of OpenSSL and will serve as some kind of library in the future.
|
||||
# The socket checks in bash may sound cool and unique -- they are -- but probably you
|
||||
# can achieve e.g. the same result with my favorite intgeractive shell: zsh (zmodload zsh/net/socket
|
||||
# -- checkout zsh/net/tcp too!) But bash is way more often used within Linux and it's perfect
|
||||
# for cross plattform support, see MacOS X and Windows MSYS2 extenstion.
|
||||
# can achieve e.g. the same result with my favorite interactive shell: zsh (zmodload zsh/net/socket
|
||||
# -- checkout zsh/net/tcp too!) /bin/bash is way more often used within Linux and it's perfect
|
||||
# for cross plattform support, see MacOS X and also under Windows the MSYS2 extention.
|
||||
# Cross-platform is one of the three ideas of this script. Second: Ease of installation.
|
||||
# No compiling, install gems, go to CPAN, use pip etc. Third: Easy to use and to interpret
|
||||
# the result.
|
||||
#
|
||||
# Did I mention it's open source?
|
||||
#
|
||||
# Q: So what's the difference to www.ssllabs.com/ssltest or sslcheck.globalsign.com/ ?
|
||||
# A: As of now ssllabs only check webservers on standard ports, reachable from
|
||||
|
@ -44,6 +46,8 @@ SWCONTACT="dirk aet testssl dot sh"
|
|||
# with you, and you need a management compatible rating -- go ahead and use those.
|
||||
# Also testssl.sh is meant as a tool in your hand and it's way more flexible.
|
||||
#
|
||||
# Oh, and did I mention testssl.sh is open source?
|
||||
#
|
||||
# Note that for "standard" openssl binaries a lot of features (ciphers, protocols, vulnerabilities)
|
||||
# are disabled as they'll impact security otherwise. For security testing though we need
|
||||
# all b0rken features. testssl.sh will over time replace those checks with bash sockets --
|
||||
|
@ -53,13 +57,15 @@ SWCONTACT="dirk aet testssl dot sh"
|
|||
|
||||
|
||||
readonly PROG_NAME=$(basename "$0")
|
||||
PROG_DIR=$(readlink "$BASH_SOURCE") 2>/dev/null
|
||||
readonly RUN_DIR=$(dirname $0)
|
||||
PROG_DIR=$(readlink "$BASH_SOURCE") 2>/dev/null
|
||||
[ -z "$PROG_DIR" ] && PROG_DIR="$(pwd -L)"
|
||||
|
||||
# following variables make use of $ENV, e.g. OPENSSL=<myprivate_path_to_openssl> ./testssl.sh <host>
|
||||
# 0 means (normally) true here. Some of the variables are also accessible with a command line switch
|
||||
|
||||
OPENSSL=${OPENSSL:-/usr/bin/openssl}
|
||||
MAP_RFC_FNAME=""
|
||||
COLOR=${COLOR:-2} # 2: Full color, 1: b/w+positioning, 0: no ESC at all
|
||||
SHOW_LOC_CIPH=${SHOW_LOC_CIPH:-1} # will client side ciphers displayed before an individual test (makes no sense normally)
|
||||
SHOW_EACH_C=${SHOW_EACH_C:-0} # where individual ciphers are tested show just the positively ones tested #FIXME: wrong value
|
||||
|
@ -331,6 +337,7 @@ if [[ "$COLOR" -eq 2 ]]; then
|
|||
green=$(tput setaf 2)
|
||||
brown=$(tput setaf 3)
|
||||
blue=$(tput setaf 4)
|
||||
grey=$(tput setaf 7)
|
||||
yellow=$(tput setaf 3; tput bold)
|
||||
off=$(tput sgr0)
|
||||
fi
|
||||
|
@ -888,7 +895,7 @@ sockread() {
|
|||
|
||||
show_rfc_style(){
|
||||
[ ! -r "$MAP_RFC_FNAME" ] && return 1
|
||||
RFCname=$(grep -iw $1 "$MAP_RFC_FNAME" | sed -e 's/^.*TLS/TLS/' -e 's/^.*SSL/SSL/')
|
||||
RFCname=$(grep -iw "$1" "$MAP_RFC_FNAME" | sed -e 's/^.*TLS/TLS/' -e 's/^.*SSL/SSL/')
|
||||
[[ -n "$RFCname" ]] && out "$RFCname"
|
||||
return 0
|
||||
}
|
||||
|
@ -905,14 +912,14 @@ neat_list(){
|
|||
strength=$(echo $strength | sed -e 's/ChaCha20-Poly1305/ly1305/g') # workaround for empty bits ChaCha20-Poly1305
|
||||
enc=$(echo $enc | sed -e 's/(.*)//g' -e 's/ChaCha20-Poly1305/ChaCha20-Po/g') # workaround for empty bits ChaCha20-Poly1305
|
||||
echo "$export" | grep -iq export && strength="$strength,export"
|
||||
if [ -r "$MAP_RFC_FNAME" ]; then
|
||||
# workaround for color escape codes:
|
||||
if printf -- "$kx" | "${HEXDUMPVIEW[@]}" | grep -q 33 ; then
|
||||
if printf -- "$kx" | "${HEXDUMPVIEW[@]}" | grep -q 33 ; then # here's a color code
|
||||
kx="$kx " # one for color code if ECDH and three digits
|
||||
[[ "${#kx}" -eq 18 ]] && kx="$kx " # 18 means DH, colored < 1000. Add another space
|
||||
[[ "${#kx}" -eq 19 ]] && kx="$kx " # 19 means DH, colored >=1000. Add another space
|
||||
#echo ${#kx} # should be alwasy 20
|
||||
#echo ${#kx} # should be always 20
|
||||
fi
|
||||
if [ -r "$MAP_RFC_FNAME" ]; then
|
||||
printf -- " %-7s %-30s %-10s %-11s%-11s${MAP_RFC_FNAME:+ %-48s}${SHOW_EACH_C:+ }" "$1" "$2" "$kx" "$enc" "$strength" "$(show_rfc_style $HEXC)"
|
||||
else
|
||||
printf -- " %-7s %-30s %-10s %-11s%-11s${SHOW_EACH_C:+ }" "$1" "$2" "$kx" "$enc" "$strength"
|
||||
|
@ -920,17 +927,32 @@ neat_list(){
|
|||
}
|
||||
|
||||
test_just_one(){
|
||||
pr_blue "--> Testing single cipher with word pattern "\"$1\"" (ignore case)"; outln "\n"
|
||||
local hexcode n ciph sslvers kx auth enc mac export
|
||||
local dhlen
|
||||
local ret
|
||||
|
||||
pr_blue "--> Testing single cipher with word pattern "\"$1\"" (ignore case)"; outln
|
||||
! $HAS_DH_BITS && pr_litemagentaln " (Your $OPENSSL is too old to show DH/ECDH bits)"
|
||||
outln
|
||||
neat_header
|
||||
for arg in $(echo $@ | sed 's/,/ /g'); do
|
||||
# 1st check whether openssl has cipher or not
|
||||
$OPENSSL ciphers -V 'ALL:COMPLEMENTOFALL:@STRENGTH' | while read hexcode dash ciph sslvers kx auth enc mac export ; do
|
||||
# FIXME: e.g. OpenSSL < 1.0 doesn't understand "-V" --> we can't do anything about it!
|
||||
normalize_ciphercode $hexcode
|
||||
neat_list $HEXC $ciph $kx $enc | grep -qwai "$arg"
|
||||
if [ $? -eq 0 ]; then
|
||||
if [ $? -eq 0 ]; then # string matches, so we can ssl to it:
|
||||
$OPENSSL s_client -cipher $ciph $STARTTLS -connect $NODEIP:$PORT $SNI &>$TMPFILE </dev/null
|
||||
ret=$?
|
||||
neat_list $HEXC $ciph $kx $enc
|
||||
if [ $kx == "Kx=ECDH" ] || [ $kx == "Kx=DH" ] || [ $kx == "Kx=EDH" ]; then
|
||||
if [ $ret -eq 0 ]; then
|
||||
dhlen=$(read_dhbits_from_file $TMPFILE quiet)
|
||||
kx="$kx $dhlen"
|
||||
else
|
||||
kx="$kx$grey TBD $off "
|
||||
fi
|
||||
fi
|
||||
neat_list $HEXC $ciph "$kx" $enc
|
||||
if [ $ret -eq 0 ]; then
|
||||
pr_cyan " available"
|
||||
else
|
||||
|
@ -957,7 +979,7 @@ allciphers(){
|
|||
|
||||
nr_ciphers=$($OPENSSL ciphers 'ALL:COMPLEMENTOFALL:@STRENGTH' | sed 's/:/ /g' | wc -w)
|
||||
pr_blue "--> Testing all locally available $nr_ciphers ciphers against the server"; outln ", ordered by encryption strength"
|
||||
! $HAS_DH_BITS && pr_litemagentaln " (Your $OPENSSL too old to show DH/ECDH bits)"
|
||||
! $HAS_DH_BITS && pr_litemagentaln " (Your $OPENSSL is too old to show DH/ECDH bits)"
|
||||
outln
|
||||
neat_header
|
||||
|
||||
|
@ -984,6 +1006,7 @@ allciphers(){
|
|||
outln
|
||||
tmpfile_handle $FUNCNAME.txt
|
||||
done
|
||||
outln
|
||||
return 0
|
||||
}
|
||||
|
||||
|
@ -995,7 +1018,7 @@ cipher_per_proto(){
|
|||
local dhlen
|
||||
|
||||
pr_blue "--> Testing all locally available ciphers per protocol against the server"; outln ", ordered by encryption strength"
|
||||
! $HAS_DH_BITS && pr_litemagentaln " (Your $OPENSSL too old to show DH/ECDH bits)"
|
||||
! $HAS_DH_BITS && pr_litemagentaln " (Your $OPENSSL is too old to show DH/ECDH bits)"
|
||||
outln
|
||||
neat_header
|
||||
outln " -ssl2 SSLv2\n -ssl3 SSLv3\n -tls1 TLS 1\n -tls1_1 TLS 1.1\n -tls1_2 TLS 1.2"| while read proto proto_text; do
|
||||
|
@ -1047,7 +1070,7 @@ testversion() {
|
|||
|
||||
$OPENSSL s_client -state $1 $STARTTLS -connect $NODEIP:$PORT $sni &>$TMPFILE </dev/null
|
||||
ret=$?
|
||||
# FIXME: hoer gibt BSD immer eine Null zurueck! --> error lesen
|
||||
# FIXME: here FreeBSD9 returns always 0 --> need to read the error
|
||||
[ "$VERBERR" -eq 0 ] && egrep "error|failure" $TMPFILE | egrep -av "unable to get local|verify error"
|
||||
|
||||
if grep -aq "no cipher list" $TMPFILE ; then
|
||||
|
@ -1167,6 +1190,7 @@ run_std_cipherlists() {
|
|||
# arg2: whether to print sparse or not (empty: no)
|
||||
read_dhbits_from_file() {
|
||||
local bits what_dh
|
||||
local add=""
|
||||
local old_fart=" (openssl too old to show DH bits)"
|
||||
|
||||
if ! $HAS_DH_BITS; then
|
||||
|
@ -1196,7 +1220,7 @@ read_dhbits_from_file() {
|
|||
fi
|
||||
# https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography, http://www.keylength.com/en/compare/
|
||||
elif [[ $what_dh == "ECDH" ]]; then
|
||||
[ -z "$2" ] && add="bit DH"
|
||||
[ -z "$2" ] && add="bit ECDH"
|
||||
if [[ "$bits" -le 128 ]]; then # has that ever existed?
|
||||
pr_red "$bits $add"
|
||||
elif [[ "$bits" -le 163 ]]; then
|
||||
|
@ -1357,7 +1381,7 @@ cipher_pref_check() {
|
|||
outln
|
||||
|
||||
if ! spdy_pre ; then # is NPN/SPDY supported and is this no STARTTLS?
|
||||
:
|
||||
outln
|
||||
else
|
||||
protos=$($OPENSSL s_client -host $NODE -port $PORT -nextprotoneg \"\" </dev/null 2>/dev/null | grep -a "^Protocols " | sed -e 's/^Protocols.*server: //' -e 's/,//g')
|
||||
for p in $protos; do
|
||||
|
@ -1730,7 +1754,7 @@ pfs() {
|
|||
|
||||
spdy_pre(){
|
||||
if [ ! -z "$STARTTLS" ]; then
|
||||
out "\n (SPDY is a HTTP protocol and thus not tested here)"
|
||||
out "(SPDY is a HTTP protocol and thus not tested here)"
|
||||
return 1
|
||||
fi
|
||||
# first, does the current openssl support it?
|
||||
|
@ -1744,7 +1768,10 @@ spdy_pre(){
|
|||
|
||||
spdy() {
|
||||
out " SPDY/NPN "
|
||||
spdy_pre || return 0
|
||||
if ! spdy_pre ; then
|
||||
echo
|
||||
return 0
|
||||
fi
|
||||
$OPENSSL s_client -host $NODE -port $PORT -nextprotoneg $NPN_PROTOs </dev/null 2>/dev/null >$TMPFILE
|
||||
tmpstr=$(grep -a '^Protocols' $TMPFILE | sed 's/Protocols.*: //')
|
||||
if [ -z "$tmpstr" -o "$tmpstr" = " " ] ; then
|
||||
|
@ -1771,7 +1798,7 @@ spdy() {
|
|||
fd_socket() {
|
||||
if ! exec 5<>/dev/tcp/$NODEIP/$PORT; then # 2>/dev/null removes an error message, but disables debugging
|
||||
outln
|
||||
pr_magenta "Unable to open a socket to $NODEIP:$PORT"
|
||||
pr_magenta "Unable to open a socket to $NODEIP:$PORT. "
|
||||
# It can last ~2 minutes but for for those rare occasions we don't do a tiemout handler here, KISS
|
||||
return 6
|
||||
fi
|
||||
|
@ -3396,7 +3423,11 @@ startup() {
|
|||
--mx587) # doesn't work with major ISPs
|
||||
do_mx_allentries=true
|
||||
PORT=587 ;;
|
||||
-V|--local)
|
||||
-V|--local) # this is only displaying local, thus we don't put it in the loop
|
||||
find_openssl_binary
|
||||
mybanner
|
||||
openssl_age
|
||||
maketempf
|
||||
initialize_engine # GOST support-
|
||||
prettyprint_local "$2"
|
||||
exit $? ;;
|
||||
|
@ -3579,11 +3610,9 @@ lets_roll() {
|
|||
################# main #################
|
||||
|
||||
|
||||
[ -z "$PROG_DIR" ] && PROG_DIR="."
|
||||
|
||||
# mapping file provides a pair "keycode/ RFC style name", see the RFCs, cipher(1) and
|
||||
# www.carbonwind.net/TLS_Cipher_Suites_Project/tls_ssl_cipher_suites_simple_table_all.htm
|
||||
[ -r "$(dirname $PROG_DIR)/mapping-rfc.txt" ] && MAP_RFC_FNAME=$(dirname $PROG_DIR)"/mapping-rfc.txt"
|
||||
[ -r "$PROG_DIR/mapping-rfc.txt" ] && MAP_RFC_FNAME="$PROG_DIR/mapping-rfc.txt"
|
||||
|
||||
initialize_globals
|
||||
|
||||
|
@ -3608,6 +3637,6 @@ fi
|
|||
|
||||
exit $ret
|
||||
|
||||
# $Id: testssl.sh,v 1.257 2015/05/26 10:51:09 dirkw Exp $
|
||||
# $Id: testssl.sh,v 1.260 2015/05/27 09:19:29 dirkw Exp $
|
||||
# vim:ts=5:sw=5
|
||||
# ^^^ FYI: use vim and you will see everything beautifully indented with a 5 char tab
|
||||
|
|
Loading…
Reference in New Issue