A professional CLI tool for concurrent headless browser screenshots and navigable HTML report generation.
ReconShot takes a list of subdomains or URLs, visits each one concurrently via a headless Chromium browser, captures full-page screenshots, and generates a modern, fully offline HTML gallery report. Built for security researchers, penetration testers, and anyone who needs to visually inspect hundreds or thousands of web endpoints.
- ⚡ Concurrent Processing — Configurable worker pool processes URLs in parallel
- 🖼️ Full-Page Screenshots — Captures the entire page, not just the viewport
- 🔄 Automatic URL Normalization — Adds
https://if no scheme is provided - 📊 HTML Gallery Report — Modern dark-themed report with search, filtering, and expandable image modal (works completely offline)
- 📋 CSV Export — Structured data export for further analysis
- 📁 Metadata JSON — Complete session metadata for programmatic processing
- 🖥️ Persistent Browser Workers — Reuses browser instances across URLs for performance; auto-recycles after 50 URLs to prevent memory leaks
- ⏱️ Configurable Timeouts — Per-URL timeout prevents hung browsers
- 🎯 Progress Indication — Real-time progress bar showing current URL and ETA
- 📦 Docker Support — Multi-stage Dockerfile for easy containerized deployment
- 🔒 Non-Root Execution — Runs as non-root user in Docker for security
# Prerequisites: Rust toolchain and Chromium/Chrome
git clone https://github.com/yourusername/reconshot.git
cd reconshot
cargo build --release
# The binary will be at ./target/release/reconshot# Build the Docker image
docker build -t reconshot .
# Or use docker-compose
docker-compose up# Simple: take screenshots of URLs listed in urls.txt
./target/release/reconshot urls.txt
# With custom output directory
./target/release/reconshot urls.txt -o screenshots/
# With 10 concurrent workers (short flag: -j)
./target/release/reconshot urls.txt --threads 10
# With 15-second timeout per URL
./target/release/reconshot urls.txt -T 15
# Generate HTML report
./target/release/reconshot urls.txt --html-report
# Export CSV
./target/release/reconshot urls.txt --csv
# Quick start — full example (HTML report + CSV)
./target/release/reconshot urls.txt --html-report --csv
# Full options
./target/release/reconshot urls.txt \
-o ./recon_output \
--threads 10 \
-T 30 \
--width 1920 \
--height 1080 \
--html-report \
--csv \
--format png \
--ignore-sslThe input file should contain one URL or subdomain per line:
https://example.com
https://admin.example.com
example.com
subdomain.example.com
# Lines starting with # are ignored
http://legacy-site.com
URLs without a scheme are automatically prefixed with https:// (with http:// as fallback).
# Build the Docker image (requires Docker installed)
docker build -t reconshot .
# Run with mounted input file
docker run --rm \
-v $(pwd)/urls.txt:/data/urls.txt:ro \
-v $(pwd)/output:/data/output \
reconshot urls.txt --threads 10 --html-report
# Or use docker-compose
docker-compose up| Argument | Short | Default | Description |
|---|---|---|---|
INPUT |
(positional) | — | Path to input file with URLs |
--output |
-o |
output |
Output directory |
--threads |
-j |
5 |
Number of concurrent browser workers |
--timeout |
-T |
30 |
Per-URL timeout in seconds |
--width |
— | 1920 |
Viewport width |
--height |
— | 1080 |
Viewport height |
--html-report |
— | false |
Generate HTML gallery report |
--csv |
— | false |
Export results as CSV |
--format |
— | png |
Image format (png or jpeg) |
--ignore-ssl |
— | false |
Ignore SSL certificate errors |
--chromium-path |
— | auto | Custom Chromium binary path |
--log-level |
— | info |
Log level (trace/debug/info/warn/error) |
output/
├── screenshots/ # Full-page screenshots
│ ├── example.com_abc123.png
│ └── ...
├── thumbnails/ # Thumbnail versions
│ ├── thumb_example.com_abc123.png
│ └── ...
├── logs/ # Log files (if enabled)
├── report.html # Interactive HTML gallery (if --html-report)
├── results.csv # CSV export (if --csv)
└── metadata.json # Complete session metadata
Contains all captured data including:
- Original URL and final URL (after redirects)
- Page title and HTTP status code
- Screenshot paths and timestamps
- Duration per URL
- Error messages for failed captures
- Session configuration and statistics
┌─────────────────────────────────────────────────────────┐
│ ReconShot CLI │
├─────────────────────────────────────────────────────────┤
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────┐ │
│ │ CLI │ │ Config │ │ Input │ │ Output │ │
│ │ Parser │─▶│ Builder │─▶│ Reader │─▶│ Writer │ │
│ └──────────┘ └──────────┘ └──────────┘ └────────┘ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Browser Worker Pool │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ Worker 1│ │ Worker 2│ │ Worker 3│ ... │ │
│ │ │(Browser)│ │(Browser)│ │(Browser)│ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
- chromiumoxide: Async-native Chrome DevTools Protocol client for high-concurrency browser automation
- Tokio-based concurrency: Async worker pool with bounded channel task distribution
- Persistent browser workers: Each worker reuses its browser for up to 50 URLs, then recycles to prevent memory leaks
- Offline-first HTML report: All screenshots are embedded as Base64, no external dependencies
- Structured logging with tracing: JSON-ready structured logs, progress bars on stderr to avoid output pollution
For best performance with large URL lists:
- Set
--threadsbased on available RAM (each browser ~200-400MB) - Use
--timeoutto prevent slow pages from blocking the queue - SSD storage is recommended for fast screenshot writes
- For 10,000+ URLs, consider splitting into batches of 1,000-2,000
- Rust toolchain (install via rustup)
- Google Chrome or Chromium installed on the system (the tool uses the Chrome DevTools Protocol).
The binary is auto-detected at runtime. You can also specify a custom path with
--chromium-path.
# 1. Clone and build the project
git clone <your-repo-url>
cd reconshot
cargo build --release
# 2. Create a file with URLs to capture
echo "https://google.com" > urls.txt
echo "https://github.com" >> urls.txt
echo "https://wikipedia.org" >> urls.txt
# 3. Run the capture (equivalent: cargo run --release -- urls.txt --html-report)
./target/release/reconshot urls.txt --html-report --threads 3
# 4. Open the report at: output/report.html# Build (debug mode — faster compile, slower runtime)
cargo build
# Build (release mode — optimized binary)
cargo build --release
# Quick test run (combines compile + execution)
cargo run --release -- urls.txt --html-report --threads 3
# Run tests
cargo test
# Check for issues
cargo clippy- Core screenshot capture with CDP
- Concurrent worker pool
- HTML report generation
- CSV export
- Docker support
- Favicon capture
- Automatic retry on failure
- Multi-viewport capture
- Live progress dashboard (TUI)
- Screenshot diffing for regressions
MIT
Found a bug or security issue? Please open an issue on GitHub.
Made for security researchers, by security researchers.
