OMEN uses lowercase `makefile` which was missed by the capital-M check.
On case-sensitive filesystems (Linux) this meant OMEN wouldn't be built
during `make submodules`.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The handler was prompting for training source and max candidates even
when the OMEN binaries weren't built, leading to confusing error output.
Now checks for createNG and enumNG up front and returns with a build
instruction if either is missing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add OMEN (Ordered Markov ENumerator) as a probability-ordered password
candidate generator. Trains n-gram models on leaked passwords via
createNG, then pipes candidates from enumNG into hashcat.
Also fix a pre-existing bug where ensure_binary() used quit(1) instead
of sys.exit(1) - quit() closes stdin before raising SystemExit, which
caused "ValueError: I/O operation on closed file" when any optional
binary check failed and the program continued to use input().
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reuses existing _count_computer_accounts() and _filter_computer_accounts()
to optionally strip computer accounts before NetNTLM deduplication.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add TestE2EPreprocessingFlow class that simulates the exact main()
preprocessing logic (format detection, filtering, NT/LM extraction)
with realistic secretsdump.py output. Covers: filter accept/decline,
no computers, all computers, LM hash detection, domain\computer$
format.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Catch PermissionError/OSError in file operations (not just FileNotFoundError)
- Refactor _dedup_netntlm_by_username to two-pass streaming (memory safe)
- Handle CRLF line endings in filter and dedup functions
- Add KeyboardInterrupt handling with temp file cleanup during preprocessing
- Track .filtered/.dedup temp files for cleanup on interruption
- Add CRLF line ending tests for both filter and dedup
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add TestWriteFieldSortedUnique (7 tests) and TestPwdumpFilterPipeline
(8 tests) covering the full filter -> extract NT/LM pipeline. Add
edge case tests for unicode, BOM, long lines, permissions, and
delimiter handling.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add type hints to _filter_computer_accounts and _dedup_netntlm_by_username
- Fix unclosed file handle when reading hash file for format detection
- Extract _count_computer_accounts helper to eliminate duplicate file reads
- Stream _filter_computer_accounts output instead of collecting in memory
- Only write .dedup file when duplicates actually exist
- Add tests for _count_computer_accounts, malformed lines, and no-file-on-zero-dupes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Detect and optionally filter Windows computer accounts (username
ending with $) from pwdump-format NTLM hash files (type 1000)
- Detect and optionally deduplicate NetNTLMv1/v2 hashes (types
5500/5600) by username, keeping first occurrence
- Add 10 tests covering both features
Fixes#27Fixes#28
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tests use HATE_CRACK_SKIP_INIT=1 and don't need submodules.
Shallow submodule clones caused flaky CI failures on PR events.
Fixes#72
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update ollamaModel from qwen2.5 to mistral and ollamaNumCtx from
8192 to 2048 to reflect recent config changes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
download_wordlist() now resolves relative filenames against
get_hcat_wordlists_dir() instead of saving to cwd. Also ensures
the parent directory exists before writing.
Fixes#70
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the denylist-oriented prompt with a capture-the-flag scenario
prompt that focuses on recovering passwords using industry terms and
company name permutations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The test built its own mock context instead of using the shared
ollama_globals helper, missing the rulesDirectory and hcatPotfilePath
patches. This caused FileNotFoundError on CI where /path/to/hashcat/rules
doesn't exist.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add LLM Attack (option 15) to menu listing and attack descriptions,
document Ollama config keys, fix broken code block, update pre-push
hook example, add make update target, and correct CI Python versions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Mock rulesDirectory in ollama test fixture so hcatOllama doesn't
fail with FileNotFoundError on CI where /path/to/hashcat/rules
doesn't exist
- Mock potfile path in hashview auto-merge test so found file cleanup
isn't blocked by missing ~/.hashcat directory
- Update pre-push hook to match CI env vars (HATE_CRACK_SKIP_INIT=1)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Strip .postN.devN and .dYYYYMMDD suffixes from setuptools-scm version
in __init__.py so the banner displays a clean version like 2.0+g05b5d6dc7.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace hardcoded version with setuptools-scm so the version updates
automatically from git tags. The ASCII banner strips the dirty date
suffix but preserves the git node hash.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Standalone tool to compare multiple Ollama models for password candidate
generation. Tests each model at multiple num_ctx values (default: 2048,
8192, 32768) to find the speed/quality sweet spot.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove wordlist-based generation option and menu selection. The LLM
attack now goes directly to target-based prompts (company, industry,
location).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove ollamaWordlist config key and all references. Wordlist mode now
requires the cracked hashes .out file to exist and extracts passwords
by splitting on the first colon. Detect Ollama refusal responses and
abort gracefully. Update tests accordingly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove 500-line wordlist cap and send the entire file to Ollama.
Add ollamaNumCtx config key (default 32768) to control the context
window size. Invert wordlist prompt to default-yes, remove unused
ollamaCandidateCount config.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rename markov_attack → ollama_attack and hcatMarkov → hcatOllama across
menu, attacks, and tests. Remove candidate count prompts and cracked-output
default wordlist logic. Rename config keys (markov* → ollama*) and drop
ollamaUrl. Fix Dockerfile.test to use granular build steps.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Merge download_left and download_found into single "Download Hashes" menu option
- Append found hash:clear pairs to potfile instead of running broken hashcat re-crack
- Append found hashes to left file so hashcat --show returns full results
- Clean up found_ temp files after merge
- Split found file on first colon (not last) to handle passwords containing colons
- Filter hashcat parse errors from --show stdout in _run_hashcat_show
- Add get_hcat_potfile_path() helper to api.py for potfile resolution
- Remove obsolete download_found_hashes API method and CLI subcommand
- Fix ollama tests to match current 4-arg hcatOllama signature and rule loop
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Log the API URL, request payload, raw response JSON, and filtered
candidate counts when debug_mode is active.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When the cracked hashes output file (.out) exists, use it as the default
wordlist for the LLM Markov attack instead of the generic markovWordlist
config. This makes the attack learn from already-cracked passwords for
the current engagement, falling back to config when no cracked output
exists.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a new attack mode that uses a local LLM via Ollama to generate
password candidates, converts them into hashcat .hcstat2 Markov
statistics via hcstat2gen, and runs a Markov-enhanced mask attack.
Two generation sub-modes:
- Wordlist-based: feeds sample from an existing wordlist to the LLM
as pattern context (config-selectable default with Y/N override)
- Target-based: prompts for company name, industry, and location
for contextual password generation
Pipeline: Ollama API -> candidate file -> hcstat2gen -> LZMA compress
-> hashcat -a 3 --markov-hcstat2
Config additions: ollamaUrl, ollamaModel, markovCandidateCount,
markovWordlist. No new pip dependencies (uses stdlib urllib/lzma).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
hcatPath now exclusively points to the hashcat install directory and is
auto-discovered from PATH when not configured. hate_path is resolved
from the package directory (installed) or repo root (development) with
no auto-discovery. Extracted vendor-assets/clean-vendor Makefile targets
to deduplicate the install logic.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When hcatBin is a relative name (e.g. "hashcat"), construct the full
path by joining hcatPath and hcatBin so the correct hashcat binary is
used instead of relying on PATH resolution.
The download_found option downloads already-cracked hashes (with cleartext
passwords). These cannot be used for cracking, so the 'Switch to this hashfile
for cracking?' prompt is inappropriate and confusing.
The switch prompt is kept for download_left since those are uncracked hashes
that can be cracked.
- Remove the switch-to-cracking prompt from download_found flow
- Add clarifying message that found hashes are already cracked
- Align with intended behavior: download_left prompts to switch, download_found just downloads
- Add HashcatRosetta and hashcat-utils to mypy exclude patterns in pyproject.toml
- Update .github/workflows/mypy.yml to exclude submodule directories
- Update pre-push hook to exclude submodules and use consistent mypy flags
- Set ignore_missing_imports=true to handle external dependencies gracefully
- Ensure pre-push hook permissions are set correctly (executable)
Fixes mypy check failures caused by missing hashcat_rosetta.formatting stub.
- Fix line length and formatting in hate_crack/api.py
- Fix line wrapping and f-string formatting in hate_crack/attacks.py
- Apply code style improvements in hate_crack/main.py
- Format test files for consistency
- All changes applied via 'ruff check --fix'