Skip to main content

reconowl

CI PyPI python license checks tests

Recon → scan → report, in one command. reconowl is a CLI penetration-testing orchestrator: point it at a target and it runs passive + active reconnaissance, a detailed vulnerability scan, and produces an HTML/JSON/Markdown report.

Its design goal is to actually produce results: it orchestrates proven engines (nmap, nuclei, httpx, sqlmap) where they exist and falls back to reliable native checks where they don't — so a scan is useful on a full Kali box and on a bare Python install alike.

reconowl example.com -y

⚠️ Authorized use only

reconowl performs active scanning and light exploitation probing. Use it only against systems you own or are explicitly authorized in writing to test. Unauthorized scanning is illegal in most jurisdictions. reconowl will not start a scan until you confirm authorization (interactively, or with -y/--authorize). You are solely responsible for how you use it.

Example

A run against an authorized target looks like this (output abbreviated):

      ,___,                              _
      (O,O)    _ _ ___ __ ___ _ _  _____ __ _| |
      /)__)   | '_/ -_) _/ _ \ ' \/ _ \ V  V / |
      -"-"-   |_| \___\__\___/_||_\___/\_/\_/|_|

  recon → scan → report   v0.3.0

╭ Phase 1 · Passive reconnaissance ╮
✓ DNS: A(1), MX(1), NS(2), TXT(3)     ✓ Subdomains: 4     ✓ Archived URLs: 118
╭ Phase 2 · Active reconnaissance ╮
✓ Open ports: 80/http, 443/https      ✓ Crawl: 22 pages, 9 forms
╭ Phase 3 · Vulnerability scanning ╮
✓ OpenAPI: parsed 31 operations from /openapi.json  (+18 URL, +6 form)
   HIGH    9.8  SQL injection (query: id)            https://target.tld/item?id=1
   HIGH    7.5  Reflected XSS (query: q)             https://target.tld/search?q=1
   MEDIUM  6.1  Missing security headers (CSP, HSTS) https://target.tld

Findings by severity:  Critical 0 · High 2 · Medium 5 · Low 3 · Info 7
✓ HTML/JSON/Markdown reports written to ./reconowl-report/

Every confirmed finding carries a CVSS score and the exact request/response that proved it (auth headers redacted). Values above are illustrative.

Proven detection

Against a deliberately vulnerable local app, the native injection checks confirm real bugs and attach the request/response that proved each one:

Finding CVSS Confirmed by
OS command injection (host) 9.8 Critical GET /ping?host=;iduid=0(root) gid=0(root)
SQL injection (id) 9.8 High GET /item?id=1'sqlite3.OperationalError: unrecognized token
LFI / path traversal (file) 7.5 High GET /read?file=../../../../etc/passwdroot:x:0:0:…
Reflected XSS (q) 6.1 Medium injected marker reflected unencoded

Each is confirmed only on real evidence (command output, a database error, a target-file signature, an unencoded reflection) — never on reflection alone — so false positives stay low. Findings are not reported from a matched banner or version string.

Features

Phase 1 — Passive recon (no packets to the target)

  • DNS records (A/AAAA/MX/NS/TXT/CNAME/SOA) with a DNS-over-HTTPS fallback so resolution works even on locked-down egress where UDP/53 is blocked.
  • WHOIS/registration data via RDAP.
  • Subdomain enumeration via certificate transparency (crt.sh).
  • Historical URL harvesting via the Wayback Machine.

Phase 2 — Active recon

  • Port/service/version scanning with nmap (or a built-in TCP connect scanner when nmap is absent).
  • HTTP probing with httpx (or a native prober) — status, title, server, tech.
  • TLS/certificate inspection (issuer, SANs, expiry, trust, protocol) — reads even invalid/self-signed certs.
  • Content discovery from robots.txt and sitemap.xml, plus an active crawler that follows links and extracts form parameters (optionally seeded by katana) so the injection checks have real inputs to test.
  • JavaScript analysis: fetches in-scope JS bundles and extracts referenced endpoints (feeding the injection checks) and hard-coded secrets (AWS, Google, Slack, GitHub, Stripe, private keys, JWTs, …), reported redacted.
  • SPA / JS rendering (--render, auto-detected): when a target renders its links/forms client-side (React/Vue/Angular/Next/…), reconowl drives a headless browser (Playwright) to render seed pages, harvesting the rendered DOM and the XHR/fetch API endpoints the app calls — then feeds them to the checks. Auto-triggers only on SPA-like pages; degrades to static + JS-endpoint extraction when no browser is installed.

Phase 3 — Vulnerability scanning

  • Native checks: missing security headers, insecure cookie flags, TLS problems (expired / self-signed / untrusted / weak protocol), version disclosure, and exposed sensitive files (.git, .env, backups, phpinfo, …) with soft-404 filtering to cut false positives.
  • Exposed services: flags internet-facing databases (MySQL, PostgreSQL, MongoDB, Redis, …), remote-access (RDP, VNC, SMB, Telnet, FTP), and admin panels (Plesk, cPanel, Webmin, phpMyAdmin, …) with risk-based severity.
  • WAF detection & adaptive throttling: fingerprints WAFs/CDNs (or runs wafw00f), and automatically backs off — then stops — when the target starts rate-limiting/blocking, warning you (use --stealth for polite scanning).
  • Email authentication (SPF/DMARC/DKIM): evaluates the registrable domain's anti-spoofing DNS — missing/permissive (+all)/weak SPF, missing or monitor-only (p=none) DMARC, and DKIM presence across common selectors — so phishing-enabling gaps are caught (DNS-only, works even if the site is down).
  • OpenAPI / Swagger parsing: discovers a published API spec (Swagger 2.0 / OpenAPI 3.x, JSON or YAML), enumerates every operation's path/query/body parameters, and feeds them to the injection checks (GET → query points, POST → form/JSON body points) — turning API docs into real test coverage. A publicly reachable spec is also reported as information disclosure.
  • Known-CVE mapping: matches detected software versions (Server header, nmap banners, tech fingerprints) against a curated offline CVE database with version-range comparison, reporting each hit with its real CVSS and NVD link.
  • Directory/file brute-force: a built-in wordlist (override with --wordlist) with soft-404 baselining so sites that answer 200 for everything don't flood results; flags directory listings, protected resources, and sensitive paths, and feeds discoveries back into later checks.
  • CORS misconfiguration: reflected arbitrary origin, trusted null origin, and wildcard policies — escalated when credentials are also allowed.
  • Open redirect: off-site redirect via common redirect parameters, confirmed only on an actual 3xx Location / meta-refresh to the attacker host.
  • Host-header injection: bogus Host / X-Forwarded-Host reflected into a redirect or absolute URLs (cache / password-reset poisoning).
  • CRLF injection / response splitting: a \r\n-and-marker payload confirmed only when the injected header (or cookie) actually appears in the response headers.
  • Subdomain takeover: matches each subdomain's CNAME and page against a fingerprint database of 25+ third-party services; unique fingerprints stand alone while generic ones require a CNAME match, and dangling CNAMEs are flagged — keeping false positives low.
  • GraphQL introspection: probes common GraphQL endpoints; flags enabled introspection (full-schema disclosure) and exposed GraphiQL/Playground IDEs.
  • XXE: posts external-entity XML to XML-accepting endpoints, confirmed by an in-band /etc/passwd read or an out-of-band callback (reusing the SSRF listener) — zero-false-positive by construction.
  • JWT weaknesses: harvests tokens from cookies/headers/bodies and analyses them offline — alg:none, brute-forced weak HMAC secrets (forgeable tokens), missing expiry, and sensitive data in the payload.
  • SSTI: injects arithmetic template expressions for several engines (Jinja2/Twig, FreeMarker/EL, ERB, Razor, …) and confirms only when the evaluated product appears — strong signal for template injection (often RCE).
  • LFI / path traversal: injects traversal payloads (multiple depths and encodings, Linux and Windows) into file-like parameters, confirmed only when a target file's signature (/etc/passwd, win.ini) appears in the response.
  • OS command injection: output-based (id / arithmetic expansion) and blind time-based (sleep) detection — confirmed only on real command output or a measured delay, so no reflection false positives.
  • Server-side prototype pollution: the Express json spaces gadget — confirmed only when polluting __proto__ visibly changes a JSON endpoint's formatting (and the cosmetic change is restored afterward).
  • SSRF: URL-shaped parameters tested two ways — an out-of-band callback listener for zero-false-positive confirmation (ideal for lab/internal, where the target can reach the scanner), plus in-band signature detection for cloud-metadata and file:// reads. Tune with --oob-host/--oob-port/--no-oob.
  • NoSQL injection: error-based (Mongo/Mongoose error signatures) plus an operator-differential probe ([$ne] vs [$eq]) that only fires when the backend actually parses the operators.
  • Default / weak credentials: tries a small, conservative set of well-known credential pairs against HTTP Basic Auth realms (401→200 is definitive) and discovered login forms (each pair submitted with CSRF/hidden fields preserved, compared to a known-bad baseline to avoid false positives). --no-default-creds.
  • CSRF (missing token): flags state-changing POST forms whose fields carry no anti-CSRF token — gated on cookie posture, so forms already protected by SameSite=Strict/Lax session cookies are not reported (low false positives).
  • Broken access control / IDOR: re-requests sensitive resources without a session (protected content reachable unauthenticated → BAC), tampers numeric IDs (different object returned → likely IDOR), and — with --second-cookie — confirms cross-user object access.
  • Injection probes: error-based SQL injection and reflected XSS candidates, with optional sqlmap confirmation.
  • GET / POST-form / JSON body coverage: SQLi/XSS, SSTI, OS command injection, NoSQL, and LFI test query parameters, application/x-www-form-urlencoded form fields, and JSON body fields alike — form parameters come from the crawler.
  • nuclei template scanning across discovered endpoints.

Subdomain deepening (--subdomains)

  • After passive recon discovers subdomains, the live ones are scanned with the full web-layer check suite (headers, cookies, TLS, exposures, CORS, open redirect, injection) and their findings merged into one report. Port scanning and nuclei are skipped per subdomain to keep a broad sweep practical; cap with --max-subdomains. Active payloads are scope-limited to the target and its sibling subdomains, never to unrelated hosts pulled from sitemaps or archives.

Phase 4 — Reporting

  • A self-contained, styled HTML report, full JSON for automation, Markdown for notes/GitHub, and SARIF 2.1.0 for CI / GitHub code scanning (--formats sarif). Findings are normalized, de-duplicated, and severity-scored.
  • CVSS v3.1 base score, rating, and vector on every finding (shown in the console and all three report formats); the summary reports the highest CVSS.
  • Request/response proof captured for each confirmed finding (the exact triggering request and response, with cookies/tokens redacted), shown in the HTML and Markdown reports and stored in JSON.
  • Scan-to-scan diff: --diff <previous report.json> shows what's new, fixed, and changed since a prior run (console + diff.json/diff.md); or diff two saved reports without scanning via --diff-reports OLD.json NEW.json.

Authenticated scanning — a cookie, bearer token, basic auth, or custom headers (--cookie / --bearer / --auth-basic / -H) are attached to every request so checks reach authenticated surface area — or let reconowl log in for you (--login-url/--login-user/--login-pass) and crawl + scan the session.

Requirements

  • Python 3.10+
  • Python packages (pip install -r requirements.txt): rich, requests, dnspython, jinja2, cryptography.
  • Optional external tools on PATH (reconowl auto-detects and degrades gracefully): nmap, nuclei, httpx, katana, sqlmap, nikto, whatweb, wafw00f, whois. All ship with Kali Linux.
  • Optional headless browser for SPA/JS rendering: install the render extra (pip install ".[render]") then playwright install chromium. Without it, reconowl falls back to static crawling.

Install

pip install reconowl        # from PyPI — installs the `reconowl` command
reconowl --help

Optional headless browser for SPA/JS rendering:

pip install "reconowl[render]" && playwright install chromium

From source (for development):

git clone https://github.com/Ayberk-Irmak/reconowl.git && cd reconowl
pip install -e .
python -m reconowl --help

Usage

The examples below use the reconowl command; python -m reconowl is equivalent.

# Full pipeline (recon + scan + report), confirming authorization inline:
reconowl example.com -y

# Web app target, aggressive intensity, HTML report only:
reconowl https://target.tld -y -i aggressive --formats html

# Recon only, no active scanning:
reconowl target.tld -y --passive-only

# Native-only (don't call nmap/nuclei/etc.):
reconowl target.tld -y --no-external

# Also scan discovered subdomains:
reconowl target.tld -y --subdomains

# Confirm SQLi candidates with sqlmap, custom output dir:
reconowl "https://target.tld/item.php?id=1" -y --sqlmap -o ./engagement

# Diff this scan against a previous run:
reconowl target.tld -y --diff ./engagement/report.json

# Diff two saved reports without scanning:
reconowl --diff-reports old/report.json new/report.json

Authenticated scanning

Send a session cookie, bearer token, or arbitrary headers so every check (native and orchestrated httpx/nuclei/sqlmap) runs authenticated:

reconowl https://app.tld -y --cookie "session=eyJ...; role=admin"
reconowl https://api.tld -y --bearer "eyJhbGciOi..."
reconowl https://app.tld -y -H "X-Api-Key: abc123" -H "X-Env: staging"
reconowl https://app.tld -y --auth-basic admin:s3cr3t

Automated form login — reconowl fetches the login page, fills the form (preserving CSRF/hidden fields), captures the session, and crawls + scans the authenticated area (avoiding logout links to keep the session alive):

reconowl https://app.tld -y \
  --login-url https://app.tld/login --login-user admin --login-pass 's3cr3t'
# fields are auto-detected; override with --login-user-field / --login-pass-field,
# and confirm success with --login-check "Dashboard".

Key options: -i/--intensity {light,normal,aggressive}, --formats html,json,md, --no-nuclei, --sqlmap, --subdomains, --timeout, --concurrency, --rate-limit, --doh/--no-doh, -q/--quiet. See --help for all.

Output

Reports are written to reconowl-report/ (or -o <dir>):

reconowl-report/
  report.html   # styled, self-contained
  report.json   # full machine-readable result
  report.md     # Markdown summary

CI / GitHub code scanning

Emit SARIF and upload it so findings appear in the repo's Security tab:

reconowl https://staging.tld -y --formats sarif -o out
# .github/workflows/reconowl.yml (excerpt)
- run: reconowl "$TARGET" -y --formats sarif -o out
- uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: out/report.sarif

CVSS scores map to SARIF security-severity, so GitHub ranks the alerts.

How it works

Every phase writes into one normalized result model; reports render purely from that model, so adding a check or a report format never touches the others. External tools are optional accelerators, not hard dependencies — the same scan runs (with less depth) when they're missing. Networking is built to survive restrictive environments: name resolution can transparently fall back to DNS-over-HTTPS, and TLS/port checks connect by resolved IP while preserving SNI.

Roadmap

  • Optional Nmap NSE and WhatWeb enrichment in the report.
  • Screenshot capture for discovered endpoints.
  • PyPI release.

License

Provided as-is for authorized security testing and education.

Download files

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

Source Distribution

reconowl-0.3.1.tar.gz (141.1 kB view details)

Uploaded Source

Built Distribution

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

reconowl-0.3.1-py3-none-any.whl (140.8 kB view details)

Uploaded Python 3

File details

Details for the file reconowl-0.3.1.tar.gz.

File metadata

  • Download URL: reconowl-0.3.1.tar.gz
  • Upload date:
  • Size: 141.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for reconowl-0.3.1.tar.gz
Algorithm Hash digest
SHA256 34a6d807430edc9919ff2c17f5f14795d6d25d180c69802cec36a2051ce892ea
MD5 9b7cc1fe7d779478501175a79f32b32d
BLAKE2b-256 274d1d63848e1a80aead4b63985a88935f7a7c47989bd69858e9a3b7fbcbb2b7

See more details on using hashes here.

Provenance

The following attestation bundles were made for reconowl-0.3.1.tar.gz:

Publisher: publish.yml on Ayberk-Irmak/reconowl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file reconowl-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: reconowl-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 140.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for reconowl-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 12c3af68bc34accabb1a7e96b4cbdd4bdf184c1c3bb10fe071ef5918a3c14c34
MD5 df03faa1aaeb4e00797b846bb1b4cee1
BLAKE2b-256 2ca04d9ef17c21a4ff5f22d38723b20ba526064f8d7ba07929c9289a7430a6ab

See more details on using hashes here.

Provenance

The following attestation bundles were made for reconowl-0.3.1-py3-none-any.whl:

Publisher: publish.yml on Ayberk-Irmak/reconowl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page