Why Nmap?

Before you can attack anything, you need to know what's there. Nmap (Network Mapper) is the standard tool for this job — used by penetration testers, security engineers, and network administrators worldwide.

In this guide, you'll go from zero to using advanced NSE scripts, evasion techniques, and output parsing like a professional.

Installation

Nmap is pre-installed on Kali Linux. On other systems:

bash
# Ubuntu/Debian
sudo apt install nmap

# macOS (Homebrew)
brew install nmap

# Windows — download from nmap.org

Verify installation:

bash
nmap --version

Host Discovery

Before scanning ports, identify which hosts are alive on the network.

bash
# Ping sweep — discover live hosts (requires root for ICMP)
nmap -sn 192.168.1.0/24

# ARP discovery (more reliable on local networks)
nmap -PR -sn 192.168.1.0/24

# Scan without ping (useful when ICMP is blocked)
nmap -Pn 192.168.1.1

# Scan multiple targets
nmap 192.168.1.1 192.168.1.5 192.168.1.10

# Scan a range
nmap 192.168.1.1-50

# Scan from a file
nmap -iL targets.txt

Port Scanning Techniques

SYN Scan (Default — Stealth Scan)

bash
sudo nmap -sS 192.168.1.10

The SYN scan (also called "half-open scan") sends a SYN packet but never completes the TCP handshake. It's:

  • Fast — doesn't complete connections
  • Stealthy — many older logging systems only log completed connections
  • Requires root — needs raw socket access

TCP Connect Scan

bash
nmap -sT 192.168.1.10

Completes the full TCP handshake. Use when you don't have root permissions. Slower and more detectable.

UDP Scan

bash
sudo nmap -sU 192.168.1.10

Slow but important — many critical services run on UDP (DNS:53, SNMP:161, DHCP:67).

Scan All Ports

bash
# Scan all 65,535 ports (slow but thorough)
nmap -p- 192.168.1.10

# Scan common top 1000 ports (default)
nmap 192.168.1.10

# Scan specific ports
nmap -p 80,443,22,3306 192.168.1.10

# Scan port range
nmap -p 1-10000 192.168.1.10

Service and Version Detection

bash
# Detect service versions on open ports
nmap -sV 192.168.1.10

# Aggressive version detection
nmap -sV --version-intensity 9 192.168.1.10

Output example:

plaintext
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.5
80/tcp   open  http    Apache httpd 2.4.41
443/tcp  open  ssl     Apache httpd 2.4.41
3306/tcp open  mysql   MySQL 8.0.28

This tells you not just that port 22 is open — it tells you it's OpenSSH 8.2p1, which you can look up for known CVEs.

OS Detection

bash
# Attempt OS fingerprinting (requires root)
sudo nmap -O 192.168.1.10

# More aggressive OS detection
sudo nmap -O --osscan-guess 192.168.1.10

The All-In-One Aggressive Scan

bash
# -A enables: OS detection + version detection + script scanning + traceroute
sudo nmap -A 192.168.1.10

# Full-port aggressive scan (go-to for CTFs and pentest assessments)
sudo nmap -A -p- -T4 192.168.1.10

Timing Templates

Speed vs. stealth. Nmap has 6 timing levels:

Template Flag Use Case
Paranoid -T0 IDS evasion — very slow
Sneaky -T1 Avoid detection — slow
Polite -T2 Avoid overloading target
Normal -T3 Default speed
Aggressive -T4 Fast networks, CTFs
Insane -T5 May miss results
bash
# Fast CTF scan
nmap -T4 -A -p- 10.10.10.50

# Slow IDS evasion scan
nmap -T1 -sS 192.168.1.10

Nmap Scripting Engine (NSE)

NSE allows nmap to run Lua scripts that extend its capabilities beyond port scanning.

bash
# Run default scripts (-sC is shorthand for --script=default)
nmap -sC 192.168.1.10

# Run specific script
nmap --script=http-title 192.168.1.10

# Run a category of scripts
nmap --script=vuln 192.168.1.10  # Check for known vulnerabilities
nmap --script=auth 192.168.1.10  # Test for default/blank credentials
nmap --script=discovery 192.168.1.10  # Network discovery

Useful NSE Scripts

bash
# Web server enumeration
nmap --script=http-enum 192.168.1.10

# Check for SMB vulnerabilities (EternalBlue, etc.)
nmap --script=smb-vuln* -p 445 192.168.1.10

# SSL certificate info
nmap --script=ssl-cert -p 443 192.168.1.10

# FTP anonymous login check
nmap --script=ftp-anon -p 21 192.168.1.10

# MySQL info (if unauthenticated)
nmap --script=mysql-info -p 3306 192.168.1.10

# Brute force SSH (use carefully + with permission)
nmap --script=ssh-brute -p 22 192.168.1.10

Output Formats

Always save your scan results:

bash
# Normal output (human readable)
nmap -oN output.txt 192.168.1.10

# XML output (for tool integration)
nmap -oX output.xml 192.168.1.10

# Grepable output
nmap -oG output.gnmap 192.168.1.10

# All formats at once
nmap -oA allformats 192.168.1.10

# Save and display on screen
nmap 192.168.1.10 | tee output.txt

Evasion Techniques

In a real engagement, you may need to avoid IDS/IPS detection:

bash
# Fragment packets (harder for stateless firewalls to filter)
nmap -f 192.168.1.10

# Decoy scan — mix your IP with fake IPs
nmap -D RND:5 192.168.1.10

# Specify source port (blend into expected traffic)
nmap --source-port 53 192.168.1.10

# Randomize target order
nmap --randomize-hosts 192.168.1.0/24

# Slow scan to avoid rate-based detection
nmap -T1 --max-retries 1 192.168.1.10

Practical Scan Workflow

Here's the exact workflow for a CTF machine or authorized pentest target:

bash
# Step 1: Quick scan to identify open ports
nmap -T4 -p- --min-rate 5000 10.10.10.50 -oN quick.txt

# Step 2: Detailed scan of open ports only
PORTS=$(grep "^[0-9]" quick.txt | cut -d "/" -f1 | tr "\n" "," | sed 's/,$//') 
nmap -sV -sC -p $PORTS 10.10.10.50 -oN detailed.txt

# Step 3: Vulnerability scan on open ports
nmap --script=vuln -p $PORTS 10.10.10.50 -oN vulns.txt

Reading Nmap Output

Understanding the state columns:

State Meaning
open Port is accepting connections
closed Port is accessible but no service listening
filtered Firewall is blocking probe — can't determine state
open|filtered Can't determine if open or filtered
unfiltered Port accessible, state unknown

This article is part of the Network Hacking 101 series.