← Nmap Scripting Engine (NSE): Writing Your Own Scripts

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.

30 minHands-on 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:

  1. Which hosts are alive? (host discovery)
  2. Which ports are open on them? (port scanning)
  3. What is running behind those ports? (service and version detection)
  4. 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.

PhaseWhat happens
Script pre-scanningNSE scripts with a prerule run (for example broadcast discovery).
Target enumerationYour target list (names, CIDR ranges, -iL files) is resolved to IPs.
Host discoveryNmap decides which targets are up (-sn stops here).
Reverse DNSNames are looked up for live hosts.
Port scanningPorts 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 scanningNSE scripts run against the hosts and ports found.
OutputResults are written in your chosen formats.
Script post-scanningScripts 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.

StateMeaning
openA service is actively accepting connections.
closedReachable, but nothing is listening.
filteredNmap can’t tell, usually because a firewall drops the probes.
unfilteredReachable, but Nmap can’t tell if it’s open or closed (ACK scan only).
open|filteredNmap can’t decide between open and filtered (common with UDP).
closed|filteredNmap 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

OptionPurpose
-snHost discovery only, no port scan.
-PnSkip host discovery, treat every target as up.
-p 22,80,8000-8100 / -p-Choose ports / all 65,535 ports.
-sS / -sTTCP SYN scan (needs raw-socket privileges) / full connect scan.
-sUUDP scan.
-sVService and version detection.
-OOS detection.
-sCRun the default NSE scripts.
-AAggressive: -sV -O -sC --traceroute.
-T0..-T5Timing template (-T3 is the default, -T4 is common on fast networks).
-oN -oX -oG -oASave normal, XML, grepable, or all three outputs.
-iL fileRead targets from a file.
--openOnly show open ports.
-v / -dMore 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.