nmap
Map live hosts, TCP and UDP ports, service versions and NSE findings with Nmap 7.94SVN, and write evidence files other tools can consume. Use when you need to know what a network or host exposes befor
Files1
View on GitHubSKILL.mdskills/nmap/SKILL.md
GitHubNmap
Nmap answers four separate questions: which hosts are alive, which ports are open, what software listens on them, and what the scripts can prove about that software. Run them as separate phases. One -A invocation mixes all four, multiplies traffic, and produces output nobody can diff.
This host runs 7.94SVN (2023) with 606 NSE scripts in /usr/share/nmap/scripts. The service probe database is old; treat version output as a hint and confirm with a banner grab.
When to use
| Question | Phase | Command shape |
|---|---|---|
| Which hosts are up on a subnet | discovery | nmap -sn -n 10.10.10.0/24 |
| Which of the common ports are open | TCP triage | nmap -Pn -n -sS --top-ports 1000 -T4 host |
| Every TCP port, fast | full TCP | nmap -Pn -n -sS -p- --min-rate 2000 host |
| What version is listening | service detection | nmap -Pn -n -sS -sV -p 22,80,443 host |
| Safe default checks | NSE default | nmap -Pn -n -sC -p 22,80 host |
| Known-weak service checks | NSE vuln | nmap -Pn -n --script vuln -p 445 host |
| UDP services (DNS, SNMP, NTP) | UDP | nmap -Pn -n -sU --top-ports 100 host |
| Machine-readable evidence | output | -oA scans/<name> on every phase |
Do not use Nmap for HTTP path discovery, TLS configuration grading, or SQL injection. It can tell you port 443 is open and which product answers; it cannot tell you what the app does.
Prerequisites
nmap --versionmust print7.94SVN. Root orCAP_NET_RAWis required for-sS,-sU,-Oand raw NSE probes; without it use-sT.-Pnis mandatory on filtered networks: most targets drop ICMP and the discovery phase will otherwise report every host down.-nstops reverse DNS. On a /24 that saves minutes and avoids leaking the target list to the resolver.- This box has 2 vCPU.
--min-rateabove roughly 2000 starts losing responses and inflates falsefilteredstates. - Write output from the first packet:
-oAkeeps normal, XML and grepable forms under one basename.
Core invocations
# 1. host discovery only, no DNS, no port scan
nmap -sn -n 10.10.10.0/24 -oA scans/discovery
# 2. fastest useful TCP picture: 1000 common ports, SYN scan, timing 4
nmap -Pn -n -sS --top-ports 1000 -T4 10.10.10.5 -oA scans/top1000
# 3. all 65535 TCP ports with a fixed packet rate and one retry
nmap -Pn -n -sS -p- --min-rate 2000 --max-retries 1 10.10.10.5 -oA scans/tcp-all
# 4. service and version detection only on ports already known open
nmap -Pn -n -sS -sV -p 22,80,443,8080 10.10.10.5 -oA scans/services
# 5. default NSE scripts plus version, the standard triage pair
nmap -Pn -n -sS -sV -sC -p 22,80,443 10.10.10.5 -oA scans/triage
# 6. raise probe intensity when a version stays "unknown"
nmap -Pn -n -sS -sV --version-intensity 7 -p 8443 10.10.10.5
# 7. NSE by category: safe checks first, then vuln only where warranted
nmap -Pn -n --script "default,safe" -p 21,22,80,443 10.10.10.5
nmap -Pn -n --script vuln -p 445,3389 10.10.10.5
# 8. NSE by name pattern, with arguments
nmap -Pn -n --script "http-title,http-headers,ssl-enum-ciphers" -p 80,443 10.10.10.5
nmap -Pn -n --script "http-brute" --script-args "http-brute.path=/admin" -p 80 10.10.10.5
# 9. selective UDP, low retries, hard host timeout (UDP is slow by nature)
nmap -Pn -n -sU -p 53,67,69,111,123,137,161,500,1900,5353 --max-retries 1 --host-timeout 10m 10.10.10.5
# 10. scan a list, skip hosts you do not own
nmap -Pn -n -sS -iL live.txt --exclude 10.10.10.1,10.10.10.254 -oA scans/batch
# 11. quieter timing for an IDS-sensitive segment
nmap -Pn -n -sS -T2 --max-rate 100 --scan-delay 200ms -p 1-1024 10.10.10.5
# 12. explain state decisions and hide closed ports
nmap -Pn -n -sS --reason --open -p 1-1024 10.10.10.5
# 13. one host, everything, only when the noise is acceptable
nmap -Pn -n -A 10.10.10.5 -oA scans/aggressive
# 14. quick reachability check before a scan campaign
nmap -Pn -n -sS -p 80,443 --reason 10.10.10.5
-oA writes scans/<name>.nmap, .xml and .gnmap. Parse the XML with xmlstarlet or python3, not with regex over the normal output.
Flags that matter
| Flag | Effect | Note |
|---|---|---|
-sn |
discovery only | no ports scanned; works with -PS/-PE probes |
-Pn |
skip discovery, assume up | required behind ICMP filtering |
-n / -R |
never / always resolve DNS | -R is noisy and slow |
-sS |
TCP SYN scan | needs root; half-open, fast, still logged by NDR |
-sT |
TCP connect scan | full handshakes, works unprivileged |
-sU |
UDP scan | slow; pair with --top-ports and --max-retries |
-sV |
service/version probes | --version-intensity 0-9 (default 7) |
-sC |
default NSE set | alias for --script=default |
--script <list> |
categories, files, or patterns | comma-separated; wildcards like http-* work |
--script-args / --script-help |
pass arguments / read script docs | check before running intrusive scripts |
-p / -p- / --top-ports |
port selection | -p- is all 65535 |
--min-rate / --max-rate |
packets per second floor / ceiling | floor is what makes -p- finish |
-T0 to -T5 |
timing template | -T4 for LAN, -T2 near IDS, -T5 unreliable |
--max-retries / --host-timeout |
cap retransmits / give up per host | essential for UDP |
-oA / -oX / -oN / -oG |
all / XML / normal / grepable | -oA for anything you may revisit |
--open / --reason |
hide closed ports / show why | use both in reports |
-O / -A |
OS detection / -sV -sC -O --traceroute |
-A is loud and often wrong on VMs |
-iL / --exclude |
target list / exclusions | keep scope in a file you can audit |
--traceroute |
path discovery | adds packets, useful for segmentation maps |
Workflow
- Discovery.
-sn -nover the in-scope CIDR. Keep the.gnmap; extract live IPs withawk '/Status: Up/{print $2}'. - Top-1000 TCP.
-sS -T4on live hosts only. This is the phase that usually finds the web ports. - Full TCP on hosts that matter.
-p- --min-rate 2000 --max-retries 1; expect a few minutes, not an hour. - Service and version on the open-port list only.
-sV -sCis one pass; do not repeat it per port. - Targeted NSE. Read
--script-helpfor the service you found. Runsafeanddefaulton everything,vulnonly on services you are authorized to poke, and neverbrutewithout a lockout policy. - UDP selectively. Only ports justified by the host role: 53 for DNS, 161 for SNMP, 123 for NTP, 137-139 for legacy Windows.
- Hand off. Feed HTTP(S) URLs to ffuf or feroxbuster, then nuclei. Feed SMB/SSH/WinRM to netexec.
First 15 minutes
mkdir -p scans
nmap -sn -n 10.10.10.0/24 -oA scans/00-discovery
awk '/Status: Up/{print $2}' scans/00-discovery.gnmap > scans/live.txt
nmap -Pn -n -sS -sV -sC --top-ports 1000 -T4 -iL scans/live.txt -oA scans/01-top1000
nmap -Pn -n -sS -p- --min-rate 2000 --max-retries 1 -iL scans/live.txt -oA scans/02-tcp-all
nmap -Pn -n -sU --top-ports 50 --max-retries 1 --host-timeout 10m -iL scans/live.txt -oA scans/03-udp
Read scans/01-top1000.nmap while the full scan runs. Do not launch the UDP phase against a /24; scope it to hosts that showed UDP-dependent services.
OPSEC and telemetry
-sSnever completes a handshake, but every SYN reaches the target's firewall and usually its NDR. Half-open is stealthier than-sT, not invisible.-T4plus-p-is a recognizable burst. Signature and flow sensors alert on exactly this pattern. Use-T2 --max-rate 100when detection matters more than time.-sVsends real probes: HTTP requests, TLS hellos, SMB negotiations. They appear in application logs with Nmap-derived payloads.defaultis mostly safe but not passive.vulnandintrusivescripts can crash old services or leave exploit artifacts;dosscripts are excluded from default scans for a reason.--script vulnruns 105 scripts on this install; each one may send several requests per port. Scope it by port and service.- UDP probes to 161/1900 can look like amplification traffic to upstream filters.
-nprevents DNS leakage.-Rdoes the opposite and is visible to the resolver.- Decoys, fragmentation and
--badsumdo not defeat modern flow analysis and mostly add noise.
Failure modes
| Symptom | Cause | Fix |
|---|---|---|
Every host is down without -Pn |
ICMP and TCP discovery probes filtered | add -Pn |
All 65535 ports filtered in seconds |
egress firewall or host-based drop | --reason, try -sT, test one known port |
| Scan takes hours | low rate and retries on -p- |
--min-rate 2000 --max-retries 1, narrow ports |
Version shows tcpwrapped |
load balancer or IPS closes after connect | -sV --version-intensity 9, or banner grab with nc |
| UDP results all `open | filtered` | no response is the normal UDP answer |
-sS fails with permission error |
not root / no raw socket capability | sudo, or -sT |
| NSE script errors on Lua | incompatible script or missing arg | --script-help <name>, drop that script |
| Output lost after a crash | no file output | always -oA; --append-output for additions |
Verification
nmap --version | head -1 # Nmap version 7.94SVN ( https://nmap.org )
ls /usr/share/nmap/scripts/*.nse | wc -l # 606
nmap --script-help default | sed -n '3,4p' # address-info / Categories: default safe
nmap -Pn -n -sS -p 1 127.0.0.1 # 1/tcp closed tcpmux, no traceback
Keep, per phase: the exact command line, the target list, the start time, and the -oA basename. A port list without a timestamp is not evidence.
Related skills
- ffuf for content and parameter discovery on the HTTP ports found here
- feroxbuster for recursive directory discovery
- nuclei for template-based checks against live services
- sqlmap once a parameter looks injectable
- netexec for SMB, LDAP and WinRM follow-up
- toolchain-router to pick a different tool