Using nmap for Network Discovery
Table of Contents
nmap is probably the first tool any security professional learns, and for good reason. It is the most capable network scanner available, it has been actively developed for over 25 years, and it does far more than most people realize. Port scanning is just the beginning.
This guide covers nmap from basic host discovery through advanced NSE scripting, with practical examples you can use in real security assessments.
What nmap Actually Does
At its core, nmap sends specially crafted packets to target hosts and analyzes the responses. From those responses, it can determine which hosts are alive, which ports are open, what services are running, what versions those services are, and often what operating system the host is running.
Install it on Linux with sudo apt install nmap. On Windows, download the installer from nmap.org - it includes Npcap, which is required for raw packet scanning. On macOS, brew install nmap.
The basic syntax is simple:
nmap [scan type] [options] [target]
Targets can be single IPs, ranges (192.168.1.1-254), CIDR notation (192.168.1.0/24), or hostnames. You can also read targets from a file with -iL targets.txt.
Host Discovery - Finding Live Targets
graph TD
subgraph "Host Discovery Methods"
A["nmap Target"] --> B{"Same Subnet?"}
B -->|Yes| C["ARP Request\n-PR"]
C --> D{"ARP Reply?"}
D -->|Yes| E["Host is UP"]
D -->|No| F["Host is DOWN"]
B -->|No| G["ICMP Echo\n-PE"]
B -->|No| H["TCP SYN :443\n-PS443"]
B -->|No| I["TCP ACK :80\n-PA80"]
B -->|No| J["ICMP Timestamp\n-PP"]
G --> K{"Any Response?"}
H --> K
I --> K
J --> K
K -->|Yes| E
K -->|No| F
end
subgraph "After Discovery"
E --> L["Port Scan"]
E --> M["Service Detection"]
E --> N["OS Fingerprint"]
end
How nmap discovers live hosts using different probe types based on network position
Before scanning ports, nmap needs to know which hosts are alive. By default, it sends an ICMP echo request, a TCP SYN to port 443, a TCP ACK to port 80, and an ICMP timestamp request. On local networks, it uses ARP instead, which is faster and more reliable.
Ping sweep (find live hosts without port scanning):
nmap -sn 192.168.1.0/24
The -sn flag means "no port scan" - just find which hosts are up. This is your first step in mapping an unknown network.
ARP discovery (local networks only):
nmap -sn -PR 192.168.1.0/24
ARP discovery cannot be blocked by host firewalls. If a device is on the network, ARP will find it.
Skip host discovery (scan regardless):
nmap -Pn 192.168.1.1
Use -Pn when you know the host is up but it blocks ping. Firewalls often drop ICMP, making hosts appear down when they are not.
Port Scanning Techniques
nmap supports multiple scan types, each with different tradeoffs in speed, stealth, and reliability.
TCP SYN scan (default, requires root):
sudo nmap -sS 192.168.1.1
Sends a SYN packet. If the port responds with SYN-ACK, it is open. nmap then sends RST to close the connection without completing the handshake. This is fast and relatively stealthy because no full TCP connection is established.
TCP Connect scan (no root needed):
nmap -sT 192.168.1.1
Uses the operating system's connect() call to complete a full TCP handshake. Slower and more visible in logs, but works without root privileges.
UDP scan:
sudo nmap -sU 192.168.1.1
UDP scanning is slow because there is no handshake to confirm open ports. An open UDP port typically sends no response, so nmap has to wait for timeouts. Combining with version detection (-sV) helps because some UDP services will respond to specific probes.
Specifying ports:
nmap -p 80,443,8080 target # Specific ports
nmap -p 1-1024 target # Range
nmap -p- target # All 65535 ports
nmap --top-ports 100 target # Most common 100 ports
The default scan covers roughly 1,000 ports selected by frequency data. A full port scan (-p-) takes longer but catches services running on unusual ports - which is exactly where administrators sometimes hide things.
Service and Version Detection
Knowing a port is open is step one. Knowing what is running on it is step two.
nmap -sV 192.168.1.1
The -sV flag tells nmap to probe open ports with protocol-specific requests. It can identify the exact software and version - not just "port 80 is open" but "Apache httpd 2.4.41 on Ubuntu".
Version detection intensity can be tuned:
nmap -sV --version-intensity 5 target # Default intensity
nmap -sV --version-all target # Try every probe (slow)
nmap -sV --version-light target # Quick check only
The version information is critical for vulnerability assessment. Knowing the exact software version lets you check for known CVEs and exploits. An Apache 2.4.49 is very different from an Apache 2.4.54 from a security perspective.
OS Fingerprinting
sudo nmap -O 192.168.1.1
OS detection works by analyzing subtle differences in how operating systems implement TCP/IP. Things like initial TTL values, window sizes, TCP options, and IP ID sequences all vary between operating systems and versions.
It requires at least one open and one closed port on the target. If all ports are filtered (by a firewall), OS detection may not work.
The -A flag enables "aggressive" mode, which combines OS detection, version detection, script scanning, and traceroute:
sudo nmap -A 192.168.1.1
This is the "give me everything" scan. It is thorough but slow and noisy. Good for lab environments, less ideal for stealth.
NSE Scripts - nmap's Secret Weapon
graph TD
subgraph "NSE Script Categories"
A["NSE Engine"] --> B["auth\nAuthentication testing"]
A --> C["broadcast\nNetwork discovery"]
A --> D["brute\nCredential brute force"]
A --> E["default\nSafe general scripts"]
A --> F["discovery\nService enumeration"]
A --> G["exploit\nVulnerability exploitation"]
A --> H["vuln\nVulnerability detection"]
A --> I["safe\nNon-intrusive scripts"]
end
subgraph "Script Execution Flow"
J["Port Scan Results"] --> K["Match Script Rules"]
K --> L["Execute Matching Scripts"]
L --> M["Parse Responses"]
M --> N["Structured Output"]
end
NSE script categories and how scripts are selected and executed against scan results
The Nmap Scripting Engine (NSE) transforms nmap from a port scanner into a full vulnerability assessment platform. nmap ships with over 600 scripts that can detect vulnerabilities, enumerate services, brute force credentials, and much more.
Run default scripts:
nmap -sC 192.168.1.1
# or equivalently:
nmap --script=default 192.168.1.1
Default scripts are safe to run - they do not attempt brute force or exploitation. They do things like grab HTTP titles, check SSH algorithms, enumerate SMB shares, and retrieve SSL certificate information.
Run specific scripts:
nmap --script=http-title 192.168.1.1
nmap --script=smb-enum-shares 192.168.1.1
nmap --script=ssl-heartbleed 192.168.1.1
Run script categories:
nmap --script=vuln 192.168.1.1 # All vulnerability scripts
nmap --script=safe 192.168.1.1 # All safe scripts
nmap --script="vuln and safe" target # Boolean combinations
Some particularly useful scripts:
-
http-enum- Enumerate directories and files on web servers -
smb-vuln-ms17-010- Check for EternalBlue -
ssl-enum-ciphers- List supported TLS cipher suites -
dns-brute- Brute force DNS subdomains -
ftp-anon- Check for anonymous FTP access -
mysql-empty-password- Test for MySQL without password
Scripts can take arguments:
nmap --script=http-enum --script-args http-enum.basepath=/api/ target
Output Formats
nmap supports several output formats, and you should almost always save results to a file.
nmap -oN scan.txt target # Normal (human-readable)
nmap -oX scan.xml target # XML (for parsing)
nmap -oG scan.gnmap target # Grepable (legacy but useful)
nmap -oA scan target # All three formats at once
The -oA flag is the best habit. It saves all three formats with the base filename you specify. The XML output is particularly useful because tools like searchsploit, Metasploit, and custom scripts can parse it directly.
For quick terminal review of previous scans:
grep "open" scan.gnmap
grep -E "80/open|443/open" scan.gnmap
Scanning Strategies for Real Engagements
Quick initial discovery:
nmap -sn 10.0.0.0/24 -oA discovery
Find live hosts first. Then scan them individually with more detail.
Fast comprehensive scan:
nmap -sS -sV -sC --top-ports 1000 -T4 -oA initial target
SYN scan with version detection and default scripts on the top 1000 ports. The -T4 flag increases timing aggressiveness (scale is T0 through T5).
Full port scan:
nmap -sS -p- -T4 --min-rate 1000 -oA fullport target
Scan all 65535 ports. The --min-rate flag ensures nmap sends at least 1000 packets per second, keeping the scan from taking forever.
Targeted deep scan on discovered ports:
nmap -sS -sV -sC -O -p 22,80,443,3306,8080 -oA deep target
Once you know which ports are open, do a detailed scan of just those ports with everything enabled.
Timing matters. The -T flags control scan speed:
- T0/T1 - Paranoid/Sneaky (IDS evasion, very slow)
- T2 - Polite (reduced load on target)
- T3 - Normal (default)
- T4 - Aggressive (good for fast networks)
- T5 - Insane (may miss ports due to timeouts)
For internal network assessments, T4 is usually fine. For external scans or when stealth matters, T2 or lower.
Common Mistakes
Not running as root. Without root, nmap cannot send raw packets and falls back to TCP connect scans. SYN scanning, OS detection, and many scripts require root.
Scanning too fast on unreliable networks. WiFi and VPN connections drop packets. If you scan at T5 over WiFi, you will get false negatives. Slow down and verify.
Ignoring UDP. Everyone scans TCP. Many forget UDP entirely. DNS (53), SNMP (161), TFTP (69), and NTP (123) run on UDP and are frequently misconfigured.
Not saving output. Always use -oA. You will need to reference scan results later, compare scans over time, and import results into other tools.
Scanning without authorization. Port scanning networks you do not own is a legal gray area in many jurisdictions and a clear violation in others. Always have written permission before scanning anything outside your own lab.
Integration with Other Tools
nmap's XML output integrates with many other security tools:
Import into Metasploit:
msf6> db_import scan.xml
msf6> hosts
msf6> services
Convert to HTML report:
xsltproc scan.xml -o report.html
Parse with Python:
import xml.etree.ElementTree as ET
tree = ET.parse('scan.xml')
for host in tree.findall('.//host'):
addr = host.find('address').get('addr')
for port in host.findall('.//port'):
portid = port.get('portid')
state = port.find('state').get('state')
print(f"{addr}:{portid} - {state}")
nmap also pairs well with tools like masscan for initial fast discovery (masscan finds open ports at millions per second, then nmap does the detailed enumeration) and with vulnerability scanners like Nessus or OpenVAS for the assessment phase.
If you are doing wireless security testing with your BLEShark Nano, nmap is typically the next step after you connect to a captured network. You have the WiFi credentials - now map what is on that network and look for vulnerabilities.
This article is for educational and authorized security testing purposes only. Only scan networks you own or have explicit written permission to test. Unauthorized network scanning may violate computer crime laws.
Get the BLEShark Nano - $36.99+