An interactive, menu-driven launcher for a penetration test. It is the top of
the five-repo stack (common_core → bash_setup → scripts → pentest_setup → pentest_menu): it installs nothing and instead runs the tools that
pentest_setup installs, over the directory model and engagement variables
defined once in pentest_setup's pentest.env.sh, using common_core
(cmd::, dns::, file::, logging, …) directly.
./pentest_menu # or: make runfzf drives the menus (installed by pentest_setup). common_core must be
installed at ~/.config/bash/lib/common_core.
- Run one task — pick a category, then pick a single task. Runs just it.
- Run a whole category — pick a category, then choose
>>> RUN ALL <category> TASKS <<<. Every task in that category runs inscript_order, best-effort (a failing task is logged and the run continues). - Run everything — pick the
ALLcategory, then>>> RUN ALL ALL TASKS <<<.
Tasks are grouped by the categories declared in each module:
external, internal, web, recon (plus the synthetic ALL). A single
module may belong to several categories.
Every module is named run_<something>. Category and run order are NOT in
the filename -- each module declares script_categories and script_order
in-file, and the menu parses those to build the category options and to sort a
category by order (so "RUN ALL " runs in script_order). Internal
workflow modules (run_validate, run_broadcast, run_dns_lookup, …) and the
external recon-suite wrappers (run_recon_osint, run_recon_cloud, …) are all
just run_ files with the right metadata inside.
pentest_menu # entrypoint: sources common_core + config + menu, launches
menu_lib.sh # category launcher + the three run modes
menu/menu.sh # fzf menu engine (_Display_Menu, _Exec_Function)
meta_module.sh # shared helpers: validate_*(), pm::run_internal_task / pm::run_external_phase
config/config.sh # sources the shared pentest.env.sh (paths, tools, engagement vars)
lib/internal_lib.sh # shared helpers/paths for the native internal modules
modules/ # one file per menu entry (see the three kinds below)
suites/
└── external/ # external recon suite (orchestrator + phases/ + lib/)
Three kinds of module live in modules/:
- Standalone tool modules (
modules/run_*.sh) wrap a single tool directly (e.g.run_gobuster,run_smb_signing). - Native internal tasks (e.g.
run_validate,run_dns_lookup,run_domain_controllers,run_smb_*,run_netexec) are full modules withscript_categories="internal": each defines its logic inline (private helpers namespaced under its menu key, e.g.run_dns_lookup::_resolver) using the sharedinternal::*helpers and DATA/ paths fromlib/internal_lib.sh. - External recon-suite wrappers (
run_recon_*) are thin: each runs one phase of the external recon suite insuites/external/as a subprocess (viapm::run_external_phase). That suite is a tightly-coupled orchestrator (scope expansion, discovery gate, resume/state), so it stays intact and runs in a child process, keeping its many globals out of the menu shell.
Every module file declares its menu key, category and order, and defines a
function of the same name. The menu discovers modules/*.sh automatically —
no engine edits are ever needed.
Add a standalone tool module — create modules/run_mytool.sh:
script_categories["run_mytool"]="web" # one or more of: external internal web recon
script_order["run_mytool"]=50 # position within its category
function run_mytool() {
validate_tools "mytool" || return 1 # meta_module.sh helper
validate_envs "RECON_DIR" || return 1 # pentest.env.sh vars
mytool --input "${RECON_DIR}/web.txt" # use pentest_setup paths/tools
}Add a native internal task — create modules/run_mytask.sh like any other
module (script_categories="internal", a run_mytask function, a
script_order for its place in the flow). Use the shared internal::run /
internal::clean_list / LOG helpers and the DATA/ path vars from
lib/internal_lib.sh, and namespace any private helpers under run_mytask::.
Add an external phase (two steps, no engine edits):
- Drop
suites/external/phases/NN-name.sh(auto-discovered byrun_recon.shinNNorder; definesrun_phase_name). - Copy an existing
modules/run_recon_*.shwrapper and change the three values at its top: the menu key,script_order, and the phase id passed topm::run_external_phase.
See the SUITE RUNNERS block in meta_module.sh for the wrapper contract.
- common_core at
~/.config/bash/lib/common_core(framework; never vendored). - pentest_setup:
pentest.env.sh(paths/engagement vars) and the installed tools (fzf,nmap,httpx,nuclei,gowitness,nxc,spoonmap,msfconsole, …). Missing tools are reported and the task degrades. - scripts: standalone one-off utilities (this repo no longer sources any scripts library at runtime; the M365 library ships inside the external suite).