Skip to main content

SUBX — Subdomain Recon Framework

A fast, async subdomain enumeration and asset management toolkit for security researchers, pentesters, and bug bounty hunters.

SUBX pulls subdomains from 12 passive sources (Shodan, VirusTotal, Censys, crt.sh, Chaos, etc.), filters them against your scope, stores everything in a database, and optionally probes for HTTP liveness with httpx. It's built to fit into real-world recon workflows without getting in the way.


How it works

                      ┌─────────────────────────────────┐
                      │               CLI               │
                      └────────────────┬────────────────┘
                                       │
                                       ▼
                      ┌─────────────────────────────────┐
                      │         Services Layer           │
                      └──────┬───────────────────┬──────┘
                             │                   │
                             ▼                   ▼
                      ┌──────────────┐   ┌──────────────┐
                      │PluginManager │   │ ToolManager   │
                      └──────┬───────┘   └──────┬───────┘
                             │                   │
                             ▼                   ▼
                      ┌──────────────┐   ┌──────────────┐
                      │ Passive APIs │   │ Active Tools  │
                      │ (12 sources) │   │   (httpx)     │
                      └──────────────┘   └──────────────┘

Plugins run concurrently via asyncio. Results are deduplicated, scope-filtered, and persisted with first_seen / last_seen timestamps so you can track changes over time.


What's included

  • Async everything — all API calls run concurrently, not sequentially
  • Plugin auto-discovery — drop a .py file in plugins/ and it's loaded automatically
  • Scope enforcement — in-scope / out-of-scope filtering from your config
  • Persistent storage — SQLite by default, PostgreSQL supported natively
  • HTTP probing — built-in httpx integration for liveness, status codes, titles, and tech detection
  • Historical tracking — first_seen, last_seen, and last_seen_alive timestamps
  • Project export — auto-generated recon/ directories with subdomains.txt, alive.txt, dead.txt, etc.
  • Cross-platform — works on Linux, macOS, and Windows
  • Live progress — real-time streaming of discovered subdomains during enumeration

Passive Sources

Source API Key Required Config Key
AlienVault OTX Yes OTX_API
AnubisDB No —
BeVigil Yes BEVIGIL_API
BGP Tools No —
Censys Yes CENSYS_API
Chaos (ProjectDiscovery) Yes CHAOS_API
crt.sh No —
HackerTarget No —
Shodan Yes SHODAN_API
urlscan.io Yes URLSCAN_API
ViewDNS Yes VIEWDNS_API
VirusTotal Yes VIRUSTOTAL_API

Installation

From PyPI (recommended)

pip install subx-recon

From source

git clone https://github.com/RiadhBenlamine/SubX.git
cd SubX
pip install -e .

Or with uv:

git clone https://github.com/RiadhBenlamine/SubX.git
cd SubX
uv sync

Debian/Ubuntu/Kali (.deb)

Download the .deb from the latest release and install:

sudo apt install ./subx_2.1.0-1_all.deb

Requirements: Python >= 3.10


Setup

Create a config.yaml (there's a sample in config_samples/):

scope:
  - example.com
  - target.org

out_of_scope:
  - testing.example.com

# Leave blank to run all plugins, or list specific ones
sources:
  - ShodanPlugin
  - CrtshPlugin

api_keys:
  SHODAN_API: "your-key-here"
  VIRUSTOTAL_API: "your-key-here"
  OTX_API: "your-key-here"
  URLSCAN_API: "your-key-here"
  CHAOS_API: "your-key-here"
  BEVIGIL_API: "your-key-here"
  VIEWDNS_API: "your-key-here"
  CENSYS_API: "your-key-here"

You can also keep API keys in ~/.config/subx/.env (e.g. SHODAN_API=your-key). Config file values take priority.


Usage

subx [COMMAND] [OPTIONS]

# From source:
uv run python main.py [COMMAND] [OPTIONS]

Enumerate subdomains

subx enum -c config.yaml

Runs all configured plugins against your scope targets. Results are saved to the database by default. Subdomains stream to your terminal in real-time as each plugin returns results.

Options:

  • -c, --config — path to your config file (required)
  • --save / --no-save — toggle database persistence (default: save)
  • --project, -p — auto-export project directory after scan
  • --debug — verbose logging

Probe for HTTP liveness

subx http-probe -d example.com

Reads subdomains from the database, runs httpx with tech detection, and updates records with status codes, titles, technologies, and timestamps.

Options:

  • -d, --domain — target domain (required)
  • -oN <file> — save alive subdomains, one per line
  • -oX '<sep>:<file>' — custom separator output (e.g. ';:alive.txt')
  • -oT <file> — save subdomains with tech stack (e.g. app.example.com [Nginx, React])

Query the database

# Show all tracked targets
subx db

# List subdomains for a target
subx db -d example.com

# Show web details (alive status, HTTP code, title, tech)
subx db -d example.com --web

# Filter by plugin source
subx db -d example.com --filter-plugin ShodanPlugin

# Filter by technology
subx db -d example.com --filter-tech Nginx

# Only alive / only dead
subx db -d example.com --alive
subx db -d example.com --down --web

# Subdomains discovered after a date
subx db -d example.com --new-since 2025-01-01

# Raw SQL query
subx db -C "SELECT subdomain, status_code, tech FROM subx_subdomain WHERE target='example.com' AND alive=1"

# Delete all records for a target
subx db -d example.com --delete

# Export to file
subx db -d example.com --alive -oN live_subs.txt

Export project directories

subx project -d example.com

Creates a structured recon folder:

projects/
  └── example.com/
        └── recon/
              ├── subdomains.txt
              ├── alive.txt
              ├── dead.txt
              ├── techs.txt
              ├── status.txt
              ├── ips.txt
              └── sources.txt

You can also pass --project / -p to enum, http-probe, or db commands to auto-generate this after any operation.

Initialize PostgreSQL

# Interactive setup
subx init-db

# Non-interactive
subx init-db -H 127.0.0.1 -u postgres -P "mypassword" -d subx

This creates the database, sets up schema tables, and saves the connection to ~/.config/subx/config.yaml so all future commands use PostgreSQL.

Import from SQLite

# Into your configured database
subx import-sqlite subx.db

# With explicit target
subx import-sqlite subx.db -t "postgresql+asyncpg://user:pass@localhost:5432/subx"

Migrates all targets, subdomains, probe results, timestamps, and source linkages.

Database migrations

subx dev-migrate

Compares your database schema against current models and adds any missing columns. Creates a backup first by default (skip with --no-backup).


PostgreSQL support

SUBX works with SQLite out of the box. To switch to PostgreSQL, either:

  1. Run subx init-db (recommended), or
  2. Set the DATABASE_URL environment variable:
export DATABASE_URL="postgresql+asyncpg://user:password@localhost:5432/subx"

All commands work identically on both backends.


Release automation

# Bump patch (2.0.19 → 2.0.20)
python scripts/release.py patch

# Bump minor (2.0.19 → 2.1.0)
python scripts/release.py minor

# Set exact version
python scripts/release.py 2.1.0

Handles version bumping, tests, wheel/sdist/deb builds, PyPI upload, git tagging, and GitHub push.


Contributing

See DEV_DOCS.md for the architecture guide, API reference, layering rules, and how to add new plugins or tool wrappers.


License

MIT — see LICENSE for details.

Metadata

Release files for subx-recon 2.1.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 subx-recon 2.1.0
File Size Uploaded
subx_recon-2.1.0.tar.gz 54.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for subx-recon 2.1.0
File Interpreter ABI Platform
subx_recon-2.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 131.7 kB

Release files / subx_recon-2.1.0.tar.gz

Download URL subx_recon-2.1.0.tar.gz
Size 54.6 kB
Tags Source
SHA-256 checksum
How to use checksums
b71bf50b869300aa524c85a477687e7f97ec1d70077f97a9b670006fd9ef9cb2
BLAKE2b-256 checksum
How to use checksums
91e5c4b75ff6577de04ac09f1a6b1068f415357f3803b222bc8af670a357ca0f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release files / subx_recon-2.1.0-py3-none-any.whl

Download URL subx_recon-2.1.0-py3-none-any.whl
Size 77.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6bfd4d777b82ce33ca01cca8a2273e7d6dcc71c3059d6fda8c18af1cd6d7afb6
BLAKE2b-256 checksum
How to use checksums
f1d6077f0b05a91b871183403625011b00a48edf63ef5afc9d8b4402cdd46e11
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6
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