References¶
- https://nmap.org/nsedoc/scripts/dhcp-discover.html
man nmap,nmap --script-help allfor the full NSE catalog
1. Scan types — what's actually happening on the wire¶
| Flag | Scan | Mechanism | Needs root? |
|---|---|---|---|
-sS |
TCP SYN scan ("half-open") | sends SYN, reads SYN/ACK or RST, never completes handshake | yes |
-sT |
TCP connect scan | full 3-way handshake via the OS socket API | no |
-sU |
UDP scan | sends UDP probe, absence of ICMP unreachable ⇒ open | filtered |
-sA |
ACK scan | maps firewall rulesets (stateless firewalls only) | yes |
-sN/-sF/-sX |
Null/FIN/Xmas scans | abuse RFC-compliant TCP stacks to slip past simple packet filters | yes |
-sP / -sn |
Ping/host-discovery only, no port scan | ARP (local) or ICMP/TCP probes (remote) | no (varies) |
-sV |
Version detection | grabs banners / sends protocol probes against open ports | no |
-O |
OS fingerprinting | analyzes TCP/IP stack quirks (window size, TTL, options ordering) | yes |
-sS is nmap's default when run as root because it's fast and doesn't complete connections (less logging on the target, lower overhead at scale). Without root, nmap silently falls back to -sT.
2. Your notes, expanded¶
Scan a subnet for an open port¶
nmap -p22 --open 192.168.0.0/24
--open suppresses closed/filtered hosts from the output — essential on a /24 or you'll drown in noise. Add -T4 for faster timing on a LAN, and --min-rate 500 to force a floor on packets/sec if nmap's adaptive timing is being too conservative:
nmap -p22 --open -T4 --min-rate 500 192.168.0.0/24
DHCP server discovery without taking an IP¶
nmap -sU -p 67 --script=dhcp-discover 192.168.0.1
PORT STATE SERVICE
67/udp open dhcps
| dhcp-discover:
| DHCP Message Type: DHCPACK
| Server Identifier: 192.168.0.1
| Subnet Mask: 255.255.255.0
| Broadcast Address: 192.168.0.255
| Domain Name Server: 192.168.0.1, 192.168.0.1
|_ Router: 192.168.0.1
This is an NSE (Nmap Scripting Engine) script — it crafts a real DHCPDISCOVER, parses the DHCPOFFER/ACK, and reports the lease parameters without actually completing a lease (no IP is consumed/bound). Genuinely useful for finding rogue DHCP servers on a network — run it broadcast-style against the whole subnet:
nmap -sU -p 67 --script=dhcp-discover 192.168.0.255 # broadcast address — surfaces every DHCP server that answers
Host discovery (subnet sweep)¶
nmap -sP 192.168.13.0/24
Note: -sP is deprecated in modern nmap in favor of -sn (same behavior, "no port scan"). On a local subnet this uses ARP requests, not ICMP, so it works even against hosts that firewall off ping.
UDP version scan¶
nmap -sUV <host>
UDP scanning is inherently slow and unreliable (no handshake, and many stacks rate-limit the ICMP "port unreachable" responses nmap relies on to infer closed ports) — expect this to take much longer than an equivalent TCP scan, and expect a lot of open|filtered results that need manual verification (see §4).
Service/version detection¶
nmap -sV home.andrewmercer.net
-sV sends nmap's probe database against each open port and pattern-matches the response — this is how it distinguishes "OpenSSH 8.9" from "some other thing on port 22." Bump intensity if it's not confident:
nmap -sV --version-intensity 9 home.andrewmercer.net # 0 (light) - 9 (try everything)
OS fingerprinting¶
nmap -O <host>
Needs at least one open and one closed/filtered TCP port on the target to fingerprint reliably; combine with -sV for nmap's overall best-guess ("OS and Service detection performed"):
nmap -A <host> # equivalent to -sV -O --script=default --traceroute, nmap's "give me everything" flag
Logging — all formats at once¶
nmap -sP 192.168.13.0/24 -oA network-192.168.13
Produces network-192.168.13.nmap (human-readable), .gnmap (grep-friendly, one host per line — great for grep/awk pipelines), and .xml (machine-readable, feeds into other tools). If you only need one:
nmap ... -oN scan.nmap # normal
nmap ... -oG scan.gnmap # grepable
nmap ... -oX scan.xml # XML
Turn XML into an HTML report with the bundled XSL stylesheet:
xsltproc scan.xml -o scan.html
Reason codes¶
nmap -sV --reason 23.233.1.230
PORT STATE SERVICE REASON VERSION
135/tcp filtered msrpc no-response
9999/tcp open ssh syn-ack OpenSSH 6.6.1 (protocol 2.0)
--reason shows why nmap classified a port the way it did — no-response (filtered, likely a firewall dropping silently), conn-refused (closed, RST received), syn-ack (open). This is the difference between "the port is closed" and "something is silently eating my probes" — worth turning on by default when triaging a firewall.
3. Advanced techniques not in your notes¶
Timing templates (speed vs. stealth)¶
nmap -T0 # paranoid — 5min between probes, IDS evasion
nmap -T1 # sneaky
nmap -T2 # polite — reduces load on the target/network
nmap -T3 # normal (default)
nmap -T4 # aggressive — assumes a reliable fast network, good for internal LANs/homelab
nmap -T5 # insane — fastest, sacrifices accuracy
Firewall/IDS evasion¶
nmap -f <host> # fragment packets
nmap -D RND:10 <host> # decoy scan — spoof 10 random source IPs alongside yours
nmap --source-port 53 <host> # spoof source port (some firewalls trust traffic "from" DNS)
nmap -sA <host> # ACK scan to map stateless firewall rules
Full-range / specific port sets¶
nmap -p- <host> # all 65535 ports
nmap -p 1-1024,8080,8443 <host> # custom ranges + individual ports
nmap -F <host> # nmap-services "fast" list (~100 most common ports)
--top-ports 20 # just the N most common ports
NSE — the real power of nmap¶
The scripting engine (--script) is where nmap goes from "port scanner" to "vulnerability/recon framework." Categories: auth, broadcast, brute, default, discovery, dos, exploit, external, fuzzer, intrusive, malware, safe, version, vuln.
nmap --script=default <host> # the scripts -A runs
nmap --script=vuln <host> # check for known CVEs against detected services
nmap --script=http-title,http-headers <host> -p80 # quick web recon
nmap --script=ssl-enum-ciphers -p443 <host> # enumerate supported TLS ciphers/protocol versions
nmap --script=smb-vuln* -p445 <host> # SMB vulnerability checks
nmap --script-help ssl-enum-ciphers # see what any script actually does before running it
Kubernetes / homelab-relevant scanning¶
# Sweep a k8s node's pod CIDR for anything listening (useful when a Service isn't routing as expected)
nmap -sn 10.244.1.0/24
# From inside the cluster (a debug pod) since nodes often can't reach pod IPs directly depending on CNI:
kubectl run nmap --rm -it --image=instrumentisto/nmap -- nmap -sV -p 1-65535 target-service.default.svc.cluster.local
Rate control for shared/production networks¶
nmap --max-rate 50 --scan-delay 100ms <target> # be gentle — avoid tripping IDS or overloading old gear
Idle/zombie scan (advanced, situational)¶
nmap -sI zombie_host:port target
Uses a third "zombie" host's IP-ID sequence to scan a target without ever sending a packet with your own source IP — mostly of academic/red-team interest now since it requires an increasingly rare kind of predictable IP-ID stack.
4. Interpreting results correctly¶
open— something is actively listening and responded.closed— reachable, but nothing listening (RST received on TCP).filtered— nmap can't tell if it's open or closed; a firewall/ACL is dropping probes silently. Combine with--reasonand try a different scan type (-sA, fragment with-f) to get more signal.open|filtered— typical UDP result; no response could mean open-and-silent, or filtered. Try-sVon that specific port for a protocol-aware probe, or fall back to an application-level test (e.g.nc -usending an actual expected payload, or a protocol-specific NSE script).unfiltered(ACK scan only) — reachable, but state (open/closed) unknown.
5. Quick cheat sheet¶
nmap -sn 192.168.1.0/24 # host discovery only
nmap -p22 --open 192.168.1.0/24 # find one open port across a subnet
nmap -sV -sC <host> # version detection + default safe scripts
nmap -A <host> # everything: OS, version, scripts, traceroute
nmap -p- -T4 <host> # full port range, fast
nmap --script=vuln <host> # known-CVE check
nmap -oA report <host> # log to .nmap/.gnmap/.xml simultaneously
nmap -sU -p 67 --script=dhcp-discover <host> # find DHCP servers safely