Port Scanning

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.

PortServiceProtocol
21FTPFile transfer
22SSHSecure shell
25SMTPEmail
53DNSName resolution
80HTTPWeb
443HTTPSEncrypted web
445SMBWindows file sharing
3389RDPRemote 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:

  1. SYN — Client says “I want to connect”
  2. SYN-ACK — Server says “OK, I’m ready”
  3. 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.50

How it works:

  1. Send a SYN packet
  2. If the port is open → server replies with SYN-ACK
  3. Nmap sends RST immediately (never completes the handshake)
  4. If the port is closed → server replies with RST
  5. 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.50

This 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.50

Since 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.50

Or target specific ports to save time:

sudo nmap -sS -sU -p T:80,443,U:161,53 10.10.10.50

Controlling 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 ports

Always 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):

TemplateNameUse case
-T0ParanoidIDS evasion (very slow)
-T1SneakyIDS evasion
-T2PoliteReduced bandwidth
-T3NormalDefault
-T4AggressiveFast, reliable networks
-T5InsaneVery 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/24

The -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/24

Then extract live hosts:

grep "Up" sweep.txt | cut -d " " -f 2

Sweep 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.50

When 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 -Pn before 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.50

Nmap 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.50

Nmap 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.50

Enables 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.50

This runs the http-headers script, which grabs HTTP response headers from web servers.


Learning About Scripts

nmap --script-help http-headers

Shows what the script does, its categories, and usage examples.


Useful Script Categories

CategoryWhat it does
authAuthentication bypass and brute-force
discoveryService and host discovery
vulnVulnerability detection
safeNon-intrusive scripts
defaultScripts that run with -sC

Run all default scripts with version detection:

nmap -sC -sV 10.10.10.50

NSE 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.50

The 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>$null

This 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.