Welcome to Day 29! Today you will build a full Nmap reconnaissance workflow that you can reuse across engagements. This guide combines planning, discovery, enumeration, validation, and reporting into one repeatable process.
By completing Day 29, you will be able to:
- Design a full recon workflow with clear phases
- Create consistent output structure for analysis
- Automate multi-step scans with scripts
- Combine safe and advanced scans responsibly
- Produce results ready for reporting and remediation
Only scan systems you own or have explicit written permission to test. Always follow rules of engagement and document all actions.
A full recon workflow usually includes:
- Scope and planning
- Target inventory
- Host discovery
- Service enumeration
- Protocol-specific deep dives
- Validation and verification
- Reporting and remediation guidance
Define and document:
- Approved IP ranges and domains
- Out-of-scope systems
- Allowed scan types and scripts
- Time windows and notification contacts
Build a single, validated target list:
- DNS records and subdomains
- Asset inventory exports
- Cloud inventory and external endpoints
Example targets.txt:
192.168.10.0/24
10.0.5.0/24
web01.corp.local
db01.corp.local
Use low-noise discovery to find live hosts:
nmap -sn -PR 192.168.10.0/24 -oA outputs/01-discoveryExtract live hosts:
awk '/Up$/{print $2}' outputs/01-discovery.gnmap > outputs/live.txtScan common services on live hosts:
nmap -sV --top-ports 1000 -iL outputs/live.txt -oA outputs/02-servicesTarget common internal protocols and exposed services.
nmap -p 445 --script smb-os-discovery,smb-enum-shares,smb-security-mode -iL outputs/live.txt -oA outputs/03-smbnmap -p 80,443,8080,8443 -sV --script http-title,http-headers -iL outputs/live.txt -oA outputs/04-webnmap -p 443,8443 --script ssl-cert,ssl-enum-ciphers -iL outputs/live.txt -oA outputs/05-tlsnmap -p 1433,1521,3306,5432,27017,6379 -sV --script ms-sql-info,oracle-tns-version,mysql-info,pgsql-info,mongodb-info,redis-info -iL outputs/live.txt -oA outputs/06-dbnmap -p 53 --script dns-recursion,dns-service-discovery -iL outputs/live.txt -oA outputs/07-dnsnmap -sU -p 161 --script snmp-info -iL outputs/live.txt -oA outputs/08-snmpValidate critical findings with:
- Repeat scans with safe timing
- Manual checks (browser, curl)
- Cross-checking DNS and certificates
Summarize:
- Scope and timing
- Open ports and services
- High-risk exposures
- Remediation guidance
outputs/
01-discovery.*
02-services.*
03-smb.*
04-web.*
05-tls.*
06-db.*
07-dns.*
08-snmp.*
live.txt
#!/usr/bin/env bash
set -euo pipefail
RANGE="${1:-192.168.10.0/24}"
OUTDIR="outputs/$(date +%Y%m%d-%H%M%S)"
mkdir -p "$OUTDIR"
nmap -sn -PR "$RANGE" -oA "$OUTDIR/01-discovery"
awk '/Up$/{print $2}' "$OUTDIR/01-discovery.gnmap" > "$OUTDIR/live.txt"
nmap -sV --top-ports 1000 -iL "$OUTDIR/live.txt" -oA "$OUTDIR/02-services"
nmap -p 445 --script smb-os-discovery,smb-enum-shares -iL "$OUTDIR/live.txt" -oA "$OUTDIR/03-smb"
nmap -p 80,443,8080,8443 -sV --script http-title,http-headers -iL "$OUTDIR/live.txt" -oA "$OUTDIR/04-web"
nmap -p 443,8443 --script ssl-cert,ssl-enum-ciphers -iL "$OUTDIR/live.txt" -oA "$OUTDIR/05-tls"
nmap -p 1433,1521,3306,5432,27017,6379 -sV --script ms-sql-info,oracle-tns-version,mysql-info,pgsql-info,mongodb-info,redis-info -iL "$OUTDIR/live.txt" -oA "$OUTDIR/06-db"
nmap -p 53 --script dns-recursion,dns-service-discovery -iL "$OUTDIR/live.txt" -oA "$OUTDIR/07-dns"
nmap -sU -p 161 --script snmp-info -iL "$OUTDIR/live.txt" -oA "$OUTDIR/08-snmp"
echo "Outputs in $OUTDIR"import subprocess
from datetime import datetime
from pathlib import Path
range_cidr = "192.168.10.0/24"
outdir = Path("outputs") / datetime.now().strftime("%Y%m%d-%H%M%S")
outdir.mkdir(parents=True, exist_ok=True)
def run(cmd):
print("Running:", " ".join(cmd))
subprocess.run(cmd, check=True)
run(["nmap", "-sn", "-PR", range_cidr, "-oA", str(outdir / "01-discovery")])
run(["nmap", "-sV", "--top-ports", "1000", "-iL", str(outdir / "01-discovery.gnmap"), "-oA", str(outdir / "02-services")])
run(["nmap", "-p", "445", "--script", "smb-os-discovery,smb-enum-shares", "-iL", str(outdir / "01-discovery.gnmap"), "-oA", str(outdir / "03-smb")])
run(["nmap", "-p", "80,443,8080,8443", "-sV", "--script", "http-title,http-headers", "-iL", str(outdir / "01-discovery.gnmap"), "-oA", str(outdir / "04-web")])
run(["nmap", "-p", "443,8443", "--script", "ssl-cert,ssl-enum-ciphers", "-iL", str(outdir / "01-discovery.gnmap"), "-oA", str(outdir / "05-tls")])
run(["nmap", "-p", "1433,1521,3306,5432,27017,6379", "-sV", "--script", "ms-sql-info,oracle-tns-version,mysql-info,pgsql-info,mongodb-info,redis-info", "-iL", str(outdir / "01-discovery.gnmap"), "-oA", str(outdir / "06-db")])
run(["nmap", "-p", "53", "--script", "dns-recursion,dns-service-discovery", "-iL", str(outdir / "01-discovery.gnmap"), "-oA", str(outdir / "07-dns")])
run(["nmap", "-sU", "-p", "161", "--script", "snmp-info", "-iL", str(outdir / "01-discovery.gnmap"), "-oA", str(outdir / "08-snmp")])
print("Outputs in", outdir)$Range = "192.168.10.0/24"
$OutDir = "outputs\" + (Get-Date -Format "yyyyMMdd-HHmmss")
New-Item -ItemType Directory -Path $OutDir | Out-Null
nmap -sn -PR $Range -oA "$OutDir\01-discovery"
Get-Content "$OutDir\01-discovery.gnmap" | ForEach-Object { if ($_ -match "Up$") { ($_ -split " ")[1] } } | Set-Content "$OutDir\live.txt"
nmap -sV --top-ports 1000 -iL "$OutDir\live.txt" -oA "$OutDir\02-services"
nmap -p 445 --script smb-os-discovery,smb-enum-shares -iL "$OutDir\live.txt" -oA "$OutDir\03-smb"
nmap -p 80,443,8080,8443 -sV --script http-title,http-headers -iL "$OutDir\live.txt" -oA "$OutDir\04-web"
nmap -p 443,8443 --script ssl-cert,ssl-enum-ciphers -iL "$OutDir\live.txt" -oA "$OutDir\05-tls"
nmap -p 1433,1521,3306,5432,27017,6379 -sV --script ms-sql-info,oracle-tns-version,mysql-info,pgsql-info,mongodb-info,redis-info -iL "$OutDir\live.txt" -oA "$OutDir\06-db"
nmap -p 53 --script dns-recursion,dns-service-discovery -iL "$OutDir\live.txt" -oA "$OutDir\07-dns"
nmap -sU -p 161 --script snmp-info -iL "$OutDir\live.txt" -oA "$OutDir\08-snmp"
Write-Host "Outputs in $OutDir"Linux example output (workflow run):
Outputs in outputs/20260206-1700
Windows example output (workflow run):
Outputs in outputs\20260206-1700
The outputs below are example outputs for the commands and automation in this workflow. Actual results will vary based on environment, permissions, and targets.
Command:
nmap -sn -PR 192.168.10.0/24 -oA outputs/01-discoveryExample output (Linux):
Starting Nmap 7.94 ( https://nmap.org ) at 2026-02-06 17:00 UTC
Nmap scan report for 192.168.10.1
Host is up (0.0014s latency).
MAC Address: 00:11:22:33:44:55 (Vendor)
Nmap scan report for 192.168.10.10
Host is up (0.0019s latency).
MAC Address: AA:BB:CC:DD:EE:FF (Vendor)
Nmap done: 256 IP addresses (2 hosts up) scanned in 3.70 seconds
Example output (Windows):
Starting Nmap 7.94 ( https://nmap.org ) at 2026-02-06 17:00 UTC
Nmap scan report for 192.168.10.1
Host is up (0.0025s latency).
Nmap scan report for 192.168.10.10
Host is up (0.0034s latency).
Nmap done: 256 IP addresses (2 hosts up) scanned in 4.20 seconds
Command:
nmap -sV --top-ports 1000 -iL outputs/live.txt -oA outputs/02-servicesExample output (Linux snippet):
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1
80/tcp open http Apache httpd 2.4.41
445/tcp open microsoft-ds Windows Server 2019 Standard 17763
Example output (Windows snippet):
PORT STATE SERVICE VERSION
135/tcp open msrpc Microsoft Windows RPC
445/tcp open microsoft-ds Windows Server 2016 Standard 14393
3389/tcp open ms-wbt-server Microsoft Terminal Services
Command:
nmap -p 445 --script smb-os-discovery,smb-enum-shares,smb-security-mode -iL outputs/live.txt -oA outputs/03-smbExample output (Linux snippet):
PORT STATE SERVICE
445/tcp open microsoft-ds
| smb-os-discovery:
| OS: Windows Server 2019 Standard 17763
|_ Domain name: CORP
| smb-enum-shares:
| Public:
|_ Comment: Public Share
Example output (Windows snippet):
| smb-security-mode:
|_ message_signing: enabled but not required
Command:
nmap -p 80,443,8080,8443 -sV --script http-title,http-headers -iL outputs/live.txt -oA outputs/04-webExample output (Linux snippet):
80/tcp open http
| http-title: Intranet Portal
|_Requested resource was /
| http-headers:
| Server: nginx
|_ Content-Type: text/html
Example output (Windows snippet):
443/tcp open https
| http-headers:
| Server: Microsoft-IIS/10.0
|_ X-Powered-By: ASP.NET
Command:
nmap -p 443,8443 --script ssl-cert,ssl-enum-ciphers -iL outputs/live.txt -oA outputs/05-tlsExample output (Linux snippet):
443/tcp open https
| ssl-cert: Subject: CN=intranet.corp.local
|_Not valid after: 2026-12-31
| ssl-enum-ciphers:
| TLSv1.2:
|_ ciphers: ...
Example output (Windows snippet):
8443/tcp open https
| ssl-enum-ciphers:
| TLSv1.3:
|_ ciphers: ...
Command:
nmap -p 1433,1521,3306,5432,27017,6379 -sV --script ms-sql-info,oracle-tns-version,mysql-info,pgsql-info,mongodb-info,redis-info -iL outputs/live.txt -oA outputs/06-dbExample output (Linux snippet):
3306/tcp open mysql
| mysql-info:
| Version: 8.0.33
|_ Protocol: 10
5432/tcp open postgresql
| pgsql-info:
|_ Version: 13.9
Example output (Windows snippet):
1433/tcp open ms-sql-s
| ms-sql-info:
| Version: 15.00.2000.05
|_ Product: Microsoft SQL Server 2019
Command:
nmap -p 53 --script dns-recursion,dns-service-discovery -iL outputs/live.txt -oA outputs/07-dnsExample output (Linux snippet):
53/tcp open domain
| dns-recursion:
|_ Recursion appears to be enabled
Example output (Windows snippet):
53/tcp open domain
| dns-service-discovery:
|_ \_ldap._tcp: 192.168.10.10
Command:
nmap -sU -p 161 --script snmp-info -iL outputs/live.txt -oA outputs/08-snmpExample output (Linux snippet):
161/udp open snmp
| snmp-info:
| enterprise: Cisco Systems
| location: DataCenter-1
|_ uptime: 12 days, 04:21:33
Example output (Windows snippet):
161/udp open snmp
| snmp-info:
| enterprise: Microsoft
|_ uptime: 3 days, 02:11:05
Command:
./recon.sh 192.168.10.0/24Example output (Linux/macOS):
Outputs in outputs/20260206-1700
Command:
python recon.pyExample output (Linux):
Running: nmap -sn -PR 192.168.10.0/24 -oA outputs/20260206-1705/01-discovery
Running: nmap -sV --top-ports 1000 -iL outputs/20260206-1705/01-discovery.gnmap -oA outputs/20260206-1705/02-services
Outputs in outputs/20260206-1705
Example output (Windows):
Running: nmap -sn -PR 192.168.10.0/24 -oA outputs\20260206-1705\01-discovery
Running: nmap -sV --top-ports 1000 -iL outputs\20260206-1705\01-discovery.gnmap -oA outputs\20260206-1705\02-services
Outputs in outputs\20260206-1705
Command:
.\recon.ps1Example output (Windows):
Outputs in outputs\20260206-1710
- Scanning out of scope
- Using aggressive timing on fragile systems
- Forgetting to save outputs
- Skipping validation of high-risk findings
- Start small, expand carefully
- Use safe scripts before advanced ones
- Keep scan options consistent
- Communicate with stakeholders
- Why is a phased workflow important?
- Which phase provides the most value for asset visibility?
- How do you ensure results are reproducible?
- What makes a recon report actionable?
Tomorrow (Day 30) you will complete a final practical challenge.
Congratulations on completing Day 29! You now have a full Nmap recon workflow you can reuse.