mirror of
				https://github.com/drwetter/testssl.sh.git
				synced 2025-10-31 13:55:25 +01:00 
			
		
		
		
	Redo utils/gmap2testssl.sh
.. mainly copied from testssl.sh. Also it adds a detection for the strings ssl and https. If those run at non-stanadard ports but nmap detected it, it'll show up in the output file. That will be backported to the main program, see #1931 .
This commit is contained in:
		| @@ -1,43 +1,169 @@ | |||||||
| #!/usr/bin/env bash | #!/usr/bin/env bash | ||||||
|  |  | ||||||
| set -e | #set -e | ||||||
|  |  | ||||||
| # utility which converts grepable nmap outout to testssl's file input | # Utility which converts grepable nmap outout to testssl's file input | ||||||
|  | # It is just borrowed from testssl.sh | ||||||
|  | # License see testssl.sh | ||||||
|  |  | ||||||
|  |  | ||||||
|  | echo A | sed -E 's/A//' >/dev/null 2>&1 && \ | ||||||
|  | declare -r HAS_SED_E=true || \ | ||||||
|  | declare -r HAS_SED_E=false | ||||||
|  |  | ||||||
| usage() { | usage() { | ||||||
|      cat << EOF |      cat << EOF | ||||||
|  |  | ||||||
| usage: | usage: | ||||||
|  |  | ||||||
|     "$0 filename<.gmap>":               looks for filename/filename.gmap and converts into basename \$(filename)-testssl.txt" |     "$0  <filename>":               looks for <filename> (nmap gmap format) and converts into basename \$(filename)-testssl.txt" | ||||||
|     "$0 filename<.gmap>" "scan option": same as before, only adds testssl.sh scan option in front of IPs" |  | ||||||
|  |  | ||||||
| EOF | EOF | ||||||
|      exit 0 |      exit 0 | ||||||
| } | } | ||||||
|  |  | ||||||
| [ -z "$1" ] && usage | fatal () { | ||||||
| FNAME="$1" |      echo "$1" >&2 | ||||||
| OPT2ADD="${2:-}" |      exit $2 | ||||||
|  | } | ||||||
|  |  | ||||||
| if ! grep -q gmap <<< "$FNAME"; then | is_ipv4addr() { | ||||||
|      FNAME="$FNAME.gmap" |      local octet="(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])" | ||||||
|  |      local ipv4address="$octet\\.$octet\\.$octet\\.$octet" | ||||||
|  |  | ||||||
|  |      [[ -z "$1" ]] && return 1 | ||||||
|  |  | ||||||
|  |      # Check that $1 contains an IPv4 address and nothing else | ||||||
|  |      [[ "$1" =~ $ipv4address ]] && [[ "$1" == $BASH_REMATCH ]] && \ | ||||||
|  |      return 0 || \ | ||||||
|  |      return 1 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | filter_ip4_address() { | ||||||
|  |      local a | ||||||
|  |  | ||||||
|  |      for a in "$@"; do | ||||||
|  |           if ! is_ipv4addr "$a"; then | ||||||
|  |                continue | ||||||
|           fi |           fi | ||||||
| [ ! -e $FNAME ] && echo "$FNAME not readable" && exit 2 |           if "$HAS_SED_E"; then | ||||||
|  |                sed -E 's/[^[:digit:].]//g' <<< "$a" | sed -e '/^$/d' | ||||||
|  |           else | ||||||
|  |                sed -r 's/[^[:digit:].]//g' <<< "$a" | sed -e '/^$/d' | ||||||
|  |           fi | ||||||
|  |      done | ||||||
|  | } | ||||||
|  |  | ||||||
|  | # arg1: a host name. Returned will be 0-n IPv4 addresses | ||||||
|  | # watch out: $1 can also be a cname! --> all checked | ||||||
|  | get_a_record() { | ||||||
|  |      local ip4="" | ||||||
|  |      local noidnout="" | ||||||
|  |  | ||||||
| TARGET_FNAME=${FNAME%.*}-testssl.txt |      ip4=$(filter_ip4_address $(dig -r +short +timeout=2 +tries=2 -t a "$1" 2>/dev/null | awk '/^[0-9]/ { print $1 }')) | ||||||
|  |      if [[ -z "$ip4" ]]; then | ||||||
|  |           ip4=$(filter_ip4_address $(host -t a "$1" 2>/dev/null | awk '/address/ { print $NF }')) | ||||||
|  |      fi | ||||||
|  |      if [[ -z "$ip4" ]]; then | ||||||
|  |           ip4=$(filter_ip4_address $(drill a "$1" | awk '/ANSWER SECTION/,/AUTHORITY SECTION/ { print $NF }' | awk '/^[0-9]/')) | ||||||
|  |      fi | ||||||
|  |      echo "$ip4" | ||||||
|  | } | ||||||
|  |  | ||||||
| # test whether there's more than one "open" per line | ports2starttls() { | ||||||
|  |      local tcp_port=$1 | ||||||
|  |      local ret=0 | ||||||
|  |  | ||||||
|  |      # https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers | ||||||
|  |      case $tcp_port in | ||||||
|  |           21)       echo "-t ftp " ;; | ||||||
|  |           23)       echo "-t telnet " ;; | ||||||
|  |           119|433)  echo "-t nntp " ;;   # to come | ||||||
|  |           25|587)   echo "-t smtp " ;; | ||||||
|  |           110)      echo "-t pop3 " ;; | ||||||
|  |           143)      echo "-t imap " ;; | ||||||
|  |           389)      echo "-t ldap ";; | ||||||
|  |           3306)     echo "-t mysql " ;; | ||||||
|  |           5222)     echo "-t xmpp " ;;   # domain of jabber server maybe needed | ||||||
|  |           5432)     echo "-t postgres " ;; | ||||||
|  |           563)                ;;  # NNTPS | ||||||
|  |           636)                ;;  # LDAP | ||||||
|  |           1443|8443|443|981)  ;;  # HTTPS | ||||||
|  |           465)                ;;  # HTTPS | SMTP | ||||||
|  |           631)                ;;  # CUPS | ||||||
|  |           853)                ;;  # DNS over TLS | ||||||
|  |           995|993)            ;;  # POP3|IMAP | ||||||
|  |           3389)               ;;  # RDP | ||||||
|  |           *) ret=1            ;;  # we don't know this ports so we rather do not scan it | ||||||
|  |      esac | ||||||
|  |      return $ret | ||||||
|  | } | ||||||
|  |  | ||||||
|  | nmap_to_plain_file () { | ||||||
|  |  | ||||||
|  |      local fname="$1" | ||||||
|  |      local target_fname="" | ||||||
|  |      local oneline="" | ||||||
|  |      local ip hostdontcare round_brackets ports_specs starttls | ||||||
|  |      local tmp port host_spec protocol dontcare dontcare1 | ||||||
|  |  | ||||||
|  |      # Ok, since we are here we are sure to have an nmap file. To avoid questions we make sure it's the right format too | ||||||
|  |      if [[ "$(head -1 "$fname")" =~ ( -oG )(.*) ]] || [[ "$(head -1 "$fname")" =~ ( -oA )(.*) ]] ; then | ||||||
|  |           # yes, greppable | ||||||
|  |           if [[ $(grep -c Status "$fname") -ge 1 ]]; then | ||||||
|  |                [[ $(grep -c  '\/open\/' "$fname")  -eq 0 ]] && \ | ||||||
|  |                fatal "Nmap file $fname should contain at least one open port" 250 | ||||||
|  |           else | ||||||
|  |                fatal "strange, nmap grepable misses \"Status\"" 251 | ||||||
|  |           fi | ||||||
|  |      else | ||||||
|  |           fatal "Nmap file $fname is not in grep(p)able format (-oG filename.g(n)map)" 250 | ||||||
|  |      fi | ||||||
|  |      target_fname="${fname%.*}"-testssl.txt | ||||||
|  |      [[ -e $target_fname ]] && fatal "$target_fname already exists" 3 | ||||||
|  |      > "${target_fname}" || fatal "Cannot create \"${target_fname}\"" 252 | ||||||
|  |  | ||||||
|  |      # Line x:   "Host: AAA.BBB.CCC.DDD (<FQDN>) Status: Up" | ||||||
|  |      # Line x+1: "Host: AAA.BBB.CCC.DDD (<FQDN>) Ports: 443/open/tcp//https///" | ||||||
|  |      # (or):      Host: AAA.BBB.CCC.DDD (<FQDN>) Ports: 22/open/tcp//ssh//<banner>/, 25/open/tcp//smtp//<banner>/, 443/open/tcp//ssl|http//<banner> | ||||||
|  |      while read -r hostdontcare ip round_brackets tmp ports_specs; do | ||||||
|  |           [[ "$ports_specs" =~ "Status: "  ]] && continue             # we don't need this | ||||||
|  |           [[ "$ports_specs" =~ '/open/tcp/' ]] || continue            # no open tcp at all for this IP --> move | ||||||
|  |           host_spec="$ip" | ||||||
|  |           fqdn="${round_brackets/\(/}" | ||||||
|  |           fqdn="${fqdn/\)/}" | ||||||
|  |           if [[ -n "$fqdn" ]]; then | ||||||
|  |                tmp="$(get_a_record "$fqdn")" | ||||||
|  |                if [[ "$tmp" == "$ip" ]]; then | ||||||
|  |                     host_spec="$fqdn" | ||||||
|  |                fi | ||||||
|  |           fi | ||||||
|           while read -r oneline; do |           while read -r oneline; do | ||||||
|      if [ $(echo "${oneline}" | tr ',' '\n' | grep -wc 'open') -gt 1 ]; then |                # 25/open/tcp//smtp//<banner>/, | ||||||
|           # not supported currently |                [[ "$oneline" =~ '/open/tcp/' ]] || continue                # no open tcp for this port on this IP --> move on | ||||||
|           echo "$FNAME contains at least on one line more than 1x\"open\"" |                IFS=/ read -r port dontcare protocol ssl_hint dontcare1 <<< "$oneline" | ||||||
|           exit 3 |                if [[ "$ssl_hint" =~ ^(ssl|https) ]] || [[ "$dontcare1" =~ ^(ssl|https) ]]; then | ||||||
|  |                     echo "${host_spec}:${port}" >>"$target_fname" | ||||||
|  |                else | ||||||
|  |                     starttls="$(ports2starttls $port)" | ||||||
|  |                     [[ $? -eq 1 ]] && continue                                  # nmap got a port but we don't know how to speak to | ||||||
|  |                     echo "${starttls}${host_spec}:${port}" >>"$target_fname" | ||||||
|                fi |                fi | ||||||
| done < "$FNAME" |           done < <(tr ',' '\n' <<< "$ports_specs") | ||||||
|  |      done < "$fname" | ||||||
|  |  | ||||||
|  |      [[ -s "$target_fname" ]] || fatal "Couldn't find any open port in $fname" 253 | ||||||
|  |      echo "$target_fname written successfully" | ||||||
|  |      return 0 | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | [[ -z "$1" ]] && usage | ||||||
|  | FNAME="$1" | ||||||
|  | [[ ! -e $FNAME ]] && echo "$FNAME not readable" && exit 2 | ||||||
|  |  | ||||||
|  | nmap_to_plain_file $FNAME | ||||||
|  |  | ||||||
| awk '/\<open\>/ { print "'"${OPT2ADD}"' " $2":"$5 }' "$FNAME" | sed 's/\/open.*$//g' >"$TARGET_FNAME" |  | ||||||
| exit $? | exit $? | ||||||
|  |  | ||||||
| #  vim:ts=5:sw=5:expandtab | #  vim:ts=5:sw=5:expandtab | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Dirk
					Dirk