
Vulnerability triage with provenance. Resolves CVEs from locally built corpora (NVD/KEV/EPSS, ExploitDB, nmap script.db) and emits verification commands classified by what running them does to the target.
A vulnerability triage tool. It takes what a scan already found, works out which CVEs plausibly apply, tells you how confident it is and why, and gives you the commands to check for yourself.
It does not scan anything, and it does not exploit anything.
git clone https://github.com/xGhst0/reconkg && cd reconkg && pip install -e . --break-system-packages && python -m reconkg.selfcheck
That last step reports what it can and cannot see: whether nmap's script.db
was found, which corpora are configured, and how many realistic fingerprints
actually produce a lead. Run it first. Out of the box the answer is "nine
hand-written CVEs", and selfcheck says so rather than letting you assume
otherwise.
The nine built-in entries are a demonstration fixture. For anything real:
export NVD_API_KEY=... # free: https://nvd.nist.gov/developers/request-an-api-key
python -m reconkg.fetch --dest ~/.reconkg/feeds --all
python -m reconkg.builddb --feeds ~/.reconkg/feeds --out ~/.reconkg/vuln.db
export RECONKG_VULN_DB=~/.reconkg/vuln.db
export RECONKG_EXPLOIT_DB=~/.reconkg/exploits.db
export RECONKG_SCRIPT_DB=/usr/share/nmap/scripts/script.db
Without the API key NVD throttles to 5 requests per 30 seconds and the full
pull takes about four hours instead of twenty-five minutes. It checkpoints,
so an interrupted pull resumes. --since pulls only what changed.
If a corpus variable is set and the file cannot be opened, reconkg refuses to start. Quietly serving nine entries when you asked for 300,000 would mean a scan that finds nothing and looks like it worked.
python -m reconkg.app # serves http://127.0.0.1:8765/ui
python -m reconkg.console # REPL
app binds loopback only, with no flag to change it. This process holds your
scan results and issues commands aimed at hosts you are testing; an SSH
tunnel is a small price next to having that reachable from the rest of the
network. --port moves it, RECONKG_PORT sets a default.
Authentication. Every route needs Authorization: Bearer <token>, from
RECONKG_TOKENS in the form name:role:token (roles: viewer, scanner,
operator, admin; tokens at least 16 characters). If it is unset, app
mints one for that process only and prints it at startup — not written to
disk, different every restart.
A browser cannot attach a header to a plain navigation, so opening /ui
directly will 401. Use a header-injecting extension, or drive the API:
export RECONKG_TOKENS="me:admin:$(openssl rand -hex 16)"
curl -H "Authorization: Bearer ${RECONKG_TOKENS##*:}" \
http://127.0.0.1:8765/api/corpus
The UI shows the knowledge graph with provenance on click, so you can see why a CVE was attached to a host rather than trusting a score, and a ledger ordered by triage priority with KEV and EPSS weighed in.
Every suggested command carries an NSE category describing what running it does to the target. That vocabulary is nmap's, not invented here.
The last row is the boundary. If a working exploit exists for a lead,
reconkg tells you the module or template and where to find it. It does not
assemble that into an invocation with your target already in it. Metasploit
suggestions stop at show options — the step where you read RHOSTS back and
confirm it is the host you are authorised against.
That is one keystroke of difference on a box you own, and a much larger difference in what the tool is.
Safety is classified per check, never per tool. That is not fussiness:
current nuclei CVE templates achieve detection by exploiting — one posts
a subprocess.run('cat /etc/passwd') payload through a Langflow RCE and
matches on root:.*:0:0:. Anything that assumes "nuclei detects, Metasploit
exploits" is wrong at the first template it meets, so nuclei is treated as
unclassified and sits behind the opt-in.
selfcheck prints the real hit
rate rather than a flattering one.describe() marks a corpus stale past 30 days and names which
feed is old.pip install -r requirements-dev.txt
python -m pytest tests/ -q # 1219 tests
python -m audit.mutation # mutation testing, 12 targets at 100%
python -m audit.scale_bench # corpus scale benchmark
docs/ carries the design notes and the reasoning behind the decisions
above. audit/AUDIT.md is the finding record: 47 findings across ten
adversarial rounds, including an analysis of the one bug shape that accounts
for 13 of them and an honest assessment of what has and has not prevented it.
MIT — see LICENSE.
reconkg ships no vulnerability data. The corpora are built on your machine from feeds you fetch yourself, which keeps their licences yours to honour; ExploitDB's index in particular is GPL-2.0-or-later and is deliberately never redistributed here.
Everything reconkg emits is a suggestion for a human to run. Running
intrusive or vuln checks against a system you do not own or have written
authorisation to test is illegal in most jurisdictions.
| Category | What reconkg does |
|---|
safe, discovery, version | composed, shown by default |
intrusive, vuln, unclassified | composed, shown when you tick the box, with the authorisation warning |
exploit, dos, fuzzer, brute | named, never composed |