What’s a Port?
An IP address gets you to a machine. A port gets you to a service on that machine.
Ports range from 0 to 65535. When a service is running, it listens on a specific port, waiting for connections.
| Port | Service | Protocol |
|---|---|---|
| 21 | FTP | File transfer |
| 22 | SSH | Secure shell |
| 25 | SMTP | |
| 53 | DNS | Name resolution |
| 80 | HTTP | Web |
| 443 | HTTPS | Encrypted web |
| 445 | SMB | Windows file sharing |
| 3389 | RDP | Remote desktop |
Port scanning answers a simple question: which ports are open, and what’s listening on them?
TCP vs UDP
Two transport protocols. They work differently, and you scan them differently.
TCP (Transmission Control Protocol)
TCP is connection-oriented. Before any data flows, the client and server perform a three-way handshake:
- SYN — Client says “I want to connect”
- SYN-ACK — Server says “OK, I’m ready”
- ACK — Client says “Let’s go”
Only then does data start flowing. This handshake is what makes TCP reliable, and it’s also what makes TCP scanning possible.
UDP (User Datagram Protocol)
UDP is connectionless. No handshake. Packets are just sent.
This makes UDP faster but unreliable. It also makes UDP scanning much harder and slower, because there’s no handshake to confirm a port is open.
The TCP Three-Way Handshake
Understanding this handshake is the key to understanding every TCP scan type.
Nmap
Nmap is the standard port scanner. It’s the tool you’ll use most during enumeration.
SYN Scan (-sS)
The default Nmap scan (when run as root). Also called a “stealth scan.”
sudo nmap -sS 10.10.10.50How it works:
- Send a SYN packet
- If the port is open → server replies with SYN-ACK
- Nmap sends RST immediately (never completes the handshake)
- If the port is closed → server replies with RST
- If the port is filtered → no response (firewall dropped it)
Why it’s “stealthy”: The connection is never fully established, so many older logging systems don’t record it. Modern IDS systems will detect it though.
SYN scan is fast, reliable, and the default for a reason. Use it unless you have a specific need for something else.
Connect Scan (-sT)
The fallback when you don’t have root privileges.
nmap -sT 10.10.10.50This completes the full TCP handshake. It’s noisier and slower than a SYN scan, but doesn’t require raw socket access.
When to use it: When you can’t run Nmap as root, or when you need to scan through certain types of proxies.
UDP Scan (-sU)
UDP scanning is a different beast.
sudo nmap -sU 10.10.10.50Since UDP has no handshake, Nmap sends a UDP packet and waits:
- No response → port is open or filtered (can’t tell)
- ICMP “port unreachable” → port is closed
- UDP response → port is definitely open
UDP scans are very slow. Nmap limits the rate to avoid overwhelming the network. Scanning all 65535 UDP ports can take hours.
Don’t skip UDP. SNMP (161), DNS (53), and TFTP (69) are all UDP services. Missing them means missing potential entry points.
Combining TCP and UDP
Scan both in one command:
sudo nmap -sS -sU 10.10.10.50Or target specific ports to save time:
sudo nmap -sS -sU -p T:80,443,U:161,53 10.10.10.50Controlling the Scan
Port Ranges
By default, Nmap scans the top 1000 most common ports. You can change this:
nmap -p 80 10.10.10.50 # single port
nmap -p 80,443,8080 10.10.10.50 # specific ports
nmap -p 1-1000 10.10.10.50 # range
nmap -p- 10.10.10.50 # ALL 65535 portsAlways do a full port scan (
-p-) during an engagement. The default top 1000 misses services running on unusual ports, which are often the most interesting.
Timing Templates
Nmap has timing presets from -T0 (paranoid) to -T5 (insane):
| Template | Name | Use case |
|---|---|---|
-T0 | Paranoid | IDS evasion (very slow) |
-T1 | Sneaky | IDS evasion |
-T2 | Polite | Reduced bandwidth |
-T3 | Normal | Default |
-T4 | Aggressive | Fast, reliable networks |
-T5 | Insane | Very fast, may miss results |
For most engagements, -T4 is the sweet spot.
Network Sweeping
Before scanning individual hosts in detail, find out which hosts are alive.
nmap -sn 10.10.10.0/24The -sn flag means “ping scan.” No port scanning, just host discovery. It uses:
- ICMP echo requests
- TCP SYN to port 443
- TCP ACK to port 80
- ICMP timestamp requests
Greppable Output
Save results in a format you can easily parse:
nmap -sn -oG sweep.txt 10.10.10.0/24Then extract live hosts:
grep "Up" sweep.txt | cut -d " " -f 2Sweep first, scan second. Don’t waste time doing full port scans against IPs that aren’t even up.
Skipping Host Discovery (-Pn)
Here’s a common trap. You scan a target and Nmap says “host seems down.” So you move on.
But the host is up. Its firewall is just blocking pings.
By default, Nmap sends a ping before scanning. If the ping fails, it skips the host entirely. You never even get to the port scan.
The -Pn flag disables this. It tells Nmap: “Don’t bother checking if the host is alive. Just scan it.”
nmap -Pn 10.10.10.50When to use -Pn:
- Target is behind a firewall that blocks ICMP
- You know the host is up but Nmap reports it as down
- Scanning a Windows network (Windows Firewall blocks ping by default)
- You’d rather scan a dead host than miss a live one
The tradeoff: Without host discovery, Nmap will try to scan every IP you give it, even ones that are truly offline. This makes scans slower across large ranges.
If a scan returns nothing, try again with
-Pnbefore giving up. A blocked ping has cost pentesters hours of wasted time.
Service and OS Detection
Finding open ports is just the start. You need to know what’s running on them.
Service Version Detection (-sV)
nmap -sV 10.10.10.50Nmap connects to each open port and analyzes the banner (the response the service sends). It matches this against a database of known services.
The output includes the service name and version:
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1
80/tcp open http Apache httpd 2.4.41 Knowing the exact version is critical. It lets you search for specific CVEs and exploits.
OS Fingerprinting (-O)
sudo nmap -O 10.10.10.50Nmap analyzes subtle differences in how the OS constructs TCP/IP packets (TTL values, window sizes, TCP options) to guess the operating system.
Not always accurate, but gives you a starting point.
The Kitchen Sink (-A)
nmap -A 10.10.10.50Enables everything: OS detection, version detection, script scanning, and traceroute. Generates more traffic, but gives you the most information in one scan.
Nmap Scripting Engine (NSE)
NSE extends Nmap with scripts that automate enumeration, brute-forcing, and vulnerability detection.
Scripts live in /usr/share/nmap/scripts/. There are hundreds of them.
Running a Script
nmap --script http-headers 10.10.10.50This runs the http-headers script, which grabs HTTP response headers from web servers.
Learning About Scripts
nmap --script-help http-headersShows what the script does, its categories, and usage examples.
Useful Script Categories
| Category | What it does |
|---|---|
auth | Authentication bypass and brute-force |
discovery | Service and host discovery |
vuln | Vulnerability detection |
safe | Non-intrusive scripts |
default | Scripts that run with -sC |
Run all default scripts with version detection:
nmap -sC -sV 10.10.10.50NSE scripts are one of Nmap’s most powerful features. There are scripts for SMB enumeration, SNMP queries, HTTP directory listing, SSL analysis, and much more. Explore them.
Port Scanning from Windows
Sometimes you land on a Windows machine with no tools. PowerShell can do basic port scanning.
Single Port Check
Test-NetConnection -Port 445 10.10.10.50The TcpTestSucceeded field tells you if the port is open.
Scanning a Range
Test-NetConnection is slow and verbose. For scanning multiple ports, use a TcpClient directly:
1..1024 | % {echo ((New-Object
Net.Sockets.TcpClient).Connect("10.10.10.50",
$_)) "TCP port $_ is open"} 2>$nullThis loops through ports 1-1024, attempts a TCP connection to each, and prints the open ones. It’s crude, but it works when you have nothing else.
Living off the land matters. In real engagements, you’ll often need to scan from a compromised host where you can’t install tools.