A local-only recon note-taking and visualisation tool for AutoRecon engagements. It was built to visualise and organise recon during OSCP-style penetration testing labs and exams, and is just as useful for general recon on any engagement.
Authorised use only. Use RecoNGraph, AutoRecon and the tools whose commands it suggests only against systems you own or have explicit permission to test. RecoNGraph does not scan or attack anything itself — it reads scan output and suggests commands — but those commands run active tools. The suggestions are general-purpose, not exam-approved: some use tools that certain exams restrict (such as
sqlmaporresponder), so check your exam's current rules, and edit the list if needed (see Customizing suggested commands). You are responsible for staying within the law and your scope.
RecoNGraph reads AutoRecon's output directory and layers a graph view, credential tracking (per-host and engagement-wide), a password-spray matrix, structured notes, and command generation on top of it — without ever modifying AutoRecon's own output. Everything is stored as YAML/Markdown on disk next to your scan results.
It ships two frontends over the same data layer:
- Web UI (
recongraph.py) — a Cytoscape.js graph with tabbed host/service detail panels, binds to127.0.0.1only. - Terminal UI (
tui.py) — a Textual-based navigator for working entirely inside a terminal/tmux session.
Every host, service and share as a graph, coloured by compromise state, with host-to-host links and the selected host's details alongside.
Per-service suggested commands, pre-filled with the host's IP, domain and your chosen credential.
Scan output with findings summarised and highlighted, and noise dimmed.
Every credential in one table, with where each one is valid.
Spray matrix: which credential works where, at a glance.
Markdown notes, per engagement and per host.
The same engagement in a terminal: hosts, services and credentials with a live preview pane.
Suggested commands in the TUI, ready to paste into a tmux pane.
All screenshots use a generated, fictional engagement.
- Python 3.10+
- AutoRecon to generate the scan data RecoNGraph reads
git clone <repo-url>
cd recongraph
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtRun AutoRecon against your target(s) first, then point RecoNGraph at the engagement root:
python recongraph.py /path/to/engagementOpen http://127.0.0.1:8420 in a browser.
For the terminal UI instead:
python tui.py /path/to/engagementThe engagement directory above is only where each tool starts — both frontends can switch to a different scan directory afterward without restarting: Open Scan in the web UI's header (browse subdirectories, or paste a path), or o in the TUI. Either one reloads all data from the new directory in place and keeps a shared list of the 5 most-recently-opened directories, whichever frontend opened them.
RecoNGraph works with these tools out of the box. It doesn't bundle or install any of them; install the ones you want (most ship with Kali).
Reads output from
- AutoRecon — its output directory is the input. Hosts, ports, services and OS come from its nmap XML, with domain details from nmap's NTLM scripts (
rdp-ntlm-info,http-ntlm-info,smtp-ntlm-info) and certificate info fromssl-cert. - Scan files from nmap, feroxbuster, gobuster, ffuf, nikto, whatweb, wpscan, hydra, enum4linux, smbclient, smbmap, ldapsearch and curl are recognised and labelled in the file viewer. Findings (CVE IDs,
Pwn3d!, writable shares, outdated software, directory listings and similar) are highlighted, and noisy header/XSS/CSRF lines are dimmed. - SMB share output from smbclient, smbmap, NetExec/CrackMapExec and nmap's
smb-enum-sharesis parsed into the shares and credential-to-host views. This happens automatically for AutoRecon output; Import accepts the same formats from your own runs.
Suggests commands for (copy-and-paste; RecoNGraph never runs them)
| Service | Tools |
|---|---|
| FTP | ftp, hydra, nmap |
| SSH | ssh, hydra, nc |
| DNS | dig, dnsenum, gobuster |
| HTTP / HTTPS | curl, whatweb, nikto, feroxbuster, gobuster, ffuf, wfuzz, wpscan, sqlmap, sslscan, openssl |
| SMB | smbclient, smbmap, enum4linux-ng, NetExec (nxc) / CrackMapExec, Impacket (psexec, smbexec, wmiexec, secretsdump, ntlmrelayx), Responder |
| LDAP | ldapsearch, NetExec / CrackMapExec, bloodhound-python |
| Kerberos | kerbrute, Impacket (GetNPUsers, GetUserSPNs, getTGT, getST), NetExec / CrackMapExec |
| WinRM | evil-winrm, NetExec / CrackMapExec |
| RDP | xfreerdp, NetExec / CrackMapExec, nmap |
| MySQL / PostgreSQL | mysql, psql, hydra, nmap |
| MSSQL | Impacket (mssqlclient), NetExec / CrackMapExec, nmap |
| RPC / MSRPC | rpcinfo, rpcclient, showmount, mount, Impacket (rpcdump, lookupsid) |
| SNMP | snmpwalk, snmp-check, onesixtyone |
| NFS | showmount, mount, nmap |
| SMTP | smtp-user-enum, swaks, nmap |
Runs itself: searchsploit (exploit lookups for service versions, alongside Exploit-DB links) and, in the TUI, tmux (to paste a suggested command into another pane, without pressing Enter). Add, remove or change any suggested command as described below.
Every service tab's "suggested actions" (nmap scripts, hydra brute-forcing, SMB enumeration, etc.) come from plain YAML, not code, and are meant to be edited.
The first time you run either frontend, RecoNGraph copies its built-in command set into ~/.config/recongraph/actions.d/00-defaults.yml and reads only from that directory from then on — the shipped suggested_actions.yml in this repo is just the seed, never touched again after that first copy. Edit 00-defaults.yml directly to fix or extend a built-in service, or drop additional files (e.g. 01-oracle.yml) into the same directory to add new ones without touching the defaults at all.
Files load in filename order, and a service key defined in a later file (e.g. redefining smb: in 01-mine.yml) fully replaces the same key from an earlier one — there's no per-action merge, so overriding a built-in service means repeating any of its actions you still want. A malformed file is skipped with a warning on stderr rather than blocking startup.
Each action is:
services:
<service-key>:
ports: [<port numbers this key matches on>]
aliases: ["<other nmap service names that should also match>"]
actions:
- label: "Short name shown in the UI"
cmd: "the command, with {placeholders}"
desc: "One-line explanation of what it does and why"{ip}, {port}, {hostname}, {domain}, {dc_ip}, {user}, {password}, {hash}, and {keyfile} are filled in automatically; {hash}/{keyfile} only resolve when the selected credential is actually that type. Any other {name} is looked up from that host's custom state fields.
Quoting is handled for you. Values (usernames, passwords, share names, AD domains...) can come from a hostile target, so every placeholder is escaped for the shell quoting context it sits in within your template — unquoted (/u:{user}), single-quoted (-p '{password}') or double-quoted. Write the surrounding quotes however the tool wants them; do not escape inside the value yourself. A value always arrives as exactly one literal argument, and line breaks in a value are flattened to a space.
Since your defaults file won't pick up upstream improvements automatically once seeded, diff it against suggested_actions.yml in a newer checkout if you want to pull in changes by hand. $RECONGRAPH_CONFIG_DIR overrides the base config directory if you'd rather keep it somewhere other than ~/.config/recongraph.
pip install -r requirements.txt -r requirements-dev.txt
pytestThe Python suite builds a small fictional engagement on the fly (tests/sample_engagement.py: three hosts on 192.0.2.0/24 under example.test), so no scan data is stored in the repo. scripts/dev_server.sh serves a fresh copy for manual testing.
The Python suite above covers recongraph.py/core.py/tui.py. The web frontend (static/app.js) has its own Playwright end-to-end suite under e2e/, driving a real browser against a disposable fixture engagement — see that directory's README to run it.
RecoNGraph is a local tool with no login, so its defences are about who can reach it and what scanned targets can make it do. Everything it displays — hostnames, banners, service names, SMB share names, AD usernames, file names, notes — is data a hostile target can influence.
- Network exposure. It binds to
127.0.0.1only. Because a browser on the same machine will talk to127.0.0.1on behalf of any web page you have open, requests are also checked: aHostheader that isn't a loopback name is refused (DNS rebinding), and state-changing requests must be same-origin (cross-site request forgery). If you reach the UI through a custom name, allow it withRECONGRAPH_ALLOWED_HOSTS=name1,name2; an SSH tunnel tolocalhostneeds nothing. - Script injection. The page ships a strict Content-Security-Policy (
script-src 'self', no inline script or event handlers, no framing) and setsno-referrer. Scan data is HTML-escaped wherever it is rendered, and markdown (notes, scan.mdfiles) is rendered with raw HTML shown as literal text and onlyhttp(s)/mailtolinks. Files served from the scan directory (/api/file/raw) are sent as sandboxed downloads, never as pages. - Pasted commands. Suggested commands are copy-to-clipboard (or pasted into a tmux pane by the TUI — never run). Placeholder values are shell-escaped for the quote context they land in, and the TUI refuses to paste anything containing a newline or other control character, since those would press Enter.
- Filesystem. Names that become file paths (host IDs, protocols, service-note keys, note IDs, imported IPs) are validated or flattened to a single path component and checked to stay inside their directory. It never edits AutoRecon's own output files; its own state lives in
_rng/subdirectories next to them (credential files are written0600), and manually added hosts or services get their own directories. - TUI. Target text is rendered as literal text, never as Textual/Rich markup (a hostname like
[/oops]can't crash it, and[@click=...]can't create actions), and terminal escape sequences in scan output are neutralised. - What it runs. The web UI launches only
searchsploit(if installed), with the query passed as a single argument and leading dashes removed. The TUI additionally callstmuxto list panes and paste text, with the text passed literally as one argument. Open Scan lets the page browse directories and switch the engagement root — which is why the checks above matter: anything that can make same-origin requests can use it. - Offline. All UI libraries (Cytoscape.js and its cose-bilkent layout, marked.js, highlight.js) are vendored under
static/vendor/and loaded from disk — zero external network calls at runtime, exam-day-safe with no internet connection required.
MIT — see LICENSE. The vendored front-end libraries under static/vendor/ keep their own licences; see static/vendor/LICENSES.md. RecoNGraph is an independent project, not affiliated with or endorsed by OffSec or the AutoRecon project.







