Nmap scans that survive real networks
Scan timing, UDP reality checks, and service detection traps on noisy client networks during authorized pentests.
The client said ICMP was blocked. So someone on the team ran nmap -Pn -p- 10.0.0.0/16 from the VPN and wondered why the engagement turned into a firewall ticket by lunch.
That is the gap between cheat sheet commands and operational reality. The nmap cheat sheet is correct. Your scope document and the network's tolerance for noise are what decide which lines you actually run.
Host discovery is not optional thinking
-Pn is a tool for when host discovery lies, not a replacement for reading the scope. If you already have a host list from the client, discovery is mostly validation: are these IPs actually reachable from your position?
A practical first pass on a medium-sized external scope:
nmap -sn -PE -PP -PS443,80,22 --max-retries 2 -T3 -iL scope-hosts.txt -oA discovery
If that returns almost nothing, then you try -Pn on the same list. Not on the whole /16 you inferred from a routing table screenshot.
Timing flags matter more than people admit
-T4 on a residential ISP link is not the same as -T4 on a datacenter VLAN with aggressive IDS. I default to -T3 on client networks and only bump up when I have written approval or I am in an isolated lab.
--min-rate and --max-rate are underrated for keeping scans inside agreed bandwidth. Example for a fragile segment:
nmap -sS -p- --max-rate 500 -T3 -iL fragile-segment.txt -oA tcp-slow
You will finish later. You will also finish the engagement.
When -sV lies to you
Service detection is probabilistic. Nmap guesses from banner shapes and probe responses. You will see http on things that are not HTTP, and tcpwrapped on things that are very much exposed.
Treat -sV output as a hypothesis. Follow with manual checks: curl -k, openssl s_client, or application-layer tools. I run version detection after I have open ports, often on a reduced port list:
nmap -sV -p $(cat open-ports.txt | tr '\n' , | sed 's/,$//') -T3 target.example -oA versions
UDP: pick battles
Full UDP scans are a calendar event. For most internal assessments I hit a short list: 53, 67, 68, 123, 161, 500, 4500, 1900. SNMP on 161/udp has paid off more often than a -sU -p- fantasy.
nmap -sU -p 53,123,161,500 --max-retries 1 -T3 target -oA udp-quick
Expect open|filtered. That is not failure. It is UDP.
Logging and repeatability
-oA basename every time. Name files with date and phase: 20260201-discovery, 20260201-tcp-top1k. Your future self during reporting will not remember which terminal buffer had the good output.
Store the exact command line in your notes, not just the XML. Scope changes, and you will need to explain why port 445 showed up on a host the client thought was decommissioned.
FAQ
Should I always run nmap with -sV on every engagement?
No. Version detection multiplies traffic and fingerprint noise. Use it on confirmed open ports after a lighter pass, or when you need service names for exploit selection. On fragile networks, -sV is often what triggers the angry email from the SOC.
Is -Pn safe to use by default?
It depends on scope. -Pn skips host discovery and treats every target as up, which can mean scanning thousands of IPs that were never meant to be in scope. Use it when ICMP is blocked but you have a tight target list, not as a lazy default.
Why do my UDP scans show nothing useful?
UDP is slow and many services do not reply unless you send the right probe. An open|filtered flood is normal. Pick high-value UDP ports (53, 123, 161, 500) instead of full UDP sweeps unless you have time and client buy-in.
FAQ
- Should I always run nmap with -sV on every engagement?
- No. Version detection multiplies traffic and fingerprint noise. Use it on confirmed open ports after a lighter pass, or when you need service names for exploit selection. On fragile networks, -sV is often what triggers the angry email from the SOC.
- Is -Pn safe to use by default?
- It depends on scope. -Pn skips host discovery and treats every target as up, which can mean scanning thousands of IPs that were never meant to be in scope. Use it when ICMP is blocked but you have a tight target list, not as a lazy default.
- Why do my UDP scans show nothing useful?
- UDP is slow and many services do not reply unless you send the right probe. An open|filtered flood is normal. Pick high-value UDP ports (53, 123, 161, 500) instead of full UDP sweeps unless you have time and client buy-in.