Skip to main content

reconflow

PyPI

Recon for bug bounty hunters that tells you what changed since your last scan.

pip install reconflow

reconflow chains subfinder and httpx into one command, filters out wildcard DNS noise, saves a snapshot of every run, and lets you diff any two runs to see new subdomains, newly live hosts, and changed responses.

Use responsibly. Only scan domains you own or that are explicitly in scope for a bug bounty / pentest program you are authorized to test.

Features

  • scan: finds subdomains, drops wildcard DNS false positives (including rotating IP pools), probes live hosts for status code, title and technologies, and writes a Markdown report
  • diff: compares your two most recent scans of a domain and highlights what's new
  • Scan history: every scan saves a structured snapshot, so nothing is overwritten
  • Cron-friendly: diff exits 1 when something changed and 0 when nothing did
  • No Python dependencies beyond the standard library

Requirements

  • Python 3.8+
  • subfinder and httpx (ProjectDiscovery's Go versions) on your PATH
  • gowitness (optional, only for --screenshots)

Note: httpx must be ProjectDiscovery's tool, not the Python httpx library. On Kali/Debian/Ubuntu it is often packaged as httpx-toolkit. reconflow checks for both names and verifies the binary.

Check your tools:

subfinder -version
httpx -version

Install

From PyPI:

pip install reconflow

From source:

git clone https://github.com/ErenYeager1836/reconflow.git
cd reconflow
pip install -e .

Usage

reconflow scan example.com
reconflow scan example.com --scope scope.txt
reconflow diff example.com
reconflow scope scope.txt api.example.com notexample.com

You can also run it as a module: python -m reconflow scan example.com

scan

Option Description
domain Target domain (required, must be in scope)
-o, --output Output folder (default: output)
--threads Number of threads for probing (default: 10)
--timeout Timeout in seconds for probing (default: 5)
--keep-wildcard Warn about wildcard DNS but don't filter wildcard results
--json Also write structured results to report.json
--screenshots Capture screenshots of live hosts (requires gowitness)
--scope Path to scope file (drops out-of-scope hosts before network activity)

scope

Verify whether targets are in or out of scope based on a program scope file:

reconflow scope scope.txt api.example.com admin.example.com 192.168.1.10

Scope file format & matching rules

  • One entry per line; blank lines and # comments are ignored.
  • In-scope entries: exact domains (example.com), wildcards (*.example.com), and IP/CIDR blocks (192.168.1.0/24).
  • Out-of-scope entries: prefixed with !, -, or out: (e.g. !admin.example.com, !10.0.0.0/8).
  • Out-of-scope entries ALWAYS override in-scope entries.
  • Wildcard matching: *.example.com matches subdomains only (e.g. api.example.com, dev.api.example.com). It does NOT match the apex domain example.com itself and does NOT match notexample.com. The apex domain must be listed explicitly if in scope.
  • Normalization: Hostnames are normalized first (lowercased; schemes, credentials, ports, paths, and trailing dots are stripped).
  • Fail closed: If --scope is given and the file is missing, unreadable, empty, or contains no valid in-scope entries, reconflow aborts immediately. Out-of-scope hosts and redirect targets are never probed.

Browser Redirects & Scope: gowitness captures screenshots in a real headless browser, which automatically follows HTTP redirects. reconflow protects your scope boundaries by capturing HTTP redirect targets (Location headers) via httpx in all modes and automatically skipping screenshots for any host that redirects to an out-of-scope destination. Note that client-side JavaScript redirects (e.g. window.location) or HTML <meta http-equiv="refresh"> redirects execute inside the browser engine and cannot be detected beforehand.

diff

Option Description
domain Target domain to compare runs for (required)
-o, --output Output folder (default: output)
--json Print the comparison as JSON
--notify Send webhook alert to Discord or Slack if changes are detected
--webhook-url Webhook URL (or set RECONFLOW_WEBHOOK_URL / DISCORD_WEBHOOK_URL / SLACK_WEBHOOK_URL)

diff needs at least two saved scans of the same domain. Run scan twice first.

mark

Set triage state for a host on a per-domain basis so reviewed assets stop cluttering differential scans:

# Mark host as reviewed and tested
reconflow mark admin.example.com --tested

# Mark host to be ignored in subsequent diffs
reconflow mark dev-api.example.com --ignore --notes "Mock API for testing"

# List all triaged hosts for a domain
reconflow mark --list -d example.com
Option Description
host Hostname or URL to mark
-d, --domain Target domain (inferred if omitted)
-o, --output Output folder (default: output)
--tested Mark host as tested
--ignore Mark host as ignored
--notes Optional notes on the triage decision
--list List all triaged hosts for domain

Triage Behavior:

  • --ignore: Permanently silences the host from appearing in new_live and changed sections in subsequent diffs.
  • --tested: Hides the host from new_live once reviewed, but if the host later undergoes a change (e.g. status code changes from 403 to 200, title changes, or new technology is detected), it automatically resurfaces under changed so you never miss critical updates.

report

Regenerate Markdown (report.md) and JSON (report.json) reports from an existing scan snapshot without re-running any network discovery or probing:

# Regenerate report from the latest scan
reconflow report example.com

# Regenerate report for a specific historical scan run
reconflow report example.com --run 2026-10-18_185218

# Output structured report as JSON
reconflow report example.com --json
Option Description
domain Target domain to generate report for (required)
-o, --output Output folder (default: output)
--run Specific scan run ID (defaults to latest scan)
--json Print the regenerated report as JSON

Track changes with diff

Most recon tools tell you what exists. reconflow also tells you what changed. New subdomains, newly live hosts, and status transitions are annotated with actionable lead hints ("worth checking"):

Example output (illustrative):

[*] Recon diff: 2026-10-18_185218 -> 2026-10-18_190412
============================================================
[+] NEW SUBDOMAINS (2):
    + beta.example.com
    + staging-api.example.com
[+] NEWLY LIVE HOSTS (1):
    + https://beta.example.com [200] [Beta Portal] [Nginx, React]
        * Worth checking: Prerelease beta environment; look for unhardened endpoints or debug flags.
[*] CHANGED HOSTS (1):
    ~ https://admin.example.com
        status: 403 -> 200
        title: 'Forbidden' -> 'Admin Login'
        tech: ['Apache'] -> ['Apache', 'PHP']
        * Worth checking: Status changed from 403 to 200; previously protected resource is now publicly accessible.
        * Worth checking: Administrative interface; test for panel access, auth bypass, or default credentials.
[-] Removed subdomains (1) [informational]:
    - old.example.com
============================================================

Incomplete Scan Safeguards: If a previous or current scan was interrupted (Ctrl+C), missing hosts are never reported as "gone" or removed, and a warning is displayed instead.

Exit codes

Code Meaning
0 No changes found (or not enough history to compare)
1 Changes were detected

Webhook Alerts & Scheduled Automation

Send alerts to Discord or Slack only when new hosts or changes are detected:

# Set webhook in environment (recommended: avoids exposing secrets in shell history or ps)
export RECONFLOW_WEBHOOK_URL="https://discord.com/api/webhooks/..."

# Every 6 hours: rescan, diff, and notify on changes
0 */6 * * * reconflow scan example.com && reconflow diff example.com --notify >> ~/recon-changes.log

Security Note: Using the RECONFLOW_WEBHOOK_URL (or DISCORD_WEBHOOK_URL / SLACK_WEBHOOK_URL) environment variable is strongly recommended over --webhook-url to prevent sensitive tokens from appearing in shell history (.bash_history) or process listings (ps aux).

Output

Files are saved under output/<domain>/:

subdomains.txt      all discovered subdomains
live.txt            live hosts with status code, title, tech
report.md           summary report
report.json         structured report (with --json)
triage.json         triage records (with reconflow mark)
screenshots/        screenshots of live hosts (with --screenshots)
runs/<run_id>/      snapshot of each scan, used by diff

Known limitations

  • Wildcard DNS domains return many fake "live" hosts that all point to the same server. reconflow detects them and filters those hosts (use --keep-wildcard to disable).
  • Discovery depends on subfinder's sources, so results can vary between runs.

Roadmap

  • Subdomain discovery and live host probing
  • Wildcard DNS detection (including rotating IP pools)
  • --threads and --timeout options
  • JSON report output
  • Screenshots of live hosts
  • Scan history and reconflow diff
  • reconflow scope: check targets against program scope
  • reconflow report: regenerate reports from saved scans
  • Lead hints in reconflow diff
  • --notify: Discord/Slack webhook alerts for diff results
  • Triage state: reconflow mark <host> --tested|--ignore
  • Save results as they come in

Contributing

Contributions are welcome. Look for issues labelled good first issue. Run the tests with:

python -m unittest discover tests -v

License

MIT

Metadata

Release files for reconflow 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for reconflow 0.3.0
File Size Uploaded
reconflow-0.3.0.tar.gz 44.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for reconflow 0.3.0
File Interpreter ABI Platform
reconflow-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 75.4 kB

Release files / reconflow-0.3.0.tar.gz

Download URL reconflow-0.3.0.tar.gz
Size 44.8 kB
Tags Source
SHA-256 checksum
How to use checksums
2557ba2dd3e04ec523fec20a2afc98ee5e819ae074eee6472a8d11b38ef1d1bb
BLAKE2b-256 checksum
How to use checksums
732f41e7f9eb177e069f8758642d442cfb9457344d8cb043976b9f30abc4b72c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.15.0

Release files / reconflow-0.3.0-py3-none-any.whl

Download URL reconflow-0.3.0-py3-none-any.whl
Size 30.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5d8f5a6fa4dbffcb4d369a54dd5984fbca14ab77ecc9c075934bc018c86785ab
BLAKE2b-256 checksum
How to use checksums
621b52c4c513d3b867a8dfb3ec788df13c26694a972cabf5c118d4550c19e5d1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.15.0

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page