All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog,
and this project adheres to the project-wide date-based versioning scheme
(YYYY.MM.DD.N).
bash/internal/tasks/08-msf-modules.shnow hands off to the shippedrun_all_modules.sh(deployed by pentest_setup beside the MSF scripts) when it can — running every module in a singlemsfconsolesession and parsing theOUTPUT/TEEspool logs for Metasploit successes ([+]), so an internal run ends with a consolidated findings summary instead of just.teefiles. It passesMSF_TEE_DIR/MSF_SCRIPTS_HOME/MSF_MODULES_DIRso the engagement paths line up. The previous per-modulemsfconsole -q -rloop is retained as a fallback and is used whenMSF_MODULES_INCLUDE/_EXCLUDEglob filters are set, when the helper is absent, or when the install is relocated off the canonical/root/DATApath (where the rc files' hardcoded runner-load line must be rewritten).- Added explicit OS guards to the four Linux-only Bash scripts, which
previously ran bare
apt,systemctl, and GNUsed -ion any platform and would abort mid-run (often after a sudo prompt) on macOS. Each now refuses up front with a clear reason:bash/wireless.sh— requires the Linux Wi-Fi stack (iw,airmon-ng,nmcli) andapt.bash/setup-mail-server.sh— targets Debian/Ubuntu (apt-get, systemd, Postfix/OpenDKIM).bash/update_gophish.sh— manages a systemd service and/etc/gophishpaths.bash/update-mail-domain.sh— edits/etc/postfixand reloads services viasystemctl.
python/azure_tenant_enum.py— resolve a DNS domain against Azure AD / Entra ID via public, unauthenticated Microsoft endpoints to recover the tenant GUID, federation brand / company name, and namespace type; also identifies any domains supplied via-f/--file. Outputs text, JSON, or CSV (-F), to stdout or a file (-o). Marked executable to match the other CLI tools inpython/.- Reports the identity provider fronting each tenant (
auth_provider: Okta, Microsoft ADFS, Ping, OneLogin, Shibboleth, Duo, Google, Auth0, CAS, or Entra-managed), derived unauthenticated from the federation AuthURL. - Optional
--mfa-testfor MFA / authentication posture, best-effort by input (useful when an engagement has a target user but no password):-u USER -p PASS(or--prompt-password) runs a real ROPC sign-in test across several first-party clients and maps theAADSTSresult to MFA enforcement / bypass (MFASweep technique);-u USERalone runs an unauthenticatedGetCredentialTypeprobe (account existence, IdP, Seamless SSO, has-password); neither reports domain-level posture only. Single-account (not a sprayer), halts on smart-lockout, and prints an authorization warning before any sign-in attempt. - Resolves the
*.onmicrosoft.comtenant name from multiple sources (most authoritative first), since Microsoft has curtailed the AutodiscoverGetFederationInformationendpoint (it now only echoes the queried domain): the ACS metadata endpoint (accounts.accesscontrol.windows.net/{domain-or-tenantId}/metadata/json/1, the TeamFiltration technique; authoritative but empty on newer tenants as ACS is retired); the Office 365 DKIM selector CNAMEs (selector1/2._domainkey.<domain>, whose target embeds the tenant name — reliable org-published DNS, recovers non-obvious names such aspaulweiss.com→pwrwg,tesla.com→teslamotorsinc; requires dnspython, imported softly); and a GUID-verified guess (domain/brand-derived candidates accepted only when<candidate>.onmicrosoft.comresolves to the same tenant GUID). A wrong name is never reported; the name is blank only when every source fails (e.g. a domain whose mail isn't Exchange Online). Tenant GUID, brand, and namespace type remain reliable regardless. - Enumerates additional tenant domains with high certainty only. Since a
full unauthenticated domain dump is no longer possible (GetFederationInfo
curtailed, ACS retired), candidate domains — from ACS metadata,
-f/--file, and optionally Certificate Transparency (--crt,--crt-limit) — are each confirmed to belong to the tenant by matching their openid-configuration tenant GUID (checked concurrently). Only verified domains are reported in a consolidatedverified_tenant_domainslist, and every per-domain record gains asame_tenantflag; unverifiable candidates are dropped. CT uses crt.sh with a certSpotter fallback (crt.sh is frequently 5xx/404;CERTSPOTTER_API_KEYraises the certSpotter rate limit); an outage of one source degrades gracefully to the others / authoritative results.
- Reports the identity provider fronting each tenant (
bash/internal/— modular internal penetration-test suite. A task-based orchestrator (run_internal_pentest.sh) that auto-discovers and runs the steps underbash/internal/tasks/in filename order: validate/prompt for targets, iptables-block excludes, DNS + domain- controller discovery, TrustedSec spoonmap scan, Metasploitdb_import, gowitness, httpx + nuclei, everySCRIPTS/MSF/modules/*.rc, and NetExec (nxc smb --pass-pol/nxc ldap). Shared bootstrap, theDATA/path layout and helpers live inbash/internal/internal_lib.sh; defaults are overridable viabash/internal/config/default.confor--config. New steps drop in astasks/NN-name.sh(definingrun_task_NN_name()) with no orchestrator edit. Seebash/internal/README.md.- Reuses tools/artifacts deployed by
pentest_setupat runtime (spoonmap, theSCRIPTS/MSF/resource scripts, gowitness, httpx, nuclei, netexec, metasploit) and follows the sameDATA/layout aspentest_setup/config/config.sh. This is a runtime tool dependency resolved by path with graceful degradation when a tool is absent — not a source-time load-order dependency, so thecommon_core → … → scripts → pentest_setupcontract is preserved.
- Reuses tools/artifacts deployed by
.shellcheckrcsynced to the canonical 108-line version used bycommon_core,bash_setup, andpentest_setup. Brings the block-commented rule taxonomy (severity=style, bash-version=4, enforced safety rules, controlled deviations, modern-Bash enables, security foot-gun rules, function-semantics policy) in line with the rest of the stack. All four repos now share a byte-identical.shellcheckrc.bash/recon/setup_engagement.sh: replaced themkdir -p …+if [[ $? -eq 0 ]]; thenpattern with theif mkdir -p …; thenform (SC2181).
bash/wireless.sh:401: the rename-failurewarnmessage interpolated${mon_iface}, but that variable does not exist in scope at that point. The intended variable was${base_iface}(the target name the rename is trying to set). Corrected; the diagnostic now prints the actual target name on failure.
- File-level
# shellcheck disable=headers (with rationale) added to recon-suite modules and other one-off scripts so the canonical.shellcheckrcdoes not surface 33 expected SC2034 / SC2154 findings. Affected files:bash/logger.sh,bash/auto-mount-shares.sh,bash/setup-mail-server.sh,bash/update_gophish.sh,bash/recon/common_utils.sh,bash/recon/dns_email_recon.sh,bash/recon/entra_azure_recon.sh,bash/recon/m365_recon_NG.sh,bash/recon/services_recon.sh,bash/recon/run_external_recon_suite.sh,bash/recon/tasks/00-validate.sh,bash/recon/tasks/01-osint.sh,bash/recon/tasks/02-nmap.sh,bash/recon/tasks/03-http-scan.sh,bash/recon/tasks/04-testssl.sh. Each disable cites the load-chain reason (e.g. CURL_UA / ENGAGEMENT_DIR are exported by the recon-suite orchestrator before invocation).
install.sh(new, ~250 lines). Deploysbash/andpython/into${HOME}/DATA/TOOLS/SCRIPTS/{bash,python}/, creating the target directory and parents if missing. install / update / uninstall subcommands; checksum-skip-unchanged on update;--dry-run,--force,--quietflags. Preflight refuses to run unless common_core is installed at the documented system path AND bash_setup has deployed${HOME}/.bashrc.Makefilerewritten to parity with common_core / bash_setup / pentest_setup: 4-partSEMVER_RE,make fmt-check, non-mutatingmake ci,make release V=…,make release-today,make style.make testtarget now finds bats files under subdirectories viafind(wasls tests/*.bats).CHANGELOG.md(this file)..github/workflows/main.ymlrewritten to mirror the standard CI workflow in the other three repos (shellcheck + pinned shfmt v3.8.0- bats; runs
make lint,make fmt-check,make test).
- bats; runs
tools/check_bash_style.sh, copied from common_core (was referenced by the new Makefile but not present in this repo). Bonus: extended the backtick check to skip backslash-escaped backticks (`\``), which are markdown formatting in heredocs that emit READMEs.- BATS coverage for
install.shundertests/independent/:10_smoke.bats(5 tests): arg parsing,--help,--version, preflight failures when common_core / bash_setup is absent.20_lifecycle.bats(10 tests): end-to-end install / update / uninstall round-trip in a sandbox HOME.30_repo_structure.bats(8 tests): repo invariants.tests/independent/helpers/common.bash: shared helper that drops a real (or mock) common_core into the sandbox HOME and stubs a.bashrc.
- README rewritten end-to-end. The previous version documented a
fictional
scripts/directory containing onlylogger.shandsafe_source.sh, ignored the actualbash/+python/+bash/recon/layout, and had atatanus/BASHtypo in the Last-Commit badge. New README mirrors the bash_setup / pentest_setup structure. - Moved
policy/CODE_OF_CONDUCT.md,policy/CONTRIBUTING.md,policy/SECURITY.mdto.github/(their standard location).policy/directory removed. - Rewrote
.github/CONTRIBUTING.mdusing the common_core template (the previous version was the sameBASH-placeholder /-bn -kpshfmt /set -euo pipefaildrift I fixed earlier for common_core).
- All 156 ShellCheck findings in the bash tree cleared:
- 79 SC2250 brace-quoting (
$var→${var}) auto-applied viashellcheck -f diff | patch -p1. - 9 SC2329 trap-handler
cleanup()functions: per-line disable with rationale (invoked viatrap cleanup EXIT). - 4 SC2249 missing default case: added
*) : ;;or*) warn ... ;;arms. - 3 SC2155 declare-and-assign-separately: split
local x="$(...)"intolocal x; x="$(...)"so the inner command's exit status is not masked bylocal. - 3 SC2016 single-quoted expressions: per-line / per-block
disable with rationale (jq filter strings, xargs-passed
bash -cbody — both intentional). - 2 SC2126
grep | wc -l→grep -creal refactor. - 2 SC2059 printf with variable format string: per-line disable with rationale (the format string is a deliberate template).
- 2 SC1112 unicode quote: replaced. (In
json_utils.sh, the U+2019 apostrophe was inside ajq -s '...'single-quoted string deliberately so the outer quotes would not close; rewrote the comment to use "do not" instead.) - 1 SC2153 false positive (
TARGETS_FILEenv-global vstargets_filelocal are intentionally different identifiers). - 1 SC2004 redundant
${}in arithmetic: removed. - 1 SC2001 sed-could-be-PE: per-line disable (bash parameter expansion does not support character classes).
- 79 SC2250 brace-quoting (
echo -e "..."→printf '%b\n' "..."across 35 sites insetup_engagement.sh,wireless.sh,smtp_utils.sh. CLAUDE.md bansecho -e. Verified semantically identical against the ANSI color globals these scripts use.set -euo pipefail→set -uo pipefailinmount-try.sh,auto-mount-shares.sh,gophish_install.sh. The-e(errexit) is banned by CLAUDE.md project-wide.
- Root
compile.sh(~170 lines). Used bannedset -Eeuo pipefail, referenced a (also-removed)lib/common_coresubmodule that was never actually registered, and overlapped withmake ci/make release-todayfrom the new Makefile. .gitmodules. Declaredlib/common_corebut had nopath/urland no gitlink in the index. Dead debris.policy/LICENSEanddocs/LICENSE. The repo had three LICENSE files (root, policy/, docs/) that differed only in the copyright year. Kept the root copy (2025); deleted the other two.
make ci(fmt-check + lint + bats) — all green.make lint— 0 findings (was 156 pre-cleanup).make fmt-check— clean.make test— 23 passing, 0 failing.make style— "All Bash scripts passed style checks."
This was the version stamped in the VERSION file before the date-based
scheme was adopted in 2026-06-27. It is recorded here only as a marker
for the historical baseline; no per-feature release notes were maintained
prior to this point. See git log for granular history before the
adoption of this changelog.
Notable history (most recent first, sourced from git log):
2026-06-27— Handedcapture_traffic.sh(script + 109-line README) andscreenshot.sh(script + 85-line README) over topentest_setup. These were the only two files in the repo that the rest of the stack actually consumed; everything else here is standalone one-off utilities.2025-09-11— Introducedcompile.shCI/release wrapper (later replaced bymake ci/make release-today).2024-12-08— Initial collection of Bash one-off utilities.
Subsequent releases use date-based versioning and carry per-release notes.