A step-by-step, logic-driven guide for authorized network reconnaissance.
START │ ├── [0] Got written authorization? ── NO ──► STOP. DO NOT PROCEED. │ YES │ ▼ ├── [0] Environment ready? (Kali, root, interface up) ── NO ──► Fix setup. │ YES │ ▼ ├── [0] Scope defined? (IPs, exclusions, boundaries) ── NO ──► Define scope. │ YES │ ▼ ├── [0] Logging enabled? ── NO ──► Set up output directory & naming. │ YES │ ▼ ├── [1.1] Host Discovery ──► Who is alive on the network? │ ▼ ├── [1.2] Port Scan ──► What ports are open on live hosts? │ ▼ │ ┌── Stealth needed? ── YES ──► SYN scan (-sS) │ └── NO ──► Connect scan (-sT) │ ▼ ├── [1.3] Service Detection ──► What software/version on each port? │ ▼ ├── [1.4] OS Detection ──► What operating system is running? │ ▼ ├── [1.5] Vuln Scan ──► Are these services vulnerable? │ ▼ ├── [3] Analyze & Interpret ──► What does this data mean? │ ▼ ├── [4] Report & Document ──► Log everything with WHY you did it. │ ▼ └── [4.3] Cleanup ──► Archive logs, shred sensitive data. │ END
Verify that you have legally binding permission to scan the target network/hosts before doing anything else. This is the single most important step in your entire engagement.
Scanning without authorization is a criminal offense in most jurisdictions. Even a simple -sn ping sweep against a network you don't own can result in legal action. Authorization protects you, your organization, and the target.
Before running a single command, ensure you have:
"I verified authorization before scanning because unauthorized network reconnaissance is a criminal act. I had written permission from [client/org] dated [date], covering IP range [range], within the testing window of [dates]."
Confirm your attack machine is properly configured: you're running as root (or with sudo), your network interface is up and has connectivity, and Nmap is installed and functional.
Many Nmap scan types (SYN scan, OS detection, raw packet scans) require root/sudo privileges because they manipulate raw sockets. If your interface is down or misconfigured, your scans will silently fail or produce garbage results. Verify before you scan.
Run these verification commands in order:
# 1. Check your user — should be root or use sudo whoami # Expected: root # 2. Verify network interface is up ip a # Look for your interface (eth0, wlan0, etc.) → should show UP and have an IP # 3. Test connectivity to target or gateway ping -c 3 192.168.1.1 # Expected: 3 packets transmitted, 3 received, 0% packet loss # 4. Verify Nmap is installed and check version nmap --version # Expected: Nmap version 7.xx (https://nmap.org)
$ whoami
root
$ ip a
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...
inet 192.168.1.100/24 brd 192.168.1.255 scope global eth0
$ nmap --version
Nmap version 7.94 ( https://nmap.org )
"I verified root access and network connectivity before scanning to ensure all scan types would function correctly and results would be reliable. Running without root would silently downgrade SYN scans to TCP connect scans, potentially yielding incomplete or inaccurate data."
Define exactly which hosts, networks, and IP ranges you are authorized to scan — and explicitly document what is out of scope. Create target list files for repeatable scans.
Scope creep is the fastest way to accidentally scan something you shouldn't. A clear scope prevents legal incidents, ensures your scans are focused, and makes your results reproducible. If your scan hits an out-of-scope host, it doesn't matter that it was an "accident."
Document your scope and create a target list file:
# Create a target list file cat << 'EOF' > targets.txt # In-scope targets — Project: [name] — Date: [date] 192.168.1.0/24 10.0.0.1-50 scanme.nmap.org EOF # Create an exclusion list (hosts to NEVER scan) cat << 'EOF' > excludes.txt # Out-of-scope — DO NOT TOUCH 192.168.1.1 # production gateway 192.168.1.254 # ISP modem EOF # Use in scans: nmap -iL targets.txt --excludefile excludes.txt
192.168.1.1 · Range: 192.168.1.1-50 · CIDR: 192.168.1.0/24 · Hostname: scanme.nmap.org · From file: -iL targets.txt
"I created explicit target and exclusion lists to ensure all scanning stayed within the authorized scope. Using -iL and --excludefile flags makes scans repeatable and auditable. The exclusion list prevents accidental scanning of critical infrastructure like gateways."
Create an organized output directory and establish a naming convention for all scan results. Configure Nmap to save output in multiple formats simultaneously.
Professional engagements require documented evidence. If you can't show your work, your findings are worthless. Multiple output formats ensure compatibility: normal output for quick reading, XML for tool import (Metasploit, etc.), and grepable for scripting/parsing.
# Create organized project directory mkdir -p ~/engagements/project-name/{scans,reports,evidence,notes} cd ~/engagements/project-name/scans # Naming convention: [type]-[target]-[date] # Example: discovery-192.168.1.0-20260222 # Save in ALL formats at once with -oA (normal + XML + grepable) nmap -sn 192.168.1.0/24 -oA discovery-192.168.1.0-$(date +%Y%m%d) # This creates three files: # discovery-192.168.1.0-20260222.nmap (human readable) # discovery-192.168.1.0-20260222.xml (import into tools) # discovery-192.168.1.0-20260222.gnmap (grepable format)
| Flag | Format | Use Case |
|---|---|---|
-oN file | Normal | Human-readable, like terminal output |
-oX file | XML | Import into Metasploit, Nessus, or custom parsers |
-oG file | Grepable | Quick parsing with grep/awk/cut |
-oA base | All three | Creates .nmap, .xml, and .gnmap files at once |
-oS file | Script kiddie | Joke format — never use professionally |
"I established a structured output directory and used -oA to capture all scans in three formats simultaneously. This ensures findings are documented for the report (normal), importable into other tools (XML), and parseable for further analysis (grepable). The timestamped naming convention prevents overwriting and creates a clear audit trail."
Determine which hosts on the target network are online and responsive before wasting time port scanning dead IPs. This is also called a ping sweep.
Scanning all 65,535 ports on every IP in a /24 (256 hosts) without first checking which are alive is wildly inefficient. Host discovery narrows your target list to only live hosts, saving massive time and reducing network noise. It also gives you a map of the network topology.
Nmap uses multiple probe types for host discovery. The default (-sn) sends ICMP echo, TCP SYN to 443, TCP ACK to 80, and ICMP timestamp. On local networks, it uses ARP instead (faster, more reliable).
# Basic host discovery (ping sweep) — no port scan sudo nmap -sn 192.168.1.0/24 -oA discovery # Breakdown: # -sn Ping scan — disable port scan, only check if host is up # 192.168.1.0/24 Target: entire /24 subnet (256 IPs) # -oA discovery Save output in all 3 formats
If ICMP is blocked (common in hardened networks), use these alternatives:
# TCP SYN discovery on common ports (bypasses ICMP block) sudo nmap -sn -PS22,80,443,445,3389 192.168.1.0/24 # TCP ACK discovery (may bypass stateless firewalls) sudo nmap -sn -PA80,443 192.168.1.0/24 # UDP discovery (DHCP, DNS, SNMP ports) sudo nmap -sn -PU53,67,161 192.168.1.0/24 # ARP discovery (local network only — fastest & most reliable) sudo nmap -sn -PR 192.168.1.0/24 # Combine multiple methods for maximum coverage sudo nmap -sn -PE -PS22,80,443 -PA80 -PU53 192.168.1.0/24 -oA discovery-aggressive
| Flag | Method | When to Use |
|---|---|---|
-sn | Default (ICMP + TCP) | Starting point for any engagement |
-PE | ICMP Echo | Standard ping — works on most internal nets |
-PP | ICMP Timestamp | Alternate ICMP — sometimes not filtered |
-PM | ICMP Address Mask | Rare, but can bypass some filters |
-PS<ports> | TCP SYN | When ICMP is blocked; target common open ports |
-PA<ports> | TCP ACK | Bypasses stateless firewalls |
-PU<ports> | UDP | Discover hosts running UDP services (DNS, SNMP) |
-PR | ARP | Local subnets — fastest & most accurate |
-Pn | Skip discovery | Assume host is up — scan even if ping fails |
Starting Nmap 7.94 ( https://nmap.org )
Nmap scan report for 192.168.1.1
Host is up (0.0023s latency).
MAC Address: AA:BB:CC:DD:EE:01 (Cisco Systems)
Nmap scan report for 192.168.1.50
Host is up (0.0041s latency).
MAC Address: AA:BB:CC:DD:EE:02 (Dell)
Nmap scan report for 192.168.1.100
Host is up (0.00012s latency).
Nmap done: 256 IP addresses (3 hosts up) scanned in 2.84 seconds
-PS/-PR). If scanning remotely, use -Pn to skip discovery and go straight to port scanning (slower but reliable).
"I performed host discovery first to identify live hosts within the authorized scope. Scanning all 65,535 ports on every IP without first determining which hosts are alive would be inefficient and generate unnecessary traffic. The -sn flag disables port scanning and only checks for host presence, minimizing network impact."
Determine which TCP and UDP ports are open on each live host. Open ports reveal running services — each one is a potential attack surface.
Every open port is a doorway into the system. A web server on port 80, SSH on port 22, or a database on port 3306 — each represents a service that could be misconfigured, outdated, or vulnerable. Port scanning is the foundation of enumeration.
Choose your scan type based on the engagement requirements: stealth, speed, or thoroughness.
# SYN scan (default, stealthy, fast) — requires root sudo nmap -sS 192.168.1.50 -oA syn-scan # Breakdown: # -sS SYN (half-open) scan — sends SYN, waits for SYN/ACK # If received → port open, send RST (never complete handshake) # Result: stealthier because no full TCP connection is logged
# Connect scan (no root needed, noisier) nmap -sT 192.168.1.50 -oA connect-scan # Breakdown: # -sT TCP connect scan — completes full 3-way handshake # Visible in logs, but works without root/sudo
# UDP scan (slow but essential — many services use UDP) sudo nmap -sU --top-ports 20 192.168.1.50 -oA udp-scan # Breakdown: # -sU UDP scan (no handshake — relies on ICMP responses) # --top-ports 20 Only scan the 20 most common UDP ports (DNS, SNMP, DHCP...) # UDP is SLOW — always limit port range unless you have time
# Scan specific ports sudo nmap -sS -p 22,80,443,445,3389,8080 192.168.1.50 # Scan ALL ports (1-65535) sudo nmap -sS -p- 192.168.1.50 -oA full-port-scan # Scan top 1000 ports (Nmap default) sudo nmap -sS --top-ports 1000 192.168.1.50 # Combined TCP + UDP scan sudo nmap -sS -sU --top-ports 100 192.168.1.50 -oA combined-scan
| Flag | Type | Root? | Speed | Stealth | Use When |
|---|---|---|---|---|---|
-sS | SYN (half-open) | Yes | Fast | High | Default choice — fast & stealthy |
-sT | TCP Connect | No | Medium | Low | When you don't have root |
-sU | UDP | Yes | Slow | Medium | Finding DNS, SNMP, DHCP services |
-sA | ACK | Yes | Fast | Medium | Mapping firewall rules |
-sF | FIN | Yes | Fast | High | Evading basic firewalls |
-sX | Xmas | Yes | Fast | High | Evading basic firewalls |
-sN | Null | Yes | Fast | High | Evading basic firewalls |
-sW | Window | Yes | Fast | Medium | Distinguish open/closed on some OSes |
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
443/tcp open https
3306/tcp open mysql
8080/tcp open http-proxy
Nmap done: 1 IP address (1 host up) scanned in 1.43 seconds
"I used a SYN scan (-sS) as the primary port scan because it's the fastest and most reliable method, and it doesn't complete TCP connections — reducing the chance of being logged by the target. I followed up with a targeted UDP scan on the top 20 ports because critical services like DNS (53), SNMP (161), and DHCP (67/68) only run on UDP."
Identify the exact software and version running on each open port. Knowing that port 80 is "open" is useful; knowing it's running Apache 2.4.49 (which has a path traversal CVE) is actionable.
Different versions of the same software have different vulnerabilities. Apache 2.4.49 is exploitable (CVE-2021-41773). Apache 2.4.54 is patched. Without version detection, you can't prioritize targets or identify known vulnerabilities. This step transforms open ports into real intelligence.
# Service & version detection on all open ports sudo nmap -sV 192.168.1.50 -oA version-scan # Breakdown: # -sV Probe open ports to determine service/version info # Sends service-specific probes and matches responses # against nmap-service-probes database # Increase intensity for stubborn services (0-9, default: 7) sudo nmap -sV --version-intensity 9 192.168.1.50 # Light version scan (faster, less accurate) sudo nmap -sV --version-light 192.168.1.50 # Combined: SYN scan + version detection + all ports sudo nmap -sS -sV -p- 192.168.1.50 -oA full-version-scan
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.52 ((Ubuntu))
443/tcp open ssl/http nginx 1.18.0 (Ubuntu)
3306/tcp open mysql MySQL 8.0.32-0ubuntu0.22.04.2
8080/tcp open http Apache Tomcat 9.0.68
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
searchsploit Apache 2.4.52 or check exploit-db.com and nvd.nist.gov.
"I ran service version detection (-sV) to identify exact software versions on each open port. This is required to cross-reference against CVE databases and determine if any running services have known vulnerabilities. Without version information, vulnerability assessment is guesswork."
Determine the operating system running on each target host based on TCP/IP stack fingerprinting. Nmap analyzes subtle differences in how different OSes implement TCP/IP protocols.
The OS determines which exploits, privilege escalation techniques, and post-exploitation tools are applicable. A Windows Server 2012 vs Ubuntu 22.04 vs a Cisco IOS device — each requires an entirely different approach. OS detection also helps identify misconfigurations (e.g., a Windows machine on a Linux-only network).
# OS detection — requires root and at least 1 open + 1 closed port sudo nmap -O 192.168.1.50 -oA os-detect # Breakdown: # -O Enable OS detection (TCP/IP fingerprinting) # Sends specially crafted packets and compares responses # to nmap-os-db database (thousands of fingerprints) # More aggressive guessing when detection is uncertain sudo nmap -O --osscan-guess 192.168.1.50 # Limit OS detection attempts (faster, give up on hard targets) sudo nmap -O --max-os-tries 1 192.168.1.50 # The ultimate recon combo: SYN + Version + OS + Default Scripts sudo nmap -sS -sV -O -sC 192.168.1.50 -oA full-recon # Shorthand for the above: sudo nmap -A 192.168.1.50 -oA aggressive-scan
OS detection performed. Please report any incorrect results at https://nmap.org/submit/
Device type: general purpose
Running: Linux 5.X
OS CPE: cpe:/o:linux:linux_kernel:5
OS details: Linux 5.4 - 5.15
Network Distance: 1 hop
Aggressive OS guesses: Linux 5.4 (97%), Linux 5.15 (94%), Linux 5.10 (92%)
--osscan-guess to get a best-effort result. Also note: VMs and containers may fingerprint differently than bare metal.
"I performed OS detection (-O) to determine the target's operating system, which directly impacts which vulnerabilities, exploits, and post-exploitation tools are relevant. This information is essential for accurate risk assessment and for guiding the next stages of the engagement."
Use Nmap's Scripting Engine (NSE) to run vulnerability checks, brute-force tests, and advanced enumeration against discovered services. NSE transforms Nmap from a port scanner into a vulnerability scanner.
Knowing a port is open and running Apache 2.4.49 is good. Confirming it's actually vulnerable to CVE-2021-41773 with a real test is proof. NSE scripts provide that confirmation. They can also enumerate users, shares, directories, and configurations — giving you actionable findings instead of theoretical ones.
# Run default safe scripts (-sC is shorthand for --script=default) sudo nmap -sV -sC 192.168.1.50 -oA default-scripts # Run all vuln-category scripts sudo nmap -sV --script vuln 192.168.1.50 -oA vuln-scan # Run a specific script sudo nmap -sV --script http-vuln-cve2021-41773 -p 80 192.168.1.50 # Run multiple script categories sudo nmap -sV --script "vuln,safe,discovery" 192.168.1.50 # SMB enumeration (Windows targets) sudo nmap --script smb-enum-shares,smb-enum-users,smb-os-discovery -p 445 192.168.1.50 # HTTP enumeration sudo nmap --script http-enum,http-headers,http-methods,http-title -p 80,443,8080 192.168.1.50 # Pass arguments to scripts sudo nmap --script http-brute --script-args userdb=users.txt,passdb=pass.txt -p 80 192.168.1.50
| Category | Description | Safe? |
|---|---|---|
default | Safe, useful scripts that run with -sC | Yes |
safe | Scripts that won't crash services or be intrusive | Yes |
vuln | Check for known vulnerabilities | Mostly |
discovery | Discover more info about the network | Yes |
auth | Deal with authentication/credentials | Varies |
brute | Brute-force credential attacks | No |
exploit | Actively exploit vulnerabilities | No |
intrusive | May crash services or generate noise | No |
dos | Denial of service tests | No |
malware | Check for malware/backdoors on target | Yes |
exploit, brute, dos, and intrusive categories can crash services, lock accounts, or cause outages. NEVER run them without explicit authorization and an understanding of the risks. Stick to vuln, safe, and default unless you have a specific reason and permission.
"I used NSE scripts in the vuln category to validate whether identified services have known vulnerabilities. This provides concrete evidence of exploitable weaknesses rather than theoretical risk. I limited scripts to safe/vuln categories to avoid service disruption."
A decision framework to choose the right Nmap scan type based on your situation: root access, stealth requirements, network type, and goal.
Q: Do you have root/sudo access? │ ├── NO │ └── Use -sT (TCP Connect) — only option without root │ └── YES │ Q: Do you need to be stealthy? │ ├── YES │ │ │ Q: Is the target behind a firewall? │ │ │ ├── YES → Try -sS first. If blocked, try -sF/-sX/-sN │ │ Add -f (fragment packets) + -D (decoys) │ │ │ └── NO → Use -sS (SYN scan) — fast & stealthy │ └── NO (speed matters more) │ Q: Need UDP services too? │ ├── YES → -sS -sU (combined TCP + UDP) │ └── NO → -sS with -T4 for speed
| Scenario | Scan Type | Flags |
|---|---|---|
| Default / first scan | SYN | -sS |
| No root access | Connect | -sT |
| Need UDP (DNS, SNMP) | UDP | -sU --top-ports 20 |
| Behind firewall | FIN/Xmas/Null | -sF / -sX / -sN |
| Map firewall rules | ACK | -sA |
| Full recon (all info) | Aggressive | -A (= -sV -O -sC --traceroute) |
| Quick check, few ports | SYN + specific | -sS -p 22,80,443 |
| CTF / lab (no stealth needed) | Aggressive | -A -T4 -p- |
Understanding the trade-off between scanning speed and detection risk, and how to calibrate your approach based on the engagement type.
| Approach | Speed | Noise | Flags | When |
|---|---|---|---|---|
| Ghost | Very slow | Minimal | -sS -T0 -f --data-length 24 -D RND:5 |
Red team engagements with active SOC monitoring |
| Quiet | Slow | Low | -sS -T2 --max-rate 10 |
Client networks with IDS/IPS |
| Normal | Medium | Medium | -sS -T3 |
Standard pentest with authorization |
| Fast | Fast | High | -sS -T4 --min-rate 1000 |
Lab environments, CTFs, time-constrained |
| Insane | Fastest | Maximum | -T5 --min-rate 5000 |
Your own lab only — may miss ports or crash services |
-T3 is the default. Use -T4 for most authorized engagements. Only use -T0/-T1 if you're specifically testing IDS evasion. Never use -T5 on production networks.
Techniques for scanning targets protected by firewalls, intrusion detection/prevention systems, or hosts that show all ports as "filtered."
# Fragment packets — split probes into tiny fragments sudo nmap -sS -f 192.168.1.50 # -f Fragment packets into 8-byte chunks (harder for firewalls to reassemble) # -ff Fragment into 16-byte chunks (even smaller) # Decoy scan — hide your IP among fake source IPs sudo nmap -sS -D RND:5 192.168.1.50 # -D RND:5 Generate 5 random decoy IPs alongside your real scan # Target sees 6 scanners — can't tell which is real # Spoof source port (some firewalls allow traffic from port 53/80) sudo nmap -sS --source-port 53 192.168.1.50 # Add random data to packets (avoid signature detection) sudo nmap -sS --data-length 24 192.168.1.50 # Use a specific MTU (must be multiple of 8) sudo nmap -sS --mtu 24 192.168.1.50 # Idle/zombie scan — scan using a third-party zombie host sudo nmap -sI zombie-host:port 192.168.1.50 # -sI Completely hides your IP — uses predictable IP-ID of zombie # The ultimate stealth scan (complex to set up) # MAC address spoofing sudo nmap -sS --spoof-mac Dell 192.168.1.50 # --spoof-mac Dell Random Dell MAC # --spoof-mac 0 Completely random MAC
Ports showing as "filtered"? │ ├── Try -Pn (skip host discovery, assume alive) │ ├── Still filtered? → Try -sA (ACK scan to map firewall rules) │ └── Shows unfiltered? → Firewall is stateless → Try -sF/-sX/-sN │ ├── Still blocked? → Try -f (fragment) + --source-port 53 │ ├── Still blocked? → Try --data-length 24 + -T2 (slow & padded) │ └── Last resort → -sI zombie:port (idle scan through third-party)
Nmap's timing templates (-T0 through -T5) control scan speed by adjusting parallelism, timeouts, and retry limits. Higher numbers = faster but noisier.
| Template | Name | Speed | Stealth | Description |
|---|---|---|---|---|
-T0 | Paranoid | ~5 min/port | Maximum | 1 port at a time, 5 min between probes. IDS evasion. |
-T1 | Sneaky | ~15 sec/port | Very high | Serial scanning, 15 sec between probes. |
-T2 | Polite | Slow | High | Serial, 0.4 sec delay. Won't overwhelm the network. |
-T3 | Normal | Default | Medium | Nmap default. Balanced speed/reliability. |
-T4 | Aggressive | Fast | Low | Recommended for authorized pentests. Parallel + short timeouts. |
-T5 | Insane | Fastest | None | Lab only. Sacrifices accuracy for speed. May miss open ports. |
# Set maximum packets per second sudo nmap -sS --max-rate 100 192.168.1.0/24 # Set minimum packets per second (force speed) sudo nmap -sS --min-rate 1000 192.168.1.0/24 # Control parallelism (how many hosts at once) sudo nmap -sS --min-parallelism 10 --max-parallelism 50 192.168.1.0/24 # Set host timeout (skip hosts taking too long) sudo nmap -sS --host-timeout 30s 192.168.1.0/24 # Set per-probe retransmission limits sudo nmap -sS --max-retries 2 192.168.1.0/24
Understanding the six possible port states that Nmap reports and what each one means for your reconnaissance.
| State | Meaning | SYN Scan Response | Action |
|---|---|---|---|
| open | A service is actively listening and accepting connections | SYN/ACK received | Enumerate! Run -sV and NSE scripts |
| closed | Port is reachable but no service is listening | RST received | Host is alive. Port may open later. Note it. |
| filtered | A firewall/filter is blocking probes — can't determine state | No response / ICMP unreachable | Try evasion techniques (-f, -D, different scan type) |
| unfiltered | Port is reachable but can't determine open/closed (ACK scan) | RST received (ACK scan) | Use SYN or Connect scan to determine actual state |
| open|filtered | Can't determine if open or filtered (UDP/FIN/Xmas/Null scans) | No response | Try version scan (-sV) to differentiate |
| closed|filtered | Can't determine if closed or filtered (IP ID idle scan) | Rare edge case | Use different scan type for confirmation |
A guide to spotting high-value targets and dangerous misconfigurations in your scan results.
| Finding | Port(s) | Risk | Why It's Bad |
|---|---|---|---|
| FTP (especially anonymous) | 21 | HIGH | Cleartext creds, anonymous upload/download, bounce attacks |
| Telnet | 23 | HIGH | Cleartext everything — should never be exposed |
| SSH (old version) | 22 | MED | Old OpenSSH = known CVEs. Check version carefully. |
| SMTP (open relay) | 25 | HIGH | Can be abused for spam, phishing, spoofing |
| DNS (zone transfer) | 53 | MED | Exposes full internal DNS map |
| HTTP (no HTTPS) | 80 | MED | Cleartext traffic, potential for MITM |
| SMB | 445 | HIGH | EternalBlue, null sessions, share enumeration |
| MySQL/PostgreSQL | 3306/5432 | HIGH | Database exposed to network — possible data breach |
| RDP | 3389 | HIGH | BlueKeep, brute-force target, should not be internet-facing |
| VNC | 5900 | HIGH | Often weak/no auth, cleartext |
| Redis | 6379 | CRIT | Often no auth, RCE via config manipulation |
| Memcached | 11211 | HIGH | No auth, DDoS amplification, data leak |
Once you have service versions, systematically check them against vulnerability databases to find known exploits.
# 1. Use searchsploit (local ExploitDB mirror, comes with Kali) searchsploit Apache 2.4.52 searchsploit OpenSSH 8.9 searchsploit MySQL 8.0 # 2. Get more details on a specific exploit searchsploit -x 50383 # View exploit details searchsploit -m 50383 # Copy exploit to current directory # 3. Online resources (when searchsploit isn't enough) # https://www.exploit-db.com ← ExploitDB (full database) # https://nvd.nist.gov ← NVD (CVE details + CVSS scores) # https://cve.mitre.org ← CVE catalog # https://vulners.com ← Aggregated vuln search # 4. Use Nmap NSE for automated checking sudo nmap -sV --script vulners 192.168.1.50 # The 'vulners' script queries the vulners.com API # and shows CVEs for detected service versions
How to rank your findings from "fix now" to "noted" using a practical risk matrix.
| Priority | Criteria | Example | Action |
|---|---|---|---|
| 🔴 CRITICAL | Known RCE exploit exists, service is public-facing, no auth required | EternalBlue on SMB 445, Redis no auth, Apache path traversal | Immediate remediation. Notify client ASAP. |
| 🟠 HIGH | Exploitable vulnerability, requires some conditions (auth, network position) | Old OpenSSH version, exposed MySQL, RDP without NLA | Remediate within 24-48 hours. |
| 🟡 MEDIUM | Misconfiguration or outdated service, not directly exploitable | HTTP without HTTPS, verbose error pages, missing headers | Include in report, remediate within sprint. |
| 🔵 LOW | Informational finding, best practice violation | Server version disclosure, unnecessary open ports | Include in report as recommendation. |
| ⚪ INFO | Observed behavior, no risk | OS type detected, network topology mapped | Document for reference. |
How to structure your report so both executives (no tech knowledge) and engineers (want all the details) can use it.
REPORT STRUCTURE:
1. EXECUTIVE SUMMARY (1 page max)
├── Engagement overview (who, what, when, why)
├── Key findings summary (plain English, no jargon)
├── Overall risk rating (Critical / High / Medium / Low)
└── Top 3 recommendations (actionable, prioritized)
2. SCOPE & METHODOLOGY
├── Authorized targets and boundaries
├── Tools used and versions
├── Scan types performed and justification
└── Testing timeline
3. FINDINGS (per finding)
├── Title (descriptive, e.g., "Exposed MySQL Database on 192.168.1.50:3306")
├── Risk Rating (Critical/High/Medium/Low)
├── Description (what was found)
├── Evidence (screenshots, Nmap output, exact command used)
├── Impact (what could an attacker do with this?)
├── Remediation (specific steps to fix)
└── References (CVE links, vendor advisories)
4. APPENDICES
├── Full Nmap output files
├── Target list and exclusion list
├── Raw scan data (XML files)
└── Tool version information
Document every action you take with a justification — the "why" behind every command. This is your defense when a senior or auditor asks, "Why did you do this?"
ACTION LOG FORMAT:
Timestamp: 2026-02-22 14:30 UTC
Action: SYN scan on 192.168.1.0/24
Command: sudo nmap -sS -p- -oA full-syn-192.168.1.0 192.168.1.0/24
Justification: Full port scan required to identify all open services after
initial host discovery revealed 12 live hosts. SYN scan chosen
for speed and stealth per engagement rules.
Result: Found 47 open ports across 12 hosts. Key findings:
- 192.168.1.50: Port 3306 (MySQL) open — investigate further
- 192.168.1.100: Port 445 (SMB) open — check for EternalBlue
Output File: scans/full-syn-192.168.1.0-20260222.nmap
Securely archive all engagement data and clean up sensitive material from your attack machine after the engagement is complete.
# 1. Archive everything into a compressed, encrypted file tar czf project-name-$(date +%Y%m%d).tar.gz ~/engagements/project-name/ # 2. Encrypt the archive (GPG) gpg -c --cipher-algo AES256 project-name-20260222.tar.gz # 3. Verify the encrypted archive gpg -d project-name-20260222.tar.gz.gpg | tar tzf - # 4. Securely delete originals (shred, not rm) shred -vfz -n 3 ~/engagements/project-name/scans/* rm -rf ~/engagements/project-name/ # 5. Clear bash history of sensitive commands history -c cat /dev/null > ~/.bash_history
| Flag | Description | When to Use |
|---|---|---|
-sn | Ping scan — discover hosts, skip port scan | First step: find live hosts |
-Pn | Skip host discovery — treat all hosts as alive | Hosts behind firewalls blocking pings |
-PS<ports> | TCP SYN discovery | ICMP blocked, try TCP probes |
-PA<ports> | TCP ACK discovery | Bypass stateless firewalls |
-PU<ports> | UDP discovery | Find hosts with UDP-only services |
-PE | ICMP echo request | Standard ping (often blocked externally) |
-PP | ICMP timestamp request | Alternate ICMP when echo is filtered |
-PM | ICMP address mask request | Rare, another ICMP alternative |
-PR | ARP discovery | Local networks — fastest method |
-n | Never do DNS resolution | Speed up scan, avoid DNS noise |
-R | Always resolve DNS | Want hostnames for all IPs |
| Flag | Description | When to Use |
|---|---|---|
-sS | SYN scan (half-open, stealthy) | Default for most scans (requires root) |
-sT | TCP connect scan (full handshake) | When you don't have root/sudo |
-sU | UDP scan | Finding DNS, SNMP, DHCP, TFTP |
-sA | ACK scan | Map firewall rules (find unfiltered ports) |
-sF | FIN scan | Bypass basic firewalls/IDS |
-sX | Xmas scan (FIN+PSH+URG) | Bypass basic firewalls/IDS |
-sN | Null scan (no flags set) | Bypass basic firewalls/IDS |
-sW | Window scan | Distinguish open/closed on some OSes |
-sI <zombie> | Idle/zombie scan | Maximum stealth — hides your IP entirely |
| Flag | Description | Example |
|---|---|---|
-p <ports> | Scan specific ports | -p 22,80,443 |
-p- | Scan all 65,535 ports | -p- |
-p 1-1000 | Scan port range | -p 1-1000 |
--top-ports <n> | Scan top N most common ports | --top-ports 100 |
-F | Fast scan (top 100 ports) | -F |
-r | Scan ports sequentially (not randomized) | -r |
| Flag | Description | When to Use |
|---|---|---|
-sV | Version detection | Always — identifies software versions |
--version-intensity <0-9> | Set version detection effort | Increase if services aren't identified |
--version-light | Light mode (intensity 2) | Quick scan, less accuracy |
--version-all | Max mode (intensity 9) | Need definitive version info |
-O | OS detection | Determine target operating system |
--osscan-guess | Aggressive OS guessing | When detection is uncertain |
-A | Aggressive (-sV -O -sC --traceroute) | Full recon — use in labs/CTFs |
| Flag | Description | Example |
|---|---|---|
-sC | Run default scripts | -sC (same as --script=default) |
--script <name> | Run specific script(s) | --script vuln |
--script-args | Pass args to scripts | --script-args userdb=u.txt |
--script-updatedb | Update script database | After adding new scripts |
--script-help <name> | Show script help | --script-help smb-enum-shares |
| Flag | Description | When to Use |
|---|---|---|
-T<0-5> | Timing template | See Section 2.4 for details |
--min-rate <n> | Minimum packets/sec | Force faster scanning |
--max-rate <n> | Maximum packets/sec | Throttle to avoid detection |
--max-retries <n> | Max probe retransmissions | Reduce retries for speed |
--host-timeout <time> | Give up on host after time | Skip unresponsive hosts |
--scan-delay <time> | Delay between probes | IDS evasion |
| Flag | Description | When to Use |
|---|---|---|
-f | Fragment packets | Bypass packet inspection |
-D <decoys> | Cloak scan with decoy IPs | Hide source among fake scanners |
-S <IP> | Spoof source IP | Specific spoofing scenarios |
--source-port <n> | Spoof source port | Exploit firewall rules (53, 80) |
--data-length <n> | Append random data to packets | Avoid size-based signatures |
--spoof-mac <mac> | Spoof MAC address | Bypass MAC filtering |
--mtu <n> | Set custom MTU (must be ×8) | Fine-grained fragmentation |
--badsum | Send packets with bad checksums | Test firewall/IDS behavior |
| Flag | Description | When to Use |
|---|---|---|
-oN <file> | Normal output | Human-readable report |
-oX <file> | XML output | Import into tools (Metasploit, etc.) |
-oG <file> | Grepable output | Parsing with grep/awk/cut |
-oA <base> | All three formats | Always use this — covers all bases |
-v / -vv | Increase verbosity | See results in real-time |
-d / -dd | Debug mode | Troubleshooting Nmap itself |
--reason | Show why port is in its state | Understanding scan results |
--open | Only show open ports | Clean output, skip closed/filtered |
| Flag / Format | Description | Example |
|---|---|---|
| Single IP | One host | 192.168.1.1 |
| CIDR | Subnet | 192.168.1.0/24 |
| Range | IP range | 192.168.1.1-50 |
| Hostname | DNS name | scanme.nmap.org |
-iL <file> | Read targets from file | -iL targets.txt |
--exclude <hosts> | Exclude hosts | --exclude 192.168.1.1 |
--excludefile <file> | Exclude from file | --excludefile skip.txt |
# Step 1: Discover live hosts sudo nmap -sn 192.168.1.0/24 -oA 01-discovery # Step 2: Quick port scan on live hosts sudo nmap -sS --top-ports 1000 -iL live-hosts.txt -oA 02-port-scan # Step 3: Full port scan on interesting hosts sudo nmap -sS -p- 192.168.1.50 -oA 03-full-ports # Step 4: Service + version + OS + default scripts sudo nmap -sS -sV -O -sC -p 22,80,443,3306 192.168.1.50 -oA 04-enum # Step 5: Vulnerability scan sudo nmap -sV --script vuln -p 22,80,443,3306 192.168.1.50 -oA 05-vuln
# One-liner: all ports, all info, aggressive timing sudo nmap -A -T4 -p- 10.10.10.5 -oA htb-target # Quick recon with vuln check sudo nmap -sV -sC --script vuln -T4 10.10.10.5 -oA htb-vuln
# Slow, fragmented, decoy scan — maximum stealth sudo nmap -sS -T2 -f -D RND:5 --data-length 24 --source-port 53 -p 22,80,443,445,3389 192.168.1.50 -oA stealth-scan
# Windows-focused scan: SMB, RDP, WinRM, LDAP, Kerberos sudo nmap -sS -sV -sC -p 21,22,53,80,88,135,139,389,443,445,636,3268,3269,3389,5985,5986 192.168.1.50 -oA windows-enum # SMB-specific enumeration sudo nmap --script "smb-*" -p 445 192.168.1.50 -oA smb-enum
# Web-focused enumeration: HTTP scripts sudo nmap -sV --script "http-enum,http-headers,http-methods,http-title,http-robots.txt,http-shellshock,http-vuln*" -p 80,443,8080,8443 192.168.1.50 -oA web-enum
# Top 20 UDP ports — catches DNS, SNMP, DHCP, TFTP, NTP sudo nmap -sU -sV --top-ports 20 192.168.1.50 -oA udp-quick # SNMP enumeration (if port 161 found open) sudo nmap -sU -sV --script snmp-info,snmp-sysdescr,snmp-netstat -p 161 192.168.1.50
| Error / Symptom | Cause | Fix |
|---|---|---|
You requested a scan type which requires root privileges |
Running SYN/OS scan without root | Use sudo or switch to -sT |
Note: Host seems down |
ICMP blocked by firewall | Add -Pn to skip host discovery |
All ports show as filtered |
Firewall blocking all probes | Try -f, -sF/-sX, or --source-port 53 |
| Scan is extremely slow | Many filtered ports causing timeouts | Use --max-retries 1 + --host-timeout 30s |
OS detection says No exact OS matches |
Need 1 open + 1 closed port | Use --osscan-guess or scan all ports first |
| UDP scan taking forever | UDP is inherently slow (no handshake) | Limit with --top-ports 20 or -p 53,161,500 |
RTTVAR has grown to over X |
Network latency / packet loss | Slow down: -T2 or --max-rate 50 |
Service version shows tcpwrapped |
TCP connection completed but service sent nothing | Service is protected by TCP wrappers. Try NSE scripts. |
Failed to open device eth0 |
Interface is down or wrong name | Run ip a to check interface names, use -e <iface> |
| State | SYN Scan Response | Connect Scan | UDP Scan | Meaning |
|---|---|---|---|---|
| open | SYN/ACK | Connection succeeds | UDP response | Service is listening |
| closed | RST | Connection refused | ICMP port unreachable | Reachable but nothing listening |
| filtered | No response / ICMP error | No response / ICMP error | No response | Firewall is blocking |
| unfiltered | N/A | N/A | N/A | ACK scan only — port reachable but unknown state |
| open|filtered | N/A | N/A | No response | Can't tell — try -sV |
| closed|filtered | N/A | N/A | N/A | Idle scan edge case |
| Port | Protocol | Service | Notes |
|---|---|---|---|
| 20-21 | TCP | FTP | File Transfer Protocol (data + control) |
| 22 | TCP | SSH | Secure Shell — remote access |
| 23 | TCP | Telnet | Insecure remote access — avoid |
| 25 | TCP | SMTP | Email sending |
| 53 | TCP/UDP | DNS | Domain Name System |
| 67-68 | UDP | DHCP | Dynamic Host Configuration |
| 69 | UDP | TFTP | Trivial FTP — no auth |
| 80 | TCP | HTTP | Web traffic (unencrypted) |
| 88 | TCP | Kerberos | Windows authentication |
| 110 | TCP | POP3 | Email retrieval |
| 111 | TCP/UDP | RPCbind | RPC port mapper (NFS, NIS) |
| 135 | TCP | MSRPC | Microsoft RPC (Windows) |
| 139 | TCP | NetBIOS | Windows file sharing (legacy) |
| 143 | TCP | IMAP | Email retrieval |
| 161 | UDP | SNMP | Network monitoring — often misconfigured |
| 389 | TCP | LDAP | Directory services (Active Directory) |
| 443 | TCP | HTTPS | Encrypted web traffic |
| 445 | TCP | SMB | Windows file sharing — high-value target |
| 993 | TCP | IMAPS | Encrypted IMAP |
| 995 | TCP | POP3S | Encrypted POP3 |
| 1433 | TCP | MSSQL | Microsoft SQL Server |
| 1521 | TCP | Oracle DB | Oracle database listener |
| 2049 | TCP | NFS | Network File System |
| 3306 | TCP | MySQL | MySQL database |
| 3389 | TCP | RDP | Remote Desktop Protocol |
| 5432 | TCP | PostgreSQL | PostgreSQL database |
| 5900 | TCP | VNC | Virtual Network Computing |
| 5985-5986 | TCP | WinRM | Windows Remote Management |
| 6379 | TCP | Redis | In-memory database — often no auth |
| 8080 | TCP | HTTP Alt | Alternative HTTP (Tomcat, proxies) |
| 8443 | TCP | HTTPS Alt | Alternative HTTPS |
| 11211 | TCP/UDP | Memcached | Caching system — no auth by default |
| 27017 | TCP | MongoDB | NoSQL database — often exposed |
| Category | Description | Example Scripts | Risk |
|---|---|---|---|
auth | Authentication & credential handling | ftp-anon, ssh-auth-methods | Low |
broadcast | Discover hosts via broadcast | broadcast-dhcp-discover | Low |
brute | Brute-force password attacks | http-brute, ssh-brute | High |
default | Safe, commonly useful scripts | http-title, ssh-hostkey | Low |
discovery | Network & service discovery | dns-brute, smb-os-discovery | Low |
dos | Denial of service | http-slowloris | High |
exploit | Active exploitation | smb-vuln-ms17-010 | High |
external | Queries external services | whois-ip | Low |
fuzzer | Fuzz testing inputs | dns-fuzz | Med |
intrusive | May crash/disrupt services | Various | High |
malware | Check for malware/backdoors | http-malware-host | Low |
safe | Won't crash or harm target | http-headers, banner | Low |
version | Enhanced version detection | Runs with -sV | Low |
vuln | Vulnerability checking | http-vuln-*, smb-vuln-* | Med |
| Term | Definition |
|---|---|
| ACK | TCP acknowledgment flag — used to confirm receipt of packets |
| ARP | Address Resolution Protocol — maps IP addresses to MAC addresses on local networks |
| Banner Grabbing | Connecting to a service and reading the initial response (banner) to identify software/version |
| CIDR | Classless Inter-Domain Routing — notation for IP ranges (e.g., /24 = 256 IPs) |
| CVE | Common Vulnerabilities and Exposures — standardized vulnerability identifier |
| CVSS | Common Vulnerability Scoring System — severity rating (0.0 to 10.0) |
| Decoy | Fake source IPs used to mask the real scanner's identity |
| Enumeration | Extracting detailed information about services, users, shares, etc. |
| Fingerprinting | Identifying OS or service by analyzing unique response characteristics |
| Half-Open Scan | SYN scan — sends SYN but never completes the TCP handshake |
| ICMP | Internet Control Message Protocol — used for ping, traceroute, error messages |
| IDS | Intrusion Detection System — monitors and alerts on suspicious activity |
| IPS | Intrusion Prevention System — monitors and blocks suspicious activity |
| MTU | Maximum Transmission Unit — largest packet size on a network link |
| NSE | Nmap Scripting Engine — Lua-based framework for extending Nmap's functionality |
| Ping Sweep | Sending probes to a range of IPs to find which hosts are alive |
| Port | A numbered endpoint (0-65535) that identifies a specific service on a host |
| RCE | Remote Code Execution — ability to run arbitrary code on a target system |
| Reconnaissance | The information-gathering phase before exploitation |
| RST | TCP reset flag — abruptly terminates a connection |
| SOC | Security Operations Center — team monitoring for security incidents |
| SYN | TCP synchronize flag — initiates a connection (first step of 3-way handshake) |
| SYN/ACK | TCP response combining SYN + ACK — indicates a port is open |
| TCP | Transmission Control Protocol — connection-oriented, reliable transport |
| Three-Way Handshake | TCP connection setup: SYN → SYN/ACK → ACK |
| UDP | User Datagram Protocol — connectionless, no handshake, no guaranteed delivery |
| Zombie Scan | Idle scan using a third-party host to completely hide the scanner's identity |