# Port Mass Scan

> Port scan /8-/24 with Masscan+RustScan and nmap banners.

- Skill: `uphiago/port-mass-scan` (Agent Skill)
- Install (CLI): `npx skillmds@latest add uphiago/port-mass-scan`
- Raw SKILL.md: https://api.skillmd.com/api/skills/uphiago/port-mass-scan/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: MIT
- Author: uphiago (https://skillmd.com/u/uphiago)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/uphiago/port-mass-scan

---


# Port Mass Scan Skill

High-speed port scanning methodology using RustScan for single hosts and Masscan for large IP ranges. RustScan provides 400x speedup over Nmap for 1000-port scans (3-10s vs 5-10min). Masscan handles /8 and /16 ranges that Nmap cannot. The ISP and government network examples below were from authorized infrastructure assessments with signed RoE.

## When to Use

- Authorized red team engagement with signed RoE covering the target IP range.
- Fast single-host port discovery before Nmap service enumeration.
- After `subdomain-enumeration` — scan resolved IPs for non-HTTP services.
- ISP-wide or /8 scanning without explicit written authorization is illegal in most jurisdictions. This skill exists for legitimate authorized engagements, not mass scanning.

## Prerequisites

- `terminal` with masscan, rustscan, and nmap installed.
- For Masscan: root access (uses raw sockets), libpcap.
- For RustScan: nmap must be installed (for service enumeration pass-through).

## How to Run

```bash
# Single host — RustScan (3-10 seconds for 1000 ports)
rustscan -a TARGET -r 1-65535 -- -sV

# /24 range — Masscan (2-5 minutes)
masscan -p1-65535 --rate=10000 -iL targets.txt -oJ scan.json

# /8 range — Masscan with banner grab (hours)
masscan -p80,443,8080,8443,22,3306,6379 --rate=50000 --banners -iL /8_range.txt -oJ scan.json
```

## Quick Reference

| Scenario | Tool | Command | Time |
|----------|------|---------|------|
| Single host, all ports | RustScan | `rustscan -a IP -r 1-65535` | 3-10s |
| /24 range, common ports | Masscan | `masscan -p1-1000 --rate=10000 -iL /24.txt` | 2-5 min |
| /16 range, web ports | Masscan | `masscan -p80,443,8080,8443 --rate=50000 -iL /16.txt` | 10-30 min |
| /8 camera hunt | Masscan | `masscan -p554,80,8010 --rate=100000 -iL /8.txt` | Hours |
| Banner grab (1 IP) | Masscan | `masscan -p1-65535 --banners --source-ip ETH0_IP IP` | 1-5 min |

### Performance Comparison (empirical, 5000+ scans)

| Tool | 1000 ports (1 host) | /24 (1000 ports each) | /8 (web ports) | Accuracy |
|------|--------------------|-----------------------|-----------------|--------|
| Nmap | 5-10 min | ~30 min | Impossible (days) | 99% |
| RustScan | 3-10s | 15-30s | ~2 min | 98% (then Nmap -sV) |
| Masscan | 15-20s | 2-5 min | 30-60 min | 99% (TCP) |

## Procedure

### RustScan — Single Host Fast Discovery

```bash
TARGET="$1"
OUTDIR="$OUTDIR/ports"
mkdir -p "$OUTDIR"

echo "[*] RustScan: all 65535 ports on $TARGET"

# Fast scan + auto Nmap service detection
rustscan -a "$TARGET" -r 1-65535 -b 500 --accessible -- -sV -oN "$OUTDIR/${TARGET}_rustscan.nmap"

echo "[*] Open ports:"
grep 'open' "$OUTDIR/${TARGET}_rustscan.nmap" || echo "  None"

# For WAF/IDS evasion: slower batch size
rustscan -a "$TARGET" -r 1-65535 -b 100 -t 1500 -- -sV
```

### Masscan — Large Range Scanning

```bash
RANGE_FILE="$1"      # One IP or CIDR per line
OUTDIR="$OUTDIR/ports"
mkdir -p "$OUTDIR"

# Step 1: Fast common ports scan
echo "[*] Masscan: common ports on $(wc -l < "$RANGE_FILE") targets"
masscan -p80,443,22,3306,6379,27017,8080,8443,554,21,25,5432,3389 \
  --rate=10000 -iL "$RANGE_FILE" -oJ "$OUTDIR/masscan_common.json" --wait=10

# Step 2: Full port scan on targets with hits
grep -Eo '"ip":"[^"]+"' "$OUTDIR/masscan_common.json" | sort -u | \
  sed 's/"ip":"//;s/"//' > "$OUTDIR/hits.txt"

echo "[*] Full scan on $(wc -l < "$OUTDIR/hits.txt") targets with open ports"
masscan -p1-65535 --rate=5000 -iL "$OUTDIR/hits.txt" \
  -oJ "$OUTDIR/masscan_full.json" --wait=30
```

### Masscan — Banner Grabbing (service identification)

```bash
TARGET="$1"
OUTDIR="$OUTDIR/ports"

# Banner grabbing requires a separate IP for the TCP handshake
SOURCE_IP=$(hostname -I | awk '{print $1}')
echo "[*] Masscan banner grab from source IP: $SOURCE_IP"

masscan -p1-10000 --rate=5000 --banners --source-ip "$SOURCE_IP" \
  "$TARGET" -oJ "$OUTDIR/${TARGET}_banners.json"

# Alternative: two-phase (Masscan ports → Nmap services)
masscan -p1-65535 --rate=10000 "$TARGET" -oG "$OUTDIR/${TARGET}_grepable.txt" --wait=10
OPEN_PORTS=$(grep -Eo 'Host: \S+ \(\)\s+Ports:\s+\K[^#]+' "$OUTDIR/${TARGET}_grepable.txt" | \
  grep -Eo '\d+/open' | cut -d/ -f1 | tr '\n' ',' | sed 's/,$//')

if [[ -n "$OPEN_PORTS" ]]; then
  echo "[*] Nmap service detection on ports: $OPEN_PORTS"
  nmap -sV -p "$OPEN_PORTS" "$TARGET" -oN "$OUTDIR/${TARGET}_services.nmap"
fi
```

### Masscan — IP Camera Hunting (RTSP port 554)

```bash
# Scan Brazilian ISP ranges for cameras (from Vivo, Claro, Oi)
echo "[*] Camera hunt on Claro 3G/4G ranges"
masscan -p554,80,8010,8011 --rate=50000 \
  --range [REDACTED_IP]-[REDACTED_IP] -oJ cameras_claro.json

echo "[*] Camera hunt on Vivo ranges"
masscan -p554,80,8010,8011 --rate=50000 \
  --range [REDACTED_IP]-[REDACTED_IP] -oJ cameras_vivo.json

# Post-process: probe discovered cameras for snapshots
grep -Eo '"ip":"[^"]+"' cameras_*.json | sed 's/"ip":"//;s/"//' | sort -u | \
while read ip; do
  # Axis camera snapshot
  code=$(curl -sk -o /dev/null -w "%{http_code}" --max-time 3 --connect-timeout 3 "http://$ip:8010/axis-cgi/jpg/image.cgi")
  [[ "$code" == "200" ]] && echo "[CAMERA] Axis: $ip:8010"
  # Generic RTSP
  code=$(curl -sk -o /dev/null -w "%{http_code}" --max-time 3 --connect-timeout 3 "http://$ip:554/")
  [[ "$code" != "000" ]] && echo "[RTSP] $ip:554"
  sleep 0.3
done
```

### Sharding — Distribute Across N Machines

```bash
# On machine 1 (shard 1/4):
masscan -p1-65535 --rate=50000 --shard 1/4 -iL /8_range.txt -oJ shard1.json

# On machine 2 (shard 2/4):
masscan -p1-65535 --rate=50000 --shard 2/4 -iL /8_range.txt -oJ shard2.json

# On machine 3 (shard 3/4):
masscan -p1-65535 --rate=50000 --shard 3/4 -iL /8_range.txt -oJ shard3.json

# On machine 4 (shard 4/4):
masscan -p1-65535 --rate=50000 --shard 4/4 -iL /8_range.txt -oJ shard4.json

# Merge results
cat shard*.json | jq -s '.[]' > merged.json
```

## Pitfalls

- **Masscan requires root.** Uses raw sockets. Run as root or with `sudo`.
- **Rate > 100k may trigger IDS/IPS.** Use `--rate=50000` or lower for stealth. Use `-T4` equivalent by setting appropriate `--rate`.
- **Banner grabbing kills connections.** Without `--source-ip`, Masscan must complete a full TCP handshake which tears down the connection. Use the two-phase approach (Masscan ports → Nmap services) for reliable service detection.
- **UDP scanning is experimental.** Masscan UDP support is limited. Use Nmap `-sU` for UDP.
- **Ctrl+C auto-saves.** Masscan saves progress on interrupt. Resume with `--resume paused.conf`.
- **`--excludefile` is critical.** Always exclude your own IPs and RFC 1918 ranges to avoid scanning yourself.

## Verification

- RustScan: open ports must be confirmed with Nmap `-sV` for service version.
- Masscan: results must be deduplicated (Masscan may report same port multiple times from retransmissions).
- Banner grab: service versions must match between Masscan banners and Nmap probes.
- All open TCP ports must have a corresponding service identified (no "unknown" ports).

