Legal disclaimer: This tool is for use only against systems you own or have explicit written authorisation to test. Unauthorised scanning is illegal under the Computer Misuse Act 1990 (UK) and equivalent legislation worldwide. The author accepts no liability for misuse. A scan will not start until the operator confirms authorisation, and every scan is restricted to a defined scope.
ReconMapper is a full-stack cyber security project that automates the reconnaissance phase of a penetration test against an authorised target.
The tool enumerates subdomains from certificate transparency logs, resolves and port-scans the live hosts, fingerprints running services, correlates service versions against the NVD CVE database, captures screenshots of exposed web services, scores each host by risk, and presents the whole attack surface as an interactive graph with a downloadable PDF report.
Reconnaissance is the first phase of every real engagement, and testers spend the opening hours of an assessment mapping an organisation's external footprint by hand. This project demonstrates practical skills in passive and active recon, service fingerprinting, vulnerability correlation, scope discipline, and full-stack tooling, packaged as one coherent workflow.
- Open the app and enter a domain you are authorised to test.
- Confirm the authorisation gate before the scan can start.
- ReconMapper queries crt.sh certificate transparency logs for subdomains.
- Each discovered host is resolved and checked against the engagement scope.
- In-scope hosts are port-scanned with Nmap for open ports and service versions.
- Detected service versions are correlated against the NVD CVE database.
- Exposed web services are screenshotted with a headless browser.
- Each host is assigned a weighted risk score.
- Results render as an interactive graph, a findings table, and a PDF export.
Every scan is bound to a target domain and an optional list of allowed CIDR ranges.
Before any packet is sent, each candidate host is checked against that scope:
- a hostname must match the target domain or one of its subdomains
- a resolved IP must fall inside an allowed CIDR range, when ranges are provided
- anything outside scope is rejected and never scanned
This keeps active scanning confined to the systems the operator is authorised to test, and makes the rules of engagement an explicit, enforced part of the tool rather than a convention.
- Passive subdomain enumeration via certificate transparency
- Active port and service/version detection with Nmap
- CVE correlation against the NVD API
- Headless screenshot capture of exposed web services
- Weighted per-host risk scoring
- Interactive attack surface graph
- Backend: Python, FastAPI, SQLAlchemy (async), httpx, python-nmap, Playwright, ReportLab
- Database: SQLite
- Frontend: React, Vite, Tailwind CSS, React Flow
- DevOps: Docker Compose
- Testing: Pytest
- CI: GitHub Actions
With Docker:
git clone https://github.com/eniat/recon-mapper.git
cd recon-mapper
cp .env.example backend/.env
docker compose up --build
Frontend on http://localhost:5173, API on http://localhost:8000, interactive API docs on http://localhost:8000/docs.
Without Docker, from the repo root:
python -m venv .venv
.venv\Scripts\Activate.ps1
python -m pip install -e ".[dev]"
python -m playwright install chromium
copy .env.example .env
python -m uvicorn app.main:app --reload
Then start the frontend in a second terminal:
cd frontend
npm install
npm run dev
Copy .env.example and fill in what you need. All values are optional and the tool runs without any keys.
| Variable | Purpose | Default |
|---|---|---|
NVD_API_KEY |
Raises the NVD rate limit from 5 to 50 requests per 30s | empty |
SCREENSHOT_ENABLED |
Toggle Playwright screenshot capture | true |
MAX_SCAN_CONCURRENCY |
Number of hosts scanned in parallel | 5 |
- Passive subdomain enumeration via crt.sh certificate transparency logs
- Retry handling for crt.sh, a flaky upstream
- Scope enforcement checked before a single packet is sent
- Nmap-driven port and service/version detection
- NVD CVE correlation with rate limiting and per-host deduplication
- Headless Playwright screenshot capture of HTTP/HTTPS services
- Weighted per-host risk scoring combining CVSS with exposure
- Interactive attack surface graph rendered with React Flow, colour-coded by risk
- Severity-coloured PDF report export
- Concurrent scan pipeline with per-host failure isolation
- Authorisation gate on the scan form
- Pytest coverage of the scope and risk-scoring logic
- Docker Compose deployment
- GitHub Actions CI
| Method | Path | Description |
|---|---|---|
| POST | /api/scans/ |
Create and start a scan |
| GET | /api/scans/ |
List all scans |
| GET | /api/scans/{id} |
Get a single scan |
| GET | /api/scans/{id}/hosts |
Hosts discovered for a scan |
| GET | /api/scans/{id}/findings |
CVE findings for a scan |
| GET | /api/reports/{id}/pdf |
Download the PDF report |
| GET | /health |
Health check |
An operator runs ReconMapper against a domain they are authorised to test. Certificate transparency reveals a forgotten staging subdomain. Resolution and an Nmap scan find it running an outdated web server, NVD correlation flags a matching high-severity CVE, and the headless browser captures the exposed login page. The host surfaces on the graph as a red, high-risk node, and the operator exports a PDF report as evidence for the engagement.
- CVE correlation uses NVD keyword search rather than precise CPE matching, so results can over-match.
- Scans run as FastAPI background tasks rather than a dedicated queue, which suits single-user lab use.
- The schema is created with
create_allrather than migrations.
- CPE-based CVE matching for precision
- Alembic migrations
- Task queue for large multi-host engagements
- Historical diffing to surface newly exposed assets between scans
This project is licensed under the MIT Licence. See the LICENSE file for details.

