@@ -114,6 +114,7 @@ HEADER_MAXSLEEP=${HEADER_MAXSLEEP:-5} # we wait this long before killing the pro
114
114
readonly MAX_WAITSOCK=10 # waiting at max 10 seconds for socket reply
115
115
readonly CCS_MAX_WAITSOCK=5 # for the two CCS payload (each)
116
116
readonly HEARTBLEED_MAX_WAITSOCK=8 # for the heartbleed payload
117
+ readonly STARTTLS_SLEEP=1 # max time to wait on a socket replay for STARTTLS
117
118
USLEEP_SND=${USLEEP_SND:- 0.1} # sleep time for general socket send
118
119
USLEEP_REC=${USLEEP_REC:- 0.2} # sleep time for general socket receive
119
120
@@ -415,22 +416,22 @@ tmpfile_handle() {
415
416
fi
416
417
}
417
418
418
- # ARG1= pid which is in the backgnd and we wait for ($2 seconds)
419
419
wait_kill (){
420
- pid=$1
421
- maxsleep=$2
420
+ local pid=$1 # pid we wait for or kill
421
+ local maxsleep=$2 # how long we wait before killing
422
+
422
423
while true ; do
424
+ [[ " $DEBUG " -ge 6 ]] && ps $pid
423
425
if ! ps $pid > /dev/null ; then
424
- return 0 # didn't reach maxsleep yet
426
+ return 0 # process terminated before didn't reach $ maxsleep
425
427
fi
426
428
sleep 1
427
429
maxsleep=$(( maxsleep - 1 ))
428
- test $maxsleep -eq 0 && break
429
- done # needs to be killed:
430
+ test $maxsleep -le 0 && break
431
+ done # needs to be killed:
430
432
kill $pid >&2 2> /dev/null
431
- wait $pid 2> /dev/null
432
- # FIXME: do we need wait here???? normally it's good to report the exit status?!
433
- return 3 # killed
433
+ wait $pid 2> /dev/null # make sure pid terminated, see wait(1p)
434
+ return 3 # means killed
434
435
}
435
436
436
437
@@ -508,8 +509,7 @@ Connection: close
508
509
509
510
EOF
510
511
) & > $HEADERFILE &
511
- pid=$!
512
- if wait_kill $pid $HEADER_MAXSLEEP ; then
512
+ if wait_kill $! $HEADER_MAXSLEEP ; then
513
513
if ! egrep -iaq " XML|HTML|DOCTYPE|HTTP|Connection" $HEADERFILE ; then
514
514
pr_litemagenta " likely HTTP header requests failed (#lines: $( wc -l < $HEADERFILE | sed ' s/ //g' ) )."
515
515
outln " Rerun with DEBUG=1 and inspect \" http_header.txt\" \n"
@@ -1042,9 +1042,7 @@ sockread() {
1042
1042
1043
1043
ddreply=$( mktemp $TEMPDIR /ddreply.XXXXXX) || return 7
1044
1044
dd bs=$1 of=$ddreply count=1 < & 5 2> /dev/null &
1045
- pid=$!
1046
-
1047
- wait_kill $pid $maxsleep
1045
+ wait_kill $! $maxsleep
1048
1046
ret=$?
1049
1047
SOCKREPLY=$( cat $ddreply )
1050
1048
rm $ddreply
@@ -1268,7 +1266,7 @@ run_protocols() {
1268
1266
1269
1267
pr_blue " --> Testing protocols " ;
1270
1268
1271
- if $SSL_NATIVE || [ -n " $STARTTLS " ]; then
1269
+ if $SSL_NATIVE || [ -n " $STARTTLS " ] && [[ $EXPERIMENTAL != " yes " ]] ; then
1272
1270
using_sockets=false
1273
1271
outln " (via native openssl)\n"
1274
1272
else
@@ -1939,7 +1937,7 @@ spdy_pre(){
1939
1937
fi
1940
1938
if [ ! -z " $PROXY " ]; then
1941
1939
[ -n " $1 " ] && pr_litemagenta " $1 "
1942
- pr_litemagenta " not being tested as proxies do not support it"
1940
+ pr_litemagenta " not tested as proxies do not support proxying it"
1943
1941
return 1
1944
1942
fi
1945
1943
# first, does the current openssl support it?
@@ -1979,8 +1977,52 @@ run_spdy() {
1979
1977
return $ret
1980
1978
}
1981
1979
1980
+
1981
+ # arg1: string to send
1982
+ # arg2: possible success strings a egrep pattern, needed!
1983
+ starttls_line () {
1984
+ debugme echo -e " \n=== sending \" $1 \" ..."
1985
+ echo -e " $1 " >&5
1986
+
1987
+ # we don't know how much to read and it's blocking! So we just put a cat into the
1988
+ # background and read until $STARTTLS_SLEEP and: cross our fingers
1989
+ cat < & 5 > $TMPFILE &
1990
+ wait_kill $! $STARTTLS_SLEEP
1991
+ debugme echo " ... received result: "
1992
+ debugme cat $TMPFILE
1993
+ if [ -n " $2 " ]; then
1994
+ if egrep -q " $2 " $TMPFILE ; then
1995
+ debugme echo " ---> reply matched \" $2 \" "
1996
+ else
1997
+ debugme echo " ---> reply didn't match \" $2 \" , see $TMPFILE "
1998
+ pr_magenta " STARTTLS handshake problem."
1999
+ outln " Please recheck your cmdline and/or debug what happened ($PROG_NAME --debug=2 <cmdline>)."
2000
+ exit 1
2001
+ fi
2002
+ fi
2003
+
2004
+ return 0
2005
+ }
2006
+
2007
+ starttls_just_read (){
2008
+ debugme echo " === just read banner ==="
2009
+ if [[ " $DEBUG " -ge 2 ]] ; then
2010
+ cat < & 5 &
2011
+ wait_kill $! $STARTTLS_SLEEP
2012
+ else
2013
+ dd of=/dev/null count=8 < & 5 2> /dev/null &
2014
+ wait_kill $! $STARTTLS_SLEEP
2015
+ fi
2016
+
2017
+ return 0
2018
+ }
2019
+
2020
+
1982
2021
# arg for a fd doesn't work here
1983
2022
fd_socket () {
2023
+ local jabber=" "
2024
+ local proyxline=" "
2025
+
1984
2026
if [[ -n " $PROXY " ]]; then
1985
2027
if ! exec 5<> /dev/tcp/${PROXYIP} /${PROXYPORT} ; then
1986
2028
outln
@@ -1989,25 +2031,80 @@ fd_socket() {
1989
2031
fi
1990
2032
echo " CONNECT $NODEIP :$PORT " >&5
1991
2033
while true ; do
1992
- read x < & 5
1993
- if [[ " ${x %/* } " == " HTTP" ]]; then
1994
- x =${x #* }
1995
- if [[ " ${x %% * } " != " 200" ]] ; then
2034
+ read proyxline < & 5
2035
+ if [[ " ${proyxline %/* } " == " HTTP" ]]; then
2036
+ proyxline =${proyxline #* }
2037
+ if [[ " ${proyxline %% * } " != " 200" ]] ; then
1996
2038
[[ " $PORT " != 443 ]] && outln " Check whether your proxy supports port $PORT and the underlying protocol."
1997
2039
pr_magenta " Unable to CONNECT via proxy. "
1998
2040
return 6
1999
2041
fi
2000
2042
fi
2001
- if [[ " $x " == $' \r ' ]] ; then
2043
+ if [[ " $proyxline " == $' \r ' ]] ; then
2002
2044
break
2003
2045
fi
2004
2046
done
2005
- elif ! exec 5<> /dev/tcp/$NODEIP /$PORT ; then # 2>/dev/null removes an error message, but disables debugging
2047
+ elif ! exec 5<> /dev/tcp/$NODEIP /$PORT ; then # 2>/dev/null would remove an error message, but disables debugging
2006
2048
outln
2007
- pr_magenta " Unable to open a socket to $NODEIP :$PORT . "
2049
+ pr_magentaln " Unable to open a socket to $NODEIP :$PORT . "
2008
2050
# It can last ~2 minutes but for for those rare occasions we don't do a timeout handler here, KISS
2009
2051
return 6
2010
2052
fi
2053
+
2054
+ if [[ -n " $STARTTLS " ]]; then
2055
+ case " $PORT " in # port
2056
+ 21) # https://tools.ietf.org/html/rfc4217
2057
+ starttls_just_read
2058
+ starttls_line " FEAT" " 211"
2059
+ starttls_line " AUTH TLS" " successful|234"
2060
+ ;;
2061
+ 25) # SMTP, see https://tools.ietf.org/html/rfc4217
2062
+ starttls_just_read
2063
+ starttls_line " EHLO testssl.sh" " 220|250"
2064
+ starttls_line " STARTTLS" " 220"
2065
+ ;;
2066
+ 110) # POP, see https://tools.ietf.org/html/rfc2595
2067
+ starttls_just_read
2068
+ starttls_line " STLS" " OK"
2069
+ ;;
2070
+ 119|433) # NNTP, see https://tools.ietf.org/html/rfc4642
2071
+ starttls_just_read
2072
+ starttls_line " CAPABILITIES" " 101|200"
2073
+ starttls_line " STARTTLS" " 382"
2074
+ ;;
2075
+ 143) # IMAP, https://tools.ietf.org/html/rfc2595
2076
+ starttls_just_read
2077
+ starttls_line " a001 CAPABILITY" " OK"
2078
+ starttls_line " a002 STARTTLS" " OK"
2079
+ ;;
2080
+ 389) # LDAP, https://tools.ietf.org/html/rfc2830, https://tools.ietf.org/html/rfc4511
2081
+ pr_magentaln " FIXME: LDAP/STARTTLS not yet supported"
2082
+ exit 1
2083
+ ;;
2084
+ 674) # ACAP = Application Configuration Access Protocol, see https://tools.ietf.org/html/rfc2595
2085
+ pr_magentaln " ACAP Easteregg: not implemented -- probably never will"
2086
+ exit 1
2087
+ ;;
2088
+ 5222) # XMPP, see https://tools.ietf.org/html/rfc6120
2089
+ starttls_just_read
2090
+ [[ -z $XMPP_HOST ]] && XMPP_HOST=" $NODE "
2091
+ jabber=$( cat << EOF
2092
+ <?xml version='1.0' ?>
2093
+ <stream:stream
2094
+ xmlns:stream='http://etherx.jabber.org/streams'
2095
+ xmlns='jabber:client'
2096
+ to='$XMPP_HOST '
2097
+ xml:lang='en'
2098
+ version='1.0'>
2099
+ EOF
2100
+ )
2101
+ starttls_line " $jabber "
2102
+ starttls_line " <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>" " proceed"
2103
+ # BTW: https://xmpp.net !
2104
+ ;;
2105
+ esac
2106
+ fi
2107
+
2011
2108
return 0
2012
2109
}
2013
2110
@@ -2017,13 +2114,9 @@ close_socket(){
2017
2114
exec 5>& -
2018
2115
return 0
2019
2116
}
2020
- # # old network code ^^^^^^
2021
-
2022
2117
2023
- # ##### new funcs for network follow
2024
2118
2025
2119
# first: helper function for protocol checks
2026
-
2027
2120
code2network () {
2028
2121
# arg1: formatted string here in the code
2029
2122
NW_STR=$( echo " $1 " | sed -e ' s/,/\\\x/g' | sed -e ' s/# .*$//g' -e ' s/ //g' -e ' /^$/d' | tr -d ' \n' | tr -d ' \t' )
@@ -2050,9 +2143,8 @@ sockread_serverhello() {
2050
2143
2051
2144
SOCK_REPLY_FILE=$( mktemp $TEMPDIR /ddreply.XXXXXX) || return 7
2052
2145
dd bs=$1 of=$SOCK_REPLY_FILE count=1 < & 5 2> /dev/null &
2053
- pid= $!
2146
+ wait_kill $! $maxsleep
2054
2147
2055
- wait_kill $pid $maxsleep
2056
2148
return $?
2057
2149
}
2058
2150
@@ -2458,7 +2550,7 @@ heartbleed(){
2458
2550
[ $VULN_COUNT -le $VULN_THRESHLD ] && outln && pr_blue " --> Testing for heartbleed vulnerability" && outln " \n"
2459
2551
pr_bold " Heartbleed\c" ; out " (CVE-2014-0160) "
2460
2552
2461
- if [ ! -z " $STARTTLS " ] ; then
2553
+ if [[ -n " $STARTTLS " ]] && [[ $EXPERIMENTAL != " yes " ] ] ; then
2462
2554
outln " (not yet implemented for STARTTLS)"
2463
2555
return 0
2464
2556
fi
@@ -2578,7 +2670,7 @@ ccs_injection(){
2578
2670
[ $VULN_COUNT -le $VULN_THRESHLD ] && outln && pr_blue " --> Testing for CCS injection vulnerability" && outln " \n"
2579
2671
pr_bold " CCS" ; out " (CVE-2014-0224) "
2580
2672
2581
- if [ ! -z " $STARTTLS " ] ; then
2673
+ if [[ -n " $STARTTLS " ]] && [[ $EXPERIMENTAL != " yes " ] ] ; then
2582
2674
outln " (not yet implemented for STARTTLS)"
2583
2675
return 0
2584
2676
fi
@@ -2629,23 +2721,27 @@ ccs_injection(){
2629
2721
2630
2722
fd_socket 5 || return 6
2631
2723
2632
- [[ $DEBUG -ge 2 ]] && out " \nsending client hello, "
2724
+ # we now make a standard handshake ...
2725
+ debugme out " \nsending client hello, "
2633
2726
socksend " $client_hello " 1
2634
2727
sockread 16384
2635
2728
2636
- [[ $DEBUG -ge 2 ]] && outln " \nreading server hello"
2729
+ debugme outln " \nreading server hello"
2637
2730
if [[ $DEBUG -ge 3 ]]; then
2638
2731
echo " $SOCKREPLY " | " ${HEXDUMPVIEW[@]} " | head -20
2639
2732
outln " [...]"
2640
2733
outln " \npayload #1 with TLS version $tls_hexcode :"
2641
2734
fi
2642
2735
2736
+ # ... and then send the a change cipher spec message
2643
2737
socksend " $ccs_message " 1 || ok_ids
2644
2738
sockread 2048 $CCS_MAX_WAITSOCK
2645
2739
if [[ $DEBUG -ge 3 ]]; then
2646
2740
outln " \n1st reply: "
2647
2741
out " $SOCKREPLY " | " ${HEXDUMPVIEW[@]} " | head -20
2648
- # ok: 15 | 0301 | 02 | 02 0a == ALERT | TLS 1.0 | Length=2 | Unexpected Message (0a)
2742
+ # ok: 15 | 0301 | 02 | 02 | 0a
2743
+ # ALERT | TLS 1.0 | Length=2 | Unexpected Message (0a)
2744
+ # or just timed out
2649
2745
outln
2650
2746
outln " payload #2 with TLS version $tls_hexcode :"
2651
2747
fi
@@ -2656,16 +2752,18 @@ ccs_injection(){
2656
2752
2657
2753
if [[ $DEBUG -ge 3 ]]; then
2658
2754
outln " \n2nd reply: "
2659
- out " $SOCKREPLY " | " ${HEXDUMPVIEW[@]} "
2660
- # not ok: 15 | 0301 | 02 | 02 | 15 == ALERT | TLS 1.0 | Length=2 | Decryption failed (21)
2755
+ printf -- " $SOCKREPLY " | " ${HEXDUMPVIEW[@]} "
2756
+ # not ok: 15 | 0301 | 02 | 02 | 15
2757
+ # ALERT | TLS 1.0 | Length=2 | Decryption failed (21)
2661
2758
# ok: 0a or nothing: ==> RST
2662
2759
outln
2663
2760
fi
2664
2761
2665
- reply_sanitized=$( echo " $SOCKREPLY " | " ${HEXDUMPPLAIN[@]} " | sed ' s/^..........//' )
2666
- lines=$( echo " $SOCKREPLY " | " ${HEXDUMP[@]} " | wc -l | sed ' s/ //g' )
2762
+ byte6=$( echo " $SOCKREPLY " | " ${HEXDUMPPLAIN[@]} " | sed ' s/^..........//' )
2763
+ lines=$( echo " $SOCKREPLY " | " ${HEXDUMP[@]} " | count_lines )
2764
+ debugme echo " lines: $lines , byte6: $byte6 "
2667
2765
2668
- if [ " $reply_sanitized " == " 0a" ] || [ " $lines " -gt 1 ] ; then
2766
+ if [ " $byte6 " == " 0a" ] || [ " $lines " -gt 1 ] ; then
2669
2767
pr_green " not vulnerable (OK)"
2670
2768
ret=0
2671
2769
else
@@ -2856,8 +2954,7 @@ Connection: close
2856
2954
2857
2955
EOF
2858
2956
) & > $HEADERFILE_BREACH &
2859
- pid=$!
2860
- if wait_kill $pid $HEADER_MAXSLEEP ; then
2957
+ if wait_kill $! $HEADER_MAXSLEEP ; then
2861
2958
result=$( grep -a ' ^Content-Encoding' $HEADERFILE_BREACH | sed -e ' s/^Content-Encoding//' -e ' s/://' -e ' s/ //g' )
2862
2959
result=$( echo $result | tr -cd ' \40-\176' )
2863
2960
if [ -z $result ]; then
4276
4373
exit $ret
4277
4374
4278
4375
4279
- # $Id: testssl.sh,v 1.301 2015/07/06 18:42:42 dirkw Exp $
4376
+ # $Id: testssl.sh,v 1.304 2015/07/07 20:59:30 dirkw Exp $
0 commit comments