recon-engine: The Bash Script That Turns One Domain Into a Recon Dossier
Seven phases, graceful degradation, and a practical way to map attack surface without a heavyweight platform.
- recon-engine treats reconnaissance as a pipeline that ends in a usable dossier, not a scrollback buffer.
- Its biggest strength is graceful degradation, because missing tools do not stop the run.
- Bash works here because the script keeps control flow visible while the filesystem stores the work.
- The `.env` and `env.js` checks show a modern bias toward predictable leaks, not only broad scanning.
One command, a lot of surface area
recon-engine is not trying to be a shiny platform. It is trying to make recon feel ordered. Feed it one domain and it grows a workspace under recon/<target>/ with subdomains, live hosts, URLs, port context, fuzz targets, and leak candidates.
That is the real story. The hard part of recon is not making one more request. It is keeping the evidence organized enough that the next decision is obvious.
The script keeps moving even when the toolchain is incomplete
The script assumes the toolchain will be partial. It checks for installed binaries with command -v, skips what is missing, and still writes whatever it can collect. That makes the output less perfect, but much more usable.
if command -v subfinder >/dev/null 2>&1; then
subfinder -d "$TARGET" -silent > "$OUT/subdomains.txt"
fi
if command -v httpx >/dev/null 2>&1; then
httpx -l "$OUT/subdomains.txt" -silent > "$OUT/live.txt"
fi
The same design shows up in other places too. The repository uses inline Python for JSON handling when a full dependency stack is not guaranteed, and it uses quick mode plus rate limiting so the workflow can trade depth for speed without changing the shape of the run.
Why Bash is the right glue here
Bash gives the author three things that matter in recon: direct control over CLI tools, portable execution, and transparent state. set -euo pipefail helps the script fail loudly when it should, while the surrounding skip logic keeps the workflow from collapsing when a tool is absent.
The cost is real. Flat files are easy to inspect and awkward to compare over time. Bash is excellent at coordinating, less elegant at modeling history, permissions, or cross-target analysis. The repo accepts that tradeoff instead of pretending it solved it.
The seven-phase pipeline, from expansion to narrowing
The pipeline is linear on purpose. Expansion comes first, refinement comes second, then deeper probes run against a smaller set of targets. Every stage writes to a predictable folder so the next one can pick up the trail without guessing.
- Passive discovery gathers subdomains from multiple sources.
- Live probing filters the list down to responsive hosts.
- Port and service context adds a little depth before deeper scans.
- Historical URL harvesting widens the map with old endpoints.
- JavaScript inspection looks for secrets and hidden paths.
- Directory fuzzing tests likely routes against live hosts.
- Phase 6.5 checks predictable exposure points such as `.env` and `env.js` before the final pass.
- Parameter extraction collects request arguments that deserve a second look.
The important part is not the tool count. It is the sequence. Each phase narrows the problem before it spends time on the next one, which is why the output feels curated instead of bloated.
Phase 6.5 is the tell
That small half-step is the tell. The repo is not only looking for exposed files in the abstract. It is looking for the predictable places real systems leak when somebody forgot that web roots are public.
That matters because many recon wins are boring in the best way. A stray config file or client-side bundle can reveal keys, endpoints, or internal service names before any noisy fuzzing ever starts.
How it stacks up against manual chaining and heavier frameworks
The right comparison is not Bash versus software. It is manual chaining versus a shell workflow versus a database-backed framework. That is where recon-engine becomes easy to place.
| Dimension | Manual shell chaining | recon-engine | reNgine |
|---|---|---|---|
| Setup complexity | Low per command, high across the run | Low once dependencies are present | Highest, because it wants a full app stack |
| Output organization | Scattered files and scrollback | Predictable folders under <code>recon/<target>/</code> | Database-backed projects and dashboards |
| Missing tools | Usually handled by the operator | Skips unavailable steps and continues | More integrated, but tied to a heavier system |
| Historical diffing | Awkward | Awkward without extra tooling | Better, because data is stored and queryable |
| Collaboration | Weak | Weak to modest | Strong |
| Speed to first signal | Fast if you know the commands | Fast after setup | Slower at the start, stronger over time |
| Control flow transparency | High, but manual | High, with explicit phase logic | Lower, because orchestration lives behind the app |
| Best fit | One-off recon | Terminal-first operator | Team workflows and repeatable campaigns |
recon-engine wins when you want fast signal, visible steps, and a low-friction terminal workflow. reNgine wins when you want teams, dashboards, stored history, and a shared operating surface. Manual chaining still has a place, but only when you want full control and do not mind paying for it in attention.
The tradeoff is the product
recon-engine is not the universal answer. It does not solve team collaboration, long-term diffing, or multi-user review. It solves something narrower and more common: turning reconnaissance into a disciplined terminal workflow that survives partial failure.
That is enough for a lot of practitioners. The product is not the Bash syntax. The product is orchestration discipline, and that is why this script feels more durable than it has any right to.