Passive reconnaissance tells you what a target has exposed to the internet. Active scanning tells you what is actually running — open ports, services, versions, operating system, and more. The two phases together give you a complete picture before you write a single line of exploit code.
I set up an isolated lab environment with Kali Linux and Metasploitable2 — a deliberately vulnerable Linux VM used for security testing practice — and ran every major Nmap scanning mode against it. Host discovery, TCP scanning, UDP scanning, OS detection, service version fingerprinting, and a full aggressive scan.
This article walks through each mode, the exact commands, and what the output actually means from a security perspective.
Lab Setup
Two VMs on an isolated NAT network in VirtualBox:
| Machine | IP Address | Role |
|---|---|---|
| Kali Linux 2026.1 | 192.168.1.4 | Attacker |
| Metasploitable2 | 192.168.1.3 | Target |
Both connected to the same internal network with no external internet access — a clean, noise-free environment for packet capture.
nmap --version
# Nmap version 7.99
Task 1: Host Discovery — What Does Nmap Send Before It Scans?
Before Nmap scans any ports, it needs to confirm the target is alive. The -sn flag runs host discovery only — no port scanning.
sudo nmap -sn 192.168.1.3
On a local ethernet network as root, Nmap uses ARP — not ICMP or TCP. ARP (Address Resolution Protocol) is a layer-2 protocol that maps IP addresses to MAC addresses. On a local network, ARP requests always get through because they operate below the IP layer. Firewalls that block ICMP cannot block ARP.
The Wireshark trace confirms: Nmap sent an ARP request (Who has 192.168.1.3? Tell 192.168.1.4) and received an ARP reply. No ICMP, no TCP — just ARP. This is why running Nmap with sudo on a local network behaves differently from running it without.
Host Discovery Against a Remote Target: 8.8.8.8
sudo nmap -sn 8.8.8.8
8.8.8.8 is Google's public DNS server. Because it is not on the local ethernet segment, ARP does not work — ARP only operates within a single broadcast domain. So Nmap switches to IP-layer methods:
- ICMP Echo Request (ping)
- ICMP Timestamp Request
- TCP SYN → port 443
- TCP ACK → port 80
Reverse DNS hostname: Nmap also sends a PTR record lookup for 8.8.8.8.in-addr.arpa. The response comes back as dns.google — confirming that 8.8.8.8 is Google's DNS infrastructure.
What replies came back: Nmap received an ICMP Echo Reply from 8.8.8.8, confirming the host is online. The TCP SYN packets may not have received responses depending on Google's firewall, but the ICMP reply was sufficient to mark the host as up.
Key insight: ARP for local targets, ICMP+TCP for remote targets. The method changes based on network layer reachability, not the target OS.
Task 2: TCP Port Scanning — The Full Port Map
sudo nmap -sT 192.168.1.3 # Connect scan — completes full TCP handshake
sudo nmap -sS 192.168.1.3 # SYN scan — sends SYN, reads response, sends RST
The SYN scan (-sS) is faster and quieter — it never completes the three-way handshake. The connect scan (-sT) is noisier but works without root privileges. Both returned identical results here.
Full PORT | STATE | SERVICE table:
PORT STATE SERVICE
21/tcp open ftp
22/tcp open ssh
23/tcp open telnet
25/tcp open smtp
53/tcp open domain
80/tcp open http
111/tcp open rpcbind
139/tcp open netbios-ssn
445/tcp open microsoft-ds
512/tcp open exec
513/tcp open login
514/tcp open shell
1099/tcp open rmiregistry
1524/tcp open ingreslock
2049/tcp open nfs
2121/tcp open ccproxy-ftp
3306/tcp open mysql
5432/tcp open postgresql
5900/tcp open vnc
6000/tcp open X11
6667/tcp open irc
8009/tcp open ajp13
8180/tcp open unknown
23 ports open. 977 ports closed.
From a security standpoint this is a serious exposure. Telnet (23) sends credentials in plaintext. Ports 512/513/514 are r-services — remote execution with notoriously weak authentication. Port 1524/ingreslock on Metasploitable2 is an intentional backdoor shell. MySQL (3306) and PostgreSQL (5432) are directly reachable with no firewall. VNC (5900) gives graphical remote access. IRC on 6667 is a classic botnet C2 channel.
Task 3: UDP Port Scanning — The Overlooked Protocol
UDP scanning is slower and trickier than TCP because UDP is connectionless — there is no SYN-ACK to confirm a port is open. Nmap infers state from service responses or the absence of ICMP "port unreachable" messages.
sudo nmap -sU -sV -T4 --top-ports=100 192.168.1.3
-
-sU— UDP scan -
-sV— service version detection (critical for UDP accuracy) -
-T4— aggressive timing (safe on a local VM) -
--top-ports=100— scan only the 100 most common UDP ports
4 UDP ports confirmed open:
| Port | Service | Version |
|---|---|---|
| 53/udp | domain | ISC BIND 9.4.2 |
| 111/udp | rpcbind | 2 (RPC #100000) |
| 137/udp | netbios-ns | Microsoft Windows netbios-ns (workgroup: WORKGROUP) |
| 2049/udp | nfs | 2-4 (RPC #100003) |
ISC BIND 9.4.2 is a 2008-era DNS server with known vulnerabilities. NFS on 2049 means the filesystem may be network-mountable. NetBIOS on 137 leaks network naming information. Without -sV, most of these would have shown as open|filtered — the version probe is what confirmed them as definitively open.
Task 4: OS Detection — Fingerprinting the Kernel
Nmap's OS detection sends specially crafted packets and analyzes TCP/IP stack characteristics — ISN sampling, TTL values, window sizes — that vary between operating systems.
sudo nmap -O 192.168.1.3
Results:
| Field | Value |
|---|---|
| Device type | general purpose |
| OS CPE | cpe:/o:linux:linux_kernel:2.6 |
| OS details | Linux 2.6.9 – 2.6.33 |
The actual kernel version, confirmed inside the VM:
uname -r
# 2.6.24-16-server
Nmap's range was 2.6.9 – 2.6.33. The real kernel is 2.6.24 — squarely within that range. OS fingerprinting is probabilistic, but tight enough to target version-specific kernel exploits.
Task 5: Version and Service Scanning
Port numbers tell you what service is supposed to be there. Version scanning tells you what is actually there — the specific software version you need to look up CVEs.
sudo nmap -sV 192.168.1.3
Selected findings:
| Port | Service | Version |
|---|---|---|
| 21/tcp | ftp | vsftpd 2.3.4 |
| 22/tcp | ssh | OpenSSH 4.7p1 Debian 8ubuntu1 (protocol 2.0) |
| 53/tcp | domain | ISC BIND 9.4.2 |
| 80/tcp | http | Apache httpd 2.2.8 (Ubuntu) DAV/2 |
| 139/tcp | netbios-ssn | Samba smbd 3.X – 4.X (workgroup: WORKGROUP) |
| 1524/tcp | bindshell | Metasploitable root shell |
| 3306/tcp | mysql | MySQL 5.0.51a-3ubuntu5 |
| 5432/tcp | postgresql | PostgreSQL DB 8.3.0 – 8.3.7 |
| 5900/tcp | vnc | VNC (protocol 3.3) |
| 8180/tcp | http | Apache Tomcat/Coyote JSP engine 1.1 |
vsftpd 2.3.4 contains a backdoor — appending :) to a username during FTP login opens a root shell on port 6200. OpenSSH 4.7p1 is from 2007. Port 1524 is labeled "Metasploitable root shell" — Nmap's script engine recognized it as an intentional backdoor, not a legitimate service.
Task 6: Complete Scan — Everything at Once
sudo nmap -A 192.168.1.3
NetBIOS workgroup: WORKGROUP
2048-bit RSA SSH host key:
56:56:24:0f:21:1d:de:a7:2b:ae:61:b1:24:3d:e8:f3 (RSA)
Additional findings from the aggressive scan:
- FTP: anonymous login allowed — no credentials required
- VNC: no authentication — Security Type None
- SMTP: PIPELINING, VRFY enabled (allows username enumeration)
- IRC: UnrealIRCd on
irc.Metasploitable.LAN - Samba: computer name
metasploitable, domainlocaldomain - MySQL: Protocol 10, version 5.0.51a
VNC with no authentication means graphical takeover from anywhere on the network. Anonymous FTP means open read/write access to the FTP share. With the root shell on 1524 and the vsftpd backdoor on 21, this machine offers multiple paths to full compromise.
The Complete Nmap Scanning Sequence
| Flag | Scan Type | How It Works | When to Use |
|---|---|---|---|
-sn |
Host discovery | ARP (local) or ICMP+TCP (remote) | Confirming targets before scanning |
-sT |
TCP connect | Full three-way handshake | When you do not have root |
-sS |
TCP SYN | Half-open (SYN → SYN-ACK → RST) | Default with root — faster, quieter |
-sU |
UDP | Protocol probes + ICMP port unreachable | Finding UDP services often missed |
-O |
OS detection | TCP/IP stack fingerprinting | Targeting kernel-specific exploits |
-sV |
Version scan | Banner grabbing + service probes | Finding exact software versions |
-A |
Aggressive | All of the above + NSE scripts + traceroute | Deep dive on specific confirmed targets |
What I Learned
ARP vs ICMP matters — On a local network, Nmap uses ARP as root. On a remote target, it uses ICMP and TCP. Understanding the difference changes how you interpret Wireshark captures alongside Nmap output.
Version numbers are the bridge to exploitation — A port number is a hint. A version number is an exploit reference. vsftpd 2.3.4 has a documented backdoor. BIND 9.4.2 has published CVEs. The version scan is where reconnaissance becomes actionable.
OS fingerprinting is probabilistic, not exact — The range 2.6.9–2.6.33 was correct, but it is a range. Exact kernel version needed uname -r inside the box. Use OS detection to narrow down — not to pin down.
UDP is hard but necessary — Skipping UDP scanning leaves DNS, NFS, and NetBIOS invisible. Those three services alone represent significant attack surface. The -sV flag is what separates open|filtered noise from confirmed open ports.
The -A scan reveals what port numbers hide — Without -A, port 1524 shows as ingreslock. With -A, it shows as "Metasploitable root shell." Scripts and banner grabbing turn a list of numbers into intelligence.
Common Mistakes
| Mistake | What Happens |
|---|---|
Running without sudo
|
No ARP on local networks, weaker host detection |
Skipping -sV on UDP |
Most UDP ports show as `open\ |
| Default timing on remote UDP | Scan can take hours |
Running {% raw %}-A against full subnets |
Takes forever, generates huge noise |
| Trusting port numbers alone | Port 1524 shows as ingreslock without version scanning |
Conclusion
Nmap is not one tool — it is a collection of scanning techniques, each suited to a different phase. A basic port scan leaves UDP services, OS details, version information, and service-level vulnerabilities completely invisible.
The sequence that makes sense: host discovery first, then TCP port scan, then UDP on interesting targets, then version and OS detection on confirmed hosts, and finally a full aggressive scan against specific high-value targets once you know they exist.
Know what you are scanning. Know what you found. Then decide what comes next.



















