Discovering open ports

Nmap, the Network Mapper, what we would do without you. Tool first developed by Gordon Lyon aka Fyodor Vaskovich, became a go-to tool for system administrators and aspiring hackers wishing to finally map the network and bring out more information from the targeted hosts, specifically open ports.

One of its best features is the adaptability that allows the output (or input) to be parsed to/from different scanning tools. Although Nmap is a godsend to cyber-security community, it is not perfect. Full scans (all 65535 TCP ports) can take a long time to complete, not to mention UDP (65535 as well) port scanning which can feel like it is taking forever.

One way to work around those issues is to use a "fast" network scanner alternative, such as Unicornscan or Masscan to discover all open ports (TCP and UDP) and parse discovered ports to Nmap for a finer analysis.

I put together a simple bash script that can accomplish just that:

#!/bin/bash
#Here we define pretty colors
RESTORE='\033[0m'
RED='\033[00;31m'
GREEN='\033[00;32m'
YELLOW='\033[00;33m'
BLUE='\033[00;34m'
PURPLE='\033[00;35m'
CYAN='\033[00;36m'
LIGHTGRAY='\033[00;37m'
LRED='\033[01;31m'
LGREEN='\033[01;32m'
LYELLOW='\033[01;33m'
LBLUE='\033[01;34m'
LPURPLE='\033[01;35m'
LCYAN='\033[01;36m'
WHITE='\033[01;37m'
OKBLUE='\033[94m'
OKRED='\033[91m'
OKGREEN='\033[92m'
OKORANGE='\033[93m'
RESET='\e[0m'
echo -e "${LGREEN}"
echo "╔════════════════════════════════════════════════════════════════╗"
echo "║ Enter domain of your Target Below example site.com ║"
echo "╚════════════════════════════════════════════════════════════════╝"
echo -e "${RESTORE}"
read TARGET
#Translating URL to IP if neccessary
nmap -n -Pn -sn -PA $TARGET | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" > targets.txt
echo -e "${LGREEN}"
echo "╔════════════════════════════════════════════════════════════════╗"
echo "║ Select your scanning interface ║"
echo "╚════════════════════════════════════════════════════════════════╝"
echo -e "${RESTORE}"
echo -ne "Your VLAN IP is wlan0: "; ip -o -4 addr show dev wlan0 | sed 's/.* inet \([^/]*\).*/\1/'
echo -ne "Your VPN local IP is tun0: "; ip -o -4 addr show dev tun0 | sed 's/.* inet \([^/]*\).*/\1/'
echo -ne "Your HTB IP is tun1: "; ip -o -4 addr show dev tun1 | sed 's/.* inet \([^/]*\).*/\1/'
echo -e "${LYELLOW}"
echo "Please, select a network interface for scanning:"
echo -e "${RESTORE}"
read interface
echo ""
echo -e "${OKGREEN}====================================================================================${RESET}"
echo -e "$OKRED RUNNING MASSCAN ON THE TARGET HOST $RESET"
echo -e "${OKGREEN}====================================================================================${RESET}"
#Define TARGET as IP keep the URL just in case we need it later
TARGET=$(cat ./targets.txt)
echo $TARGET > url.txt
URL=$(cat ./url.txt)
echo -e "${LYELLOW}"
echo "[+] Discovering TCP ports..."
echo -e "${RESTORE}"
#Discover open TCP ports using masscan
masscan -e $interface --open --source-port 60000 -p1-65535 --max-rate 2000 $TARGET | tee ./masscan-output-tcp.txt
echo -e "${LYELLOW}"
echo "[+] Discovering UDP ports..."
echo -e "${RESTORE}"
#Discover open UDP ports using masscan
masscan -e $interface --open --source-port 60000 -pU:1-65535 --max-rate 2000 $TARGET | tee ./masscan-output-udp.txt
echo -e "${LYELLOW}"
echo "[+] Ports discovery has finished, parsing open ports to nmap..."
echo -e "${RESTORE}"
sleep 2
#Define TCP ports for NMAP
TCPPORTS=$(cat masscan-output-tcp.txt | awk '/open/ { print $4 }' | rev | cut -f1 -d: | rev | grep -Eo '[0-9]{1,5}' | tr , "\n" | sort | tr "\n" , | sed 's/.$//')
#Define UDP ports for NMAP
UDPPORTS=$(cat masscan-output-udp.txt | awk '/open/ { print $4 }' | rev | cut -f1 -d: | rev | grep -Eo '[0-9]{1,5}' | tr , "\n" | sort | tr "\n" , | sed 's/.$//')
echo -e "${OKGREEN}====================================================================================${RESET}"
echo -e "$OKRED RUNNING NMAP TCP PORT ANALYSIS $RESET"
echo -e "${OKGREEN}====================================================================================${RESET}"
#If no UDP ports are found, move on to TCP Scan
if cat ./masscan-output-udp.txt | [ -s masscan-output-udp.txt ];
then
echo -e "${LYELLOW}"
echo "[+] Running UDP and TCP port scan"
echo -e "${RESTORE}"
nmap -sV -sT -sU -O --max-rate 15000 -Pn -T4 -n -p U:$UDPPORTS,T:$TCPPORTS -oX ./nmap-$URL.xml $URL;
#Start TCP scan
else
echo -e "${LYELLOW}"
echo "[+] Running only TCP port scan"
echo -e "${RESTORE}"
nmap -sV -sT -O --max-rate 15000 -Pn -T4 -n -p $TCPPORTS -oX ./nmap-$URL.xml $URL;
fi

It is VERY FEASIBLE to execute a Denial of Service against the target networks, even when launching from a single source. You should start with a very low masscan max-rate (5,000-10,000 kpps) and increase slowly to test. On bare metal, pushing beyond 20,000 seems to increase the chances of missing responses from the target. 40,000 kpps has been known to DoS ESXi virtual switches (even on the source). ~200,000 is often enough to take out ISP equipment. - johnnyxmas

Here, I played it safe and have set masscan pps (packets per second) to "just" 2000. Output of the bash script:

Script needs to run as root, both nmap and masscan require that.

First this script is going to ask a user to provide a target, either single IP or URL. Next, an interface (wlan0, tun0 or tun1) needs to be specified for a Masscan scanner to use.

Script taking open UDP and TCP ports and parsing them to Nmap.

Once variables are set Masscan will scan all TCP and UDP ports and save them to a file : masscan-output-tcp.txt and masscan-output-udp.txt . Discovered TCPPORTS and UDPPORTS are taken from this file and parsed to be analysed by Nmap. Here, the script is going to recognize if any open UDP ports were discovered at all and decide whether to start Nmap UDP scan as well or just stick to TCP one.

The whole scan took around 10 minutes and Nmap output can be parsed further to other scanning tools to automate the process and save time. The reasoning behind translating URL to IP is that Masscan cannot start with URL specified, it needs an IP.

There are drawbacks to using Masscan though. Because of its speed, it can sometimes miss a port here and there, therefore in an engagement that requires 100% accuracy slower Nmap scan is still the king.

Have fun!