from pyzmap import ZMap
# Initialize with custom path to the ZMap executable
zmap = ZMap(zmap_path="/usr/local/bin/zmap")
# Run scan as usual
results = zmap.scan(target_port=80, subnets=["192.168.0.0/24"])from pyzmap import ZMap
zmap = ZMap()
results = zmap.scan(target_port=443, subnets=["10.0.0.0/8"])from pyzmap import ZMap, ZMapScanConfig
# Option 1: Configure via parameters
results = zmap.scan(
target_port=22,
bandwidth="10M", # 10 Mbps
subnets=["192.168.0.0/16"]
)
# Option 2: Configure via config object
config = ZMapScanConfig(
target_port=22,
bandwidth="10M"
)
zmap = ZMap()
zmap.config = config
results = zmap.scan(subnets=["192.168.0.0/16"])from pyzmap import ZMap
zmap = ZMap()
results = zmap.scan(
target_port=80,
subnets=["172.16.0.0/12"],
output_file="scan_results.csv"
)from pyzmap import ZMap
zmap = ZMap()
# Using a blocklist file
zmap.blocklist_from_file("/path/to/blocklist.txt")
# Creating a blocklist file
zmap.create_blocklist_file(
subnets=["10.0.0.0/8", "192.168.0.0/16"],
output_file="private_ranges.conf"
)
# Using a allowlist file
zmap.allowlist_from_file("/path/to/allowlist.txt")
# Run scan with blocklist
results = zmap.scan(
target_port=443,
blocklist_file="private_ranges.conf"
)from pyzmap import ZMap
zmap = ZMap()
results = zmap.scan(
target_port=80,
max_targets=1000, # Limit to 1000 targets
max_runtime=60, # Run for max 60 seconds
cooldown_time=5, # Wait 5 seconds after sending last probe
probes=3, # Send 3 probes to each IP
dryrun=True # Don't actually send packets (test mode)
)from pyzmap import ZMap, ZMapScanConfig
# Create configuration
config = ZMapScanConfig(
target_port=443,
bandwidth="100M",
interface="eth0",
source_ip="192.168.1.5",
source_port="40000-50000", # Random source port in range
max_targets="10%", # Scan 10% of address space
sender_threads=4, # Use 4 threads for sending
notes="HTTPS scanner for internal audit",
seed=123456 # Set random seed for reproducibility
)
# Initialize ZMap with configuration
zmap = ZMap()
zmap.config = config
# Run scan
results = zmap.scan(subnets=["10.0.0.0/16"])from pyzmap import ZMap
zmap = ZMap()
# Run scan and save results
zmap.scan(
target_port=22,
subnets=["192.168.1.0/24"],
output_file="scan_results.csv",
output_fields=["saddr", "daddr", "sport", "dport", "classification"]
)
# Parse the results file
parsed_results = zmap.parse_results("scan_results.csv")
# Process the structured data
for result in parsed_results:
print(f"Source IP: {result['saddr']}, Classification: {result['classification']}")
# Extract just the IPs
ip_list = zmap.extract_ips(parsed_results)from pyzmap import ZMap
zmap = ZMap()
# For large scans, stream the results instead of loading all at once
for result in zmap.stream_results("large_scan_results.csv"):
process_result(result) # Your processing function
# Count results without loading everything
count = zmap.count_results("large_scan_results.csv")
print(f"Found {count} results")PyZMap includes a REST API that allows you to control ZMap operations remotely.
You can start the API server in two ways:
# Start API server on default host (127.0.0.1) and port (8000)
pyzmap api
# Start API server with custom host and port
pyzmap api --host 0.0.0.0 --port 9000
# Start API server with verbose logging
pyzmap api -vfrom pyzmap import APIServer
# Create and start the API server
server = APIServer(host="0.0.0.0", port=8000)
server.run()The REST API provides the following endpoints:
| Endpoint | Method | Description |
|---|---|---|
/ |
GET | Basic information about the API |
/probe-modules |
GET | List available probe modules |
/output-modules |
GET | List available output modules |
/output-fields |
GET | List available output fields for a probe module |
/interfaces |
GET | List available network interfaces |
/scan-sync |
POST | Run a scan synchronously and return results |
/blocklist |
POST | Create a blocklist file from a list of subnets |
/standard-blocklist |
POST | Generate a standard blocklist file |
/allowlist |
POST | Create an allowlist file from a list of subnets |
The API includes automatic documentation using Swagger UI and ReDoc:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
curl -X GET "http://localhost:8000/"Response:
{
"name": "PyZmap API",
"version": "2.1.1",
"description": "REST API for ZMap network scanner"
}curl -X GET "http://localhost:8000/probe-modules"Response:
["tcp_synscan", "icmp_echoscan", "udp", "module_ntp", "module_dns"]curl -X GET "http://localhost:8000/output-modules"Response:
["csv", "json", "extended_file", "redis"]curl -X GET "http://localhost:8000/interfaces"Response:
["eth0", "lo", "wlan0"]curl -X POST "http://localhost:8000/scan-sync" \
-H "Content-Type: application/json" \
-d '{
"target_port": 80,
"bandwidth": "10M",
"probe_module": "tcp_synscan",
"return_results": true
}'Response:
{
"scan_id": "direct_scan",
"status": "completed",
"ips_found": ["192.168.1.1", "192.168.1.2", "10.0.0.1"]
}curl -X POST "http://localhost:8000/blocklist" \
-H "Content-Type: application/json" \
-d '{
"subnets": ["192.168.0.0/16", "10.0.0.0/8"]
}'Response:
{
"file_path": "/tmp/zmap_blocklist_a1b2c3.txt",
"message": "Blocklist file created with 2 subnets"
}curl -X POST "http://localhost:8000/standard-blocklist" \
-H "Content-Type: application/json" \
-d '{}'Response:
{
"file_path": "/tmp/zmap_std_blocklist_x1y2z3.txt",
"message": "Standard blocklist file created"
}curl -X POST "http://localhost:8000/allowlist" \
-H "Content-Type: application/json" \
-d '{
"subnets": ["1.2.3.0/24", "5.6.7.0/24"],
"output_file": "my_allowlist.txt"
}'Response:
{
"file_path": "my_allowlist.txt",
"message": "Allowlist file created with 2 subnets"
}