feat: wire --username auto-injection into hashcat commands

Calls `detect_username_hash_format` once during preprocessing in
`main()` (after NTLM/NetNTLM handling and before the potfile check) and
stores the result in `hcatUsernamePrefix`. A new helper
`_maybe_append_username_flag` is invoked from the universal
command-finalization chokepoint `_append_potfile_arg`, so every hashcat
command path automatically receives `--username` when a `user:hash`
file is detected. The helper guards against duplicates if `--username`
is already present in `hcatTuning`.

Skips detection for modes 1000/5500/5600 because the existing NTLM
preprocessing already strips usernames into a bare `.nt` file.

Also adds `hcatUsernamePrefix` to the proxy sync tuple in
`hate_crack.py` so tests that patch the root module propagate into
`hate_crack.main`.

Refs #107

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Justin Bollinger
2026-04-22 14:39:45 -04:00
parent 2e5887654a
commit 3a47a5a765
2 changed files with 20 additions and 0 deletions

View File

@@ -30,6 +30,7 @@ def _sync_globals_to_main():
"hcatHashFileOrig",
"pipalPath",
"debug_mode",
"hcatUsernamePrefix",
):
if name in globals():
setattr(_main, name, globals()[name])

View File

@@ -75,6 +75,7 @@ from hate_crack.cli import ( # noqa: E402
)
from hate_crack import attacks as _attacks # noqa: E402
from hate_crack.menu import interactive_menu # noqa: E402
from hate_crack.username_detect import detect_username_hash_format # noqa: E402
# Import HashcatRosetta for rule analysis functionality
try:
@@ -353,6 +354,13 @@ else:
hcatPotfilePath = os.path.join(hate_path, hcatPotfilePath)
def _maybe_append_username_flag(cmd):
"""Append --username if the active hash file has user:hash format and
the flag isn't already present (from hcatTuning or elsewhere)."""
if hcatUsernamePrefix and "--username" not in cmd:
cmd.append("--username")
def _append_potfile_arg(cmd, *, use_potfile_path=True, potfile_path=None):
if use_potfile_path:
pot = potfile_path or hcatPotfilePath
@@ -366,6 +374,7 @@ def _append_potfile_arg(cmd, *, use_potfile_path=True, potfile_path=None):
except OSError:
pass
cmd.append(f"--potfile-path={pot}")
_maybe_append_username_flag(cmd)
_debug_cmd(cmd)
@@ -710,6 +719,7 @@ hcatGenerateRulesCount = 0
hcatPermuteCount = 0
hcatProcess: subprocess.Popen[Any] | None = None
debug_mode = False
hcatUsernamePrefix: bool = False
def _open_wordlist(path):
@@ -4787,6 +4797,15 @@ def main():
_cleanup_preprocessing_temps()
sys.exit(1)
# Detect username:hash format to inject --username into hashcat commands.
# Skip modes already handled by the NTLM (1000) and NetNTLM (5500/5600)
# preprocessing blocks above.
global hcatUsernamePrefix
if hcatHashType not in ("1000", "5500", "5600"):
hcatUsernamePrefix = detect_username_hash_format(hcatHashFile, hcatHashType)
if hcatUsernamePrefix:
print("[*] Username prefixes detected \u2014 adding --username flag")
# Check POT File for Already Cracked Hashes
if not os.path.isfile(hcatHashFile + ".out"):
hcatOutput = open(hcatHashFile + ".out", "w+")