Appearance
Zmap Cheat Sheet
Overview
Zmap is a fast single packet network scanner designed for Internet-wide network surveys and large-scale network discovery. Developed by researchers at the University of Michigan, Zmap is capable of scanning the entire IPv4 address space in under 45 minutes on a gigabit network connection. Unlike traditional port scanners that are designed for scanning small networks thoroughly, Zmap is optimized for scanning large address spaces quickly by sending a single probe packet to each host and maintaining minimal per-connection state. This makes it an invaluable tool for security researchers, network administrators, and penetration testers who need to perform large-scale network reconnaissance and Internet-wide security studies.
⚠️ Warning: Zmap is a powerful network scanning tool that can generate significant network traffic. Only use Zmap against networks you own or have explicit written permission to scan. Internet-wide scanning may violate terms of service and local laws. Always follow responsible disclosure practices and ethical scanning guidelines.
Installation
Ubuntu/Debian Installation
bash
# Install from package repository
sudo apt update
sudo apt install zmap
# Verify installation
zmap --version
# Install additional dependencies
sudo apt install libpcap-dev libgmp-dev libssl-dev
# Install development tools if building from source
sudo apt install build-essential cmake libpcap-dev libgmp-dev libssl-dev
CentOS/RHEL Installation
bash
# Install EPEL repository
sudo yum install epel-release
# Install Zmap
sudo yum install zmap
# Install dependencies for building from source
sudo yum groupinstall "Development Tools"
sudo yum install cmake libpcap-devel gmp-devel openssl-devel
Building from Source
bash
# Clone Zmap repository
git clone https://github.com/zmap/zmap.git
cd zmap
# Create build directory
mkdir build
cd build
# Configure build
cmake ..
# Compile
make -j$(nproc)
# Install
sudo make install
# Verify installation
zmap --version
Docker Installation
bash
# Pull Zmap Docker image
docker pull zmap/zmap
# Run Zmap in Docker
docker run --rm --net=host zmap/zmap zmap --version
# Create alias for easier usage
echo 'alias zmap="docker run --rm --net=host zmap/zmap zmap"' >> ~/.bashrc
source ~/.bashrc
# Run with volume mount for output
docker run --rm --net=host -v $(pwd):/data zmap/zmap zmap -p 80 10.0.0.0/8 -o /data/scan_results.txt
macOS Installation
bash
# Install using Homebrew
brew install zmap
# Install dependencies
brew install libpcap gmp openssl cmake
# Verify installation
zmap --version
# If building from source on macOS
git clone https://github.com/zmap/zmap.git
cd zmap
mkdir build && cd build
cmake -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl ..
make -j$(sysctl -n hw.ncpu)
sudo make install
Basic Usage
Simple Port Scans
bash
# Scan single port on subnet
zmap -p 80 192.168.1.0/24
# Scan multiple subnets
zmap -p 443 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
# Scan with output to file
zmap -p 22 192.168.0.0/16 -o ssh_hosts.txt
# Scan with rate limiting
zmap -p 80 10.0.0.0/8 -r 1000
# Scan with bandwidth limiting
zmap -p 443 192.168.0.0/16 -B 10M
# Verbose output
zmap -p 80 192.168.1.0/24 -v
Advanced Scanning Options
bash
# Scan with custom source port
zmap -p 80 192.168.1.0/24 -s 12345
# Scan with custom interface
zmap -p 80 192.168.1.0/24 -i eth0
# Scan with custom gateway MAC
zmap -p 80 192.168.1.0/24 -G 00:11:22:33:44:55
# Scan with custom source IP
zmap -p 80 192.168.1.0/24 -S 192.168.1.100
# Scan with probe module
zmap -p 80 192.168.1.0/24 -M tcp_synscan
# Scan with output module
zmap -p 80 192.168.1.0/24 -O csv -o results.csv
Probe Modules
bash
# TCP SYN scan (default)
zmap -p 80 192.168.1.0/24 -M tcp_synscan
# ICMP echo scan
zmap 192.168.1.0/24 -M icmp_echoscan
# UDP scan
zmap -p 53 192.168.1.0/24 -M udp
# TCP ACK scan
zmap -p 80 192.168.1.0/24 -M tcp_ackscan
# NTP scan
zmap -p 123 192.168.1.0/24 -M ntp
# DNS scan
zmap -p 53 192.168.1.0/24 -M dns
# List available probe modules
zmap --list-probe-modules
Output Modules
bash
# Default output (IP addresses)
zmap -p 80 192.168.1.0/24
# CSV output
zmap -p 80 192.168.1.0/24 -O csv -o results.csv
# JSON output
zmap -p 80 192.168.1.0/24 -O json -o results.json
# Extended output with additional fields
zmap -p 80 192.168.1.0/24 -O extended_file -o results.txt
# Redis output
zmap -p 80 192.168.1.0/24 -O redis --redis-server 127.0.0.1
# List available output modules
zmap --list-output-modules
Advanced Features
Large-Scale Internet Scanning
bash
# Scan entire IPv4 space for HTTP servers
zmap -p 80 0.0.0.0/0 -o http_servers.txt -r 10000
# Scan for HTTPS servers with rate limiting
zmap -p 443 0.0.0.0/0 -o https_servers.txt -r 5000 -B 100M
# Scan for SSH servers
zmap -p 22 0.0.0.0/0 -o ssh_servers.txt -r 2000
# Scan for DNS servers
zmap -p 53 0.0.0.0/0 -M udp -o dns_servers.txt -r 1000
# Scan with blacklist file
zmap -p 80 0.0.0.0/0 -b blacklist.txt -o results.txt
# Scan with whitelist file
zmap -p 80 -w whitelist.txt -o results.txt
Custom Probe Configuration
bash
# TCP SYN scan with custom TCP options
zmap -p 80 192.168.1.0/24 -M tcp_synscan --probe-args="tcp_window=1024"
# ICMP scan with custom payload
zmap 192.168.1.0/24 -M icmp_echoscan --probe-args="icmp_payload=deadbeef"
# UDP scan with custom payload
zmap -p 53 192.168.1.0/24 -M udp --probe-args="udp_payload_file=dns_query.bin"
# NTP scan with custom NTP packet
zmap -p 123 192.168.1.0/24 -M ntp --probe-args="ntp_version=3"
# DNS scan with custom query
zmap -p 53 192.168.1.0/24 -M dns --probe-args="dns_query=google.com"
Performance Optimization
bash
# High-speed scanning with multiple threads
zmap -p 80 10.0.0.0/8 -r 100000 -T 4
# Optimize for gigabit networks
zmap -p 80 0.0.0.0/0 -r 1400000 -B 1G
# Memory optimization for large scans
zmap -p 80 0.0.0.0/0 -r 10000 --max-targets 1000000
# CPU optimization
zmap -p 80 192.168.0.0/16 -T $(nproc)
# Network buffer optimization
zmap -p 80 192.168.1.0/24 --sender-threads 4 --cores 4
Filtering and Targeting
bash
# Exclude private networks
zmap -p 80 0.0.0.0/0 --exclude-file private_networks.txt
# Include only specific ASNs
zmap -p 80 --include-file target_asns.txt
# Scan with seed for reproducible randomization
zmap -p 80 192.168.1.0/24 --seed 12345
# Scan with custom target list
zmap -p 80 --target-file targets.txt
# Scan with CIDR exclusions
zmap -p 80 0.0.0.0/0 --exclude 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
Automation Scripts
Large-Scale Port Discovery
bash
#!/bin/bash
# Large-scale port discovery using Zmap
TARGET_RANGE="$1"
OUTPUT_DIR="zmap_discovery_$(date +%Y%m%d_%H%M%S)"
RATE_LIMIT=10000
BANDWIDTH_LIMIT="100M"
if [ -z "$TARGET_RANGE" ]; then
echo "Usage: $0 <target_range>"
echo "Example: $0 '0.0.0.0/0'"
echo "Example: $0 '10.0.0.0/8'"
exit 1
fi
mkdir -p "$OUTPUT_DIR"
# Common ports to scan
COMMON_PORTS=(
21 22 23 25 53 80 110 111 135 139 143 443 993 995 1723 3306 3389 5432 5900 8080
)
# Function to scan single port
scan_port() {
local port="$1"
local output_file="$OUTPUT_DIR/port_${port}_hosts.txt"
local log_file="$OUTPUT_DIR/port_${port}_scan.log"
echo "[+] Scanning port $port on $TARGET_RANGE"
# Determine probe module based on port
local probe_module="tcp_synscan"
case "$port" in
53|123|161|162|514) probe_module="udp" ;;
*) probe_module="tcp_synscan" ;;
esac
# Perform scan
zmap -p "$port" "$TARGET_RANGE" \
-M "$probe_module" \
-r "$RATE_LIMIT" \
-B "$BANDWIDTH_LIMIT" \
-o "$output_file" \
-v 2> "$log_file"
if [ $? -eq 0 ]; then
local host_count=$(wc -l < "$output_file" 2>/dev/null || echo 0)
echo " [+] Port $port: $host_count hosts found"
# Generate summary
echo "Port: $port" >> "$OUTPUT_DIR/scan_summary.txt"
echo "Hosts found: $host_count" >> "$OUTPUT_DIR/scan_summary.txt"
echo "Probe module: $probe_module" >> "$OUTPUT_DIR/scan_summary.txt"
echo "---" >> "$OUTPUT_DIR/scan_summary.txt"
else
echo " [-] Port $port: Scan failed"
fi
}
# Function to scan ports in parallel
scan_ports_parallel() {
local max_jobs=5
local job_count=0
for port in "${COMMON_PORTS[@]}"; do
# Limit concurrent jobs
while [ $(jobs -r | wc -l) -ge $max_jobs ]; do
sleep 1
done
# Start scan in background
scan_port "$port" &
job_count=$((job_count + 1))
echo "[+] Started scan job $job_count for port $port"
# Small delay between job starts
sleep 2
done
# Wait for all jobs to complete
wait
echo "[+] All port scans completed"
}
# Function to analyze results
analyze_results() {
echo "[+] Analyzing scan results"
local analysis_file="$OUTPUT_DIR/analysis_report.txt"
cat > "$analysis_file" << EOF
Zmap Port Discovery Analysis Report
==================================
Target Range: $TARGET_RANGE
Scan Date: $(date)
Output Directory: $OUTPUT_DIR
Port Scan Summary:
EOF
# Analyze each port
for port in "${COMMON_PORTS[@]}"; do
local port_file="$OUTPUT_DIR/port_${port}_hosts.txt"
if [ -f "$port_file" ]; then
local count=$(wc -l < "$port_file")
echo "Port $port: $count hosts" >> "$analysis_file"
fi
done
# Find most common open ports
echo "" >> "$analysis_file"
echo "Top 10 Most Common Open Ports:" >> "$analysis_file"
for port in "${COMMON_PORTS[@]}"; do
local port_file="$OUTPUT_DIR/port_${port}_hosts.txt"
if [ -f "$port_file" ]; then
local count=$(wc -l < "$port_file")
echo "$count $port"
fi
done | sort -nr | head -10 >> "$analysis_file"
# Generate combined host list
echo "" >> "$analysis_file"
echo "Generating combined host list..." >> "$analysis_file"
cat "$OUTPUT_DIR"/port_*_hosts.txt | sort -u > "$OUTPUT_DIR/all_responsive_hosts.txt"
local total_hosts=$(wc -l < "$OUTPUT_DIR/all_responsive_hosts.txt")
echo "Total unique responsive hosts: $total_hosts" >> "$analysis_file"
echo "[+] Analysis completed: $analysis_file"
}
# Function to generate visualization data
generate_visualization() {
echo "[+] Generating visualization data"
local viz_file="$OUTPUT_DIR/visualization_data.json"
cat > "$viz_file" << 'EOF'
{
"scan_metadata": {
"target_range": "TARGET_RANGE_PLACEHOLDER",
"scan_date": "SCAN_DATE_PLACEHOLDER",
"total_ports_scanned": TOTAL_PORTS_PLACEHOLDER
},
"port_data": [
EOF
# Replace placeholders
sed -i "s/TARGET_RANGE_PLACEHOLDER/$TARGET_RANGE/g" "$viz_file"
sed -i "s/SCAN_DATE_PLACEHOLDER/$(date -Iseconds)/g" "$viz_file"
sed -i "s/TOTAL_PORTS_PLACEHOLDER/${#COMMON_PORTS[@]}/g" "$viz_file"
# Add port data
local first=true
for port in "${COMMON_PORTS[@]}"; do
local port_file="$OUTPUT_DIR/port_${port}_hosts.txt"
if [ -f "$port_file" ]; then
local count=$(wc -l < "$port_file")
if [ "$first" = true ]; then
first=false
else
echo "," >> "$viz_file"
fi
cat >> "$viz_file" << EOF
{
"port": $port,
"host_count": $count,
"service": "$(getent services $port/tcp 2>/dev/null | awk '{print $1}' || echo 'unknown')"
}
EOF
fi
done
echo "" >> "$viz_file"
echo " ]" >> "$viz_file"
echo "}" >> "$viz_file"
echo "[+] Visualization data generated: $viz_file"
}
# Function to create HTML report
create_html_report() {
echo "[+] Creating HTML report"
local html_file="$OUTPUT_DIR/scan_report.html"
cat > "$html_file" << 'EOF'
<!DOCTYPE html>
<html>
<head>
<title>Zmap Port Discovery Report</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
.header { background-color: #f0f0f0; padding: 20px; border-radius: 5px; }
.port-section { margin: 20px 0; padding: 15px; border: 1px solid #ddd; border-radius: 5px; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
.chart { margin: 20px 0; }
</style>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
<div class="header">
<h1>Zmap Port Discovery Report</h1>
<p><strong>Target Range:</strong> TARGET_RANGE_PLACEHOLDER</p>
<p><strong>Scan Date:</strong> SCAN_DATE_PLACEHOLDER</p>
<p><strong>Total Ports Scanned:</strong> TOTAL_PORTS_PLACEHOLDER</p>
</div>
<div class="port-section">
<h2>Port Scan Results</h2>
<div class="chart">
<canvas id="portChart" width="400" height="200"></canvas>
</div>
<table>
<tr><th>Port</th><th>Service</th><th>Hosts Found</th><th>Percentage</th></tr>
EOF
# Add port data to HTML
local total_scanned_hosts=0
for port in "${COMMON_PORTS[@]}"; do
local port_file="$OUTPUT_DIR/port_${port}_hosts.txt"
if [ -f "$port_file" ]; then
local count=$(wc -l < "$port_file")
total_scanned_hosts=$((total_scanned_hosts + count))
fi
done
for port in "${COMMON_PORTS[@]}"; do
local port_file="$OUTPUT_DIR/port_${port}_hosts.txt"
if [ -f "$port_file" ]; then
local count=$(wc -l < "$port_file")
local service=$(getent services $port/tcp 2>/dev/null | awk '{print $1}' || echo 'unknown')
local percentage=0
if [ $total_scanned_hosts -gt 0 ]; then
percentage=$(echo "scale=2; $count * 100 / $total_scanned_hosts" | bc -l)
fi
echo " <tr><td>$port</td><td>$service</td><td>$count</td><td>${percentage}%</td></tr>" >> "$html_file"
fi
done
cat >> "$html_file" << 'EOF'
</table>
</div>
<script>
// Load visualization data and create chart
fetch('visualization_data.json')
.then(response => response.json())
.then(data => {
const ctx = document.getElementById('portChart').getContext('2d');
const chart = new Chart(ctx, {
type: 'bar',
data: {
labels: data.port_data.map(p => `Port ${p.port}`),
datasets: [{
label: 'Hosts Found',
data: data.port_data.map(p => p.host_count),
backgroundColor: 'rgba(54, 162, 235, 0.6)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 1
}]
},
options: {
responsive: true,
plugins: {
title: {
display: true,
text: 'Port Discovery Results'
}
},
scales: {
y: {
beginAtZero: true
}
}
}
});
});
</script>
</body>
</html>
EOF
# Replace placeholders
sed -i "s/TARGET_RANGE_PLACEHOLDER/$TARGET_RANGE/g" "$html_file"
sed -i "s/SCAN_DATE_PLACEHOLDER/$(date)/g" "$html_file"
sed -i "s/TOTAL_PORTS_PLACEHOLDER/${#COMMON_PORTS[@]}/g" "$html_file"
echo "[+] HTML report created: $html_file"
}
# Main execution
echo "[+] Starting large-scale port discovery"
echo "[+] Target range: $TARGET_RANGE"
echo "[+] Output directory: $OUTPUT_DIR"
echo "[+] Rate limit: $RATE_LIMIT packets/second"
echo "[+] Bandwidth limit: $BANDWIDTH_LIMIT"
# Check if running as root
if [ "$EUID" -ne 0 ]; then
echo "[-] This script requires root privileges for raw socket access"
exit 1
fi
# Check if zmap is installed
if ! command -v zmap &> /dev/null; then
echo "[-] Zmap not found. Please install zmap first."
exit 1
fi
# Perform scans
scan_ports_parallel
# Analyze results
analyze_results
# Generate visualization data
generate_visualization
# Create HTML report
create_html_report
echo "[+] Large-scale port discovery completed"
echo "[+] Results saved in: $OUTPUT_DIR"
echo "[+] Open $OUTPUT_DIR/scan_report.html for detailed report"
Internet-Wide Service Discovery
bash
#!/bin/bash
# Internet-wide service discovery using Zmap
SERVICE_TYPE="$1"
OUTPUT_DIR="internet_discovery_$(date +%Y%m%d_%H%M%S)"
RATE_LIMIT=50000
BANDWIDTH_LIMIT="500M"
if [ -z "$SERVICE_TYPE" ]; then
echo "Usage: $0 <service_type>"
echo "Service types: web, ssh, dns, mail, ftp, telnet, ntp, snmp"
exit 1
fi
mkdir -p "$OUTPUT_DIR"
# Service configuration
declare -A SERVICE_CONFIG
SERVICE_CONFIG[web]="80,tcp_synscan"
SERVICE_CONFIG[web_ssl]="443,tcp_synscan"
SERVICE_CONFIG[ssh]="22,tcp_synscan"
SERVICE_CONFIG[dns]="53,udp"
SERVICE_CONFIG[mail_smtp]="25,tcp_synscan"
SERVICE_CONFIG[mail_pop3]="110,tcp_synscan"
SERVICE_CONFIG[mail_imap]="143,tcp_synscan"
SERVICE_CONFIG[ftp]="21,tcp_synscan"
SERVICE_CONFIG[telnet]="23,tcp_synscan"
SERVICE_CONFIG[ntp]="123,ntp"
SERVICE_CONFIG[snmp]="161,udp"
# Function to perform service discovery
discover_service() {
local service="$1"
local config="${SERVICE_CONFIG[$service]}"
if [ -z "$config" ]; then
echo "[-] Unknown service type: $service"
return 1
fi
local port=$(echo "$config" | cut -d, -f1)
local probe_module=$(echo "$config" | cut -d, -f2)
local output_file="$OUTPUT_DIR/${service}_servers.txt"
local log_file="$OUTPUT_DIR/${service}_scan.log"
echo "[+] Discovering $service servers on port $port"
echo "[+] Using probe module: $probe_module"
echo "[+] Rate limit: $RATE_LIMIT packets/second"
# Create blacklist for private networks
cat > "$OUTPUT_DIR/blacklist.txt" << 'EOF'
0.0.0.0/8
10.0.0.0/8
100.64.0.0/10
127.0.0.0/8
169.254.0.0/16
172.16.0.0/12
192.0.0.0/24
192.0.2.0/24
192.88.99.0/24
192.168.0.0/16
198.18.0.0/15
198.51.100.0/24
203.0.113.0/24
224.0.0.0/4
240.0.0.0/4
255.255.255.255/32
EOF
# Perform Internet-wide scan
zmap -p "$port" 0.0.0.0/0 \
-M "$probe_module" \
-r "$RATE_LIMIT" \
-B "$BANDWIDTH_LIMIT" \
-b "$OUTPUT_DIR/blacklist.txt" \
-o "$output_file" \
-v 2> "$log_file"
if [ $? -eq 0 ]; then
local server_count=$(wc -l < "$output_file" 2>/dev/null || echo 0)
echo "[+] Discovery completed: $server_count $service servers found"
# Generate statistics
generate_statistics "$service" "$output_file"
return 0
else
echo "[-] Discovery failed for $service"
return 1
fi
}
# Function to generate statistics
generate_statistics() {
local service="$1"
local results_file="$2"
local stats_file="$OUTPUT_DIR/${service}_statistics.txt"
echo "[+] Generating statistics for $service"
cat > "$stats_file" << EOF
Service Discovery Statistics: $service
======================================
Discovery Date: $(date)
Total Servers Found: $(wc -l < "$results_file")
Geographic Distribution:
EOF
# Analyze geographic distribution using GeoIP
if command -v geoiplookup &> /dev/null; then
echo "Analyzing geographic distribution..." >> "$stats_file"
# Sample first 1000 IPs for geographic analysis
head -1000 "$results_file" | while read ip; do
geoiplookup "$ip" | grep "GeoIP Country Edition" | cut -d: -f2 | xargs
done | sort | uniq -c | sort -nr | head -20 >> "$stats_file"
else
echo "GeoIP lookup not available" >> "$stats_file"
fi
# Analyze ASN distribution
echo "" >> "$stats_file"
echo "ASN Distribution (Top 20):" >> "$stats_file"
if command -v whois &> /dev/null; then
# Sample first 100 IPs for ASN analysis
head -100 "$results_file" | while read ip; do
whois "$ip" | grep -i "origin" | head -1 | awk '{print $2}'
done | sort | uniq -c | sort -nr | head -20 >> "$stats_file"
else
echo "Whois lookup not available" >> "$stats_file"
fi
echo "[+] Statistics generated: $stats_file"
}
# Function to perform follow-up analysis
followup_analysis() {
local service="$1"
local results_file="$OUTPUT_DIR/${service}_servers.txt"
local analysis_file="$OUTPUT_DIR/${service}_analysis.txt"
echo "[+] Performing follow-up analysis for $service"
# Sample servers for detailed analysis
local sample_size=100
local sample_file="$OUTPUT_DIR/${service}_sample.txt"
shuf -n "$sample_size" "$results_file" > "$sample_file"
cat > "$analysis_file" << EOF
Follow-up Analysis: $service
===========================
Analysis Date: $(date)
Sample Size: $sample_size servers
Detailed Analysis Results:
EOF
# Service-specific analysis
case "$service" in
"web"|"web_ssl")
analyze_web_servers "$sample_file" "$analysis_file"
;;
"ssh")
analyze_ssh_servers "$sample_file" "$analysis_file"
;;
"dns")
analyze_dns_servers "$sample_file" "$analysis_file"
;;
"ntp")
analyze_ntp_servers "$sample_file" "$analysis_file"
;;
*)
echo "Generic analysis for $service" >> "$analysis_file"
;;
esac
echo "[+] Follow-up analysis completed: $analysis_file"
}
# Function to analyze web servers
analyze_web_servers() {
local sample_file="$1"
local analysis_file="$2"
echo "Web Server Analysis:" >> "$analysis_file"
echo "===================" >> "$analysis_file"
# Analyze HTTP headers
while read ip; do
echo "Analyzing $ip..." >> "$analysis_file"
# Get HTTP headers
timeout 10 curl -I "http://$ip" 2>/dev/null | head -10 >> "$analysis_file"
echo "---" >> "$analysis_file"
# Rate limiting
sleep 0.1
done < "$sample_file"
}
# Function to analyze SSH servers
analyze_ssh_servers() {
local sample_file="$1"
local analysis_file="$2"
echo "SSH Server Analysis:" >> "$analysis_file"
echo "===================" >> "$analysis_file"
# Analyze SSH banners
while read ip; do
echo "Analyzing $ip..." >> "$analysis_file"
# Get SSH banner
timeout 5 nc "$ip" 22 < /dev/null 2>/dev/null | head -1 >> "$analysis_file"
# Rate limiting
sleep 0.1
done < "$sample_file"
}
# Function to analyze DNS servers
analyze_dns_servers() {
local sample_file="$1"
local analysis_file="$2"
echo "DNS Server Analysis:" >> "$analysis_file"
echo "===================" >> "$analysis_file"
# Test DNS resolution
while read ip; do
echo "Testing DNS server $ip..." >> "$analysis_file"
# Test DNS query
timeout 5 dig @"$ip" google.com +short 2>/dev/null >> "$analysis_file"
echo "---" >> "$analysis_file"
# Rate limiting
sleep 0.1
done < "$sample_file"
}
# Function to analyze NTP servers
analyze_ntp_servers() {
local sample_file="$1"
local analysis_file="$2"
echo "NTP Server Analysis:" >> "$analysis_file"
echo "===================" >> "$analysis_file"
# Test NTP response
while read ip; do
echo "Testing NTP server $ip..." >> "$analysis_file"
# Test NTP query
timeout 5 ntpdate -q "$ip" 2>/dev/null >> "$analysis_file"
echo "---" >> "$analysis_file"
# Rate limiting
sleep 0.1
done < "$sample_file"
}
# Function to generate final report
generate_final_report() {
local service="$1"
local report_file="$OUTPUT_DIR/final_report.html"
echo "[+] Generating final report"
cat > "$report_file" << EOF
<!DOCTYPE html>
<html>
<head>
<title>Internet-Wide $service Discovery Report</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
.header { background-color: #f0f0f0; padding: 20px; border-radius: 5px; }
.section { margin: 20px 0; padding: 15px; border: 1px solid #ddd; border-radius: 5px; }
.warning { background-color: #fff3cd; border-color: #ffeaa7; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
pre { background-color: #f5f5f5; padding: 10px; border-radius: 3px; overflow-x: auto; }
</style>
</head>
<body>
<div class="header">
<h1>Internet-Wide $service Discovery Report</h1>
<p><strong>Discovery Date:</strong> $(date)</p>
<p><strong>Service Type:</strong> $service</p>
<p><strong>Scan Rate:</strong> $RATE_LIMIT packets/second</p>
</div>
<div class="section warning">
<h2>⚠️ Important Notice</h2>
<p>This report contains results from Internet-wide scanning. Use this information responsibly and in accordance with applicable laws and ethical guidelines.</p>
</div>
<div class="section">
<h2>Discovery Summary</h2>
<table>
<tr><th>Metric</th><th>Value</th></tr>
<tr><td>Total Servers Found</td><td>$(wc -l < "$OUTPUT_DIR/${service}_servers.txt" 2>/dev/null || echo 0)</td></tr>
<tr><td>Scan Duration</td><td>$(grep "completed" "$OUTPUT_DIR/${service}_scan.log" 2>/dev/null | tail -1 || echo "Unknown")</td></tr>
<tr><td>Output Files</td><td>$(ls -1 "$OUTPUT_DIR" | wc -l)</td></tr>
</table>
</div>
<div class="section">
<h2>Files Generated</h2>
<ul>
<li><strong>Server List:</strong> ${service}_servers.txt</li>
<li><strong>Statistics:</strong> ${service}_statistics.txt</li>
<li><strong>Analysis:</strong> ${service}_analysis.txt</li>
<li><strong>Scan Log:</strong> ${service}_scan.log</li>
</ul>
</div>
<div class="section">
<h2>Next Steps</h2>
<ol>
<li>Review the server list and statistics</li>
<li>Analyze the follow-up analysis results</li>
<li>Consider responsible disclosure for any security issues found</li>
<li>Implement appropriate security measures based on findings</li>
</ol>
</div>
</body>
</html>
EOF
echo "[+] Final report generated: $report_file"
}
# Main execution
echo "[+] Starting Internet-wide $SERVICE_TYPE discovery"
echo "[+] Output directory: $OUTPUT_DIR"
# Check if running as root
if [ "$EUID" -ne 0 ]; then
echo "[-] This script requires root privileges for raw socket access"
exit 1
fi
# Check if zmap is installed
if ! command -v zmap &> /dev/null; then
echo "[-] Zmap not found. Please install zmap first."
exit 1
fi
# Perform service discovery
if discover_service "$SERVICE_TYPE"; then
# Perform follow-up analysis
followup_analysis "$SERVICE_TYPE"
# Generate final report
generate_final_report "$SERVICE_TYPE"
echo "[+] Internet-wide $SERVICE_TYPE discovery completed"
echo "[+] Results saved in: $OUTPUT_DIR"
echo "[+] Open $OUTPUT_DIR/final_report.html for detailed report"
else
echo "[-] Service discovery failed"
exit 1
fi
Continuous Network Monitoring
bash
#!/bin/bash
# Continuous network monitoring using Zmap
MONITOR_CONFIG="monitor.conf"
LOG_DIR="monitoring_logs"
ALERT_WEBHOOK="$1"
CHECK_INTERVAL=3600 # 1 hour
if [ -z "$ALERT_WEBHOOK" ]; then
echo "Usage: $0 <alert_webhook_url>"
echo "Example: $0 'https://hooks.slack.com/services/...'"
exit 1
fi
mkdir -p "$LOG_DIR"
# Function to perform monitoring scan
perform_monitoring_scan() {
local timestamp=$(date +%Y%m%d_%H%M%S)
local scan_output="$LOG_DIR/scan_$timestamp.txt"
local baseline_file="$LOG_DIR/baseline.txt"
echo "[+] Performing monitoring scan at $(date)"
# Read monitoring configuration
if [ ! -f "$MONITOR_CONFIG" ]; then
create_default_config
fi
source "$MONITOR_CONFIG"
# Perform scan
zmap -p "$MONITOR_PORT" "$MONITOR_RANGE" \
-M "$PROBE_MODULE" \
-r "$SCAN_RATE" \
-o "$scan_output" \
-v 2> "$LOG_DIR/scan_$timestamp.log"
if [ $? -ne 0 ]; then
echo "[-] Monitoring scan failed"
return 1
fi
# Compare with baseline
if [ -f "$baseline_file" ]; then
echo " [+] Comparing with baseline"
local changes_file="$LOG_DIR/changes_$timestamp.txt"
compare_scans "$baseline_file" "$scan_output" "$changes_file"
# Analyze changes
analyze_changes "$changes_file" "$timestamp"
else
echo " [+] Creating initial baseline"
cp "$scan_output" "$baseline_file"
fi
# Update baseline if significant time has passed
local baseline_age=$(stat -c %Y "$baseline_file" 2>/dev/null || echo 0)
local current_time=$(date +%s)
local age_hours=$(( (current_time - baseline_age) / 3600 ))
if [ $age_hours -gt 168 ]; then # 1 week
echo " [+] Updating baseline (age: ${age_hours} hours)"
cp "$scan_output" "$baseline_file"
fi
return 0
}
# Function to compare scans
compare_scans() {
local baseline="$1"
local current="$2"
local changes="$3"
# Find new hosts
comm -13 <(sort "$baseline") <(sort "$current") > "${changes}.new"
# Find disappeared hosts
comm -23 <(sort "$baseline") <(sort "$current") > "${changes}.gone"
# Create summary
cat > "$changes" << EOF
Scan Comparison Results
======================
Baseline: $baseline
Current: $current
Comparison Time: $(date)
New Hosts: $(wc -l < "${changes}.new")
Disappeared Hosts: $(wc -l < "${changes}.gone")
New Hosts List:
$(cat "${changes}.new")
Disappeared Hosts List:
$(cat "${changes}.gone")
EOF
}
# Function to analyze changes
analyze_changes() {
local changes_file="$1"
local timestamp="$2"
local new_count=$(wc -l < "${changes_file}.new" 2>/dev/null || echo 0)
local gone_count=$(wc -l < "${changes_file}.gone" 2>/dev/null || echo 0)
echo " [+] Changes detected: $new_count new, $gone_count disappeared"
# Check thresholds
if [ "$new_count" -gt "$NEW_HOST_THRESHOLD" ]; then
echo " [!] New host threshold exceeded: $new_count > $NEW_HOST_THRESHOLD"
send_alert "NEW_HOSTS" "$new_count" "${changes_file}.new"
fi
if [ "$gone_count" -gt "$GONE_HOST_THRESHOLD" ]; then
echo " [!] Disappeared host threshold exceeded: $gone_count > $GONE_HOST_THRESHOLD"
send_alert "DISAPPEARED_HOSTS" "$gone_count" "${changes_file}.gone"
fi
# Analyze new hosts for suspicious patterns
if [ "$new_count" -gt 0 ]; then
analyze_new_hosts "${changes_file}.new" "$timestamp"
fi
}
# Function to analyze new hosts
analyze_new_hosts() {
local new_hosts_file="$1"
local timestamp="$2"
local analysis_file="$LOG_DIR/new_host_analysis_$timestamp.txt"
echo " [+] Analyzing new hosts"
cat > "$analysis_file" << EOF
New Host Analysis
================
Analysis Time: $(date)
New Hosts Count: $(wc -l < "$new_hosts_file")
Detailed Analysis:
EOF
# Analyze IP ranges
echo "IP Range Analysis:" >> "$analysis_file"
cat "$new_hosts_file" | cut -d. -f1-3 | sort | uniq -c | sort -nr | head -10 >> "$analysis_file"
# Check for suspicious patterns
echo "" >> "$analysis_file"
echo "Suspicious Pattern Detection:" >> "$analysis_file"
# Check for sequential IPs
local sequential_count=$(cat "$new_hosts_file" | sort -V | awk '
BEGIN { prev = 0; seq_count = 0 }
{
split($1, ip, ".")
current = ip[4]
if (current == prev + 1) seq_count++
prev = current
}
END { print seq_count }
')
if [ "$sequential_count" -gt 10 ]; then
echo "WARNING: $sequential_count sequential IP addresses detected" >> "$analysis_file"
send_alert "SEQUENTIAL_IPS" "$sequential_count" "$new_hosts_file"
fi
# Perform reverse DNS lookups on sample
echo "" >> "$analysis_file"
echo "Reverse DNS Analysis (sample):" >> "$analysis_file"
head -20 "$new_hosts_file" | while read ip; do
local hostname=$(timeout 5 dig +short -x "$ip" 2>/dev/null | head -1)
echo "$ip -> ${hostname:-No PTR record}" >> "$analysis_file"
done
}
# Function to send alerts
send_alert() {
local alert_type="$1"
local count="$2"
local details_file="$3"
echo "[!] Sending alert: $alert_type"
local message="🚨 Network Monitoring Alert: $alert_type detected ($count items) at $(date)"
# Send to webhook
if [ -n "$ALERT_WEBHOOK" ]; then
curl -X POST -H 'Content-type: application/json' \
--data "{\"text\":\"$message\"}" \
"$ALERT_WEBHOOK" 2>/dev/null || echo "Webhook alert failed"
fi
# Send email if configured
if [ -n "$ALERT_EMAIL" ]; then
echo "$message" | mail -s "Network Monitoring Alert: $alert_type" \
-A "$details_file" "$ALERT_EMAIL" 2>/dev/null || echo "Email alert failed"
fi
# Log alert
echo "$(date): $alert_type - $count items" >> "$LOG_DIR/alerts.log"
}
# Function to generate monitoring report
generate_monitoring_report() {
echo "[+] Generating monitoring report"
local report_file="$LOG_DIR/monitoring_report_$(date +%Y%m%d).html"
cat > "$report_file" << 'EOF'
<!DOCTYPE html>
<html>
<head>
<title>Network Monitoring Report</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
.header { background-color: #f0f0f0; padding: 20px; border-radius: 5px; }
.alert { background-color: #ffebee; border: 1px solid #f44336; padding: 15px; border-radius: 5px; margin: 10px 0; }
.section { margin: 20px 0; padding: 15px; border: 1px solid #ddd; border-radius: 5px; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
</style>
</head>
<body>
<div class="header">
<h1>Network Monitoring Report</h1>
<p>Generated: $(date)</p>
<p>Monitoring Period: Last 24 hours</p>
</div>
EOF
# Add recent alerts
if [ -f "$LOG_DIR/alerts.log" ]; then
local recent_alerts=$(tail -10 "$LOG_DIR/alerts.log" 2>/dev/null)
if [ -n "$recent_alerts" ]; then
cat >> "$report_file" << EOF
<div class="alert">
<h2>⚠️ Recent Alerts</h2>
<pre>$recent_alerts</pre>
</div>
EOF
fi
fi
# Add scan statistics
cat >> "$report_file" << EOF
<div class="section">
<h2>Scan Statistics</h2>
<table>
<tr><th>Metric</th><th>Value</th></tr>
<tr><td>Total Scans</td><td>$(ls -1 "$LOG_DIR"/scan_*.txt 2>/dev/null | wc -l)</td></tr>
<tr><td>Current Baseline Hosts</td><td>$(wc -l < "$LOG_DIR/baseline.txt" 2>/dev/null || echo 0)</td></tr>
<tr><td>Last Scan</td><td>$(ls -1t "$LOG_DIR"/scan_*.txt 2>/dev/null | head -1 | xargs stat -c %y 2>/dev/null || echo "None")</td></tr>
</table>
</div>
</body>
</html>
EOF
echo " [+] Monitoring report generated: $report_file"
}
# Function to cleanup old logs
cleanup_logs() {
echo "[+] Cleaning up old monitoring logs"
# Keep logs for 30 days
find "$LOG_DIR" -name "scan_*.txt" -mtime +30 -delete
find "$LOG_DIR" -name "scan_*.log" -mtime +30 -delete
find "$LOG_DIR" -name "changes_*.txt*" -mtime +30 -delete
find "$LOG_DIR" -name "new_host_analysis_*.txt" -mtime +30 -delete
# Keep reports for 90 days
find "$LOG_DIR" -name "monitoring_report_*.html" -mtime +90 -delete
}
# Function to create default configuration
create_default_config() {
cat > "$MONITOR_CONFIG" << 'EOF'
# Network Monitoring Configuration
# Scan parameters
MONITOR_RANGE="192.168.0.0/16"
MONITOR_PORT="80"
PROBE_MODULE="tcp_synscan"
SCAN_RATE="1000"
# Alert thresholds
NEW_HOST_THRESHOLD=10
GONE_HOST_THRESHOLD=5
# Notification settings
ALERT_EMAIL=""
EOF
echo "Created default configuration: $MONITOR_CONFIG"
}
# Main monitoring loop
echo "[+] Starting continuous network monitoring"
echo "[+] Check interval: $((CHECK_INTERVAL / 60)) minutes"
echo "[+] Alert webhook: $ALERT_WEBHOOK"
# Check if running as root
if [ "$EUID" -ne 0 ]; then
echo "[-] This script requires root privileges for raw socket access"
exit 1
fi
while true; do
echo "[+] Starting monitoring cycle at $(date)"
if perform_monitoring_scan; then
echo " [+] Monitoring scan completed successfully"
else
echo " [-] Monitoring scan failed"
send_alert "SCAN_FAILURE" "1" "/dev/null"
fi
# Generate daily report and cleanup
if [ "$(date +%H)" = "06" ]; then # 6 AM
generate_monitoring_report
cleanup_logs
fi
echo "[+] Monitoring cycle completed at $(date)"
echo "[+] Next check in $((CHECK_INTERVAL / 60)) minutes"
sleep "$CHECK_INTERVAL"
done
Integration with Other Tools
Nmap Integration
bash
# Use Zmap for initial discovery, then Nmap for detailed scanning
zmap -p 80 192.168.1.0/24 -o web_hosts.txt
nmap -sV -p 80 -iL web_hosts.txt -oA detailed_scan
# Combine Zmap and Nmap in pipeline
zmap -p 22 10.0.0.0/8 | head -1000 | nmap -sV -p 22 -iL - -oA ssh_scan
Masscan Integration
bash
# Compare Zmap and Masscan results
zmap -p 80 192.168.0.0/16 -o zmap_results.txt
masscan -p80 192.168.0.0/16 --rate=1000 -oL masscan_results.txt
# Combine results
cat zmap_results.txt masscan_results.txt | sort -u > combined_results.txt
Shodan Integration
bash
# Use Zmap results to query Shodan
while read ip; do
shodan host "$ip"
sleep 1
done < zmap_results.txt > shodan_analysis.txt
Troubleshooting
Common Issues
Permission Denied
bash
# Run as root for raw socket access
sudo zmap -p 80 192.168.1.0/24
# Check capabilities
getcap $(which zmap)
# Set capabilities (alternative to root)
sudo setcap cap_net_raw=eip $(which zmap)
High Packet Loss
bash
# Reduce scan rate
zmap -p 80 192.168.1.0/24 -r 100
# Increase bandwidth limit
zmap -p 80 192.168.1.0/24 -B 10M
# Check network interface
zmap -p 80 192.168.1.0/24 -i eth0 -v
Memory Issues
bash
# Limit target count
zmap -p 80 0.0.0.0/0 --max-targets 1000000
# Monitor memory usage
top -p $(pgrep zmap)
# Use output modules that don't buffer
zmap -p 80 192.168.1.0/24 -O csv -o results.csv
Network Configuration
bash
# Check routing table
ip route show
# Check ARP table
arp -a
# Test connectivity
ping -c 1 192.168.1.1
# Check firewall rules
iptables -L
Performance Optimization
bash
# Optimize for high-speed scanning
zmap -p 80 0.0.0.0/0 -r 1400000 -B 1G --sender-threads 4
# CPU optimization
zmap -p 80 192.168.0.0/16 --cores 8
# Memory optimization
zmap -p 80 0.0.0.0/0 --max-targets 10000000
# Network buffer optimization
echo 'net.core.rmem_max = 134217728' >> /etc/sysctl.conf
echo 'net.core.rmem_default = 134217728' >> /etc/sysctl.conf
sysctl -p
Resources
- Zmap Official Website
- Zmap GitHub Repository
- Zmap Research Papers
- Internet-Wide Scanning Best Practices
- Network Scanning Ethics
- Large-Scale Network Measurement
- ZGrab Banner Grabber
This cheat sheet provides a comprehensive reference for using Zmap for large-scale network scanning and Internet-wide surveys. Always ensure you have proper authorization before scanning networks and follow ethical scanning practices.