Back to All Modules

Port Scanning with Nmap & Alternatives

#Overview

Port scanning is the foundational enumeration technique used to discover open TCP and UDP ports, identify running services, fingerprint operating systems, and detect service versions. Nmap is the industry-standard tool, complemented by faster alternatives like Masscan and RustScan for initial discovery. This technique covers scan recipes from quick initial sweeps through exhaustive full-port scans, NSE script usage, output parsing, and operational security considerations.

#Prerequisites

  • Tools: nmap, masscan, rustscan, xsltproc (for HTML reports)
  • Access Level: Network connectivity to target (same subnet or routable path)
  • Recommended: sudo/root access for SYN scans (-sS), UDP scans (-sU), and OS detection (-O)

#Detection & Enumeration

#Quick Initial Scan (First Pass)

Start with a fast SYN scan of the top 1000 ports to quickly identify obvious services:

# Quick TCP scan (top 1000 ports, SYN stealth)
sudo nmap -sS -T4 --min-rate=1000 -Pn 10.10.10.161

# Even faster: top 100 ports only
sudo nmap -sS -T4 -F 10.10.10.161

# Quick scan with version detection on discovered ports
sudo nmap -sS -sV -T4 -F 10.10.10.161
BASH

Flag Explanations:

  • -sS : SYN stealth scan (half-open TCP, never completes handshake). Requires root.
  • -T4 : Timing template 4 (aggressive). Faster but noisier. Range is T0 (paranoid) through T5 (insane).
  • --min-rate=1000 : Send at least 1000 packets/sec. Prevents nmap from being too slow on responsive hosts.
  • -Pn : Skip host discovery (ping). Treat all hosts as up. Use when ICMP is filtered.
  • -F : Fast mode (top 100 ports instead of top 1000).
  • -sV : Probe open ports to determine service/version info.

#Comprehensive Full-Port TCP Scan

The standard pattern used across nearly every HTB walkthrough:

# Phase 1: Discover all open TCP ports quickly
ports=$(nmap -p- --min-rate=1000 -T4 10.10.10.161 | grep '^[0-9]' | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)

# Phase 2: Deep scan only the open ports
nmap -p$ports -sC -sV 10.10.10.161
BASH

Flag Explanations:

  • -p- : Scan all 65535 TCP ports.
  • grep '^[0-9]' : Filter to lines starting with digits (port numbers).
  • cut -d '/' -f 1 : Extract just the port number from "PORT/STATE" lines.
  • tr '\n' ',' : Replace newlines with commas to create comma-separated port list.
  • sed s/,$// : Remove trailing comma.
  • -sC : Run default NSE scripts (equivalent to --script=default). Safe, useful collection.
  • -sV : Version detection. Probes open ports to identify service name and version number.

#One-Liner Combined Scan

nmap -p- --min-rate=1000 -sC -sV -T4 -Pn -oA full_scan 10.10.10.161
BASH

Flag Explanations:

  • -oA full_scan : Output in all three formats (.nmap normal, .gnmap grepable, .xml XML).

#UDP Scanning

UDP scanning is slow because UDP is connectionless and responses may not come. Always do UDP after TCP.

# Top 100 UDP ports (common services)
sudo nmap -sU -T4 --top-ports 100 -Pn 10.10.10.161

# Full UDP scan (can take hours - use with caution)
sudo nmap -sU -p- --min-rate=500 -T4 -Pn 10.10.10.161

# UDP with service detection on specific port
sudo nmap -sU -sV -p 161,500,4500 10.10.10.161
BASH

Flag Explanations:

  • -sU : UDP scan. Always requires root.
  • --top-ports 100 : Scan the 100 most common ports instead of all ports.
  • UDP scan speeds are inherently slower than TCP; expect 10-100x longer.

#Alternative Scanners

Masscan (Fastest Initial Discovery)

# Scan all TCP ports at high speed
sudo masscan -p1-65535 --rate=10000 10.10.10.161 -e tun0

# Scan specific ports, output to file
sudo masscan -p80,443,8080,8443 --rate=5000 10.10.10.0/24 -oJ masscan_output.json
BASH

Key Differences from Nmap:

  • Masscan is designed for Internet-scale scanning. Can scan the entire IPv4 space.
  • --rate controls packets per second. Higher = faster but packet loss increases.
  • Does NOT do service/version detection. Use for port discovery, feed results to nmap.
  • SYN scanning only. No TCP connect scan mode.

RustScan (Fast with Nmap Integration)

# Default scan (top 1000 ports, then feeds to nmap)
rustscan -a 10.10.10.161

# Custom port range with nmap args
rustscan -a 10.10.10.161 -p 1-65535 -- -sC -sV

# Ultra fast with batch size tuning
rustscan -a 10.10.10.161 --range 1-65535 -b 5000 -- -A
BASH

Key Features:

  • Scans all 65535 ports in ~3 seconds using adaptive batch sizing.
  • Automatically pipes discovered ports to nmap for service detection.
  • -b : Batch size (number of ports to scan simultaneously).

#OS Detection

# Full OS detection (requires at least one open and one closed TCP port)
sudo nmap -O 10.10.10.161

# Aggressive OS detection (combines -O, -sC, -sV, --traceroute)
sudo nmap -A 10.10.10.161

# OS detection with specific port requirements met
sudo nmap -O --osscan-guess 10.10.10.161
BASH

#Common NSE Script Categories

# Default scripts (safe, informative)
nmap -sC 10.10.10.161

# All scripts in a category
nmap --script=discovery 10.10.10.161
nmap --script=vuln 10.10.10.161
nmap --script=safe 10.10.10.161

# Multiple specific scripts
nmap --script=smb-os-discovery,smb-enum-shares,http-title,ssl-cert 10.10.10.161

# Vulnerability scanning (can be noisy/intrusive)
nmap --script=vuln -p- 10.10.10.161
BASH

Most Useful NSE Scripts for Pentesting:

ScriptPurposePorts
smb-os-discoveryOS, computer name, domain, FQDN via SMB445
http-titleHTML title from web servers80,443,8080
ssl-certExtract SSL certificate details (CN, SANs, expiry)443,8443
http-enumDirectory enumeration via NSE80,443
ftp-anonCheck for anonymous FTP access21
ldap-rootdseLDAP root DSE information389,3268
rdp-ntlm-infoNTLM info from RDP3389
dns-zone-transferAttempt DNS zone transfer53
snmp-infoSNMP system information extraction161
bannerSimple banner grab across all open portsany

#Output Formats and Parsing

# All output formats at once
nmap -p- -oA scan_results 10.10.10.161

# Grepable output for quick parsing
nmap -p- -oG scan.gnmap 10.10.10.161
grep "open" scan.gnmap | cut -d " " -f 2,5-

# Extract open ports from grepable output
grep -oP '\d+/open' scan.gnmap | cut -d '/' -f 1 | sort -n | uniq

# Generate HTML report from XML
xsltproc scan_results.xml -o scan_report.html

# Extract IP and open ports in concise format
cat scan.gnmap | grep "open" | awk '{print $2, $5}' | sed 's/Ports://'
BASH

#Execution

#Standard Two-Phase Workflow (Most Common)

This is the pattern used in virtually every HTB walkthrough:

# Step 1: Quick full-port discovery
ports=$(nmap -p- --min-rate=1000 -T4 10.10.10.161 | grep '^[0-9]' | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)

# Step 2: Targeted deep scan with scripts and version detection
nmap -p$ports -sC -sV -oA targeted_scan 10.10.10.161
BASH

#Firewall Evasion Scenarios

# Fragment packets (bypass simple firewalls)
sudo nmap -f 10.10.10.161

# Custom MTU (fragment to specific size, must be multiple of 8)
sudo nmap --mtu 24 10.10.10.161

# Decoy scan (mix traffic with decoy IPs - ethical engagements only)
sudo nmap -D RND:5 10.10.10.161

# Source port spoofing (common bypass: port 53 DNS, 80 HTTP)
sudo nmap --source-port 53 10.10.10.161

# Idle scan (stealthy, uses zombie host - needs a host with predictable IP ID)
sudo nmap -sI zombie_host 10.10.10.161

# Connect scan (no root required, completes TCP handshake - very noisy)
nmap -sT 10.10.10.161
BASH

#Scan Timing Templates Reference

TemplateNameMin DelayMax DelayUse Case
T0Paranoid5 min--IDS evasion, extreme stealth
T1Sneaky15 sec--IDS evasion
T2Polite0.4 sec--Slower, less bandwidth used
T3Normal----Default, balanced
T4Aggressive--1.25 secFast LAN/internal scans
T5Insane--0.3 secFastest, may miss ports, very noisy

#Scanning All Hosts in a Subnet

# Ping sweep to find live hosts
nmap -sn 10.10.10.0/24

# Full port scan on a /24 subnet (use with care)
nmap -p 22,80,443,445,3389 10.10.10.0/24 -oA subnet_common

# From a file of targets
nmap -p- -iL targets.txt -oA full_scans
BASH

#Key NSE Vulnerability Scripts

ScriptPortPurpose
--script smb-vuln-ms17-010445EternalBlue check
--script smb-vuln-cve2009-3103445Samba vulnerability
--script ssl-heartbleed443Heartbleed check
--script ssl-poodle443POODLE check
--script ssl-ccs-injection443CCS injection check
--script http-vuln*80,443All HTTP vulnerability scripts
--script rdp-vuln-ms12-0203389BlueKeep check
--script dns-brute53DNS subdomain brute-force
--script redis-info6379Redis server info
--script ldap-rootdse389LDAP root DSE info
--script ms-sql-info1433MSSQL server info
--script dns-zone-transfer53DNS zone transfer attempt
--script vulscan/vulscan.nseAnyOS/Service version to CVE mapping

Usage: nmap --script <script-name> -p <port> <target>

#Additional Nmap Features

# Update NSE scripts (important for new CVE coverage)
nmap --script-updatedb

# Version intensity (control how aggressive service detection is)
nmap -sV --version-intensity 5 <target>   # 0=all, 9=only most reliable, 7=default
# Lower intensity = faster but less accurate service detection

# Pass arguments to NSE scripts
nmap --script smb-vuln-ms17-010 --script-args smbusername=user,smbpassword=pass -p 445 <target>
nmap --script http-enum --script-args http.useragent="Mozilla/5.0" -p 80 <target>
BASH

#Common Pitfalls

  • Skipping host discovery when ICMP is blocked. Use -Pn to skip ping check and treat host as up.
  • UDP scans timing out. UDP scans are inherently slow. Start with --top-ports 100 for UDP, and increase timeouts with --host-timeout.
  • Missing ports due to high packet loss at high rates. If -T5 or high --min-rate causes drops, reduce to -T4 or even -T3.
  • Forgetting that -sC is NOT a full vulnerability scan. It runs only "default" scripts. Use --script vuln for vulnerability checks (noisier).
  • Assuming a closed port means the service is absent. Firewall rules may drop or reject packets. A "filtered" state is ambiguous.
  • Running -A on production without authorization. -A includes traceroute, OS detection, script scanning, and version detection -- very intrusive.
  • Forgetting to add discovered domain names to /etc/hosts. Many services (Kerberos, IIS virtual hosts, SMB) require proper name resolution.
  • Using -sT (TCP connect scan) when you have root. It is slower, completes the TCP handshake (creating full log entries), and offers no advantage over -sS.

#OPSEC Considerations

  • SYN scans (-sS) generate connection attempts to every port scanned. Rate and port count determine noise level. A full 65535-port scan will generate log entries on every open (and many closed) ports.
  • Default scripts (-sC) may trigger IDS/IPS signatures. For example, http-sql-injection and similar intrusive scripts in the default set can trigger WAF alerts.
  • Version detection (-sV) sends probes that some services log. Database servers, SSH, and HTTP servers may log version probes as suspicious activity.
  • Nmap sends TCP SYN packets by default. These are logged by most firewalls and HIDS. Each SYN to an unfiltered closed port triggers a RST; each to an open port triggers a SYN-ACK. Firewalls may log every connection attempt.
  • T4 timing is the standard in HTB/CTF environments but is noticeably aggressive on production networks. T3 or lower is recommended for stealth.
  • OS detection (-O) sends unusual packet sequences that are easily flagged by NIDS/NIPS systems.
  • UDP scans generate ICMP "port unreachable" responses which are logged by host-based firewalls and kernel audit systems.
  • Consider timing your scans during business hours if blending in with normal traffic is possible. Off-hours scanning may stand out more.
  • Nmap's default User-Agent and probe patterns are well-known and signatured by most security products. Customizing --script-args can help but does not fully anonymize.
  • Using --source-port 53 or --source-port 80 may bypass poorly configured firewall rules but is still logged.
  • Masscan and RustScan are even noisier than Nmap due to their ultra-high packet rates. They should only be used on internal assessments or with explicit authorization.
  • Scan results (especially XML/GNMAP outputs) contain sensitive network topology info. Encrypt or delete after reporting.
  • OPSEC: -sC default scripts are "safe" category but some (http-sql-injection) are intrusive. T4/T5 timing templates create distinctive packet patterns fingerprinted by modern IDS. SYN scan (-sS) completion triggers kernel connection state logging on some systems. --script vuln is very noisy -- runs dozens of exploit checks, triggers IDS/WAF alerts.

#Post-Exploitation Value

Port scanning provides the complete network surface map that guides all subsequent enumeration. Without a thorough port scan:

  • Hidden services (high ports, UDP services) remain undiscovered.
  • Service versions cannot be correlated with known vulnerabilities.
  • The attack surface remains incompletely understood, increasing the chance of missing the intended exploitation path.

After obtaining a foothold, internal port scanning from the compromised host reveals services not exposed externally (e.g., MySQL on 127.0.0.1:3306, internal web apps on 8080, Redis on 6379).

#Cross-References

#Common Port/Service Reference Table

PortProtocolServiceEnumeration Focus
21TCPFTPAnonymous login, file download, version exploits
22TCPSSHBanner, auth methods, user enumeration, weak keys
23TCPTelnetDefault credentials, cleartext capture
25TCPSMTPUser enumeration (VRFY/EXPN/RCPT TO)
53TCP/UDPDNSZone transfer, subdomain enumeration, DNSSEC
80TCPHTTPWeb enumeration, directory brute-force, CMS fingerprinting
88TCP/UDPKerberosAS-REP roasting, user enumeration, SPN discovery
110TCPPOP3Credential capture, version exploits
111TCP/UDPRPC (Portmapper)RPC service enumeration
135TCPMSRPCDCOM, RPC endpoint enumeration
139TCPNetBIOS-SSNNetBIOS name service, shares
143TCPIMAPCredential capture, version exploits
161UDPSNMPCommunity string brute-force, MIB enumeration
389TCP/UDPLDAPAnonymous bind, user/group enumeration, domain info
443TCPHTTPSSame as HTTP + SSL/TLS certificate inspection
445TCPSMB (Direct)Share enumeration, null sessions, version detection
464TCP/UDPkpasswd5Kerberos password change
514UDPSyslogLog capture, sensitive data
636TCPLDAPSSame as LDAP, encrypted
873TCPRsyncModule enumeration, anonymous access
993TCPIMAPSSame as IMAP, encrypted
995TCPPOP3SSame as POP3, encrypted
1433TCPMSSQLVersion, default credentials, xp_cmdshell
1521TCPOracle TNSSID enumeration, version, default credentials
2049TCPNFSExport enumeration, mount access
2375TCPDocker (unencrypted)Container enumeration, API access
3000TCPVarious dev serversWeb app frameworks (Node, Rails, React dev)
3128TCPSquid ProxyOpen proxy detection
3268TCPGlobal Catalog LDAPSame as LDAP, forest-wide
3269TCPGlobal Catalog LDAPSSame as LDAPS, forest-wide
3306TCPMySQL/MariaDBVersion, default credentials, database enumeration
3389TCPRDPNLA status, NTLM info leak, BlueKeep (CVE-2019-0708)
4444TCPMeterpreter (common)Often used by Metasploit payloads
5432TCPPostgreSQLVersion, default credentials, database enumeration
5555TCPAndroid Debug BridgeUnauthenticated access
5900-5903TCPVNCAuthentication bypass, weak passwords
5985TCPWinRM (HTTP)PowerShell Remoting enumeration
5986TCPWinRM (HTTPS)Same, encrypted
6379TCPRedisUnauthenticated access, data dump, RCE via modules
8080TCPHTTP-Proxy/AltWeb enumeration, often Tomcat/Jenkins/dev servers
8443TCPHTTPS-AltSame as HTTPS, often admin panels
8888TCPVariousJupyter, dev servers
9091TCPVariousWebSocket services, admin panels
9389TCPADWSActive Directory Web Services
27017TCPMongoDBUnauthenticated access, database enumeration
47001TCPWinRM (HTTP alt)PowerShell Remoting

#Tool References

ToolDescriptionLink
NmapIndustry-standard port scannerhttps://nmap.org/
MasscanMass IP/port scanner (Internet-scale)https://github.com/robertdavidgraham/masscan
RustScanFast port scanner with nmap integrationhttps://github.com/RustScan/RustScan
xsltprocXML-to-HTML report generationBuilt into most Linux distros
ZenmapGUI for Nmaphttps://nmap.org/zenmap/
AutoReconAutomated multi-threaded enumerationhttps://github.com/Tib3rius/AutoRecon

#Source Machines

  • Forest (Easy, AD) -- Standard two-phase nmap with LDAP/SMB follow-up
  • Sauna (Easy, AD) -- Two-phase scan, port discovery leading to LDAP/Web/SMB enumeration
  • Cascade (Medium, AD) -- Full port scan with -Pn flag
  • BoardLight (Easy, Linux) -- Standard nmap with -Pn, discovered SSH+Apache
  • Broker (Easy, Linux) -- Nmap reveals ActiveMQ on port 61616
  • Authority (Medium, AD/Windows) -- Full-port scan revealing PWM on 8443
  • Manager (Medium, AD/Windows) -- Version scan discovers MSSQL 2019 on 1433
  • Soccer (Easy, Linux) -- Port 9091 unknown service discovered via full scan
  • Support (Easy, Windows) -- nmap -sC -sV -Pn reveals DC ports, LDAP, SMB, WinRM