Nmap: The First Thing You Run on Everything
- Tony Kelly
- May 25
- 8 min read

Series: The Community's Red Team
Post: 02 of 16
Tags: nmap, recon, enumeration, port scanning, tools
Read time: ~12 min
Prerequisites: Post 01 — Red Team Methodology Overview
Before you can attack anything, you need to know it exists. Before you know it exists, something has to scan for it. That something is Nmap — Network Mapper — and it's the first tool you'll run on every single target, without exception.
Nmap has been around since 1997. It's open source, it's on every major security distribution, and it's so standard that you'll find it in the toolkit of everyone from junior CTF players to seasoned red teamers billing $300 an hour. The reason it's lasted this long is simple: it does its job better than anything else, and its job is foundational to everything that comes after it.
This post covers Nmap end to end — what it does, how to use it efficiently, the flags that matter, and how to read the output to build your actual attack plan.
What Nmap Actually Does
At its core, Nmap sends packets to a target and listens for responses. From those responses it determines:
Which ports are open (something is listening)
Which ports are closed (the port exists but nothing is listening)
Which ports are filtered (a firewall is blocking the response)
What software is running on each open port
What version that software is
Sometimes what operating system the machine is running
This information is your attack surface. Without it you're blind. With it, you know exactly which doors to try.
The Flags That Matter
You don't need to memorize every Nmap flag. You need to know the ones you'll actually use, and understand what they're doing so you can adjust when something doesn't work.
Flag | What it does |
-sC | Runs default NSE scripts — safe, informative, always use this |
-sV | Detects service versions — what software, what version |
-sU | UDP scan — required for SNMP, DNS, TFTP |
-O | OS detection — needs sudo |
-A | Aggressive: combines -sC, -sV, -O, and traceroute |
-p- | Scan all 65535 ports, not just the top 1000 |
-p 80,443 | Scan specific ports only |
--top-ports 1000 | Default behavior — top 1000 most common ports |
-T4 | Timing level 4 (fast) — good for lab environments |
-Pn | Skip host discovery, treat all hosts as up |
--open | Only show open ports in output |
-oN | Save output in normal readable format |
-oG | Save output in grepable format (useful for scripting) |
-oA | Save all three output formats at once |
--script | Run a specific NSE script or category |
-v / -vv | Verbose — show results as they come in, not at the end |
The ones you'll type on autopilot: -sC -sV -p- -oN output.txt. Everything else is situational.
The Standard Workflow
Every target gets hit in the same sequence. This saves time because you start with a fast wide scan to find open ports, then go deeper only on what's actually there — instead of running slow detailed scans against all 65535 ports from the start.
Step 1 — Fast Full Port Scan
nmap -T4 --open -p- <target> -oN initial.txt
This scans all 65535 TCP ports as fast as practically useful. -T4 is fast without being reckless. --open filters output to only show ports that are actually open so you're not reading through pages of closed ports. -oN initial.txt saves the result.
This scan tells you what's there. It won't tell you much about what's running.
Step 2 — Detailed Scan on Open Ports Only
Take the port numbers from Step 1 and run the detailed scan only against those:
nmap -sC -sV -p 22,80,445 <target> -oN detailed.txt
This runs default scripts and version detection against the open ports you already know about. Running -sV against all 65535 ports from the start wastes time probing ports that have nothing on them. This two-step approach gets you full information faster.
Step 3 — UDP Scan
sudo nmap -sU --top-ports 100 <target> -oN udp.txt
UDP scans are slow, which is why you limit to top 100 ports. What you're looking for: SNMP on 161, DNS on 53, TFTP on 69, and IPMI on 623. Any of these being open dramatically changes your enumeration path. Don't skip this step and then wonder why you missed a critical service.
UDP scanning requires sudo because it needs raw packet access.
Step 4 — OS Detection (When You Need It)
sudo nmap -O -sV <target>
OS detection is most useful when you need to know Windows vs. Linux to decide which attack paths to pursue — different privilege escalation techniques, different credential storage locations, different lateral movement options. Nmap guesses based on TCP/IP stack behavior and it's usually right, but not always. Treat it as a strong hint, not ground truth.
Step 5 — Full Aggressive (When Stealth Doesn't Matter)
nmap -A -p- <target> -oN aggressive.txt
The nuclear option. Combines everything — version detection, default scripts, OS detection, and traceroute — against all ports. This is noisy as hell and will trigger any halfway decent IDS. For CTF boxes and lab environments where stealth is irrelevant, it's convenient. In real engagements, use it only when you've confirmed noise doesn't matter.
NSE Scripts: Where Nmap Gets Powerful
NSE stands for Nmap Scripting Engine. It's a library of scripts that run against open ports and extract specific information. Default scripts (-sC) run a safe subset automatically. The interesting ones you run manually when you know what you're looking at.
Vulnerability Scanning
nmap --script vuln <target>
Runs the vuln category — checks for known CVEs, misconfigurations, and common vulnerabilities. This is a good sweep when you find an unusual version number and want a quick check before pulling up a browser.
SMB Scripts
nmap --script smb-enum-shares,smb-enum-users,smb-vuln-ms17-010 -p 445 <target>
smb-enum-shares lists all shares and their permissions. smb-enum-users attempts to enumerate domain/local users. smb-vuln-ms17-010 checks for EternalBlue — the NSA exploit that powered WannaCry. Still works on unpatched Windows 7 and Server 2008 machines more often than it should.
HTTP Scripts
nmap --script http-enum,http-title,http-methods -p 80,443 <target>
http-enum brute forces common web paths and reports what it finds. http-title grabs page titles — useful for quick fingerprinting without opening a browser. http-methods reveals what HTTP methods the server accepts (DELETE, PUT, TRACE — any of these being enabled is worth investigating).
FTP Scripts
nmap --script ftp-anon,ftp-bounce -p 21 <target>
ftp-anon checks if anonymous login is allowed. If it comes back positive, connect immediately and list everything — you'd be surprised what gets left on FTP servers with anonymous access. ftp-bounce checks for a decades-old FTP feature that can be abused to port scan other hosts through the FTP server.
LDAP Scripts
nmap --script ldap-search,ldap-rootdse -p 389 <target>
ldap-rootdse queries the root directory service entry — gives you domain name, Active Directory functional level, and naming context. Useful for building the full picture of an AD environment before you start digging deeper.
Reading the Output: What to Actually Look At
A detailed Nmap result gives you a lot of information. Here's what to focus on:
Service Banners
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
Apache httpd 2.4.41 on Ubuntu. Google that version. Does it have CVEs? Check ExploitDB. Check Metasploit. The version number is always the first thing you search.
SSL Certificate Details
| ssl-cert: Subject: commonName=dev.inlanefreight.local
A hostname in an SSL certificate that wasn't in your scope. Add it to /etc/hosts immediately and scan it separately. SSL certs reveal internal hostnames, subdomains, and sometimes email addresses for the organization.
echo "<ip> dev.inlanefreight.local" | sudo tee -a /etc/hosts
OS Guesses
Aggressive OS guesses: Windows Server 2016 (93%)
93% confidence is usually right. Windows Server 2016 has a specific set of known vulnerabilities and attack paths — this tells you where to look next.
Script Output
| smb-vuln-ms17-010:
| VULNERABLE:
| Remote Code Execution vulnerability in Microsoft SMBv1
This is what you want to see. SMB signing status, anonymous access allowed, vulnerability confirmations — script output is where Nmap goes from a port scanner to a security assessment tool.
Parsing Grepable Output
When you save with -oG or -oA, you can script against the output to extract exactly what you need:
# Extract open ports as comma-separated list for the next scan
grep "/open" initial.gnmap | grep -oP '\d+(?=/open)' | tr '\n' ',' | sed 's/,$//'
# Find all hosts with port 445 open
awk '/445\/open/ {print $2}' initial.gnmap
# Find all hosts with port 3389 open (RDP targets)
awk '/3389\/open/ {print $2}' initial.gnmap
This becomes useful when you're scanning subnets with multiple hosts. Pull all the RDP targets into one list, all the SMB targets into another, and run service-specific enumeration against each group.
Common Problems and Fixes
Everything shows as filtered. The host might be blocking ICMP pings so Nmap thinks it's down. Add -Pn to skip host discovery:
nmap -Pn -sC -sV -p- <target>
Scan is extremely slow. If you're on a slow connection or scanning through a tunnel, drop the timing or scan fewer ports at once. -T2 instead of -T4, or scan port ranges in chunks.
Need sudo but don't want to run the whole scan as root. SYN scans (-sS, the default when run as root) and OS detection require root. Run without sudo and Nmap falls back to a connect scan, which is louder but doesn't need elevated privileges.
Ports showing as open|filtered. This is a UDP scan result meaning Nmap sent a probe and got no response — either the port is open and not responding to that probe type, or a firewall dropped the packet. Try a service-specific probe or enumerate the port directly with the service's own client.
Building Your Attack Plan from Nmap Output
When you've finished scanning, you should have answers to these questions:
What services are running, and what versions? Every version gets searched for CVEs.
Is there a web server? If port 80 or 443 is open, Gobuster and Nikto are next (Posts 03 and 04).
Is SMB open? Port 139 or 445 means Enum4linux and CrackMapExec next (Posts 05 and 06).
Are there Windows-specific ports? Ports 88 (Kerberos), 389 (LDAP), 3268 (Global Catalog), or 5985 (WinRM) together indicate an Active Directory environment — a completely different attack chain.
Are there database ports? 1433 (MSSQL), 3306 (MySQL), 1521 (Oracle) — each has its own enumeration and exploitation path.
Did you get any hostnames? Add them all to /etc/hosts before doing anything else.
Your Nmap output is the index. Everything else in your engagement flows from it.
Quick Reference
# Standard workflow
nmap -T4 --open -p- <target> -oN initial.txt
nmap -sC -sV -p <ports> <target> -oN detailed.txt
sudo nmap -sU --top-ports 100 <target> -oN udp.txt
# OS detection
sudo nmap -O -sV <target>
# Full aggressive
nmap -A -p- <target> -oN aggressive.txt
# NSE — vuln sweep
nmap --script vuln <target>
# NSE — SMB
nmap --script smb-enum-shares,smb-enum-users,smb-vuln-ms17-010 -p 445 <target>
# NSE — HTTP
nmap --script http-enum,http-title,http-methods -p 80,443 <target>
# NSE — FTP
nmap --script ftp-anon,ftp-bounce -p 21 <target>
# NSE — LDAP
nmap --script ldap-search,ldap-rootdse -p 389 <target>
# Skip host discovery (when ICMP is blocked)
nmap -Pn -sC -sV -p- <target>
# Parse grepable output for open ports
grep "/open" initial.gnmap | grep -oP '\d+(?=/open)' | tr '\n' ','
What's Next
With your port map built, the next step depends on what you found. The most common result in CTFs and real environments is a web server — port 80 or 443 is open on almost everything. That means Post 03 is where most paths go next: Gobuster for directory and DNS brute forcing to find what the web server isn't supposed to show you.
If you found SMB instead, jump to Post 05 on Enum4linux. The series is designed so each post references which other posts are relevant to your specific findings — follow the chain, not the sequence.
MeshForge — Training the Community's Red Team
They count on your ignorance. The exploit only works on the uninformed.



Comments