Port Enumeration
Port scanning is the method used to identify open ports and services on a network or system. In penetration testing, it helps security professionals detect vulnerabilities, understand the network structure, and pinpoint potential entry points for unauthorized access.
Nmap
Nmap, short for “Network Mapper,” is a powerful open-source tool used for network discovery and security auditing. It’s one of the most popular and widely used network scanning tools in the cybersecurity community. You can find a comprehensive cheat sheet and links to download Nmap.
Port Scanning
The following are some commands I commonly use with the Nmap tool to port scan targets and networks.
sudo nmap -sTCV -O -A 10.1.1.1 -p 1-65535 -oA All_TCP_ports # Performs a TCP connect and default script scan of all ports on a target with output in all formats with advanced scanning techniques enabledsudo nmap -sTCV -A -O -iL IPs.txt -Pn -p- -oX targets.xml # Performs a TCP connect and default script scan of all ports on a list of targets with no ping and advanced scanning techniques enabled and output to XML filesudo nmap -sTCV -A -v -Pn -p- 10.1.1.1 # Performs a TCP connect and default script scan of all ports on a target with no ping enabledPort Sweep
An Nmap port sweep is a technique used to scan a range of IP addresses for specific open ports. This method is useful for identifying which devices on a network are running specific services associated with particular ports.
sudo nmap -p80 10.1.1.1-254 # Performs a ping sweep of port 80 across the specified IP rangesudo nmap -p22 10.1.1.0/24 # Performs a ping sweep of port 22 across the specified CIDR
Masscan
Masscan is known for its speed, making it possible to scan the entire Internet in minutes. It uses asynchronous transmission to achieve high speeds, making it ideal for large-scale scanning operations. You can find Masscan here.
masscan -p1-65535 10.1.1.1 --rate=1000 # Scans all TCP ports on the target IP with a rate of 1000 packets per secondmasscan 10.1.1.1/24 -p80,443,22 --rate 5000 # Scans common ports on a subnetmasscan -iL targets.txt -p1-1000 --rate 10000 # Read target IPs from filemasscan 10.1.1.1/24 -p80 --source-ip 10.1.1.1 # Spoof source IPmasscan 10.1.1.1/24 -p80 --spoof-mac 00:11:22:33:44:55 # Spoof MAC addressHere is a list of common commands I use with Masscan and the most common ports I’ve seen on engagements.
sudo masscan -p 21,22,23,53,80,111,135,445,139,443,389,1521,3306,8080,8081,1433,8200,8500,8999,9000,10000,8443 10.1.1.0/24 --rate 1500sudo masscan 10.1.1.0/22 -p 1-65535 --banners --rate 1000sudo masscan -iL External_IPs.txt -p 1-65535 --rate 500 --http-user-agent "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0"You can use the following script to take in Masscan results and produce an output which can be fed into Nmap:
# This script will take in Masscan results and produce an output which can be fed into NMap# Save your Masscan result as mscan.txt then run this script to produce nmap.txt then you can run:# while read item; do sudo nmap -sV -sA -sU $item; done < nmap.txt
# If you want to export to .xml file you can use the following command and then later use this script to merge files: https://github.com/sidaf/scripts/blob/master/nmap_merge.py# while read item; do filename=$(echo $item | grep -o "^\S*"); sudo nmap -sV -sA -sU -vv $item -oX $filename.xml; done < nmap.txt
import reimport socket
regex = re.compile(r"Discovered open port (\d+)\/(udp|tcp) on (\d+\.\d+\.\d+\.\d+)", re.I)
ip_list = {}
with open('mscan.txt') as f: lines = f.readlines() for line in lines: port = regex.match(line).group(1) protocol = regex.match(line).group(2) ip = regex.match(line).group(3)
# Add the IP to dictionary if it's not already try: ip_list[ip] except KeyError: ip_list[ip] = {}
# Add protocol to dictionary if it's not already try: ip_list[ip][protocol] except KeyError: ip_list[ip][protocol] = []
# Append the port to the list ip_list[ip][protocol].append(port)
with open('nmap.txt', 'a') as f: sorted_ips = sorted(ip_list.items(), key=lambda item: socket.inet_aton(item[0])) for ip, protocols in sorted_ips: udp_ports = "" tcp_ports = ""
# Check to see if any UDP ports were found try: for port in protocols['udp']: udp_ports += port + ',' except KeyError: pass
# Check to see if any TCP ports were found try: for port in protocols['tcp']: tcp_ports += port + ',' except KeyError: pass
# Print IP and ports to file ready for NMap scan if udp_ports and tcp_ports: line = ip + ' -p U:' + udp_ports + 'T:' + tcp_ports elif udp_ports: line = ip + ' -p U:' + udp_ports elif tcp_ports: line = ip + ' -p T:' + tcp_ports f.write(line + '\n')Save your Masscan result as mscan.txt, and then run this script to produce nmap.txt. Then you can run:
while read item; do filename=$(echo $item | grep -o "^\S*"); sudo nmap -sCV -T4 -O --version-light -vv $item -oX $filename.xml; done < ../nmap.txtwhile read item; do filename=$(echo $item | grep -o "^\S*"); sudo nmap -sCV -T4 -O -F --version-light -vv $item -oX $filename.xml; done < nmap.txtScanning the whole internet
You can scan the whole internet for port 80 for example using the following:
sudo masscan -p 80 0.0.0.0/0 --rate 1000000 --exclude 255.255.255.255 > port80.txtOnce you have a list of IP addresses with port 80 open you can run it through a tool like HTTPX to get the title of the web page running on the port.
httpx -l port80.txt -ports 80 -title -no-color > port80_titles.txthttpx -list Web_Ports.txt -p 80,443 -silent -sc -location -title -server -mc 200 -fr
ZMap
ZMap is a free, open-source security scanner developed as a faster alternative to Nmap. ZMap can scan the entire IPv4 address space in 44 minutes on a single port using one gigabit per second of network bandwidth. It can complete a scan in under five minutes with a ten-gigabit connection. You can find the details, as well as installation instructions for Zmap, here.
zmap -p 80 10.1.1.0/24 -o results.csv # Scans port 80 across the specified subnet and outputs the results to a CSV filezmap -p 22,80,443 --target-ip=10.1.1.1 -o output.txt # Scan SSH, HTTP, and HTTPS on a single IPzmap -p 23 -o telnet_scan.txt --rate=1000000 # Scan the whole internet for open Telnet ports
PowerShell Port Scanning
If you are in a Windows environment or only have access to a compromised Windows host, an excellent set of scripts for native Windows PowerShell port scanning is Minimalistic TCP and UDP port scanners, which can be found here.
Import-Module .\port-scan-tcp.ps1port-scan-tcp 10.1.1.1 8080 # Scanning a single IP and Portport-scan-tcp 10.1.1.1 (21,22,23,25,80,443,445,3389) # Scanning a single IP for a list TCP portsport-scan-tcp (gc .\targets.txt) 22 # Scanning a list of IPs in a file for port 221..255 | foreach { port-scan-tcp 10.1.1.$_ 8080} # Scanning a range of IPs for a single PortIf you have no script execution, you can try using the Test-NetConnection cmdlet, which displays diagnostic information for a connection.
80,3601|%{ Test-NetConnection -Port $_ 10.1.1.1 -WA SilentlyContinue} | ?{$_.TCPTestSucceeded -eq $true} | select ComputerName,RemoteAddress,RemotePort # Single IP with a list of ports1..254 | % {"10.1.1.$($_): $(Test-Connection -count 1 -comp 10.1.1.$($_) -quiet)"} # Test if a range of IPs are aliveAnother native PowerShell script you can use to scan for hosts on a network is:
1..254 | ForEach-Object {$ip = "10.1.1.$_"$hostname = [System.Net.Dns]::GetHostEntry($ip).HostNameif ($hostname -ne $null) { Write-Host "IP: $ip, Hostname: $hostname" }}You can also use Test-Connection to perform a PowerShell Ping on a network to test for live hosts and return if they are reachable or not:
$baseIP = "10.1.1."
for ($i = 1; $i -le 254; $i++) { $ip = $baseIP + $i $result = Test-Connection -ComputerName $ip -Count 1 -Quiet if ($result -eq $true) { Write-Host "$ip is reachable" } else { Write-Host "$ip is unreachable" }}The above script can be used to take a file of IPs and write the results to a file:
$file = "IPs.txt"$outputFile = "Ping_Responded.txt"$ips = Get-Content $file
foreach ($ip in $ips) { $result = Test-Connection -ComputerName $ip -Count 1 -Quiet if ($result) { Write-Output "$ip is live" | Out-File -FilePath $outputFile -Append } else { Write-Output "$ip is dead" | Out-File -FilePath $outputFile -Append }}



