Lesson 1 of 10
Introduction to Nmap
What Nmap does, how a scan works from start to finish, and the options you'll use in every lab.
What Nmap is
Nmap (“Network Mapper”) is a free, open-source network scanner created by Gordon “Fyodor” Lyon and first released in 1997. It answers four basic questions about a network:
- Which hosts are alive? (host discovery)
- Which ports are open on them? (port scanning)
- What is running behind those ports? (service and version detection)
- What else can we learn? (OS detection, and the Nmap Scripting Engine)
It runs on Linux, macOS and Windows, and its output can be read by humans (normal), scripts (XML, grepable) or both.
Anatomy of a scan
Nmap does its work in phases. Knowing them explains why scripts behave the way they do later in the course.
| Phase | What happens |
|---|---|
| Script pre-scanning | NSE scripts with a prerule run (for example broadcast discovery). |
| Target enumeration | Your target list (names, CIDR ranges, -iL files) is resolved to IPs. |
| Host discovery | Nmap decides which targets are up (-sn stops here). |
| Reverse DNS | Names are looked up for live hosts. |
| Port scanning | Ports are probed and classified. |
| Version detection | -sV sends probes to identify the service and version. |
| OS detection | -O fingerprints the operating system. |
| Traceroute | --traceroute maps the path to each host. |
| Script scanning | NSE scripts run against the hosts and ports found. |
| Output | Results are written in your chosen formats. |
| Script post-scanning | Scripts with a postrule summarise the whole run. |
The key takeaway: by the time your port scripts run, Nmap already knows which ports are open and (with -sV) what service is on them. Your script’s job is to go one step deeper.
Port states
Nmap classifies every probed port into one of six states.
| State | Meaning |
|---|---|
open | A service is actively accepting connections. |
closed | Reachable, but nothing is listening. |
filtered | Nmap can’t tell, usually because a firewall drops the probes. |
unfiltered | Reachable, but Nmap can’t tell if it’s open or closed (ACK scan only). |
open|filtered | Nmap can’t decide between open and filtered (common with UDP). |
closed|filtered | Nmap can’t decide between closed and filtered (idle scan only). |
Port scripts only run against ports in states the script’s rule accepts, usually open.
Options you’ll use constantly
| Option | Purpose |
|---|---|
-sn | Host discovery only, no port scan. |
-Pn | Skip host discovery, treat every target as up. |
-p 22,80,8000-8100 / -p- | Choose ports / all 65,535 ports. |
-sS / -sT | TCP SYN scan (needs raw-socket privileges) / full connect scan. |
-sU | UDP scan. |
-sV | Service and version detection. |
-O | OS detection. |
-sC | Run the default NSE scripts. |
-A | Aggressive: -sV -O -sC --traceroute. |
-T0..-T5 | Timing template (-T3 is the default, -T4 is common on fast networks). |
-oN -oX -oG -oA | Save normal, XML, grepable, or all three outputs. |
-iL file | Read targets from a file. |
--open | Only show open ports. |
-v / -d | More verbosity / debugging output (you’ll live in -d in lesson 9). |
Lab: your first scans
mkdir lab && cd lab
echo "hello nse" > index.html
python3 -m http.server 8000
Leave that running, and in a second terminal try these against 127.0.0.1:
# 1. Is it up, and what's open on a few ports?
nmap -p 22,80,8000 127.0.0.1
# 2. What is actually listening on 8000?
nmap -sV -p 8000 127.0.0.1
# 3. Add the default scripts and save every output format
nmap -sC -sV -p 8000 -oA first-scan 127.0.0.1
The second command should report something like this (your version strings will differ):
PORT STATE SERVICE VERSION
8000/tcp open http SimpleHTTPServer 0.6 (Python 3.12.3)
Now open first-scan.nmap (normal) and first-scan.xml. Notice the script results under the port: you’ll produce output like that yourself by lesson 7.
Checkpoint
At which phase do port scripts (those with a portrule) run, and why does that matter?
After port scanning and version detection. That means the script already knows the port state and, with -sV, the detected service name, so its rule can select ports by service instead of guessing from the port number.
What's the difference between -sn and -Pn?
-sn does host discovery only and skips port scanning. -Pn skips host discovery and goes straight to scanning, assuming every target is up.
Why might a script report nothing for a port marked filtered?
Script rules typically require the port to be open. A filtered port hasn’t been confirmed to accept connections, so most port scripts are never run against it.