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.

9 min read • View on GitHub • More from shuvonsec

A single domain seed enters a mechanical sorting machine and splits into drawers for subdomains, live hosts, ports, URLs, scripts, fuzz targets, and leak checks. The image explains how the project turns one input into an organized recon workspace instead of a pile of terminal output.
One target goes in. A structured attack-surface dossier comes out.
Key Takeaways

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.

The point is not perfect completeness. It is useful output, even when some stages are skipped.

A conveyor belt runs through a row of recon stations, but one station is empty and the belt reroutes around it while the rest keep working. The scene explains why the script can still produce useful output when a dependency is missing.
A missing tool does not stop the line. It just changes the route.

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.

  1. Passive discovery gathers subdomains from multiple sources.
  2. Live probing filters the list down to responsive hosts.
  3. Port and service context adds a little depth before deeper scans.
  4. Historical URL harvesting widens the map with old endpoints.
  5. JavaScript inspection looks for secrets and hidden paths.
  6. Directory fuzzing tests likely routes against live hosts.
  7. Phase 6.5 checks predictable exposure points such as `.env` and `env.js` before the final pass.
  8. 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

A cracked sealed folder sits under a magnifying glass while keys, tokens, and folded papers spill from the seam onto a white tray. The close-up explains why the repo cares about predictable config exposures before it spends more time on brute-force discovery.
The smart money is often in the obvious places.

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.

DimensionManual shell chainingrecon-enginereNgine
Setup complexityLow per command, high across the runLow once dependencies are presentHighest, because it wants a full app stack
Output organizationScattered files and scrollbackPredictable folders under <code>recon/&lt;target&gt;/</code>Database-backed projects and dashboards
Missing toolsUsually handled by the operatorSkips unavailable steps and continuesMore integrated, but tied to a heavier system
Historical diffingAwkwardAwkward without extra toolingBetter, because data is stored and queryable
CollaborationWeakWeak to modestStrong
Speed to first signalFast if you know the commandsFast after setupSlower at the start, stronger over time
Control flow transparencyHigh, but manualHigh, with explicit phase logicLower, because orchestration lives behind the app
Best fitOne-off reconTerminal-first operatorTeam 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.