pentest_setup deploys a pen-testing-ready Bash environment on top of
common_core and
bash_setup. It ships:
- A set of pentest-specific dotfiles (
pentest.path.sh,pentest.env.sh,pentest.aliases.sh,pentest.keys,renew_tgt.sh, thescreenshothelper) deployed to${HOME}/.config/bash/. - A
pentest.shhook thatbash_setup'sbashrcalready sources, which pulls the above into every interactive shell. - Five interactive menus under
menus/that walk through preflight checks, environment setup, apt/python/go/ruby dependency installs, 60+ tool installs frommodules/tools/, and post-install cleanup. - A
config/layer that definesDATA_DIR,ENGAGEMENT_DIR,BACKUP_DIR,LOOT_DIR, and related engagement paths used by both pentest helpers andbash_setup'stgt.aliases.sh.
It is the fourth repo in a five-repo stack:
common_core → bash_setup → scripts → pentest_setup → pentest_menu
pentest_setup's install.sh will refuse to run unless the earlier repos
in the chain are in place. See Requirements.
- Bash 4+ (macOS users:
brew install bash) - Python 3.12+ for the tool-install modules that ship Python helpers
common_coreinstalled at${HOME}/.config/bash/lib/common_core/(install instructions)bash_setupinstalled (specifically: itsbashrcdeployed to${HOME}/.bashrc, which sources the${BASH_DIR}/pentest.shhook this repo deploys)- Recommended for development:
shellcheck(lint)shfmt(format) — must support-i 4 -ci -srbats(test)
# 1. Install common_core and bash_setup first (see those repos).
# 2. Then clone and install pentest_setup:
git clone https://github.com/tatanus/pentest_setup.git
cd pentest_setup
make install # equivalent to: bash install.shinstall.sh is interactive — it presents the five-menu flow
(00_preflight, 01_environment, 02_requirements, 03_tools,
04_post). Pass --dry-run for a no-op preview.
After install, start a new shell or re-source bashrc to pick up the deployed dotfiles:
exec bash -l.
├── install.sh # menu-driven installer (entry point)
├── Makefile # quality gates + release automation
├── VERSION # date-based version: YYYY.MM.DD.N
├── CHANGELOG.md # Keep a Changelog
├── config/
│ ├── config.sh # DATA_DIR, ENGAGEMENT_DIR, BACKUP_DIR, etc.
│ └── lists.sh # PENTEST_FILES, APT/PIP/GO/RUBY package lists
├── dotfiles/ # files deployed to ${HOME}/.config/bash/
│ ├── pentest.sh # source hook for ${BASH_DIR}/pentest.sh
│ ├── pentest.path.sh # exports DATA_DIR, ENGAGEMENT_DIR, PATH adds
│ ├── pentest.env.sh # NETWORK_IFACE, DC_IP, credentials defaults
│ ├── pentest.alias.sh # pentest-flavored aliases
│ ├── pentest.keys # SSH/PGP key references
│ ├── renew_tgt.sh # cron-payload script (renews Kerberos TGTs)
│ └── screenshot.sh # interactive screenshot helper
├── menus/ # auto-sourced by install.sh in order
│ ├── 00_preflight.sh # tool/OS/root/common_core checks
│ ├── 01_environment.sh # dotfile deploy, dirs, cron jobs
│ ├── 02_requirements.sh # apt / pip / go / ruby package installs
│ ├── 03_tools.sh # interactive 60+ tool installer
│ └── 04_post.sh # cleanup + summary
├── modules/
│ └── tools/ # one *.sh per tool, sourced by 03_tools.sh
├── tests/ # BATS coverage (structural)
└── tools/
└── check_bash_style.sh # comprehensive style scan
dotfiles/renew_tgt.sh looks like a duplicate of bash_setup's
tgt.aliases.sh::renewTGT but isn't — it's a self-contained cron payload
scheduled by menus/01_environment.sh::environment::setup_cron_jobs. It
must stay independent of any sourced shell environment because cron does
not load bashrc.
| Target | What it does |
|---|---|
make help |
Show all targets. |
make ci |
Format check + lint + tests. Non-mutating. Run before PRs. |
make fmt |
Auto-format with shfmt -i 4 -ci -sr. |
make fmt-check |
Verify formatting without writing; same flags as make fmt. |
make lint |
shellcheck -x across git ls-files '*.sh'. |
make test |
bats -r tests. |
make style |
Comprehensive style scan via tools/check_bash_style.sh. |
make install |
bash install.sh — deploy dotfiles, run setup menus. |
make show-version |
Print current VERSION. |
make release V=… |
Cut a release (see Releases). |
make release-today |
Cut a release using today's UTC date (YYYY.MM.DD.0). |
The mandated formatter flags are -i 4 -ci -sr. Do not add -bn or
-kp anywhere.
- Depends on:
common_core(installed at${HOME}/.config/bash/lib/common_core/util.sh) andbash_setup(specifically: itsbashrcmust be deployed so that${BASH_DIR}/pentest.shgets sourced). - Provides for
bash_setup:- The
pentest.shhook deployed to${BASH_DIR}/pentest.sh. DATA_DIRandENGAGEMENT_DIRexports (viapentest.path.sh), whichbash_setup'stgt.aliases.shreads. (tgt.aliases.shalso has a${HOME}/DATAsafe-default fallback so it does not crash ifpentest_setupis not installed.)
- The
Enforced by .shellcheckrc and tools/check_bash_style.sh:
- Bash 4+,
set -uo pipefail,IFS=$'\n\t'. - No
set -e— handle errors explicitly. - No
evaloutside heavily-audited metaprogramming. function name() { … }form; never barename() { … }.- All expansions quoted and braced (
"${var}","$@"). [[ … ]]not[ … ];command -vnotwhich;$(…)not backticks.- Source-guard idiom on every helper:
if [[ -z "${X_LOADED:-}" ]]; then declare -g X_LOADED=true # … fi
See CLAUDE.md (auto-generated) for the canonical policy hash chain.
The repo uses date-based four-part versioning (YYYY.MM.DD.N), tracked in
VERSION and CHANGELOG.md. To cut a release:
# 1. Land your changes as normal commits with `## [Unreleased]` notes.
git add …; git commit -m "feat(…): …"; git push
# 2. Cut the release. `make release` will:
# - run `make ci` (refuse if anything fails)
# - refuse on a dirty working tree
# - stamp `## [Unreleased]` -> `## [Vx] - YYYY-MM-DD` (UTC) in CHANGELOG
# - write VERSION
# - single commit `chore(release): cut Vx`
# - annotated tag `vVx`
# - `git push --follow-tags`
make release-today # uses today's UTC date.0
make release-today N=1 # second cut of the same UTC day -> .1
make release V=2026.06.27.0 # explicit versionThis project is licensed under the MIT License.