Skip to main content

PhantomProbe

Passive-first reconnaissance scanner for penetration testers and bug bounty hunters.

Python 3.8+ License: MIT Tests

PhantomProbe maps a target's attack surface and reports what is actually wrong with it. The core runs on the Python standard library alone, so a default install has no dependencies and starts in one command. Optional features (a web dashboard, screenshots, a Burp bridge) each pull in their own packages and nothing else.

Two ideas run through it:

  • Observe before you touch. Everything except the opt-in --aggressive phase either reads what the target already sends or resolves DNS. Records that the standard library cannot reach, such as TXT, MX and DNSKEY, are fetched over DNS-over-HTTPS rather than by adding a DNS dependency.
  • Say something only when it means something. Severities are set by what a finding buys an attacker today, not by dated checklists. A missing SameSite is hardening; a session cookie readable by script is not. A CVE that CISA lists as exploited outranks a higher-scored one nobody uses. On a well-configured target, PhantomProbe stays quiet.

Quick start

git clone https://github.com/Ravel226/PhantomProbe.git
cd PhantomProbe
pip install -e .
phantomprobe example.com

That first scan is entirely passive. Add phases as you need them:

phantomprobe example.com --phase2                 # active recon (ports, subdomains, takeover)
phantomprobe example.com --phase2 --cve           # correlate versions to CVEs (KEV/EPSS ranked)
phantomprobe example.com --phase2 --cve --js      # add JavaScript endpoint/secret discovery
phantomprobe example.com --phase2 --aggressive    # opt-in active probes (authorized targets only)
phantomprobe example.com --phase2 --cve --dashboard   # serve results in the web UI

Every scan writes report-<target>.md and report-<target>.json to the --output-dir (default: the current directory).

Installation

The core scanner is dependency-free. Install extras only for the features you want; pip install -e . is enough for a full passive and active scan.

Command Adds
pip install -e . Core scanner (no dependencies)
pip install -e ".[dashboard]" Interactive web dashboard (FastAPI, uvicorn)
pip install -e ".[screenshot]" Full-page screenshots (Playwright)
pip install -e ".[burp]" Burp Professional REST integration (requests)
pip install -e ".[all]" Every feature above

Screenshots need the browser as well as the package:

pip install -e ".[screenshot]"
playwright install chromium

Run it without installing at all, straight from a checkout:

PYTHONPATH=src python -m phantomprobe example.com

What it checks

Phase 1: passive (always on)

Reads what the target already sends and resolves DNS. No probing.

  • DNS - A/AAAA records, reverse DNS, wildcard detection
  • SSL/TLS - certificate details and expiry, weak ciphers, deprecated TLS versions
  • Security headers - the six response headers that harden a browser session (CSP, HSTS, X-Frame-Options and the rest)
  • Cookies - Secure, HttpOnly and SameSite, weighted by whether a cookie looks like a session or a tracker
  • Email security - SPF, DMARC and DKIM over DoH. Missing SPF or DMARC lets anyone forge mail from the domain, the cheapest phishing route into an org
  • CAA and DNSSEC - certificate-issuance restrictions and zone signing, reported as hardening
  • HSTS preload eligibility - judged against hstspreload.org's current one-year max-age floor
  • Redirect chain - flags plain HTTP that never reaches HTTPS, and redirects that leave the target host
  • security.txt - the RFC 9116 disclosure contact

Phase 2: active reconnaissance (--phase2)

  • Port scan - common service ports, concurrently
  • Subdomain enumeration - common-name discovery
  • Technology fingerprinting - server and framework detection
  • Subdomain takeover - dangling-CNAME detection against a two-signal check (the CNAME must point at a known service and the service must report the resource unclaimed), using the can-i-take-over-xyz fingerprints. Disable with --no-takeover.
  • WAF / CDN - passive fingerprinting of 35 WAFs from the wafw00f signature set

CVE correlation (--cve)

Matches fingerprinted technology versions to NVD, across 74 products whose CPE vendor/product pairs were each verified against the live API before being added (a wrong vendor returns a clean empty result, so it fails silently). It only correlates where a banner gave a version, reads CVSS v4.0/v3.1/v3.0/v2 scores, and enriches every match with:

  • CISA KEV - whether the CVE is exploited in the wild, with a ransomware marker
  • EPSS - the probability of exploitation in the next 30 days

An exploited CVE is ranked above a higher-scored dormant one. Keep the CPE table honest as vendors change hands:

python scripts/audit_cpe_mapping.py            # re-check every mapping against NVD

Phase 3: active vulnerability probing (--aggressive, opt-in)

Off by default, and it prints an authorization notice when it runs, because these checks send crafted requests to the target rather than observing it. All four are non-destructive.

  • CORS - a reflected origin with credentials is high; a bare *, which browsers already block from credentialed use, is not reported
  • Open redirect - common redirect parameters on the root path
  • HTTP parameter pollution - flags a status-code change on a duplicated parameter, filed as an informational hint
  • S3 buckets - guesses bucket names from the domain; a public listing is high

Request smuggling is deliberately excluded: a faithful probe desyncs the connection and can affect other users of a shared server, which belongs in a dedicated tool under a scoped engagement.

Other features

  • JavaScript analysis (--js) - extracts API endpoints, exposed secrets (API keys, tokens, AWS keys) and hidden paths from linked scripts
  • Screenshot (--screenshot) - a full-page capture via headless Chromium
  • Burp Professional (--burp) - runs a Burp scan and imports its issues; see below

CLI options

Flag Description
-a, --phase2 Active recon: ports, subdomains, fingerprinting, takeover
--no-takeover Skip the takeover check (it queries DoH and third-party services)
--aggressive Phase 3 active probes. Sends crafted requests; authorized targets only
-c, --cve CVE correlation via NVD, ranked by KEV and EPSS
-s, --screenshot Full-page screenshot (needs [screenshot])
-j, --js JavaScript endpoint and secret discovery
-b, --burp Run a Burp Professional scan and import its issues (needs [burp])
--burp-timeout SECONDS How long to wait for the Burp scan (default: 300)
-d, --dashboard Serve the interactive web dashboard (needs [dashboard])
--output-dir DIR Where to write reports and screenshots (default: .)
-v, --verbose Verbose output

Environment variables

Variable Purpose
NVD_API_KEY Raises the NVD rate limit from 5 to 50 requests / 30s. Without it, --cve throttles to ~1 query every 6.5s. Request one.
BURP_API_KEY Burp REST API key, used by --burp. Sent as a URL path prefix.
BURP_API_URL Burp REST service URL (default: http://127.0.0.1:1337).
PHANTOMPROBE_DASHBOARD_HOST Dashboard bind address (default: 127.0.0.1).
PHANTOMPROBE_DASHBOARD_PORT Dashboard port (default: 8080).

Reports and dashboard

Each scan writes two reports next to the output directory:

  • report-<target>.md - a HackerOne-style Markdown report
  • report-<target>.json - the same findings as structured JSON, including the CVE matches with their KEV and EPSS fields

The --dashboard flag serves the findings in a dark, dense web UI with severity filtering, live WebSocket updates, and a CVE table that surfaces which matches are actively exploited. Serve an empty dashboard, without running a scan, straight from the ASGI app:

pip install -e ".[dashboard]"
uvicorn phantomprobe.asgi:app --host 127.0.0.1 --port 8080

Docker

git clone https://github.com/Ravel226/PhantomProbe.git
cd PhantomProbe
mkdir -p reports

# One-off scan (results land in ./reports)
docker build -t phantomprobe .
docker run -v "$(pwd)/reports:/app/reports" phantomprobe example.com --output-dir /app/reports

The container runs as uid 1000. If your host reports/ directory is owned by a different user, the scan fails with Permission denied; run it as yourself with --user "$(id -u):$(id -g)".

Compose ships a profile per edition:

docker compose --profile core up phantomprobe-core            # CLI only, smallest image
docker compose --profile dashboard up phantomprobe-dashboard  # dashboard at http://localhost:8080
docker compose --profile full up phantomprobe-full            # every feature, includes Chromium
docker compose --profile dev up phantomprobe-dev              # dashboard with source reload
docker compose --profile api up phantomprobe-api              # dashboard API only, no scan
docker compose --profile burp up phantomprobe-burp            # with a Burp REST endpoint

Burp Suite integration

PhantomProbe can run a scan in Burp Professional and pull its issues into the same report. Burp's REST API only scans, so results flow one way: there is no endpoint for pushing findings back or driving the proxy, and PhantomProbe does not pretend to offer either.

  1. Burp Professional: enable the REST API under Settings → Suite → REST API
  2. Create an API key on that screen (Burp shows the value only once)
  3. pip install -e ".[burp]"
export BURP_API_KEY=your-api-key
phantomprobe target.com --burp --burp-timeout 1800

The key is a URL path prefix, not a header: Burp serves the API under http://127.0.0.1:1337/<your-key>/v0.1/. Opening that URL in a browser shows the API documentation for your exact Burp version.

Architecture

src/phantomprobe/
├── cli.py            Argument parsing and scan orchestration
├── constants.py      Version and User-Agent (single source of truth)
├── models.py         Finding, Severity
├── http_client.py    Fetch helper with a URL-scheme allowlist
├── doh.py            DNS-over-HTTPS resolver (shared)
│
├── passive.py        Phase 1: DNS, SSL/TLS, HTTP headers
├── cookies.py        Cookie security attributes
├── dns_security.py   SPF, DMARC, DKIM, CAA, DNSSEC
├── http_checks.py    HSTS preload, redirect chain, security.txt
│
├── active.py         Phase 2: ports, subdomains, fingerprinting
├── takeover.py       Subdomain takeover (two-signal)
├── waf.py            WAF/CDN fingerprinting
│
├── aggressive.py     Phase 3: CORS, open redirect, HPP, S3 (opt-in)
│
├── cve.py            NVD correlation + KEV/EPSS enrichment
├── js.py             JavaScript endpoint/secret discovery
├── screenshot.py     Playwright capture            (extra: screenshot)
├── burp.py           Burp REST integration         (extra: burp)
├── report.py         Markdown and JSON reports
├── dashboard.py      FastAPI dashboard             (extra: dashboard)
└── asgi.py           Standalone ASGI entry point   (extra: dashboard)

scripts/audit_cpe_mapping.py   Re-check the CVE table against live NVD
tests/                         264 tests, network stubbed

Development

pip install -r requirements-dev.txt   # editable install with all extras + tooling

pytest                    # run the suite (network is stubbed; no target needed)
pytest --cov=phantomprobe # with coverage
black src tests           # format
flake8 src tests          # lint
bandit -r src -ll         # security scan

The test suite stubs every network call, so it runs offline and touches no real host. See CONTRIBUTING.md for the workflow.

Security notice

Use PhantomProbe only against systems you own or are explicitly authorized to test. Passive checks read what a target already exposes, but active reconnaissance (--phase2) and vulnerability probing (--aggressive) send traffic to it. Unauthorized scanning is illegal in most jurisdictions.

Disclaimer

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.

Credits

License

MIT - see LICENSE. Author: @Ravel226.

Changelog

Release history and unreleased changes are in CHANGELOG.md.

Contributing

Contributions are welcome. Fork, branch, add tests, and open a pull request. See CONTRIBUTING.md.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

phantomprobe-0.9.0.tar.gz (99.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

phantomprobe-0.9.0-py3-none-any.whl (79.0 kB view details)

Uploaded Python 3

File details

Details for the file phantomprobe-0.9.0.tar.gz.

File metadata

  • Download URL: phantomprobe-0.9.0.tar.gz
  • Upload date:
  • Size: 99.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.9

File hashes

Hashes for phantomprobe-0.9.0.tar.gz
Algorithm Hash digest
SHA256 9220f0b355e74d87c63e4bca02c1cc47a8dbcc243a50acbab83448c96e262af3
MD5 2e049e170628b672a9f61fb9ba5be3a5
BLAKE2b-256 c350d53b336e580bc6fc9f0dbef48f4ddaebcbca112a93d809ee54880986628d

See more details on using hashes here.

File details

Details for the file phantomprobe-0.9.0-py3-none-any.whl.

File metadata

  • Download URL: phantomprobe-0.9.0-py3-none-any.whl
  • Upload date:
  • Size: 79.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.9

File hashes

Hashes for phantomprobe-0.9.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4d668df502b1480ccc213a49585bc99f937b614dd779f072fa6c7ddc44226c90
MD5 054b7a83252ad16071d8af55fb1dd7bb
BLAKE2b-256 8386c09a59cb25d65ed68196172b814f7ad5c4cc6d9e4de699a364b17b296ceb

See more details on using hashes here.

Release history Release notifications | RSS feed

0.9.1

2 files

This release

0.9.0 This release

2 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