List Nmap Top Ports
Purpose
If you're running a lengthy nmap scan and do not want to enumerate all 65,535 TCP (or UDP) ports. You may opt to use the --top-ports scan option to reduce the duration of the scan. But, you may wonder which ports exactly you may be targeting when you choose a top-ports scan.
Method
Top TCP Ports
# Expands port ranges in ###-### notation to an array
# In addition to other ports in the array
num_ports=100
tcp_ports=( $(nmap -sT --top-ports $num_ports -v -oG - 2>/dev/null | grep TCP | cut -d ';' -f 2 | cut -d ')' -f 1 | tr ',', "\n") )
for port in ${tcp_ports[@]} ; do
if [[ "$port" =~ ^[0-9]+\-[0-9]+$ ]] ; then
start_range=$(echo "$port" | cut -d '-' -f 1)
end_range=$(echo "$port" | cut -d '-' -f 2)
for ((port=start_range; port<=end_range; port++)); do
echo "$port"
done
else
echo "$port"
fi
done
Top UDP Ports
# Expands port ranges in ###-### notation to an array
# In addition to other ports in the array
num_ports=100
udp_ports=( $(sudo nmap -sU --top-ports $num_ports -v -oG - 2>/dev/null | grep UDP | cut -d ';' -f 3 | cut -d ')' -f 1 | tr ',', "\n") )
for port in ${udp_ports[@]} ; do
if [[ "$port" =~ ^[0-9]+\-[0-9]+$ ]] ; then
start_range=$(echo "$port" | cut -d '-' -f 1)
end_range=$(echo "$port" | cut -d '-' -f 2)
for ((port=start_range; port<=end_range; port++)); do
echo "$port"
done
else
echo "$port"
fi
done
This works by passing nothing to stdin causing nmap to scan no hosts, but still return the top ports output. You need sudo privileges for the UDP output due to nmap requiring root to create UDP packets.
If you want to turn it into a function you can put in your shell .rc file, then see below
list_nmap_top_ports()
function list_nmap_top_ports() {
proto=$1
num_ports=$2
usage="Usage: list_nmap_top_ports: <UDP/TCP> <1-65535>"
if ! [ $# -eq 2 ] ; then
echo "$usage"
return
elif ! [[ "$proto" == "tcp" || "$proto" == "udp" || "$proto" == "TCP" || "$proto" == "UDP" ]] ; then
echo "$usage"
return
elif ! [[ "$num_ports" -ge 1 && "$num_ports" -le 65535 ]] ; then
echo "$usage"
return
else
if [[ "$proto" == "tcp" || "$proto" == "TCP" ]] ; then
tcp_ports=( $(nmap -sT --top-ports $num_ports -v -oG - 2>/dev/null | grep TCP | cut -d ';' -f 2 | cut -d ')' -f 1 | tr ',', "\n") )
for port in ${tcp_ports[@]} ; do
if [[ "$port" =~ ^[0-9]+\-[0-9]+$ ]] ; then
start_range=$(echo "$port" | cut -d '-' -f 1)
end_range=$(echo "$port" | cut -d '-' -f 2)
for ((port=start_range; port<=end_range; port++)); do
echo "$port"
done
else
echo "$port"
fi
done
else
udp_ports=( $(sudo nmap -sU --top-ports $num_ports -v -oG - 2>/dev/null | grep UDP | cut -d ';' -f 3 | cut -d ')' -f 1 | tr ',', "\n") )
for port in ${udp_ports[@]} ; do
if [[ "$port" =~ ^[0-9]+\-[0-9]+$ ]] ; then
start_range=$(echo "$port" | cut -d '-' -f 1)
end_range=$(echo "$port" | cut -d '-' -f 2)
for ((port=start_range; port<=end_range; port++)); do
echo "$port"
done
else
echo "$port"
fi
done
fi
fi
}
