Commit Graph
758 Commits
Author SHA1 Message Date
Justin BollingerandGitHub 9459c21b14 Merge pull request #133 from trustedsec/docs/changelog-2130
docs: split changelog to match the v2.12.0 and v2.13.0 tags
2026-07-24 19:11:52 -04:00
Justin BollingerandClaude e9727631be docs: split changelog to match the v2.12.0 and v2.13.0 tags
The UI polish, cracked-password mode, and target research were all written
into the [2.12.0] section on the assumption they would ship in that release.
They did not: auto-tag cuts a release per merge that contains feat/fix
commits, so #129 became v2.12.0 and #132 became v2.13.0.

Move those entries into a new [2.13.0] section so each heading lists what its
tag actually contains. No entry is duplicated or dropped.

Verified against 'git log v2.11.4..v2.12.0' and 'git log v2.12.0..v2.13.0'.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-24 19:10:47 -04:00
Justin BollingerandGitHub 748bf72e35 Merge pull request #132 from trustedsec/feat/ui-polish
feat(llm): cracked-password mode, target research, and LLM attack UI polish
v2.13.0
2026-07-24 19:03:20 -04:00
Justin BollingerandGitHub fe578777b1 Merge pull request #129 from trustedsec/feature/llm-atomic-agents
feat(llm): refactor LLM attack onto Atomic Agents, add wordlist mode (2.12.0)
v2.12.0
2026-07-24 19:01:44 -04:00
Justin BollingerandClaude 119dc29da4 docs: record UI polish and LLM mode additions under 2.12.0
2.12.0 is not yet tagged (latest tag is v2.11.4), so this work folds into that
entry rather than cutting a new version.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-24 18:53:39 -04:00
Justin BollingerandClaude a751342744 style(ui): normalize interactive prompt decoration and default-value format
- Remove [*] prefix from all input() prompts (10 sites); [*] is a
  status/output marker and must not appear in user-facing input prompts.
  print() calls that use [*] are untouched.
- Normalize default-value hints to the bare-parentheses form (7 instances
  already used it vs. 1 using "default N"); the lone outlier
  "\nEnter n-gram group size (default 3): " is rewritten to "(3)".
- Add \n prefix to combipow "Add spaces between words?" prompt so it does
  not run flush against the last output line of the wordlist path loop.
- All other prompts already satisfy: capital first letter, ends with ": ",
  and correct leading-whitespace context (tab-indented where the surrounding
  menu uses tabs, plain \n or none where it follows un-indented output).
- No input() calls added or removed (verified: attacks.py 42→42,
  main.py 26→26).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-24 18:51:48 -04:00
Justin BollingerandClaude 6448f550ee feat(llm): pre-fill LLM target industry/location from local model research
Target-info mode (menu 12) asked for company, industry, and location as three
blank prompts. Once the company name is known the local Ollama model can often
supply the other two, so ask it and offer the answers as editable defaults.

- llm.research_target(): TargetResearchInput/TargetResearchOutput schemas plus a
  research SystemPromptGenerator that tells the model to return empty strings
  when it does not genuinely recognize the organization, so an unknown small
  client yields blank prompts instead of a confident hallucination.
  APITimeoutError is translated to LLMTimeoutError like generate_candidates.
- clean_research_field(): strips, collapses whitespace, caps at 80 chars, and
  turns anything non-string into "" so model output cannot be pasted unbounded
  into a prompt default.
- main.hcatOllamaResearchTarget(): runs the call inside the existing spinner and
  degrades to blank suggestions on timeout or any other failure, so research can
  never block the attack.
- attacks.ollama_attack(): shows suggestions as "Industry (freight rail): "
  defaults, labelled explicitly as the model's GUESSES rather than OSINT.
- New ollamaAutoResearch config toggle (default true) in both config examples.

Research uses only the configured local Ollama server; the client name is never
sent to a search engine or third-party company-data API.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-24 18:42:50 -04:00
Justin BollingerandClaude 24e574bc8e fix(ui): print picker grids once and report rejected menu keys
The re-prompt loops repainted the whole multicolumn wordlist grid after every
typo, burying the error message under dozens of entries. Hoist the grid and the
p/q legend out of the loop so only the prompt repeats.

ollama_attack's loop also fell through to a silent redraw on an unrecognised
key, leaving no way to tell a rejected key from a repainted prompt.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-24 18:33:11 -04:00
Justin BollingerandClaude 07ca6ba7e3 fix(ui): route ollama/omen submenus through interactive_menu; re-prompt pickers on invalid input
- ollama_attack: convert generation-mode menu to interactive_menu with
  dynamic items list (option 3 only present when cracked file exists);
  cancel via 99 or Escape; re-prompts in a while loop
- omen_attack: convert existing-model menu to interactive_menu; cancel
  via 99 or Escape (replaces hard-coded "3. Cancel"); re-prompts in loop
- _omen_pick_training_wordlist: replace abort-on-invalid with re-prompt
  loop; add explicit 'q' cancel key so users can exit without being
  trapped; callers already handle None correctly
- _markov_pick_training_source: same re-prompt-loop + 'q' cancel fix;
  callers already handle None correctly
- Update all affected tests to patch interactive_menu at
  hate_crack.attacks.interactive_menu (module-level import path) and
  drive follow-up prompts via builtins.input
- Add new tests: arrow-menu reach, Escape/99 cancel, re-prompt loop
  coverage for both pickers, and conditional option-3 key presence

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-24 18:31:04 -04:00
Justin BollingerandClaude 39e0dd956a feat(llm): add cracked-password generation mode to the LLM attack
Adds a third LLM Attack generation mode ("cracked") that samples the
plaintexts already recovered this session from <hashfile>.out and asks the
model to infer the target organization's password conventions and emit new
candidates in the same style.

- llm.py: new _CRACKED_PROMPT (offensive candidate generation, explicitly
  not the denylist-oriented _WORDLIST_PROMPT), a _PROMPTS mode->prompt map,
  and a "cracked" branch in _build_request that tells the model not to
  repeat already-cracked passwords.
- main.py: extract the wordlist sampling logic into the shared module-level
  helper _sample_plaintext_file(path, cap, source_label) and call it from
  both the wordlist and cracked branches of hcatOllama; guard missing and
  empty .out files.
- attacks.py: offer mode 3 only when <hashfile>.out exists and is non-empty
  (matching _markov_pick_training_source), with a clear message otherwise.
- README: document the three modes and the widened ollamaMaxSampleLines
  scope.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-24 18:18:52 -04:00
Justin BollingerandClaude 86fac864a0 fix(ui): clear spinner line after joining its thread
Clearing before the join left a race in the normal path: a spinner thread
sitting just past its stop_event.is_set() check could repaint the line after
the erase, leaving the terminal dirty. Join first so no further writes are
possible, and nest the erase in a finally so an interrupted join (hate_crack
raises DoubleInterrupt on a second SIGINT) still leaves a clean line.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-24 18:13:23 -04:00
Justin BollingerandClaude 142c1fc99f refactor: address code-quality review findings on ui-polish branch
- Remove review-artifact "Defect 2" comment in main.py:2076; replace with
  accurate description of the invalid-cap fallback.  Same label removed from
  the test section header in test_ollama_wordlist_sampling.py.
- Lift nested _usable helper to module-level _usable_plaintext in main.py,
  placed alongside the other private wordlist helpers after _wordlist_path.
  Add six direct unit tests covering blank, whitespace, plain, hash:pw,
  multi-colon, and empty-plaintext cases.
- Move spinner line-clear before thread.join() in progress.py so the terminal
  is cleaned up even if join() is interrupted by a DoubleInterrupt/second Ctrl-C.
  Add test_tty_clears_line_even_if_join_raises to cover this path.
- Replace time.sleep-based elapsed-counter test with a deterministic version
  that patches time.monotonic; assert on actual rendered format with r"\d+s".
  Drop the misleading 0.05s sleep in test_tty_clears_line_on_exit (shorter
  than one tick, so no frame was ever guaranteed).
- Add missing ollama* keys to hate_crack/config.json.example (package-data
  copy); root config.json.example already had them.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-24 18:08:11 -04:00
Justin BollingerandClaude fef606dbf4 fix(llm): fix stride sampling exactness, zero-cap crash, and test quality
- Defect 1 (main.py): Replace floating-point stride loop with exact
  floor(k * total / cap) index formula so sampling always returns
  EXACTLY cap items for any 1 <= cap <= total_usable, including the
  stride < 2 regime where the old approach returned cap-1 items.

- Defect 2 (main.py): Validate ollamaMaxSampleLines before computing
  the stride; values <= 0 are nonsensical and fall back to 500
  (same as the default) rather than raising ZeroDivisionError.

- Defect 3 (test_progress_spinner.py): Rewrite test_non_tty_no_extra_thread
  to patch threading.Thread and assert it was never called, so the test
  actually fails when the spinner starts a thread in the non-TTY path.

- Defect 4 (test_progress_spinner.py): Simplify test_non_tty_prints_message
  to use monkeypatch.setattr instead of the dead mock.patch.object +
  manual assign/restore layering; removes two # type: ignore comments.

- docs(README.md): Document ollamaMaxSampleLines alongside ollamaNumCtx /
  ollamaTimeout in the Ollama Configuration section.

- tests: Add boundary-case tests for stride < 2 (total==cap, total==cap+1,
  total=3/cap=2, cap=1) and zero-cap fallback; make
  test_ollama_max_sample_lines_default exercise behaviour rather than
  the ambient config value.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-24 17:57:09 -04:00
Justin BollingerandClaude e5e1107359 fix(llm): add spinner during Ollama generation and cap wordlist sample
Defect 1 — hcatOllama showed a plain print then blocked silently for
up to 300 s while waiting for the LLM.  A new generic context manager
`hate_crack/progress.py::spinner()` now runs a daemon thread that
repaints a single line with a frame + elapsed-seconds counter every
~120 ms.  TTY guard ensures non-TTY/test environments get a single
plain print instead of ANSI control characters.  The line is erased
with \033[2K\r on exit (normal and exceptional).

Defect 2 — the wordlist path materialised every line in memory and
built a prompt that could massively overflow ollamaNumCtx on large
wordlists.  The path now does a two-pass evenly-spaced sample: pass 1
counts usable lines, pass 2 stride-selects up to `ollamaMaxSampleLines`
(default 500, new config key) spread across the full file.  When no
capping occurs the message reads "Loaded N passwords"; when capping
occurs it reads "Sampled N of M passwords".

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-24 17:49:24 -04:00
Justin BollingerandClaude e88315dfb9 build: pin local uv Python to 3.13
requires-python is ">=3.13", so a fresh worktree's "uv sync --dev" picks the
newest interpreter on the box - currently CPython 3.15.0a7 - and the build
fails because pyo3 0.26 (via jiter/fastuuid/pydantic-core) does not support
3.15 yet:

    error: failed to run custom build command for `pyo3-ffi v0.26.0`

CI already pins 3.13 via setup-uv, so this only bit local worktrees. Pinning
matches CI and leaves requires-python alone.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-24 17:39:20 -04:00
Justin BollingerandClaude 549c5a0a64 fix(llm): bound Ollama requests with a configurable timeout
The Atomic Agents client was built with no timeout, so an Ollama server that
accepted the TCP connection but never replied (most commonly a large model still
loading into VRAM) left the CLI blocked in agent.run() forever. The caller's
`except Exception` handler only ever fired on connection-refused.

- llm.generate_candidates() takes a `timeout` parameter (default
  DEFAULT_TIMEOUT_SECONDS = 300.0) and forwards it to the OpenAI client.
- openai.APITimeoutError is translated into a new domain-level
  llm.LLMTimeoutError so main.py need not import openai itself, keeping the
  atomic-agents/instructor dependency isolated to llm.py as documented.
- hcatOllama passes the new `ollamaTimeout` config value and prints
  timeout-specific guidance (elapsed seconds, VRAM-loading hint, the setting to
  raise) instead of the misleading "ensure Ollama is running" message.
- Documented `ollamaTimeout` in config.json.example and README.

Also closes two test gaps: the defensive `except ValueError` handler in
hcatOllama now has coverage, and the misleadingly-named `test_unknown_mode_raises`
is split into explicit unit tests of _build_request's mode validation. Ticked the
completed steps in the LLM Atomic Agents plan doc.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-24 17:17:58 -04:00
Justin BollingerandClaude e49be6122a build(deps): declare instructor, openai, and pydantic explicitly
hate_crack/llm.py imports all three directly, but only atomic-agents was
declared -- they were available purely as transitive deps. A future
atomic-agents release that loosened its coupling to any of them would make
`uv sync` silently omit it and break `import hate_crack.llm` at runtime.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-24 17:07:19 -04:00
Justin BollingerandClaude 81577ae060 Merge branch 'main' into feature/llm-atomic-agents
Conflicts resolved:
- CHANGELOG.md: kept both [2.12.0] (branch) and [2.11.4] (main), newest first
- pyproject.toml: kept main's tighter version pins (click>=8.4.2, requests>=2.34.2,
  packaging>=26.2, pytest-cov==7.1.0) and the branch's atomic-agents>=2.0.0 dep

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-24 16:57:24 -04:00
Justin BollingerandGitHub a99b36369a Merge pull request #125 from trustedsec/dependabot/uv/click-gte-8.4.2
chore(deps): update click requirement from >=8.0.0 to >=8.4.2
2026-07-24 16:51:02 -04:00
Justin BollingerandGitHub 9674f991b3 Merge pull request #124 from trustedsec/dependabot/uv/requests-gte-2.34.2
chore(deps): update requests requirement from >=2.31.0 to >=2.34.2
2026-07-24 16:50:47 -04:00
Justin BollingerandGitHub 8906636ec4 Merge pull request #123 from trustedsec/dependabot/uv/packaging-gte-26.2
chore(deps): update packaging requirement from >=21.0 to >=26.2
2026-07-24 16:50:31 -04:00
Justin BollingerandGitHub 6a7a2a5f47 Merge pull request #122 from trustedsec/dependabot/uv/pytest-cov-7.1.0
chore(deps-dev): bump pytest-cov from 7.0.0 to 7.1.0
2026-07-24 16:50:15 -04:00
Justin BollingerandGitHub cf6c9c2f8b Merge pull request #121 from trustedsec/dependabot/github_actions/softprops/action-gh-release-3.0.2
chore(ci): bump softprops/action-gh-release from 2.6.2 to 3.0.2
2026-07-24 16:49:55 -04:00
dependabot[bot]andGitHub b385f391a4 chore(deps): update click requirement from >=8.0.0 to >=8.4.2
Updates the requirements on [click](https://github.com/pallets/click) to permit the latest version.
- [Release notes](https://github.com/pallets/click/releases)
- [Changelog](https://github.com/pallets/click/blob/main/CHANGES.md)
- [Commits](https://github.com/pallets/click/compare/8.0.0...8.4.2)

---
updated-dependencies:
- dependency-name: click
  dependency-version: 8.4.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-24 20:48:13 +00:00
dependabot[bot]andGitHub 9297670980 chore(deps): update requests requirement from >=2.31.0 to >=2.34.2
Updates the requirements on [requests](https://github.com/psf/requests) to permit the latest version.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.31.0...v2.34.2)

---
updated-dependencies:
- dependency-name: requests
  dependency-version: 2.34.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-24 20:48:08 +00:00
dependabot[bot]andGitHub 14c332d2b1 chore(deps): update packaging requirement from >=21.0 to >=26.2
Updates the requirements on [packaging](https://github.com/pypa/packaging) to permit the latest version.
- [Release notes](https://github.com/pypa/packaging/releases)
- [Changelog](https://github.com/pypa/packaging/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pypa/packaging/compare/21.0...26.2)

---
updated-dependencies:
- dependency-name: packaging
  dependency-version: '26.2'
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-24 20:48:07 +00:00
dependabot[bot]andGitHub 415255e1ec chore(deps-dev): bump pytest-cov from 7.0.0 to 7.1.0
Bumps [pytest-cov](https://github.com/pytest-dev/pytest-cov) from 7.0.0 to 7.1.0.
- [Changelog](https://github.com/pytest-dev/pytest-cov/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-cov/compare/v7.0.0...v7.1.0)

---
updated-dependencies:
- dependency-name: pytest-cov
  dependency-version: 7.1.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-24 20:48:01 +00:00
dependabot[bot]andGitHub ba6bb999bb chore(ci): bump softprops/action-gh-release from 2.6.2 to 3.0.2
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.6.2 to 3.0.2.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/3bb12739c298aeb8a4eeaf626c5b8d85266b0e65...3d0d9888cb7fd7b750713d6e236d1fcb99157228)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-version: 3.0.2
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-24 20:47:32 +00:00
Justin BollingerandGitHub ca1eea6d5e Merge pull request #120 from trustedsec/fix/ci-hardening
fix(ci): add test CI, repair auto-tag releases, harden action pins (2.11.4)
v2.11.4
2026-07-24 16:47:01 -04:00
Justin BollingerandClaude 665c8ab47c fix(ci): add test CI, repair auto-tag releases, harden action pins (2.11.4)
The repo had no CI: ruff/ty/pytest ran only in local prek pre-push hooks, so
a commit pushed without hooks installed reached main unvalidated -- and
auto-tag would then cut a release from it. Adds ci.yml (ruff, ty, pytest on
3.13) and gates tagging on it.

Auto-tagged versions also never produced a release. The tag is pushed with
the default GITHUB_TOKEN, and GitHub suppresses workflow triggers for
GITHUB_TOKEN-created events, so the tag-triggered release.yml never fired --
v2.11.3 was tagged with no release. auto-tag now creates the release itself,
idempotently; release.yml stays as the manual-tag path.

Also fixes version logic that matched the `!` breaking marker but only ever
bumped minor (and never saw BREAKING CHANGE: footers, since only subjects
were inspected), serializes concurrent merges that both computed the same
tag, and repins softprops/action-gh-release from an arbitrary master commit
to v2.6.2 with all workflows on one actions/checkout version.

Clears the pre-existing ty error in notify/tailer.py that would have made
the new type-check step red: _read_new_lines read self._file_pos
(int | None) while its only None-guard lived in the caller, so the position
is passed in explicitly as an int. Behavior unchanged.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-24 16:39:59 -04:00
Justin BollingerandClaude Opus 4.8 f424783eb2 style(llm): drop vestigial global hcatProcess in hcatOllama
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 12:15:10 -04:00
Justin BollingerandClaude Opus 4.8 519d395708 docs(llm): document Atomic Agents refactor, new default model, wordlist mode (2.12.0)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 12:11:26 -04:00
Justin BollingerandClaude Opus 4.8 bcea02b2e7 test(llm): cover wordlist-mode abort when no wordlist picked
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 12:10:39 -04:00
Justin BollingerandClaude Sonnet 4.6 a4da571ab4 feat(llm): add wordlist (denylist) mode to LLM attack menu
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-24 12:08:20 -04:00
Justin BollingerandClaude Opus 4.8 d6da721414 feat(llm): default Ollama model to qwen2.5:32b for structured output
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 12:06:29 -04:00
Justin BollingerandClaude Opus 4.8 93960e2d58 test(llm): cover per-rule hashcat loop and hash:password stripping
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 12:06:12 -04:00
Justin BollingerandClaude Sonnet 4.6 4df1121051 refactor(llm): delegate candidate generation to llm module; drop auto-pull
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-24 11:59:04 -04:00
Justin BollingerandClaude Opus 4.8 9dd6ad746f style(llm): drop noise Any annotation on agent result
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 11:52:32 -04:00
Justin BollingerandClaude Sonnet 4.6 a57a4165f1 refactor(llm): validate AgentConfig in prod; spec-mock the client in tests
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-24 11:50:19 -04:00
Justin BollingerandClaude Sonnet 4.6 1cc71abfef feat(llm): structured candidate generation module via Atomic Agents
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-24 11:48:19 -04:00
Justin Bollinger 66e6d593c4 build(deps): add atomic-agents for structured LLM candidate generation 2026-07-24 11:45:24 -04:00
Justin BollingerandGitHub a0dc56ce08 Merge pull request #117 from trustedsec/fix/cleanup-rules-mode
fix(rules): pass required mode arg to cleanup-rules.bin (2.11.3)
v2.11.3
2026-07-24 11:29:20 -04:00
Justin BollingerandClaude Opus 4.8 fe206420e9 fix(rules): pass required mode arg to cleanup-rules.bin (2.11.3)
cleanup-rules.bin requires a mode argument (1=CPU, 2=GPU) and exits with
usage text otherwise, so Rule File Tools cleanup always failed. Pass the
mode (defaulting to GPU) so cleanup actually runs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 11:28:56 -04:00
Justin Bollinger 04be489c60 Merge branch 'fix/upload-counts' (2.11.2) v2.11.2 2026-07-23 14:26:31 -04:00
Justin BollingerandClaude Opus 4.8 a15860a63e feat(hashview): report cracked-hash upload counts (2.11.2)
The upload previously printed only "✓ Success: OK", so there was no way
to tell how many hashes were accepted. upload_cracked_hashes now surfaces
client-side uploaded/skipped counts in its return value, and the CLI
prints them plus the server's verified/updated/unmatched breakdown when a
newer Hashview reports them (see hashview #355/#356).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 14:26:26 -04:00
Justin Bollinger a14272a058 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	CHANGELOG.md
v2.11.1
2026-07-23 14:00:58 -04:00
Justin Bollinger 4c70185270 Merge branch 'fix/upload-hex-decode' (2.10.11) 2026-07-23 13:59:22 -04:00
Justin BollingerandClaude Opus 4.8 a3ca2a19e8 docs(changelog): add 2.10.11 (Hashview $HEX upload fix + client-side validation)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 13:59:15 -04:00
Justin BollingerandClaude Opus 4.8 2ed9cc28e6 fix(hashview): decode $HEX[...] before upload for older servers
hate_crack forwarded hashcat's $HEX[...] plaintext verbatim. A Hashview
that verifies plaintext literally hashes the string "$HEX[..]" and
rejects the batch. Decode $HEX to the exact bytes the server must
re-hash and send those on the wire (body is now bytes):

- UTF-16LE modes (NTLM 1000, MSSQL 1731): latin-1 code points -> UTF-8
- raw-byte modes (0/100/300/900/1400/1700): the decoded bytes as-is
- unsafe (embedded CR/LF) or unknown modes: keep the $HEX token verbatim
  and rely on a $HEX-aware server

Also fixes the NTLM validation digest to use latin-1 -> UTF-16LE so
high-byte $HEX plaintexts verify instead of being silently unverifiable.
Verified end-to-end: the emitted wire verifies against both the old
(literal) and new ($HEX-aware) Hashview verifiers.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 13:26:09 -04:00
Justin BollingerandGitHub 0a6dfd26fc Merge pull request #116 from trustedsec/feature/shard-multi-part
feat(wordlist): shard into all N parts in one run with numbered filenames
v2.11.0
2026-07-23 13:15:38 -04:00