When you need to scan tens of thousands of hosts in minutes rather than hours, Masscan is the tool for the job. Written by Robert Graham of Errata Security, Masscan is an asynchronous TCP port scanner capable of scanning the entire public internet in under six minutes at 25 million packets per second. In real-world penetration tests, it excels at rapidly identifying which hosts have which ports open across large corporate networks — a task that would take Nmap hours. This tutorial covers installation, key flags, responsible rate limiting, output formats, and the optimal workflow of combining Masscan with Nmap for deep service analysis.
How Masscan Differs from Nmap
| Feature | Masscan | Nmap |
|---|
| Speed | Extremely fast (millions of pps) | Moderate |
| Service detection | No | Yes (version scan) |
| Script engine | No | Yes (NSE) |
| OS detection | No | Yes |
| Stealth | SYN-only (no handshake) | Configurable |
| Accuracy | Slightly lower (stateless) | High |
| Best use | Wide initial sweep | Deep single-host analysis |
The optimal workflow: use Masscan to quickly identify open ports across an entire network, then feed those results into Nmap for detailed service version detection and scripting.
Installation
Masscan is available in the package repositories of most security-oriented Linux distributions:
# Kali Linux / Parrot OS / Debian
sudo apt install masscan -y
# Build from source (latest version)
git clone https://github.com/robertdavidgraham/masscan
cd masscan
make -j4
sudo make install
Verify the installation:
masscan --version
Note: Masscan requires raw socket access and must be run as root (or with sudo) on Linux. On some systems, you may need to grant the binary CAP_NET_RAW capabilities instead.
Basic Syntax
masscan [target] -p [ports] [options]
Examples:
# Scan a single host for ports 22, 80, 443
sudo masscan 192.168.1.1 -p22,80,443
# Scan a subnet for common ports
sudo masscan 192.168.1.0/24 -p22,80,443,8080,8443
# Scan a full Class C for all ports
sudo masscan 10.0.0.0/24 -p1-65535
# Scan with rate limit set (important!)
sudo masscan 10.0.0.0/24 -p1-65535 --rate 1000
Understanding Rate Limiting
This is the most important parameter to get right. Without --rate, Masscan defaults to 100 packets per second, which is conservative but safe. For large networks you will want to increase this — but understand the consequences:
| Rate | Packets/sec | Notes |
|---|
| 100 (default) | 100 pps | Very safe, slow |
| 1,000 | 1K pps | Good for corporate LANs |
| 10,000 | 10K pps | Fast; may trigger IDS/IPS |
| 100,000 | 100K pps | Aggressive; may crash consumer routers |
| 1,000,000+ | 1M+ pps | Internet-scale; requires 10GbE NIC |
For internal pentesting engagements on modern corporate networks:
sudo masscan 10.0.0.0/16 -p1-65535 --rate 10000
For sensitive environments or production systems where availability matters:
sudo masscan 10.0.0.0/16 -p1-65535 --rate 1000 --wait 5
The --wait flag (default: 10 seconds) tells Masscan how long to wait after finishing transmission before exiting, allowing late-arriving responses to be captured.
Scanning Common Port Ranges
# Top 100 ports (approximation)
sudo masscan 192.168.1.0/24 \
-p21,22,23,25,53,80,110,111,135,139,143,443,445,993,995,\
1723,3306,3389,5900,8080 \
--rate 5000
# All TCP ports (1-65535)
sudo masscan 192.168.1.0/24 -p1-65535 --rate 10000
# Common web ports
sudo masscan 10.0.0.0/8 -p80,443,8080,8443,8888,8000 --rate 50000
# Database ports
sudo masscan 10.0.0.0/24 -p1433,1521,3306,5432,6379,27017 --rate 5000
Excluding Hosts
Exclude specific IPs or ranges to avoid scanning out-of-scope systems:
# Exclude a specific host
sudo masscan 10.0.0.0/24 -p1-65535 --exclude 10.0.0.1
# Exclude a range using an exclusion file
echo "10.0.0.1" > excludes.txt
echo "10.0.0.100-10.0.0.120" >> excludes.txt
sudo masscan 10.0.0.0/24 -p1-65535 --excludefile excludes.txt
Always create an exclude file for your pentesting engagements and include hosts explicitly marked out-of-scope.
Masscan supports several output formats:
# XML output (best for parsing and importing into other tools)
sudo masscan 10.0.0.0/24 -p1-65535 \
--rate 5000 \
-oX results.xml
# JSON output
sudo masscan 10.0.0.0/24 -p1-65535 \
--rate 5000 \
-oJ results.json
# Grepable list format
sudo masscan 10.0.0.0/24 -p1-65535 \
--rate 5000 \
-oL results.list
# Binary format (resumable)
sudo masscan 10.0.0.0/24 -p1-65535 \
--rate 5000 \
-oB results.bin
The binary format allows you to resume interrupted scans:
# Resume from binary checkpoint
sudo masscan --resume results.bin
Parsing Results
Extract open ports and IPs from the list format output:
# View list output
cat results.list
# Format: open tcp 80 10.0.0.1 1617900000
# Extract all open IPs
grep "^open" results.list | awk '{print $4}' | sort -u > live_hosts.txt
# Extract IPs with port 80 open
grep "^open tcp 80" results.list | awk '{print $4}' | sort -u > web_hosts.txt
# Count open ports per host
grep "^open" results.list | awk '{print $4}' | sort | uniq -c | sort -rn | head -20
Parse JSON output with jq:
jq -r '.[] | "\(.ip):\(.ports[0].port)"' results.json | sort
Combining Masscan with Nmap: The Optimal Workflow
This two-phase approach gives you the speed of Masscan and the depth of Nmap:
Phase 1 — Fast wide sweep with Masscan:
sudo masscan 10.0.0.0/24 -p1-65535 \
--rate 10000 \
-oL masscan_results.list
Phase 2 — Extract target IPs and ports:
# Get live hosts
grep "^open" masscan_results.list | awk '{print $4}' | sort -u > live_hosts.txt
# Get open ports per host (for Nmap -p argument)
grep "^open" masscan_results.list | awk '{print $4":"$3}' | sort > host_ports.txt
Phase 3 — Deep Nmap scan on discovered open ports only:
# Scan only open ports found by Masscan (much faster than full port scan)
nmap -sV -sC -p $(grep "10.0.0.5" masscan_results.list | awk '{print $3}' | tr '\n' ',') \
10.0.0.5 -oA nmap_10.0.0.5
# Batch scan all live hosts from file
nmap -sV -sC --open \
-iL live_hosts.txt \
-oA nmap_all_hosts
A combined shell script for the whole workflow:
#!/bin/bash
TARGET=$1
RATE=${2:-5000}
OUTDIR="./scan_$(date +%Y%m%d_%H%M%S)"
mkdir -p $OUTDIR
echo "[*] Phase 1: Masscan wide sweep"
sudo masscan $TARGET -p1-65535 --rate $RATE -oL $OUTDIR/masscan.list
echo "[*] Extracting live hosts"
grep "^open" $OUTDIR/masscan.list | awk '{print $4}' | sort -u > $OUTDIR/live_hosts.txt
echo "[*] Found $(wc -l < $OUTDIR/live_hosts.txt) live hosts"
echo "[*] Phase 2: Nmap deep scan"
nmap -sV -sC -O --open -iL $OUTDIR/live_hosts.txt -oA $OUTDIR/nmap_results
echo "[*] Done. Results in $OUTDIR/"
Using a Configuration File
For repeated scans with the same settings, use a Masscan config file:
# Create masscan.conf
cat > masscan.conf << EOF
rate = 10000
output-format = xml
output-filename = scan.xml
ports = 1-65535
wait = 10
EOF
sudo masscan 10.0.0.0/24 -c masscan.conf
Detecting Masscan Scans on the Blue Team Side
If you are on the defensive side, Masscan scans produce distinctive patterns:
- SYN packets from a single source to many ports in rapid succession
- Equally spaced inter-packet timing (randomized by default, but still pattern-able)
- No corresponding ACK packets for most SYN-ACK responses (stateless)
IDS signatures for Masscan exist in Snort, Suricata, and Zeek. The --randomize-hosts flag (enabled by default) randomizes target IP order to make sweep detection harder.
Practical Tips
- Always use
--rate explicitly — never let it run at maximum on a production network.
- Test your rate on a known host first:
sudo masscan 10.0.0.1 -p1-65535 --rate 100000 to see if your NIC and network can handle it.
- Use binary output for long scans — you can resume if the scan is interrupted.
- Pair with Nmap — Masscan identifies open ports; Nmap tells you what is running.
- Document everything — save all output files with timestamped directories.
Legal and Ethical Notice
Masscan’s speed makes it particularly visible and disruptive. Scanning networks without written authorization is illegal under computer fraud laws in most countries, and a high-rate Masscan can cause service disruptions on misconfigured network equipment. Only run Masscan against networks you own or have explicit written permission to test, and always agree on an acceptable rate with the client before scanning.
Summary
Masscan fills a critical gap in the network scanner landscape — when you need to survey a large IP range quickly, nothing else comes close. Use it as the first phase of your network reconnaissance, extract the open ports, then hand those targets to Nmap for the detailed analysis that Masscan cannot provide. Together, they form a fast and thorough network discovery workflow that is a staple of professional penetration testing.