Passive OSINT Vulnerability Scanner
Identify potentially vulnerable internet-facing systems using FOFA / Shodan / Censys exports + InternetDB + NVD CVE data — without sending a single packet to the target.
- What is ReconHawk?
- How it works
- Legal disclaimer
- Requirements
- Installation
- API Keys
- Workflow
- Usage
- Output formats
- Project structure
- Architecture
- Rate limits & responsible use
- FAQ
- Contributing
- License
ReconHawk is a passive reconnaissance tool built for security researchers, bug bounty hunters, and penetration testers. It combines three publicly available data sources:
| Source | What it provides |
|---|---|
| FOFA / Shodan / Censys (web export) | Already-indexed data of internet-facing hosts (IP, port, domain, org) |
| InternetDB (Shodan) | Free, keyless API – returns known CVE IDs and tags for any IP |
| NVD (NIST) | The official CVE database – CVSS scores, descriptions, publish dates |
By correlating these sources, ReconHawk surfaces hosts that are likely running software with known, published CVEs — without ever touching the target system.
No packets are sent to any target. All data comes from FOFA's / Shodan's / Censys's existing index, InternetDB, and the NVD REST API.
┌─────────────────────────────────────────────────────────────────┐
│ ReconHawk Flow │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 1. You export a CSV from FOFA, Shodan, or Censys │
│ FOFA query example: app="WordPress" && country="HU" │
│ Or: supply a plain-text IP/domain list, or pass targets │
│ directly with --target / --targets │
│ │
│ 2. The appropriate Reader parses the file │
│ Extracts: IP, hostname, domain, org, port │
│ Deduplicates IPs (one lookup per unique IP) │
│ │
│ 3. InternetDBClient ──► internetdb.shodan.io/{ip} │
│ Returns: known CVE IDs, tags, hostnames │
│ Free, no API key required │
│ │
│ 4. NVDClient ──► NVD CVE API (per CVE ID) │
│ Enriches each CVE with: CVSS score, severity, description │
│ Filters by: --severity + --age │
│ │
│ 5. OutputWriter ──► CSV / JSON / TEXT │
│ (format determined by output file extension) │
│ │
└─────────────────────────────────────────────────────────────────┘
⚠️ Read this before using ReconHawk.
ReconHawk only queries publicly available, already-indexed data. It does not perform active scanning, exploitation, or any direct connection to target systems.
However, you are solely responsible for how you use the output:
- Always obtain explicit written permission before performing any active testing on a target
- Unauthorized access to computer systems is illegal in Hungary (Btk. 423–424. §), the EU, and most jurisdictions worldwide
- Using this tool's output to attack systems without authorization is illegal, even if the vulnerability information is public
- The author assumes no liability for misuse
This tool is intended for:
- Authorized penetration testing engagements
- Bug bounty hunting within defined scope
- Security researchers studying exposure landscapes
- System owners auditing their own infrastructure
- Python 3.10+
- A FOFA, Shodan, or Censys account (for CSV export modes)
- An NVD API key (free, strongly recommended)
- InternetDB requires no account or key
# 1. Clone the repository
git clone https://github.com/CrashizVok/ReconHawk.git
cd ReconHawk
# 2. Create a virtual environment (recommended)
python3 -m venv .venv
source .venv/bin/activate # Linux / macOS
# .venv\Scripts\activate # Windows
# 3. Install dependencies
pip install -r requirements.txt
# 4. Set up your environment file
cp .env.example .env
# Edit .env and fill in your NVD API keyFOFA is used via its web interface only — no API key needed for the CSV export workflow.
- Register at fofa.info
- Search for your targets (e.g.
app="WordPress" && country="HU") - Click the Download button → set quantity to
2990(free credit limit) → export as CSV - Save the file and pass it with
--input
Shodan is used via its web interface only — export your search results as CSV and pass with --input.
Censys is used via its web interface only — export your search results as CSV and pass with --input.
- Visit nvd.nist.gov/developers/request-an-api-key
- Fill in the form — the key is emailed within minutes
- Free with no subscription required
- Without a key: 5 requests per 30 seconds. With a key: 50 requests per 30 seconds
No registration or API key required. Free public API by Shodan.
# FOFA
1. Go to fofa.info → search → download CSV (up to 2990 free)
2. Run: py -m main --mode fofa --input fofa.csv --output results.csv
# Shodan
1. Go to shodan.io → search → download CSV
2. Run: py -m main --mode shodan --input shodan.csv --output results.csv
# Censys
1. Go to censys.io → search → export CSV
2. Run: py -m main --mode censys --input censys.csv --output results.csv
# Plain IP/domain list
3. Run: py -m main --mode list --list targets.txt --output results.csv
# Single target / quick check
4. Run: py -m main --target example.hu
Run: py -m main --targets 1.2.3.4,2.3.4.5,example.hu --output results.json
ReconHawk supports five input modes:
| Mode | Flag | Description |
|---|---|---|
fofa |
--mode fofa --input FILE |
FOFA web export CSV |
shodan |
--mode shodan --input FILE |
Shodan search export CSV |
censys |
--mode censys --input FILE |
Censys search export CSV |
list |
--mode list --list FILE |
Plain text file, one IP or domain per line (lines starting with # are ignored) |
| direct | --target IP/HOST or --targets IP,... |
One or more IPs/domains, no file needed |
usage: reconhawk [-h]
[--mode {fofa,shodan,censys,list}]
[--input FILE] [--list FILE]
[--target IP/HOST] [--targets IP,...]
[--output FILE]
[--severity {CRITICAL,HIGH,MEDIUM,LOW,ALL}]
[--age DAYS] [--country "HU"] [--tld ".hu"]
[--all]
[--lang {en,hu}]
[--delay-nvd SEC] [--delay-idb SEC]
Input (pick one):
--mode fofa --input export.csv FOFA web export
--mode shodan --input export.csv Shodan search export
--mode censys --input export.csv Censys search export
--mode list --list targets.txt Plain text, one IP/domain per line
--target 1.2.3.4 Single IP or domain
--targets 1.2.3.4,2.3.4.5,h.hu Multiple IPs/domains, comma-separated
Output (optional — omit to print only, not save):
--output results.csv → CSV (any extension other than .json / .txt)
--output results.json → JSON
--output results.txt → plain text
The output format is determined automatically by the file extension.
Filters:
--severity LEVEL Minimum CVE severity to include [default: HIGH]
--age DAYS Max CVE age in days [default: 730]
--country "HU" Filter by country code (fofa / shodan / censys)
--tld ".hu" Filter by domain TLD (fofa / shodan / censys)
--all Include targets with no CVEs in output
Advanced:
--lang {en,hu} Log language [default: en]
--delay-nvd SEC Delay between NVD requests [default: 0.6]
--delay-idb SEC Delay between InternetDB requests [default: 0.3]
Examples:
# FOFA export, Hungarian targets only, save as CSV
py -m main --mode fofa --input fofa.csv --country "HU" --tld ".hu" --output results.csv
# FOFA export, CRITICAL CVEs only, save as JSON
py -m main --mode fofa --input fofa.csv --severity CRITICAL --output hits.json
# Shodan export, CVEs from the last year, save as CSV
py -m main --mode shodan --input shodan.csv --age 365 --output results.csv
# Censys export, save as plain text
py -m main --mode censys --input censys.csv --output results.txt
# Plain IP/domain list, MEDIUM and above
py -m main --mode list --list ips.txt --severity MEDIUM
# Single domain
py -m main --target example.hu
# Multiple targets, save as JSON
py -m main --targets 8.8.8.8,1.1.1.1,example.hu --output results.json| Flag | Included severities |
|---|---|
--severity CRITICAL |
CRITICAL only (CVSS 9.0–10.0) |
--severity HIGH |
HIGH + CRITICAL (default) |
--severity MEDIUM |
MEDIUM + HIGH + CRITICAL |
--severity LOW |
everything |
--severity ALL |
everything including UNKNOWN |
The output format is inferred from the file extension of --output:
py -m main --mode fofa --input fofa.csv --output results.json # → JSON
py -m main --mode fofa --input fofa.csv --output results.txt # → plain text
py -m main --mode fofa --input fofa.csv --output results.csv # → CSV (default)Omitting --output prints results to the console only without saving.
One row per CVE. Best for importing into Excel or Google Sheets.
IP,Hostname,Domain,Org,Country,Port,Product,Version,CVE ID,Severity,CVSS,Published,Source,Description
1.2.3.4,example.hu,example.hu,Example Kft.,HU,80,WordPress,,CVE-2023-1234,HIGH,8.8,2023-03-15,InternetDB+NVD,Authenticated SQL injection...
Nested structure — one object per target, CVEs as an array:
[
{
"ip": "1.2.3.4",
"hostnames": ["example.hu"],
"domain": "example.hu",
"org": "Example Kft.",
"country": "HU",
"port": 80,
"product": "WordPress",
"version": "",
"cves": [
{
"id": "CVE-2023-1234",
"severity": "HIGH",
"cvss": 8.8,
"published": "2023-03-15",
"source": "InternetDB+NVD",
"description": "Authenticated SQL injection..."
}
]
}
]Human-readable format for quick review:
ReconHawk – Scan Results
Generated : 2026-05-02 20:00 UTC
Targets : 3
============================================================
[1]
IP : 1.2.3.4
Hostname : example.hu
Domain : example.hu
Org : Example Kft.
Port : 80
Software : WordPress
CVEs (1):
[InternetDB+NVD] [HIGH] CVE-2023-1234 (CVSS 8.8) [2023-03-15] Authenticated SQL injection...
ReconHawk/
├── main.py # Main script (all classes + entry point)
├── data.csv # FOFA/Shodan/Censys export — your input file (not committed)
├── results.csv # Scan output (not committed)
├── requirements.txt # Python dependencies
├── .env.example # Environment variable template
├── .env # Your actual secrets (never commit this!)
├── .gitignore
└── README.md
ReconHawk (orchestrator)
├── FOFAReader
│ └── read() parses FOFA-exported CSV → Target objects
│
├── ShodanReader
│ └── read() parses Shodan-exported CSV → Target objects
│
├── CensysReader
│ └── read() parses Censys-exported CSV → Target objects
│
├── ListReader
│ └── read() parses plain-text IP/domain list → Target objects
│
├── DirectReader
│ └── read() wraps --target / --targets values → Target objects
│
├── InternetDBClient
│ ├── lookup() GET internetdb.shodan.io/{ip}
│ ├── get_cves() extracts CVE IDs from response
│ ├── get_tags() extracts software tags
│ └── get_hostnames() extracts hostnames
│
├── NVDClient
│ ├── enrich_cve() fetches full CVE details by ID
│ ├── enrich_list() enriches a list of CVEEntry objects via NVD
│ ├── by_cpe() CPE-based CVE search (fallback when version is known)
│ ├── _cvss() parses CVSSv3.1 / v3.0 / v2
│ └── _passes() filters by --severity threshold
│
└── OutputWriter
├── _csv()
├── _json()
└── _text()
Data models (dataclasses):
├── ScanConfig – all configuration in one place
├── Target – one internet-facing host
└── CVEEntry – one CVE record (source: InternetDB / NVD / InternetDB+NVD)
Helpers:
├── _detect_product() infers technology from page title / domain
├── _resolve() resolves hostname to IP via DNS
└── _make_target() convenience factory for Target objects
| API | Key required | Rate limit | ReconHawk default delay |
|---|---|---|---|
| FOFA / Shodan / Censys | No (web export) | varies by plan | N/A |
| InternetDB | No | ~1 req/s recommended | 0.3 s |
| NVD | Optional | 5 req/30s (no key) / 50 req/30s (with key) | 0.6 s |
- For large CSVs (1000+ IPs) a full run may take 30–60 minutes due to NVD rate limits
- NVD CVE results are cached in-memory — same CVE ID is only fetched once per run
- Add
NVD_API_KEYto your.envfor 10× faster NVD lookups
Q: Does this actually connect to the targets?
A: No. FOFA / Shodan / Censys have already crawled the internet. InternetDB and NVD are passive lookup APIs. ReconHawk never connects to any target IP.
Q: Why does a target show no CVEs?
A: InternetDB may not have data for that IP, or the CVEs found may be older than the --age limit / below the --severity threshold. Use --severity ALL --all to see everything.
Q: The version field is empty in the output.
A: FOFA's free tier does not expose version data in the CSV export. The CPE-based NVD fallback (by_cpe) is only triggered when a version is available, so it will not run in most free-tier exports. CVE lookup via InternetDB still works without a version.
Q: Can I scan a different country?
A: Yes — change your FOFA / Shodan / Censys search query, export the CSV, and add --country DE (or whichever code) to filter the results. For Germany: app="WordPress" && country="DE" in FOFA.
Q: Can I add more technologies to detect?
A: Yes. Add entries to TITLE_TO_TECH in main.py (keyword → technology name) and DEFAULT_TECHNOLOGIES (technology name → NVD CPE prefix).
Q: How do I find the correct CPE prefix for a product?
A: Search nvd.nist.gov/products/cpe/search and copy the vendor:product part of the CPE URI.
Q: Can I run it in Hungarian?
A: Yes — add --lang hu to get Hungarian log messages.
Pull requests are welcome. Please:
- Fork the repo
- Create a feature branch (
git checkout -b feature/my-feature) - Keep all comments and docstrings in English
- Test your changes before opening a PR
- Do not commit
.env,data.csv, or output files
MIT License — Copyright (c) 2026 CrashiZ (https://github.com/CrashizVok)
Built for educational and authorized security research purposes only.