返回更新列表
新发布Sep 4, 2026

hate_crack v2.36.1

TrustedSec 团队开发的一款通过 Hashcat 自动化执行破解方法的工具。

分享
  ___ ___         __             _________                       __
 /   |   \_____ _/  |_  ____     \_   ___ \____________    ____ |  | __
/    ~    \__  \\   __\/ __ \    /    \  \/\_  __ \__  \ _/ ___\|  |/ /
\    Y    // __ \|  | \  ___/    \     \____|  | \// __ \\  \___|    <
 \___|_  /(____  /__|  \___  >____\______  /|__|  (____  /\___  >__|_ \
       \/      \/          \/_____/      \/            \/     \/     \/

安装

从源码安装是唯一受支持的途径。hate_crack 在 PyPI 上分发:pip install hate-crack 会解析到一个 0.0.0 占位包,该包会故意安装失败并指向此处。保留该名称只是为了防止其他人在其下发布仿冒包——参见 packaging/pypi-placeholder/

1. 安装 hashcat

Hashcat 必须已安装并可在你的 PATH 中使用:

Ubuntu/Kali:```bash sudo apt-get install -y hashcat

macOS(Homebrew):```bash
brew install hashcat

或者从 https://hashcat.net/hashcat/ 下载预编译的二进制文件,并在 config.json 中将 hcatPath 设置为其所在位置。

2. 下载 hate_crack

使用子模块进行克隆(hashcat-utils、princeprocessor、pcfg_cracker、Corporate_Masks 以及可选的 omen 所必需):```bash git clone --recurse-submodules https://github.com/trustedsec/hate_crack.git cd hate_crack

如果您克隆时未包含子模块,请初始化它们:```bash
git submodule update --init --recursive

然后根据需要自定义配置。hate_crack 使用两个配置文件,各自负责一组不同的设置:

  • config.json — 字典路径、掩码、规则、调优、potfile、hashcat 路径、候选数量限制、通知开关、CLI 偏好默认值(35 项设置)。
  • .env — 仅包含第三方集成设置:Hashview 和 Hashmob 凭据、Pushover 凭据、Ollama 和 pipal(14 项设置)。不被 git 跟踪,创建时权限为 0600

这条分界线存在的原因只有一个:.env 是可以存放机密信息的文件。第三方服务的凭据及其配置放在未被跟踪、权限为 0600 的文件中;hate_crack 在本地所做的一切都保留在 config.json 中,该文件可以安全地共享、进行 diff 对比,并记录到你自己的笔记中。这也是为什么 Pushover 的凭据放在 .env 中,而 Pushover 的开关切换项放在 config.json 中——这些开关是本地偏好设置,不是机密信息。

每个键只有一个归属位置。放在另一个文件中的键会被忽略,hate_crack 会打印一条警告,指明它应归属的文件。任何键仍然可以通过导出其环境变量在单次运行中被覆盖。大多数用户可以跳过此步骤,因为默认路径开箱即用。

config.json 是永久且一等公民——它并未被弃用,也没有移除时间表。只有集成设置被迁移了。

从单个 config.json 升级? hate_crack 会在首次运行时为你迁移:集成设置会被复制到新的 0600 .env 中,然后从 config.json 中移除,以免两个文件都声称拥有它们。它会打印出哪些键被迁移了(绝不打印其值),并在改动之前将你的原始文件保存为 config.json.pre-split.bakconfig.json 中的其他所有内容都保持原样,包括键的顺序。

首次运行: hate_crack 会为你创建这两个文件,因此无需任何操作。若要改为手动设置 .env,请复制被跟踪的模板:```bash cp .env.example .env chmod 600 .env

`.env.example` 已提交,且每个凭据键均为空。`.env` 本身**绝不能**被提交——它已被 gitignore,连同其常见的备份拼写形式,并且 hate_crack 始终以 `0600` 模式(仅所有者可读写)创建它。`.env.example` 由 schema 生成;在修改 `hate_crack/config_schema.py` 后,使用 `uv run python -m hate_crack.config_writer` 重新生成它。

### 3. 安装依赖和 hate_crack

最简单的方式是运行 `make`(或 `make install`),它会自动检测你的操作系统并安装:
- 外部依赖(p7zip、transmission-daemon / transmission-remote)
- 构建子模块(hashcat-utils、princeprocessor、pcfg_cracker,以及可选的 omen)并检出仅含数据的 Corporate_Masks 掩码集
- 通过 uv 安装 Python 依赖,并在 `~/.local/bin/hate_crack` 处创建 CLI 垫片```bash
make

这是幂等的——它会跳过已安装的工具。要强制进行全新安装:```bash make reinstall

**或手动安装依赖:**

### 外部依赖
这些是某些下载/解压流程所必需的:

- `7z`/`7za` (p7zip) — 用于解压 `.7z` 归档文件。
- `transmission-daemon` / `transmission-remote` — 用于下载 Weakpass 种子文件。

手动安装命令:

Ubuntu/Kali:```bash
sudo apt-get update
sudo apt-get install -y p7zip-full transmission-daemon

macOS(Homebrew):```bash brew install p7zip transmission-cli # provides transmission-daemon and transmission-remote

然后安装 Python 依赖项和 CLI 垫片:```bash
uv sync
mkdir -p ~/.local/bin
printf '#!/usr/bin/env bash\nset -euo pipefail\nexec uv run --directory %s python -m hate_crack "$@"\n' "$(pwd)" > ~/.local/bin/hate_crack
chmod +x ~/.local/bin/hate_crack

项目结构

核心逻辑现已拆分为 hate_crack/ 下的多个模块:

  • hate_crack/cli.py:argparse 辅助函数和配置覆盖。
  • hate_crack/api.py:Hashview、Weakpass 和 Hashmob 集成(下载/菜单/辅助函数)。
  • hate_crack/attacks.py:菜单攻击处理器。
  • hate_crack/corpus_stats.py:用于向 LLM 描述语料库的全语料库密码统计。
  • hate_crack/plaintext.py:从语料库行中恢复密码(哈希前缀剥离、$HEX[...] 解码);由 LLM 模式、corpus_stats 和 rulegen 共享。
  • hate_crack/llm.py:通过 Atomic Agents 进行结构化(JSON)LLM 候选生成。
  • hate_crack/menu.py:共享菜单渲染器,包括可选的箭头键导航。
  • hate_crack/noninteractive.py:脚本化攻击子命令的分发器。
  • hate_crack/notify/:通知包(Pushover 后端、每次破解的 tailer)。
  • hate_crack/username_detect.py:检测 username:hash 输入文件,以决定 hashcat 的 --username
  • hate_crack/formatting.pyhate_crack/progress.py:输出格式化和进度显示辅助函数。
  • hate_crack/main.py:主 CLI 实现。

顶层的 hate_crack.py 仍然是主入口点,并协调这些模块。


参考与致谢

本项目依赖并受多个外部项目和服务启发。感谢:


用法

使用 make 安装后,可从任意位置运行 hate_crack:```bash hate_crack

or with arguments:

hate_crack <hash_file> <hash_type> [options]

或者,通过 `uv` 运行:```bash
uv run hate_crack.py <hash_file> <hash_type>

作为工具运行(推荐)

在仓库根目录使用 make 进行安装——这会构建子模块并打包资源:```bash cd /path/to/hate_crack make hate_crack

`make install` 命令会在 `~/.local/bin/hate_crack` 创建一个 bash shim,该 shim 从仓库目录运行,因此无论当前工作目录是什么,配置和资源始终能被找到。

配置还会在以下位置搜索:
- 仓库根目录和包目录
- `~/.hate_crack`

**注意:** `config.json` 中的 `hcatPath` 仅用于指定 hashcat 二进制文件的位置(如果 hashcat 已在 PATH 中,则此项可选)。Hate_crack 资源(hashcat-utils、princeprocessor、pcfg_cracker、Corporate_Masks、omen)从仓库目录加载,并由 `make install` 自动打包。

### 作为脚本运行
该脚本使用 `uv` shebang。使其可执行并运行:```bash
chmod +x hate_crack.py
./hate_crack.py

你也可以直接使用 Python:```bash python hate_crack.py

### 非交互式 / 脚本化使用

对于自动化场景,你可以直接启动单次攻击,绕过菜单。攻击名称是第一个参数,后面跟着哈希文件和 hashcat 哈希类型。预处理提示(计算机账户过滤、LM 优先暴力破解、重复账户去重)在此模式下自动接受其默认值。进程在成功时退出码为 `0`,出错时(哈希文件缺失、哈希类型非数字、词表缺失或规则文件名未知)退出码为非零。```bash
# Quick crack: one wordlist + optional rule(s) from the rules directory
hate_crack quick hashes.txt 1000 --wordlist rockyou.txt --rules best64.rule

# Chain two rules in a single run
hate_crack quick hashes.txt 1000 --wordlist rockyou.txt --rules best64.rule+d3ad0ne.rule

# Run two rules as two separate passes
hate_crack quick hashes.txt 1000 --wordlist rockyou.txt --rules best64.rule d3ad0ne.rule

# Canned dictionary methodology (uses your configured wordlists)
hate_crack dict hashes.txt 1000

# Brute force lengths 1-8
hate_crack brute hashes.txt 1000 --min 1 --max 8

# Top-mask attack targeting ~4 hours
hate_crack topmask hashes.txt 1000 --target-time 4

故障排除

错误:更新时出现“would clobber existing tag”

较旧的克隆可能拒绝更新,并打印出一长串类似以下内容的行:``` ! [rejected] v2.5.0 -> v2.5.0 (would clobber existing tag)

这会影响在 2026 年 7 月之前创建的克隆。当时已发布的历史被重写,以移除一些本不应被提交的文件,这导致每个提交都获得了新的 ID;因此,较旧克隆中的标签指向了本仓库不再包含的对象,而 git 拒绝移动它已经拥有的标签。你的检出没有任何问题,也没有任何破解数据面临风险。

通过一次性重置来恢复。这会丢弃检出中的本地提交和编辑,因此如果你对任何受 git 跟踪的内容(与 `config.json` 不同,后者不受跟踪)进行了自定义,请先将其提交到一个分支:```bash
cd /path/to/hate_crack
git fetch --tags --force origin
git checkout -B main origin/main
make install

--force 在这里只会更新标签;它无法触及你的提交。之后内置更新器即可正常工作。2.18 之前的版本无法自行执行此恢复操作,因此必须手动执行一次。

错误:构建目录不存在

如果你看到类似这样的错误:``` Error: Build directory /opt/hashcat/hashcat-utils does not exist. Expected to find expander at /opt/hashcat/hashcat-utils/bin/expander.

这意味着 hate_crack 资源并未打包到已安装的软件包中。

**理解路径:**
- config.json 中的 `hcatPath` → 指向 **hashcat 二进制文件位置**(可选,可以位于 PATH 中)
- `hashcat-utils/` 和 `princeprocessor/` → 由 `make install` 打包到软件包中

**解决方案:**
使用 Makefile 重新安装,它会构建子模块并安装该工具:```bash
cd /path/to/hate_crack  # the repository checkout
make install

默认配置(config.json.example):

大多数用户可以使用默认配置,无需自定义:

  • hcatWordlists./wordlists(相对于仓库根目录或 HOME/.hate_crack)
  • hcatOptimizedWordlists./optimized_wordlists(Quick Crack 使用的目录;如果未找到则回退到 hcatWordlists
  • rules_directory./hashcat/rules(包含子模块规则)
  • hcatTuning:``(空字符串 - 无默认调优标志)

config.json 自定义示例:```json { "hcatPath": "/usr/local/bin", # Location of hashcat binary (optional, auto-detected from PATH) "hcatBin": "hashcat", # Hashcat binary name "hcatWordlists": "./wordlists", # Dictionary wordlist directory (relative or absolute) "rules_directory": "./hashcat/rules", # Rules directory (relative or absolute) "hcatTuning": "", # Additional hashcat flags (empty by default) ... }

**配置加载:**
- 每个键的优先级:`os.environ` > 该键自己的主目录文件(`.env` 或 `config.json`)> 内置默认值
- 缺失的键回退到内置默认值;`config.json.example` 记录了每个 `config.json` 键
- 两个文件都会被搜索,彼此独立,按以下顺序:**仓库根目录**,然后是**已安装的包目录**,然后是 **`~/.hate_crack`**。第一个匹配项胜出;两个文件来自不同目录是正常的。
- 首次运行时,两者都会被创建——`config.json` 来自 `config.json.example`,`.env` 来自内置默认值。如果旧的 `config.json` 仍包含集成密钥,它们会被复制到新的 `.env` 中,并且 hate_crack 会告诉你应从 `config.json` 中删除哪些密钥;它从不自行编辑该文件。
- 每次运行时,hate_crack 会打印它实际加载的两个文件:  ```
  [*] config.json: /home/you/.hate_crack/config.json
  [*] .env:        /home/you/.hate_crack/.env

在调试一个“没有生效”的设置之前,先读这两行。它们的存在是因为搜索顺序中有两个陷阱:

  • 检出目录优先于你的主目录。 仓库根目录会最先被搜索,因此你运行该工具的任何检出目录中的 .envconfig.json 都会优先于 ~/.hate_crack 中的对应文件——而从检出目录运行该工具,正是最初在那里创建这些文件的原因。如果这曾经遮蔽了真正的 ~/.hate_crack 配置,hate_crack 现在会通过第三行 [!] 指出这一点,并列出两个路径——请把该行理解为“下面的文件正在被忽略”,而不是第二个同样有效的配置。
  • 当前工作目录永远不会被搜索。 你恰好所在目录中的 .env 会被有意忽略:项目目录里充满了并非有意作为配置的文件。请把它放在仓库根目录或 ~/.hate_crack 中。

错误:merge with ref 'refs/heads/master' but no such ref was fetched

如果你看到:``` Your configuration specifies to merge with the ref 'refs/heads/master' from the remote, but no such ref was fetched.

默认分支已从 `master` 重命名为 `main`。使用以下命令修复:```bash
git remote set-head origin -a
git branch -m master main
git branch --set-upstream-to=origin/main main
git pull

Makefile 目标

默认(完整安装) - 构建子模块、安装依赖项并安装该工具:```bash make

or explicitly:

make install

这是幂等的——它会跳过已安装的工具。

**强制清理并重新安装:**```bash
make reinstall

快速更新 - 重新构建子模块并重新安装工具(在拉取更改后):```bash make update

**卸载** - 移除操作系统依赖项和工具:```bash
make uninstall

仅构建 hashcat-utils:```bash make hashcat-utils

**运行测试** - 在需要时自动处理 HATE_CRACK_SKIP_INIT:```bash
make test

覆盖率报告:```bash make coverage

**清理构建/测试产物:**```bash
make clean

开发

设置开发环境

安装项目及可选的开发依赖(包括代码检查工具和测试工具):```bash make dev-install

### 运行 Linter 和类型检查

在推送更改之前,请在本地运行这些检查。使用 `make lint` 运行所有检查,或单独运行各项检查:

**Ruff(代码检查与格式化):**```bash
make ruff
# or manually:
uv run ruff check hate_crack tests tools packaging hate_crack.py

自动修复问题:```bash uv run ruff format hate_crack tests tools packaging hate_crack.py uv run ruff check --fix hate_crack tests tools packaging hate_crack.py

**ty(类型检查):**```bash
make ty
# or manually:
uv run ty check hate_crack

同时运行所有检查:```bash make lint

### 运行测试

当子模块未构建时,测试会自动检测并自动设置 `HATE_CRACK_SKIP_INIT=1`。```bash
make test

或直接运行 pytest:```bash uv run pytest -v

带覆盖率:```bash
make coverage

或者使用 pytest:```bash uv run pytest --cov=hate_crack

### Git Hooks (prek)

Git hooks 由 [prek](https://github.com/j178/prek)(v0.3.3+)管理。使用以下命令安装 hooks:```bash
prek install --hook-type pre-push --hook-type pre-commit

这会使用 pre-commit 本地仓库 TOML schema 安装 prek.toml 中定义的钩子:

  • pre-push(本地钩子):ruff、ruff-format、ty、pytest、pytest-lima、bandit
  • pre-commit(来自 pre-commit/pre-commit-hooks):trailing-whitespace、 end-of-file-fixer、check-yaml、check-merge-conflict、check-added-large-files、 detect-private-key

pre-commit 自动修复器会就地重写文件,因此在其运行后需要重新暂存并再次提交。

注意:prek 0.3.3 期望在顶层使用 repos = [...]。旧的 [hooks.<stage>] commands = [...] 格式不受支持。

方向键菜单导航

菜单默认使用经典的数字 print() + input() 选择方式,这种方式接受完整的多位数字键。

要通过 simple-term-menu 启用方向键导航,请设置 HATE_CRACK_ARROW_MENU=1。在该模式下,只有单位数快捷键可用; 编号为 10 及以上的选项必须通过方向键访问。方向键模式还需要 TTY,因此当输出被管道传输时会保持关闭。

开发依赖

可选的 [dev] 组包括:

  • ty - 静态类型检查器
  • ruff - 快速的 Python linter 和格式化工具
  • pytest - 测试框架
  • pytest-cov - 覆盖率报告

常用选项:

  • --download-hashview:在破解前从 Hashview 下载哈希。
  • --hashview:交互式 Hashview 菜单,用于管理哈希、字典和任务。
  • --hashview --help:显示 Hashview 命令行选项。
  • --weakpass:从 Weakpass 下载字典。
  • --hashmob:从 Hashmob.net 下载字典。
  • --hashmob-masks:从 Hashmob.net 下载掩码。
  • --download-torrent <FILENAME>:下载指定的 Weakpass torrent 文件。
  • --download-all-torrents:从缓存下载所有可用的 Weakpass torrent。
  • --wordlists-dir <PATH> / --optimized-wordlists-dir <PATH>:覆盖字典目录。
  • --pipal-path <PATH>:覆盖 pipal 路径。
  • --restore-potfile:启动时从 hashcat POT 文件重建 <hashfile>.out,替换任何现有内容,然后继续进入正常菜单。如果不使用此标志,POT 查找仅在 .out 尚不存在时运行。菜单选项 93 可按需执行相同操作,并带有确认提示。
  • --maxruntime <SECONDS>:覆盖最大运行时间。
  • --bandrel-basewords <PATH>:覆盖 bandrel 基础词文件。
  • --update:更新到最新版本并重新安装。如果检出位于其他分支,则将其切换到 main,因为发布标签位于该分支。
  • --nightly:改为从 nightly-dev 分支更新到最新 nightly。Nightly 已通过 CI,但不属于已发布的正式版本。也可以写作 --update --nightly
  • --no-optimized-kernel(或 --no-optimize):在整个运行过程中绝不向 hashcat 传递 -O。覆盖 config.json 中的 optimizedKernelAttacks,并移除你在 hcatTuning 中放入的任何 -O。不会向配置写回任何内容,因此仅适用于本次运行。与子命令一起使用时,请将其放在子命令之前:./hate_crack.py --no-optimize quick hashes.txt 1000 --wordlist words.txt
  • --debug:启用调试日志记录(写入 stderr)。

Hashview 集成

hate_crack 与 Hashview 集成,用于集中式哈希管理和分布式破解。

交互式菜单

访问交互式 Hashview 菜单:```bash hate_crack.py --hashview

菜单选项:
- **(1) Upload Cracked Hashes** - 将当前会话中已破解的结果上传到 Hashview
- **(2) Upload Wordlist** - 将字典文件上传到 Hashview
- **(3) Download Wordlist** - 从 Hashview 下载字典
- **Download Rule** - 从 Hashview 下载规则文件(解压为明文,可直接用于 `hashcat -r`)。在规则 ID 提示符处输入 `a`(或 `all`)可下载列出的所有规则,而非仅下载一个
- **Download All Rules** - 一次性下载 Hashview 列出的所有规则文件;单个规则失败会报告错误,但不会中止其余下载
- **(4) Download Left Hashes** - 下载剩余的未破解哈希(会提示是否切换以进行破解)
- **(5) Download Found Hashes** - 下载已破解的哈希及其明文密码(用于参考/分析)
- **(6) Upload Hashfile and Create Job** - 上传新的哈希文件并创建破解任务
- **(99) Back to Main Menu** - 返回主菜单

**重要:Download Found 与 Download Left 的区别**
- **Download Left Hashes (4)**:下载需要破解的未破解哈希。如果存在已找到的哈希,会自动合并,并提示是否切换到此哈希文件进行破解。
- **Download Found Hashes (5)**:以 hash:cleartext 格式下载已破解的哈希。这些仅用于参考,无法进一步破解。不会显示切换提示。

#### 命令行界面

Hashview 操作也可以通过命令行执行:

上传已破解的哈希:```bash
hate_crack.py --hashview upload-cracked --file <output_file>.out --hash-type 1000

上传一个词表:```bash hate_crack.py --hashview upload-wordlist --file .txt --name "My Wordlist"

下载规则文件(已解压保存,可直接用于 `hashcat -r`):```bash
hate_crack.py --hashview download-rules --rules-id 4 --output best64.rule

下载左侧哈希(用于破解的未破解哈希):```bash hate_crack.py --hashview download-left --customer-id 1 --hashfile-id 123

下载已找到的哈希(已破解的哈希及其明文):```bash
hate_crack.py --hashview download-found --customer-id 1 --hashfile-id 123

上传哈希文件并创建任务:```bash hate_crack.py --hashview upload-hashfile-job --file hashes.txt --customer-id 1
--hash-type 1000 --job-name "NTLM Crack Job" --hashfile-name "Domain Hashes"

#### 配置

在 `.env` 中设置 Hashview 凭据(它们是集成设置,因此不存放在 `config.json` 中):```
HASHVIEW_URL=https://hashview.example.com
HASHVIEW_API_KEY=your-api-key-here
HASHVIEW_VERIFY_TLS=true

HASHVIEW_VERIFY_TLS 默认为 true:hate_crack 会验证 Hashview 服务器的 TLS 证书,连接到使用自签名证书或内部 CA 证书的 Hashview 将会失败,直到该证书被信任(将其添加到系统信任存储中,或使用由系统已信任的 CA 签发的证书)。如果无法做到这一点,请设置 HASHVIEW_VERIFY_TLS=false —— 当验证关闭时,hate_crack 会在每次进程启动时打印一行警告,指明主机名,因为禁用验证会失去对伪造服务器或路径上的攻击者拦截连接的保护。

LLM 配置

LLM 攻击(选项 12)和 Rosetta 掩码攻击(选项 23)使用本地模型生成候选密码。在 .env 中配置模型、上下文窗口和请求超时:``` LLM_BACKEND=ollama OLLAMA_MODEL=qwen3:4b-instruct OLLAMA_NUM_CTX=8192 OLLAMA_TIMEOUT=300

**下面的 `OLLAMA_*` 键适用于所有后端,而不仅仅是 Ollama。** 它们保留该前缀是因为 `OLLAMA_HOST` 与 Ollama 自身 CLI 读取的是同一个变量,重命名它们会破坏所有现有的 `.env` 文件,却没有任何功能上的收益——vLLM 或 OpenAI 兼容服务器也需要相同的主机、模型、超时、上下文和采样参数,且名称相同。`LLM_BACKEND` 只选择请求的构造方式。

- **`OLLAMA_MODEL`** — 用于候选生成的 Ollama 模型(默认:`qwen3:4b-instruct`)。LLM 攻击使用结构化(JSON)输出,因此请选择具有良好工具/JSON 支持的模型。
- **`OLLAMA_NUM_CTX`** — 模型的上下文窗口大小(默认:`8192`)。在引入语料库统计之前,该值为 `2048`,太小而无法容纳所给的提示:500 个采样明文在系统提示和响应之前大约就有 2,000–3,500 个 token,因此 Ollama 会静默截断采样器精心分散在文件中的部分样本。
- **`OLLAMA_TIMEOUT`** — 在放弃之前等待生成响应的秒数(默认:`300`)。如果大型模型在首次请求时仍在加载到 VRAM 中,可以调高此值,否则可能会超过超时时间;当超时触发时,hate_crack 会打印经过的超时时间和此设置的名称。
- **`OLLAMA_MAX_SAMPLE_LINES`** — 低于此阈值时,LLM 模式还会将字面明文粘贴到提示中(默认:`500`)。值 ≤ 0 会被视为 500。

  基于语料库的模式(**Wordlist**、**Cracked passwords**、**Pattern rules**)始终以统计方式描述*整个*语料库——基础词占比、掩码、大小写、长度、末尾数字和符号、年份——而不是粘贴其中一部分。聚合是有界的,因此 120,000 个密码的转储与 500 行的转储占用的提示空间大致相同。当整个语料库低于此阈值时,原始明文也会被包含在内,因为向模型隐藏一个小语料库没有任何好处。

  这取代了之前粘贴最多 `ollamaMaxSampleLines` 个均匀间隔密码样本的行为。大型转储的样本完全无法传达频率信息:模型无法区分被组织 8% 的人使用的基础词和被单个人使用的基础词,而这恰恰是使一次猜测值得运行的信号。
- **`OLLAMA_NO_CLOUD`** — 当为 `true` 时,拒绝将任何内容发送到本机之外,适用于三种 LLM 后端(Ollama、vLLM 或通用 OpenAI 兼容服务器)中的任何一种。两项检查由这一个设置控制:Ollama 会将带有 `-cloud` 标签的模型(`gpt-oss:120b-cloud`、`deepseek-v3.1:671b-cloud`)通过本地模型使用的同一本地端点代理到 ollama.com,因此请求看起来没有任何不同——这会按模型名称被拒绝。配置的后端 URL 也会被检查:不是环回、私有或链路本地(也不是 `localhost` 或 `.local`/`.internal`/`.lan`/`.localdomain` 名称)的目标会按目标被拒绝,而此检查无法解析的主机名也会被拒绝,采用故障关闭策略,而不是让无法验证的目标通过。hate_crack 的提示包含恢复的明文、语料库统计信息以及客户的名称、行业和位置,因此任一检查触发都意味着请求在构建之前就被拒绝。默认为 `false`,因此有意配置的云模型或远程服务器可以继续工作;在客户数据不得离开本机的项目中请将其打开。
- **`OLLAMA_AUTO_RESEARCH`** — 当为 `true`(默认)时,**Target info** 模式会在你输入公司名称后立即要求本地模型建议行业、位置和母公司/收购历史,并将它们作为可编辑的提示默认值提供。设置为 `false` 则始终得到空白提示(在模型较慢时有用,因为研究会在攻击开始前多花费一次往返)。
- **`OLLAMA_HOST`** — 配置的后端正在监听的位置。接受裸 `host:port`(`theplague.lan:11434`)或带协议的完整 URL(`https://ollama.example.com`);无论哪种方式,基础 URL 在使用前都会被规范化。默认为 `localhost:11434`,即 Ollama 的端口——vLLM 或 OpenAI 兼容服务器需要将其设置为自己的端口(vLLM 通常监听 `:8000`)。在 `.env` 中设置它,或将其导出为真实环境变量以在单次运行中覆盖该值——它与 Ollama 自身 CLI 读取的变量名相同。
- **`LLM_BACKEND`** — 要与之通信的 OpenAI 兼容服务器:`ollama`(默认)、`vllm`,或用于通用服务器的 `openai`。每个后端都使用相同的 `/v1` 聊天补全 API,因此这仅选择它们不同的两个请求构造细节:`ollama` 获得 `options.num_ctx`,而 `vllm` 获得 `chat_template_kwargs={"thinking": false}`——否则运行推理解析器的 vLLM 服务器会将整个结构化响应路由到 `message.reasoning`,使 `message.content` 为空,并破坏 JSON 解析。`openai` 两者都不发送,因为 `num_ctx` 在那里没有等价物。它**不会**改变主机、模型、超时、上下文或采样设置的来源——对于所有三者来说,这些都是上面的 `OLLAMA_*` 键。
- **`LLM_API_KEY`** — 发送到配置后端的凭据。默认为字面量 `ollama`,即 Ollama 自身服务器忽略的占位符,因此现有安装的请求保持不变;空值会回退到同一占位符,因为 OpenAI SDK 拒绝 `api_key=""`。如果服务器强制要求,请将其设置为真实值——使用 `--api-key` 启动的 vLLM 服务器否则会返回 401。
- 在使用 LLM Attack 之前,确保 Ollama 正在运行且模型已拉取(`ollama pull qwen3:4b-instruct`)——hate_crack 不再自动拉取缺失的模型。

该攻击提供三种生成模式:

1. **Target info** — 公司/行业/位置/母公司;模型根据这些细节推导候选。

   在你输入公司名称后,hate_crack 会向同一个本地模型询问它对该组织已有的了解,并用答案预填 **Industry**、**Location** 和 **Parent Company** 提示,答案显示在括号中:   ```
   Company name: Acme Rail Services

   [!] The values in parentheses below are the local model's GUESSES, not verified OSINT.
       Press Enter to accept, or type your own value to override.
   Industry (freight rail maintenance):
   Location (Omaha, Nebraska):
   Parent company / acquired by:

按 Enter 接受建议或直接输入覆盖。这些值是模型的回忆,并非 OSINT——应将其视为起点,而非关于客户的情报。查询仅使用本地 Ollama 服务器,因此客户名称绝不会离开主机;没有任何网络或第三方 API 调用。如果模型不认识该组织(对于小型客户而言是常见情况),则不会返回任何内容,你将得到纯空白提示: ``` Company name: Acme Rail Services Industry: Location: Parent company / acquired by:

研究失败——超时、Ollama 未运行、回答为空——绝不会阻断攻击;它只会回退到空白提示。将 `ollamaAutoResearch` 设为 `false` 可完全跳过研究。
2. **词表** — 从样本词表推导基础词。
3. **已破解密码** — 将本次会话中已恢复的明文(`<hashfile>.out`)反馈给模型,使其能够推断目标组织自身的密码习惯(基础词、季节、年份、后缀、leet 变体),并生成相同风格的*新*候选密码。此选项仅在至少破解出一个哈希后才会列出;整个文件会像词表模式一样进行统计分析(参见上文 `ollamaMaxSampleLines`)。

#### PCFG 配置

PCFG 攻击(选项 20)和 PRINCE-LING 攻击(选项 21)使用 `pcfg_cracker` 子模块。在 `config.json` 中配置它们:```json
{
"pcfgRuleset": "DEFAULT",
"pcfgMaxCandidates": 50000000,
"pcfgPrinceLingMaxCandidates": 10000000
}
  • pcfgRuleset — 要使用的已训练语法名称(默认:DEFAULT),解析为 pcfg_cracker/Rules/<name>/。使用 pcfg_cracker 的 trainer.py 训练你自己的语法,并将此项设置为规则集名称。
  • pcfgMaxCandidatespcfg_guesser.py 为 PCFG 攻击输出的最大候选数(默认:50000000)。
  • pcfgPrinceLingMaxCandidatesprince_ling.py 写入缓存的 PRINCE 基础词表的最大基础词数(默认:10000000)。

优化内核(optimizedKernelAttacks

hashcat 的 -O 标志会选择优化内核,这些内核速度显著更快,但会限制候选长度(大约 31 个字符,某些模式下更低),并会静默跳过任何更长的内容。config.json 中的 optimizedKernelAttacks 列出了使用 -O 运行的攻击;从列表中省略某个攻击即可使用全长度内核运行它。config.json.example 中的列表与不存在 config.json 时应用的内置默认值一致。

有四种攻击遵循该设置,但默认进行优化,因为它们提供的候选可能超过 -O 上限——将它们添加到列表中以选择启用:

  • hcatNgramXhcatOllamahcatOmenhcatLMtoNT

要在单次运行中在不编辑配置的情况下全局关闭 -O,请传递 --no-optimized-kernel(短形式 --no-optimize)。它会覆盖所有攻击的列表,并且还会移除写入 hcatTuning 中的 -O,否则无论列表如何,该 -O 都会到达 hashcat。

名称必须精确匹配,无法识别的条目会在启动时报告,而不是被忽略。请注意,委托给另一个攻击的攻击由它所委托的攻击控制,而不是由它自己的名称控制:PRINCE-LING 遵循 hcatPrince,而 Spoonman、Rosetta 以及 LLM 模式规则模式遵循 hcatQuickDictionary

攻击覆盖跟踪(coverage_enabled

在长期任务中,同一个哈希文件会在许多会话中被攻击,使用轮换的字典、规则文件和掩码列表,很容易浪费数小时重新运行你已经覆盖过的内容——尤其是因为同一条规则行存在于多个规则文件中。hate_crack 会记录它已经针对每个哈希文件运行过的内容,并提供跳过重叠部分的功能。

覆盖是按条目记录,而不是按文件记录:单个规则行和单个 .hcmask 行,每个都与其运行时所针对的字典配对。这正是它能够识别出你今天运行的自定义规则文件重复了上周 best64.rule 已经覆盖的 40 条规则的原因,也是为什么一条规则只对它尝试过的特定字典才算是“已覆盖”——同样的规则在不同的语料库上会尝试完全不同的候选。

哈希文件通过其内容的 sha256 来标识,因此覆盖信息在重命名或在会话之间移动后仍然有效。字典也以相同方式标识,摘要会根据大小和 mtime 进行记忆化,因此多 GB 的语料库只会被哈希一次,而不是在每次攻击时都进行哈希。

只有在确实有内容可以跳过时,才会提示你:``` [*] Coverage: 40 of 45 rules in this Dictionary have already been run against this hash file. [?] Skip them and run only the 5 new rules? [Y/n]:

回答 `Y`,hate_crack 会构建一个临时规则文件,其中仅包含尚未尝试过的条目;回答 `n` 则无论如何都运行整个内容。如果*每个*条目都是重复的,系统会询问你是否直接跳过该攻击,因此有意重新运行已覆盖的内容永远不需要重启工具。

从未被过滤的攻击仍会被记录为已运行,这正是让你能够回答“我是否已经针对此目标运行过 PRINCE?”的原因。

一次选择多个规则文件的攻击(Quick Crack、Loopback)会在任何 hashcat 调用之前,**一次性针对整个批次**提出跳过问题。这个问题被有意设计得很轻量——它不会读取或哈希任何选定的规则文件,因为一个 YOLO 批次可能运行到数百万行,你不应该为了回答一个是/否问题而等待那么久。它只向存储询问此攻击是否已经针对此哈希文件**使用这些词表之一**运行过;逐条目的差异仍然延迟进行,一次一个规则文件,并决定实际跳过什么。因此,全新的语料库永远不会被标记,即使其上的规则都已针对另一个语料库运行过。

三个有意的限制:

- **仅当 hashcat 穷尽密钥空间时才会记录覆盖情况**(退出码 1)。ctrl-C 或错误不会记录任何内容,退出码 0 也不会——那意味着所有哈希都已破解,hashcat 报告此情况时*并未*完成密钥空间,并且在退化的“所有哈希都作为 potfile 条目找到”的情况下,甚至没有尝试任何一个候选。记录不足只会导致以后多一次冗余运行。
- **动态候选生成器永远不会被过滤。** PRINCE、PCFG、OMEN、Markov 暴力破解和 LLM 模式没有固定的集合可供差异比较,因此它们会被记录为已运行,除此之外不做处理。链式规则文件(`-r a -r b`)作为单个单元进行跟踪,而不是逐条目跟踪,因为 hashcat 会应用两个文件的*笛卡尔积*,丢弃单独一行会静默地移除它所参与的每一个组合。
- **`--loopback` 运行会被记录,但永远不会被过滤。** hashcat 会将新破解的明文作为*额外*候选反馈回去,因此这样的运行会尝试完整的词表和规则集,再加上那些回收明文所能触及的内容。这使得两个方向不对称:记录它是合理的,因此之后对同一词表和规则的普通运行会被正确识别为重复,但第二次 loopback 运行有更多破解需要回收,因此永远不会被跳过。

在 `config.json` 中将 `coverage_enabled` 设置为 `false` 可关闭此功能,或为单次运行传递 `--no-coverage`——它既不查询也不更新存储。

#### 检查与重置覆盖情况

主菜单选项 **85 — Attack Coverage** 显示已针对加载的哈希文件运行过什么、其运行历史,并可以清除它。同样的三个操作也可脚本化:```bash
# What has already been run against this hash file?
hate_crack coverage status --hashfile hashes.txt

# Every attack that has run against it, oldest first
hate_crack coverage history --hashfile hashes.txt

# Start over for this hash file only (prompts unless --yes)
hate_crack coverage forget --hashfile hashes.txt --yes

哈希文件通过内容识别,因此无论它此后被移动到何处,这些操作都能正常工作。forget 仅影响那一个目标——存储位于 ~/.hate_crack/coverage/attack_coverage.sqlite3,删除该文件会重置所有目标的覆盖记录。

脚本化运行

被覆盖机制完全跳过的脚本化攻击默认仍会以 0 退出,因此启用覆盖不会导致现有测试框架开始失败。传入 --exit-code-on-skip 可在未启动任何内容时改为获得退出码 3:```bash hate_crack --exit-code-on-skip hashes.txt dict

0 = ran, 1 = bad input, 2 = unknown command, 3 = everything was already covered

Exit 3 表示*什么都没*运行。一个被部分过滤的 pass —— 有些条目被跳过,有些被尝试 —— 仍然以 `0` 退出,因为攻击确实做了工作。

### hashcat brain 支持(`brain_enabled`)

hashcat 本身自带一个 "brain" —— 一个小型服务器,运行中的 hashcat 实例将候选密码流式传输给它,这样针对同一目标的第二次运行就可以跳过第一次已经尝试过的候选密码。hate_crack 会自动启用它,无需任何菜单步骤:每当它准备对 hashcat 报告为慢速的哈希模式(bcrypt、scrypt 以及其他基于 KDF 的模式,这些模式下哈希本身而非候选密码生成才是瓶颈)发起攻击时,它会启动或复用一个本地 brain 服务器,并为你向 hashcat 调用添加 `--brain-*` 标志。快速模式不会被处理,除非其模式编号列在 `brain_modes_force` 中;而列在 `brain_modes_exclude` 中的模式无论 hashcat 自己的判定如何都绝不会启用 brain —— exclude 始终优先。

**Brain 与攻击覆盖率不是一回事,两者是互补的而非冗余的。** 覆盖率(上文)在整条规则、掩码行和字典的层面进行去重 —— 它决定最初要启动什么,在 hashcat 运行之前就已完成。Brain 在单个候选密码的层面进行去重,并且它通过一个比任何单次 hashcat 调用都更持久的服务器来实现,因此它能捕获覆盖率看不到的重叠:同一次运行中通过两条不同规则或两个不同字典可达的候选密码,以及 —— 正如 `tests/e2e/test_brain_e2e.py` 中的往返测试所演示的 —— 在针对同一目标的第二次独立 hashcat 运行中重新发送的相同候选密码。两者可以同时启用,互不冲突。

`config.json` 中有七个键控制它,全部位于 `brain_*` 前缀下:`brain_enabled`(主开关,默认开启)、`brain_host`(为空表示 hate_crack 在回环地址上管理一个本地服务器;有值表示仅连接到该主机 —— hate_crack 绝不会生成一个它未被要求管理的服务器)、`brain_port`(默认 `6863`)、`brain_client_features`(`1` 哈希密码,`2` 攻击位置,`3` 两者 —— `3` 去重最多,但服务器每看到一个候选密码大约消耗 12 字节 RAM)、`brain_server_timer`(hashcat 自身设置,控制服务器将 `.ldmp`/`.admp` 转储写入磁盘的频率,最小 60 秒,默认 `300`),以及 `brain_modes_force` / `brain_modes_exclude`(逗号分隔的哈希模式编号,用于覆盖 hashcat 自身的慢速/快速判定,exclude 优先)。

**自动生成的服务器完全没有空闲超时。** `brain_server_timer` 并不控制它保持运行多久 —— 没有任何东西控制;它会在生成它的进程的整个生命周期内运行(或直到 `shutdown()`/`atexit` 停止它),并在会话中的每次攻击中复用。在默认值 `300` 下,这意味着只要 hate_crack 在运行,每五分钟就会向 `~/.hate_crack/brain/` 写入一次转储。

第八个键 `BRAIN_PASSWORD` 位于 `.env` 而非 `config.json` 中,因为它是共享密钥,而不是因为 brain 是第三方集成 —— 它仅在你连接到已自行运行的远程 brain 服务器时使用;自动生成的本地服务器会为每个会话生成自己的随机密码,无需配置。

**brain 密码在 hashcat 运行的整个生命周期内对 `ps` 可见,** 因为 hashcat 只接受它作为命令行参数 —— 没有环境变量形式。对于本地自动生成的服务器,这是一个很小的窗口:密码是随机的且仅限该会话,因此其他本地用户只有在攻击实际运行时才能看到它,而会话结束后它就无用了。共享远程 brain 服务器的密码没有这样的缓解措施 —— 它在每次调用中都是相同的值,只要针对该服务器的任何 hate_crack 运行正在进行,机器上的任何其他本地用户都能看到它。在共享或多租户硬件上请相应对待。

传入 `--no-brain` 可在单次运行中禁用 brain,无论 `brain_enabled` 如何;或在 `config.json` 中将 `brain_enabled` 设为 `false` 以在所有地方关闭它。

**Brain 将状态保存在 `~/.hate_crack/brain/` 中** —— 一个小的 `slow_modes.json` 缓存,记录 hashcat 自身按 hashcat 版本划分的慢速/快速判定,另外对于自动生成的服务器,还有其 `.ldmp`/`.admp` 转储文件。这些转储是源自候选密码的材料:它们让新服务器在恢复时知道针对某个目标已经尝试过什么,这在一次渗透中意味着客户衍生的数据会在操作员的主目录中不断累积,只要 brain 曾在那里运行过。与上面的覆盖率存储一样,删除该目录会重置 brain —— 之前被拒绝的候选密码不再被记住,代价是失去该转储所代表的去重能力。如果 brain 看起来跳过了它不该跳过的工作(来自之前不同范围运行的陈旧转储),这就是解决办法。

**删除 `~/.hate_crack/brain/` 不会清除孤立的服务器。** 自动生成的服务器在自己的会话中运行(`start_new_session=True`),因此它能在终端关闭或 SIGHUP 后存活 —— 只有显式 kill,或生成它的进程干净退出并运行其 `atexit` 处理器,才能停止它。孤立的服务器会继续占用回环端口。在默认空 `BRAIN_PASSWORD` 下,你会在每次慢速模式攻击时注意到它表现为 `"[!] ... no brain server could be reached; running without candidate de-duplication"`:孤立服务器的密码是临时的,随生成它的进程一起消亡,因此 hate_crack 拒绝采用它所占据的端口,而不是去猜测一个无法验证的密码。找到并停止它:```bash
pgrep -f 'hashcat --brain-server'
kill <pid>

之后,下一次攻击会像往常一样生成一个新的服务器。

通知(菜单选项 82)

hate_crack 可以在攻击完成时发送 Pushover 推送通知,并且可选地在单个哈希被破解时也发送通知。所有控制项都位于主菜单选项 82 — Notifications 下:

  1. 切换 Pushover 通知 [开/关] — 总开关。持久化到 config.json 中为 notify_enabled
  2. 切换每次破解通知 [开/关] — 开启时,后台 tailer 会监视 .out 文件,并为每次破解推送一条通知(带有按 tick 的突发聚合)。持久化到 config.json 中为 notify_per_crack_enabled。在总开关关闭时无法启用——请先启用选项 1。
  3. 发送测试 Pushover 通知 — 触发一条预设推送,以便你确认 Pushover token/user 对是否有效。即使总开关关闭也能工作。

凭据位于 .env 中;其余调优参数仅通过配置文件 config.json 设置:

  • NOTIFY_PUSHOVER_TOKENNOTIFY_PUSHOVER_USER(位于 .env 中)— 任何推送触发所必需。菜单中没有任何内容会写入这些;请自行编辑 .env
  • notify_attack_allowlist — 无需 [y/N/always] 提示即可自动同意的攻击名称。当你回答 always 时会自动填充。
  • notify_suppress_in_orchestrators(默认 true)— 静默由 Extensive Crack 串联的各个攻击,改为触发一条汇总通知。设置为 false 可为每个串联攻击获取一条通知。其他运行多轮次的菜单项(例如带有多个规则链的 Quick Crack)不是编排器,并且始终按轮次通知。
  • notify_max_cracks_per_burst(默认 5)、notify_poll_interval_seconds(默认 5.0)— 每次破解 tailer 的调优参数。突发聚合逻辑见 hate_crack/notify/tailer.py

字典工具(菜单选项 80)

字典工具子菜单提供由 hashcat-utils 二进制文件支持的字典预处理实用程序,以及从 Hashmob.net 和 Weakpass 下载字典。通过主菜单中的选项 80 访问。

选项二进制文件功能
1len.bin按长度过滤 - 仅保留最小和最大长度之间的单词
2req-include.bin要求字符类别 - 仅保留包含所有必需字符类型的单词
3req-exclude.bin排除字符类别 - 移除包含任何被排除字符类型的单词
4cutb.bin提取子串 - 从每个单词中截取一个字节范围
5splitlen.bin按长度拆分 - 为每种单词长度创建单独的文件(文件在输出目录中命名为 01-64
6rli.bin / rli2.bin减去单词 - 移除出现在一个或多个其他文件中的条目
7gate.bin分片 - 提取每第 N 个单词,以便跨多台机器进行分布式破解
8-优化字典 - 去重并按长度拆分为优化字典目录下的文件
9-从 Hashmob.net 下载字典
10-从 Weakpass 下载字典(通过 BitTorrent)

字符类别掩码位(由选项 2 和 3 使用):1=小写,2=大写,4=数字,8=符号,16=其他。将值相加:7 = 小写+大写+数字。

分片的预期用法:分片将一个字典拆分为 N 个相等、不重叠的部分,以便将工作分散到多台机器或 GPU 上。每个部分都是交错的(每第 N 行),因此每个分片都是整个列表的代表性样本,而不是连续的前/后块——没有任何单个节点会卡在只破解低概率尾部。

运行一次选项 7,给它一个输入字典、一个输出基础路径和一个分片数量(N)。它会在一次遍历中写入所有 N 个部分,并以零填充的部分编号命名(base.001base.002、… 直到 base.00N)。将每个部分复制到每个节点,并将该节点的 hashcat 运行指向它。在单 GPU 系统上,分片不会带来加速,但单个部分仍然是一个快速、有代表性的样本,可用于在提交完整列表之前进行快速分类。

自动更新检查

hate_crack 可以在启动时自动检查 GitHub 上是否有更新的版本。此功能由 check_for_updates 配置选项控制:```json { "check_for_updates": true }

- **`check_for_updates`** — 启动时启用自动版本检查(默认:`true`)。
- 启用后,hate_crack 会从 GitHub 获取最新发布信息,并在有可用更新时显示通知。
- 该检查异步运行,不会阻塞启动。网络错误会被静默忽略。

##### 更新通道

| 通道 | 标志 | 来源 | 你将获得 |
|---------|------|--------|--------------|
| Release | `--update` | `main` | 最新的正式发布版本。这是默认选项,也是启动检查所提供的。 |
| Nightly | `--nightly` | `nightly-dev` | 已通过 CI 但尚未发布的工作。 |

版本遵循常规 semver,版本号的递增取决于批次中实际包含的内容。第二个组成部分**仅在功能变更时**递增:包含任何 `feat` 提交的周期将走向 `X.(Y+1).0`,而仅包含修复、文档和杂务的周期将走向 `X.Y.(Z+1)`。

`nightly-dev` 为批次所指向的版本打上候选发布标签——`v2.20.1rc1`、`v2.20.1rc2`、……——合并到 `main` 后会将同一目标提升为最终发布版本。候选版本是真正的 PEP 440 预发布版本,因此在两端都能正确排序:

    2.20.0  <  2.20.1rc1  <  2.20.1rc2  <  2.20.1  <  2.21.0rc1  <  2.21.0

目标可以在周期中途改变:第一个落地的 `feat` 会将其从 `X.Y.(Z+1)` 移至 `X.(Y+1).0`,候选编号会为新目标重新开始。该编号始终表示该批次在今天会以什么版本发布。

主版本号永远不会自动递增——`!` 主题或 `BREAKING CHANGE:` 页脚会被视为功能变更,因为自动主版本递增只需一个打错的主题行,就可能导致不可逆的已发布版本。主版本递增是明确的人工操作:手动打标签并推送。

该策略位于 `tools/next_version.py`,由两个打标签工作流共享,并在 `tests/test_next_version.py` 中进行单元测试。

启动检查只会提供正式发布版本,因为 nightly 构建根本不发布 GitHub release,而该检查读取的是 GitHub 的“latest release”端点——因此启用 `check_for_updates` 永远不会将你拉到 nightly 上。现在有两件事将通道区分开来:这一点,以及候选版本是真正的 PEP 440 预发布版本,因此即使是对原始版本号进行排序的工具也会将其视为比它最终成为的正式版本更旧。

任一标志都会先将你的检出切换到对应分支(如果有未提交的更改则拒绝执行)。如果你正在运行 nightly 并想回到已发布的代码,`--update` 会将你移回 `main`。

#### 自动合并已找到的哈希(仅下载未破解哈希)

当下载左侧哈希(未破解哈希)时,hate_crack 会自动:
1. 尝试从 Hashview 下载任何已找到(已破解)的哈希作为辅助操作
2. 将已找到的哈希与本地 `.out` 文件合并(例如,对于 pwdump 格式为 `left_1_123.txt.out` 或 `left_1_123.nt.txt.out`)
3. 移除重复条目
4. 合并后清理临时拆分文件

这确保你在处理未破解哈希时,本地破解结果与 Hashview 的集中式数据库保持同步。

**注意:** 下载已找到哈希的选项会单独下载已破解的哈希以供参考,不执行任何合并,也不会提示进行破解。

<hash_type> 通过运行 `hashcat --help` 获得

示例哈希:http://hashcat.net/wiki/doku.php?id=example_hashes```
$ hashcat --help |grep -i ntlm
   5500 | NetNTLMv1                                        | Network protocols
   5500 | NetNTLMv1 + ESS                                  | Network protocols
   5600 | NetNTLMv2                                        | Network protocols
   1000 | NTLM                                             | Operating-Systems

工具

  • AFL++:AFL++ 是 Google 的 AFL 的社区版本,具有许多额外功能,包括更快的模糊测试、自定义变异器、更多架构支持等。

  • AFL:American Fuzzy Lop 是一款广为人知的模糊测试工具,它使用编译时插桩和遗传算法来高效地探索代码路径。

  • Angr:Angr 是一个 Python 框架,用于对二进制文件进行符号执行和二进制分析,常用于漏洞发现和逆向工程。

  • APKLab:APKLab 是一个 VS Code 扩展,用于对 Android APK 文件进行逆向工程、反编译、修改和重新打包。

  • Apktool:Apktool 是一个用于对 Android APK 文件进行逆向工程的工具,可以解码资源并重建它们。

  • BinDiff:BinDiff 是 Google 开发的一款二进制文件比较工具,用于识别不同版本二进制文件之间的差异和相似性。

  • Binwalk:Binwalk 是一个用于分析、逆向工程和提取固件映像的工具,常用于嵌入式设备安全研究。

  • Boomerang:Boomerang 是一个反编译器,可以将二进制可执行文件转换为高级源代码。

  • capa:capa 是 Mandiant 开发的一款工具,用于识别可执行文件中的能力,帮助分析恶意软件和漏洞。

  • Capstone:Capstone 是一个轻量级的多平台、多架构反汇编框架,支持多种指令集。

  • Cutter:Cutter 是一个基于 Rizin 的免费开源逆向工程平台,提供图形用户界面。

  • decompyle3:decompyle3 是一个用于将 Python 3 字节码反编译为源代码的工具。

  • dnSpy:dnSpy 是一个用于调试和编辑 .NET 程序集的工具,无需源代码即可进行逆向工程。

  • Frida:Frida 是一个动态代码插桩工具包,允许在运行时注入 JavaScript 来分析和修改应用程序行为。

  • Ghidra:Ghidra 是美国国家安全局(NSA)开发的一款软件逆向工程套件,支持多种处理器架构和可执行格式。

  • GhidraMCP:GhidraMCP 是一个将 Ghidra 与 MCP(模型上下文协议)集成的工具,用于自动化逆向工程任务。

  • Hopper:Hopper 是一款用于 macOS 和 Linux 的逆向工程工具,支持反汇编和反编译。

  • IDA Pro:IDA Pro 是业界标准的交互式反汇编器和调试器,广泛用于逆向工程和漏洞分析。

  • ILSpy:ILSpy 是一个开源的 .NET 程序集浏览器和反编译器。

  • JADX:JADX 是一个用于将 Android DEX 文件反编译为 Java 源代码的工具。

  • JD-GUI:JD-GUI 是一个独立的图形实用程序,用于显示 Java 源代码。

  • Kaitai Struct:Kaitai Struct 是一种声明式语言,用于描述二进制数据结构,并生成多种语言的解析器代码。

  • LIEF:LIEF 是一个库,用于解析、修改和抽象 ELF、PE、MachO 等可执行文件格式。

  • Miasm:Miasm 是一个逆向工程框架,提供反汇编、符号执行和中间表示等功能。

  • objdump:objdump 是 GNU binutils 的一部分,用于显示二进制文件的信息,包括反汇编。

  • OllyDbg:OllyDbg 是一款用于 Windows 的 32 位汇编级调试器,广泛用于逆向工程。

  • PE-bear:PE-bear 是一个用于分析 PE(可移植可执行)文件的工具,提供图形界面。

  • PEiD:PEiD 是一个用于检测 PE 文件打包器和编译器的工具。

  • pin:Pin 是 Intel 开发的一款动态二进制插桩工具,用于程序分析和性能评估。

  • pycdc:pycdc 是一个用于将 Python 字节码反编译为源代码的工具。

  • Radare2:Radare2 是一个先进的逆向工程框架,提供反汇编、调试、分析和脚本功能。

  • RetDec:RetDec 是 Avast 开发的一款可重定向的反编译器,支持多种架构和文件格式。

  • Rizin:Rizin 是 Radare2 的一个分支,是一个用于逆向工程的框架。

  • Snowman:Snowman 是一个反编译器,可以将二进制代码转换为 C/C++ 源代码。

  • Uncompyle6:Uncompyle6 是一个用于将 Python 字节码反编译为源代码的工具,支持多个 Python 版本。

  • x64dbg:x64dbg 是一款用于 Windows 的开源 x64/x32 调试器,具有图形界面。

  • Xposed:Xposed 是一个用于 Android 的框架,允许在运行时修改应用程序行为,无需修改 APK。``` $ ./hate_crack.py 1000


/ | _____ / | ____ _ ___ ____________ ____ | | __ / ~ __ \ / __ \ / \ /_ __ _ \ / | |/ / \ Y // __ | | \ / \ _| | // __ \ _| < ___| /(__ /| _ >______ /|__| ( /___ >|_
/ / /
___/ / / / / Version 2.0

-------------------------------------------------------------------
## 测试

测试套件主要离线运行,使用 mock/fixture。实时网络检查和系统依赖检查通过环境变量选择启用。

### 本地运行测试```bash
# Run all tests
uv run pytest -v

# Run specific test
uv run pytest tests/test_hashview.py -v

你也可以使用 make test 运行完整测试套件。

实时测试(可选启用)

设置以下任意一项以启用实时检查:

  • HASHMOB_TEST_REAL=1 — 实时 Hashmob 连接/CLI 菜单检查
  • HASHVIEW_TEST_REAL=1 — 实时 Hashview CLI 菜单检查
  • WEAKPASS_TEST_REAL=1 — 实时 Weakpass CLI 菜单检查
  • HATE_CRACK_REQUIRE_DEPS=1 — 如果缺少 7ztransmission-daemontransmission-remote 则失败

实时 Hashview 上传测试

实时 Hashview 上传测试默认跳过。要运行它,请设置 环境变量并在 .env 中提供有效凭据:```bash HATE_CRACK_RUN_LIVE_TESTS=1 uv run pytest tests/test_upload_cracked_hashes.py -v

### 针对本地 Docker 栈的实时 Hashview 测试

无需将实时测试指向远程 Hashview 服务器,你可以让测试套件启动一个本地 [Hashview](https://github.com/hashview/hashview) Docker 栈,对其进行初始化,针对其运行实时测试,然后将其拆除。设置 `HASHVIEW_TEST_LOCAL=1` 并将 `HASHVIEW_REPO` 指向 Hashview 检出目录:```bash
HASHVIEW_TEST_LOCAL=1 HASHVIEW_REPO=~/projects/hashview \
  HATE_CRACK_SKIP_INIT=1 uv run pytest tests/test_hashview_cli_subcommands_subprocess.py -v

这会在 Hashview 仓库中启动 docker compose,初始化一个管理员 API 密钥、一个客户、一个哈希文件以及破解后的“有效任务”数据,然后导出测试所读取的 HASHVIEW_* 环境变量。有用的环境变量:

  • HASHVIEW_TEST_LOCAL=1 — 启用本地栈(否则为空操作)
  • HASHVIEW_REPO=<path> — Hashview 检出目录(默认 ~/projects/hashview
  • HASHVIEW_KEEP=1 — 会话结束后保留容器运行(加快重新运行速度)
  • HASHVIEW_LOCAL_PORT=5000 — 应用发布的主机端口

hate_crack CLI 遵循 HASHVIEW_URL / HASHVIEW_API_KEY 环境变量(覆盖这两个键所在的 .env 文件),这使得测试套件可以将 CLI 指向本地栈,而无需编辑你持久化的配置。

端到端安装测试(本地 + Docker)

本地 uv 工具安装 + 脚本执行(使用临时 HOME):```bash HATE_CRACK_RUN_E2E=1 uv run pytest tests/test_e2e_local_install.py -v

基于 Docker 的端到端安装/运行(通过 `Dockerfile.test` 缓存):```bash
HATE_CRACK_RUN_DOCKER_TESTS=1 uv run pytest tests/test_docker_script_install.py -v

Docker E2E 测试还会下载 rockyou 的一小部分,并运行基本的 hashcat 破解,以验证外部工具集成。

Lima VM 端到端测试(仅限 macOS):

前提条件:必须安装 Limarsync。```bash brew install lima

测试虚拟机会自动配置所有 Linux 依赖项(hashcat、build-essential、curl、git、gzip、p7zip-full、transmission-daemon、ocl-icd-libopencl1、pocl-opencl-icd、uv)。```bash
HATE_CRACK_RUN_LIMA_TESTS=1 uv run pytest tests/test_lima_vm_install.py -v

此测试验证在 macOS 上的轻量级 Linux 虚拟机中的安装和执行。

测试结构

  • tests/test_hashview.py:HashviewAPI 类的综合测试套件,使用模拟 API 响应,包括:
    • 客户列表和数据验证
    • 身份验证和授权测试
    • Hashfile 上传功能
    • 完整的任务创建工作流

所有测试均使用模拟 API 调用,因此无需连接 Hashview 服务器即可运行。


(1) 快速破解 (2) 广泛的 Pure_Hate 方法论破解 (3) 暴力破解攻击 (4) 顶级掩码攻击 (5) 指纹攻击 (6) 组合器攻击 (7) 混合攻击 (8) Pathwell 前 100 掩码暴力破解 (9) PRINCE 攻击 (10) Bandrel 方法论 (11) 回环攻击 (12) LLM 攻击 (13) OMEN 攻击 (14) 临时掩码攻击 (15) 马尔可夫暴力破解攻击 (16) N-gram 攻击 (17) 排列攻击 (18) 随机规则攻击 (19) Combipow 密码短语攻击 (20) PCFG 攻击 (21) PRINCE-LING 攻击 (22) Spoonman 攻击 (23) Rosetta 攻击 (24) 企业掩码暴力破解 (25) 智能掩码攻击

(80) 词表工具 (81) 规则文件工具 (82) 通知 (83) 掩码工具

(93) 从 POT 文件重新生成 .out (94) Hashview API (95) 使用 Pipal 分析哈希 (96) 将输出导出为 Excel 格式 (97) 显示已破解的哈希 (98) 显示 README (99) 退出

选择一个任务:```

Option 94 — Hashview API is only listed when HASHVIEW_API_KEY is set in .env.

The YOLO, Middle, and Thorough Combinator attacks were previously at keys 10-12. They now live in the Combinator Attacks submenu (option 6) along with Combinator3 and CombinatorX.

Quick Crack

Runs a dictionary attack against wordlists in your hcatOptimizedWordlists directory (falls back to hcatWordlists if not configured) and optionally applies rules. Multiple rules can be selected by comma-separated list, and chains can be created with the '+' symbol. Pressing Enter at the wordlist prompt uses the configured optimized wordlists directory as the default.

Selecting a directory — including that default — expands to the wordlists directly inside it before hashcat runs. Subdirectories are not searched, matching hashcat's own behaviour for a directory in the dictionary position, and dot-files and .7z/.torrent/.out files are skipped, which hashcat would otherwise try to read. The candidates are the same either way; the expansion is what lets attack coverage track each wordlist separately, since a directory has no content fingerprint to key on. If the expansion finds nothing — an empty directory, or one holding only subdirectories or archives — the attack aborts rather than launching hashcat with no wordlist, which would put it in stdin mode and leave it reading the terminal.

你想运行哪条(些)规则?
(1) best64.rule
(2) d3ad0ne.rule
(3) T0XlC.rule
(4) dive.rule
(99) YOLO...运行所有规则
输入你想运行的规则的逗号分隔列表。要链式运行规则,请使用 + 符号。
例如,1+1 将链式运行 best64.rule 两次,而 1,2 将依次运行 best64.rule,然后运行 d3ad0ne.rule。
明智地选择:```




#### Extensive Pure_Hate Methodology Crack
Runs several attack methods provided by Martin Bos (formerly known as pure_hate):
  * Brute Force Attack (7 characters)
  * Dictionary Attack
    * All wordlists in `hcatWordlists` with `best64.rule`
    * `rockyou.txt` with `d3ad0ne.rule`
    * `rockyou.txt` with `T0XlC.rule`
  * Top Mask Attack (Target Time = 4 Hours)
  * Fingerprint Attack
  * Smart Mask Attack
  * Combinator Attack
  * Hybrid Attack
  * Extra - Just For Good Measure
    - Runs a dictionary attack using `rockyou.txt` with chained `combinator.rule` and `InsidePro-PasswordsPro.rule` rules

#### Brute Force Attack
Brute forces all characters with the choice of a minimum and maximum password length.

#### Top Mask Attack
Uses StatsGen and MaskGen from PACK (https://thesprawl.org/projects/pack/) to perform a top mask attack using passwords already cracked for the current session.
Presents the user a choice of target cracking time to spend (default 4 hours).

#### Fingerprint Attack
https://hashcat.net/wiki/doku.php?id=fingerprint_attack

Runs a fingerprint attack using passwords already cracked for the current session. Expander substring length escalates automatically (7, 14, 21, ... up to the chosen ceiling), and an optional wordlist can be combined against the expanded fragments in addition to self-combination. Set `hcatFingerprintWordlist` in `config.json` to a default wordlist path so the prompt offers it instead of asking for a path every time; leave it as `""` to always ask (or skip).

#### Smart Mask Attack
Looks for literal "skeleton" patterns shared by 3+ already-cracked passwords for the current session -- e.g. a fixed stem like `CrawlingHorse` followed by a run of digits, or `ChangeMe2day` followed by digits and symbols drawn from a consistent charset. Every qualifying pattern runs against the full remaining hash list, so other accounts sharing a stem get swept up even though brute-forcing the stem itself was never tried.

Patterns with a fixed run at either end -- nearly all of them -- are grouped by mask and run as hybrid attacks (`-a 6` when the mask trails the stem, `-a 7` when it leads), with every pattern's literal stem a line in that group's wordlist. Dozens of patterns that vary the same way therefore become one hashcat pass over one wordlist rather than one mask line each. Whatever cannot be grouped that way -- variation at *both* ends, which leaves no fixed run to seed a wordlist with -- falls back to a single `-a 3` mask file, and has its charsets widened (up to `?a`) to compensate, as far as the guardrail below allows.

Prompts once, before the attack starts, for an optional per-pattern candidate-count guardrail (default 50,000,000,000; 0 disables it) that excludes any individual pattern whose keyspace is too large without blocking the rest.

#### Combinator Attack
https://hashcat.net/wiki/doku.php?id=combinator_attack

Runs a combinator attack using the "rockyou.txt" wordlist.

#### Hybrid Attack
https://hashcat.net/wiki/doku.php?id=hybrid_attack

* Runs sixteen hybrid passes per wordlist, cheapest first. Each mask length
  from 1 to 4 is tried appended and then prepended, first over `?s?d` and then
  over `?a`, and a single ctrl-C abandons the whole attack rather than only the
  current pass.
  - Hybrid Wordlist + Mask - ?s?d wordlists/rockyou.txt ?1
  - Hybrid Mask + Wordlist - ?s?d ?1 wordlists/rockyou.txt
  - ... the same for ?1?1, ?1?1?1 and ?1?1?1?1
  - Hybrid Wordlist + Mask - wordlists/rockyou.txt ?a
  - Hybrid Mask + Wordlist - ?a wordlists/rockyou.txt
  - ... the same for ?a?a, ?a?a?a and ?a?a?a?a

  `?a` is every printable character, so the second group is a superset of the
  first plus letters and roughly 24x the work at the longest mask — over
  rockyou.txt those passes alone are ~1.2e15 candidates, about ten hours for
  NTLM on hardware doing 32 GH/s. That is why the cheap `?s?d` group runs first
  and why the attack as a whole is time-bounded:

  - `hcatHybridMaxRuntime` in `config.json`, in seconds, default `3600`, is the
    time the **whole attack** may spend — not the time one pass may spend. All
    sixteen passes share one deadline, and each is handed whatever is left of it
    as hashcat's `--runtime`. Any pass the budget does not reach is reported
    rather than skipped quietly. Set it to `0` for no limit, which runs every
    pass to exhaustion.

  Within each group the order is by mask length across every wordlist rather
  than all lengths of one wordlist and then the next, so a budget that runs out
  has still given every wordlist its cheap passes.

  Each pass declares what it covers to the attack-coverage store, so a repeat
  hybrid against the same hash file offers to skip the passes already run. A
  pass that runs out of budget is not recorded, so it will be retried.
  Wordlist entries may be glob patterns or directories; both are expanded
  before hashcat runs, a directory into the wordlists directly inside it.
  Subdirectories are not searched, matching hashcat's own behaviour, and
  dot-files and `.7z`/`.torrent`/`.out` files are skipped — a Weakpass
  download leaves archives in the wordlists directory and hashcat would
  otherwise try to read them.

#### Pathwell Top 100 Mask Brute Force Crack
Runs a brute force attack using the top 100 masks from KoreLogic:
https://blog.korelogic.com/blog/2014/04/04/pathwell_topologies

#### PRINCE Attack
https://hashcat.net/events/p14-trondheim/prince-attack.pdf

Runs a PRINCE attack using wordlists/rockyou.txt

#### YOLO Combinator Attack
Runs a continuous combinator attack using random wordlists from the configured wordlists directory for the left and right sides.

#### Middle Combinator Attack
https://jeffh.net/2018/04/26/combinator_methods/

Runs a modified combinator attack adding a middle character mask:
wordlists/rockyou.txt + masks + worklists/rockyou.txt

Where the masks are some of the most commonly used separator characters:
2 4 <space> - _ , + . &

#### Thorough Combinator Attack
https://jeffh.net/2018/04/26/combinator_methods/

* Runs many rounds of different combinator attacks with the rockyou list.
  - Standard Combinator attack: rockyou.txt + rockyou.txt
  - Middle Combinator attack: rockyou.txt + ?n + rockyou.txt
  - Middle Combinator attack: rockyou.txt + ?s + rockyou.txt
  - End Combinator attack: rockyou.txt + rockyou.txt + ?n
  - End Combinator attack: rockyou.txt + rockyou.txt + ?s
  - Hybrid middle/end attack: rockyou.txt + ?n + rockyou.txt + ?n
  - Hybrid middle/end attack: rockyou.txt + ?s + rockyou.txt + ?s


#### Bandrel Methodology

Prompts for comma-separated names and creates a pseudo hybrid attack by capitalizing the first letter and adding up to six additional characters at the end. Each word is limited to a total of five minutes.

  - Built-in common words (seasons, months) included as a customizable `config.json` entry (`bandrel_common_basedwords`)
  - The default five-minute time limit is customizable via `bandrelmaxruntime` in `config.json`

#### Loopback Attack
https://hashcat.net/wiki/doku.php?id=loopback_attack

Uses hashcat's loopback mode to feed cracked passwords from the current session back into the attack pipeline with rules applied. This generates new password candidates based on variations of already-cracked passwords, which is particularly effective for finding related passwords that follow similar patterns.

* Prompts for rule selection to apply to the loopback candidates
* Uses an empty wordlist with the --loopback flag to process previously cracked passwords
* Automatically downloads Hashmob rules if no rules are available locally

#### LLM Attack
Uses a local LLM — Ollama by default, or a vLLM / OpenAI-compatible server via `LLM_BACKEND` — to generate password candidates for a capture-the-flag scenario. Prompts for the fake company name, industry, location, and parent company / acquisition history, then sends these details to the configured LLM model to produce likely password candidates using industry terms and company name permutations. The generated candidates are fed into a hashcat wordlist+rules attack.

* Requires a running server at `OLLAMA_HOST` (default: `http://localhost:11434`, Ollama's port; override in `.env` or the environment) already serving the model — hate_crack does not auto-pull
* Candidate generation uses structured (JSON) output via Atomic Agents, so pick a model with good schema adherence (default: `qwen3:4b-instruct`)
* Configurable backend, model, context window, request timeout, and sample size via `.env` (see [LLM Configuration](#llm-configuration))
* Prompts for target company name, industry, location, and parent company / acquisition history. The industry, location, and parent company prompts are pre-filled with the local model's guesses about the named organization (editable, and clearly labelled as guesses rather than verified OSINT); disable with `ollamaAutoResearch: false`
* Alternatively derives basewords from a sample **wordlist**, or from the **cracked passwords** of the current session (`<hashfile>.out`) so the model mirrors the target organization's own password conventions and produces new candidates in that style (only offered once something has been cracked)
* A live spinner with an elapsed-seconds counter runs during generation, and requests are bounded by `ollamaTimeout` so a model stuck loading into VRAM reports a timeout instead of hanging

**Pattern rules mode** (option 4 in the LLM submenu) takes the same shape as the [Spoonman Attack](#spoonman-attack) — a baseword list run through a rule file, both derived from one corpus — but infers each side with the model instead of extracting it. Spoonman is exact and therefore bounded: its basewords all appear in the corpus and its rules only reproduce transformations the corpus already shows. This asks the model to generalize on both axes, so it can name the *word families* behind a sample (the company and its products, site names, local sports teams, seasons, mascots) and write decorations the corpus does not contain.

* Pattern source is either the current session's cracked passwords (offered first, and only once something has been cracked, since those reveal the target's real conventions) or a sample wordlist
* **You are not asked to pick a rule file.** The model writes one, from the same corpus statistics — a stock rule file encodes the internet's habits, and the point of spending a model round trip is to encode *this* organization's
* Basewords are normalized to lowercase letters only, discarding anything under 3 characters, so the generated rules supply case, digits, and punctuation exactly once
* Generated rules are validated before hashcat sees them, and anything using an op hashcat does not have, a position argument outside `0-9A-Z`, more than 31 functions, or a stray comment or non-ASCII character is discarded. hashcat drops an invalid rule *silently* when valid rules share the file, so an unscreened line would become missing coverage rather than an error. The op table was established by testing hashcat itself, not from its rule documentation, which lists ops hashcat will not actually run
* Local-model yield varies a lot run to run, so a thin answer is asked again once and the two rounds are merged — a handful of rules would waste the pass they are spent on
* If no rule survives validation the basewords still run, unmutated, rather than throwing away the expensive half of the run
* Output lands in `<hashfile>.llm_patterns/` as `basewords.txt` and `rules.rule` — per-run scratch, laid out like `.spoonman/` and removed on exit

#### OMEN Attack
Uses the Ordered Markov ENumerator (OMEN) to train a statistical password model from a wordlist and generate password candidates. This attack learns patterns from known passwords and generates new candidates based on those patterns.

* Requires OMEN binaries (createNG and enumNG) to be built from the omen submodule
* Interactive menu: use existing model, train new model, or cancel
* Training wordlist picker shows available wordlists from configured directory or accepts a custom path
* Validates all 5 required model files (createConfig, CP/IP/EP/LN.level) before running
* Captures and reports enumNG errors instead of failing silently
* Generates up to a specified number of password candidates (configurable via `omenMaxCandidates`)
* Pipes generated candidates directly into hashcat for cracking
* Model files and metadata are stored in `~/.hate_crack/omen/` for persistence across sessions

#### Combinator Attacks Submenu
Opens an interactive submenu with six combinator attack variants (formerly at menu keys 10-12). Consolidates related attacks for cleaner menu organization:
- Combinator Attack - combines two wordlists
- YOLO Combinator Attack - combines all permutations of multiple wordlists
- Middle Combinator Attack - combines wordlists with an extra word in the middle
- Thorough Combinator Attack - comprehensive combination of wordlists with rules
- Combinator3 Attack - combines exactly 3 wordlists using `combinator3.bin`, generating all `word1+word2+word3` combinations piped to hashcat
- CombinatorX Attack - combines 2-8 wordlists using `combinatorX.bin` with optional `--sepFill` separator character between word segments

#### Ad-hoc Mask Attack
Runs hashcat mask attack (mode 3) with a user-specified custom mask string. Allows fine-grained control over character-set brute forcing.

* Opens with a choice between typing a mask and selecting a mask file
* Prompts for a hashcat mask (e.g., `?u?l?l?l?d?d` for uppercase + lowercase + lowercase + lowercase + digit + digit)
* Supports custom character sets for specialized character combinations: `-1` through `-4` on any hashcat, plus `-5` through `-8` on hashcat 7 and newer. A mask using `?5`–`?8` against an older hashcat is flagged before the run rather than failing inside it; if the version cannot be read, the mask is passed through and hashcat decides
* Only prompts for the custom slots the mask actually references — `?1?3?d` asks about `-1` and `-3` and nothing else, and a mask with no custom tokens is never asked at all. Detection is token-aware, so the escaped `??1` is a literal `?1` and prompts for nothing. A slot left blank is still skipped, with a warning that hashcat will reject a mask whose charset is undefined
* Mask files (`.hcmask`) can be selected with tab completion, defaulting to the bundled `masks/` directory; hashcat runs every mask in the file in order. Because a mask file defines its own charsets inline, the `-1` through `-4` prompts are skipped when one is chosen
* Optionally runs the mask incrementally (`--increment`), trying shorter lengths before the full mask. Answering yes prompts for an increment minimum and maximum; either can be left blank, and leaving both blank increments over the mask's full keyspace with hashcat choosing the bounds. Offered for typed masks and mask files alike
* Useful for targeted brute forcing when you know password structure patterns

#### Markov Brute Force Attack
Generates password candidates using Markov chain statistical models. Similar to OMEN but simpler and faster.

* Checks for existing `.hcstat2` Markov table from previous sessions (with option to reuse, regenerate, or cancel)
* Generates table from training source if needed:
  - Can use cracked passwords from current session (`.out` file) as training data
  - Or select any wordlist from configured directory or custom path
* Interactive menu: choose minimum and maximum password length
* Uses `--increment` flag to test lengths in sequence
* Markov table persists with hash file (filename.out.hcstat2) for fast subsequent runs
* Faster than OMEN for general-purpose brute forcing

#### N-gram Attack
Generates n-gram candidates from a corpus file using `ngramX.bin` from hashcat-utils and pipes them into hashcat.

* Prompts for a corpus file with tab completion, defaulting to the configured wordlist directory
* Prompts for an n-gram group size (default 3)
* Gzip-compressed corpus files are auto-detected and decompressed on the fly
* Useful when you have target-relevant prose (scraped site copy, leaked documents, internal wiki exports) rather than a password list

#### Permutation Attack
Generates all character permutations of each word in a targeted wordlist and pipes them to hashcat via `permute.bin` from hashcat-utils.

* Prompts for a single wordlist file (not a directory)
* Effective against short targeted wordlists where the character set is known but the order is not (company abbreviations, name fragments, known tokens)
* WARNING: Scales as N! per word - an 8-character word produces 40,320 permutations. Only practical for words up to ~8 characters.
* Uses `permute.bin < wordlist | hashcat` pipeline pattern

#### Random Rules Attack
Generates a set of random hashcat mutation rules using `generate-rules.bin`, writes them to a temporary file, then runs hashcat against a chosen wordlist with those rules.

* Prompts for rule count (default 65536)
* Prompts for wordlist path with tab-completion and numbered selection
* Temporary rules file is cleaned up after the run regardless of outcome
* Useful when known rule sets are exhausted - explores random rule-space for additional cracks

#### Combipow Passphrase Attack
Generates all unique non-empty subset combinations from a short wordlist using `combipow.bin` and pipes them into hashcat. Designed for passphrase cracking when you know the pool of words a password was built from.

* Prompts for a wordlist file (max 63 lines - combipow generates up to 2^n-1 combinations)
* Optional space separator (`-s` flag) to insert spaces between words in each combination
* Warns if the wordlist exceeds 20 lines (output volume may be large)
* Aborts with a clear message if the wordlist exceeds 63 lines (hard limit)
* Candidates are piped directly to hashcat stdin

#### PCFG Attack
Uses [pcfg_cracker](https://github.com/lakiw/pcfg_cracker) to generate candidates from a Probabilistic Context-Free Grammar, piping `pcfg_guesser.py` output directly into hashcat's stdin mode. A PCFG models password *structure* (baseword + digits + symbol, capitalization habits, keyboard walks) with learned probabilities, so candidates come out roughly in descending likelihood order.

* Requires the `pcfg_cracker` submodule. Presence is checked at startup and reported non-fatally: if it is missing, the PCFG attacks are simply unavailable. Run `make` to fetch it.
* Uses the trained grammar named by `pcfgRuleset` in `config.json` (default `DEFAULT`), read from `pcfg_cracker/Rules/<name>/`
* Candidate count is capped by `pcfgMaxCandidates` (default 50,000,000)
* hate_crack does not wrap grammar training. To build a grammar from a target-specific password set, run pcfg_cracker's own `trainer.py` and point `pcfgRuleset` at the resulting ruleset name

#### PRINCE-LING Attack
Uses pcfg_cracker's `prince_ling.py` to derive an optimized PRINCE base wordlist from a trained grammar, then hands it to the existing PRINCE attack. PRINCE-LING picks base words the grammar says are actually productive, so the PRINCE combination space is far less wasteful than pointing PRINCE at a generic wordlist.

* Requires the `pcfg_cracker` submodule and a trained ruleset directory, same as the PCFG attack
* The generated wordlist is cached at `<hcatOptimizedWordlists>/pcfg_prince_ling_<ruleset>.txt` and reused across sessions
* Regenerates only when the ruleset directory is newer than the cached wordlist, so retraining a grammar invalidates the cache automatically
* Generation is written to a temporary file and atomically moved into place; a failed or interrupted run cleans up its partial file and leaves any existing cache intact
* Base wordlist size is capped by `pcfgPrinceLingMaxCandidates` (default 10,000,000)

#### Spoonman Attack
Derives a baseword list and a hashcat rule file from a corpus of known plaintext passwords — a previous engagement's cracked output, a leak dump, or any password list — such that the baseword x rule cross product reconstructs the corpus exactly (see the memory bound below for the one case where it does not). Contributed as issue #169 by @Spoonman1091.

Each password is split into its letters-only lowercased core (the baseword) plus a rule that rebuilds the original from it, using `l`/`u`/`c` for casing, `T{p}` toggles, `${x}`/`^{x}` for trailing and leading characters, and `i{p}{x}` for interior ones.

* When the current session already has cracked plaintexts (`<hash file>.out` exists and is non-empty), a picker offers those as the corpus ahead of a free-form path — the target's own recovered passwords derive rules describing that target's actual conventions, which is exactly what you want to fire back at the remaining uncracked hashes. Deriving from `.out` and then cracking the same hash file appends new plaintexts to that same file, growing the corpus for the next run; that is the intended feedback loop, not corruption. Sessions with no cracked output yet see no picker at all — just today's path prompt
* Prompts for the corpus, then for how much of the rule file to run: top 50% coverage (listed first and recommended), top 75%, top 95%, top 99%, or the full set
* Rules are sorted by how many passwords each one rebuilds, so a truncated file keeps the most productive rules. Coverage is extremely long-tailed: on a 98.2M-password sample, 50% coverage needed 4,120 rules while 95% needed 16,119,661 and 100% needed 21,029,696 — the last few percent typically costs orders of magnitude more rules than the first half, which is why the smallest tier is listed first and is usually the right choice
* Output is written beside the hash file in `<hash file>.spoonman/`, alongside the other ephemeral wordlists: `basewords.txt`, `rules.full.rule`, the capped rule files, and `coverage.txt` with per-milestone rule counts. Derivation is skipped on later runs of the same hash file unless the corpus has been modified since, and the directory is removed on exit by the temp-file cleanup
* Derivation is bounded in memory. Both counters would otherwise grow for the whole read with nothing written until the end, so a corpus large enough to exhaust RAM lost the entire pass to an OOM kill and produced no output; a measured run against a 31 GB corpus reached 14.1 GB resident at 11% of the file and was still accelerating. Each counter is now capped at 20 million distinct keys (about 1.6 GB apiece), and the lowest-frequency keys are discarded once it is exceeded. If that happens, the run says so on the console and in `coverage.txt`, the output reconstructs the retained keys rather than 100% of the corpus, and the coverage percentages are relative to those. Corpora below the cap are unaffected
* Passwords that cannot be expressed as a rule are written verbatim as their own baseword with a `:` no-op, so coverage stays complete. This covers two hashcat limits: rule positions cannot address past index 35, and hashcat rejects any rule with more than 31 functions — silently, when valid rules share the file
* A password carrying a literal CR or LF (which arrives hex-wrapped, as `$HEX[...0a]`) cannot go in a baseword at all, because a wordlist line has no escape syntax for one. The break is lifted out into an insert op instead, spelled `\x0a`/`\x0d` in the rule, which hashcat decodes to the byte. When the break sits past addressable index 35 the rule reverses the word first, inserts from the other end, and reverses back. One frame has to hold every break in the password, so what is still skipped is a password with one break outside the first 36 characters *and* another outside the last 36, or one needing more inserts than the 31-function cap leaves room for. Those are counted as `unwritable basewords` in `coverage.txt` and reported, never dropped silently
* The derivation self-checks every password by reconstructing it in-process, and reports any failures rather than reporting success
* Corpus lines may carry a hash in front of the password, as cracked output does. A leading field is dropped only when it has the shape of a hash (a hex digest at a known length, or a crypt-style `$id$` string), so `hash:salt:plain` is handled while a plaintext or wordlist entry containing a colon survives intact. `$HEX[...]` plaintexts are decoded. If most lines look like an uncracked dump rather than cracked output, `coverage.txt` records the count and the attack warns — the derived basewords and rules would otherwise be meaningless without any error being raised

#### Rosetta Attack
Mines hashcat `--debug-mode 5` logs for the basewords and rules that already cracked something, then runs their full cross product. Powered by [HashcatRosetta](https://github.com/bandrel/HashcatRosetta), the same library behind [Analyze Hashcat Rules](#analyze-hashcat-rules-rule-file-tools-option-5).

No setup is needed to feed it: `_add_debug_mode_for_rules` appends `--debug-mode 5 --debug-file` to every rule-based hashcat invocation hate_crack makes, so the logs accumulate in `hcatDebugLogPath` (`~/.hate_crack/hashcat_debug` by default, one file per session) as a side effect of normal use. A mode 5 log records only candidates that cracked a hash, in the form `baseword:rule:candidate:wordlist`, which is what makes both halves known-productive against this target population; the trailing wordlist field also shows which list is earning its keep on a multi-wordlist run. HashcatRosetta parses mode 4 and mode 5 alike, so logs written before the switch are still read.

The value is in the cross product rather than the recorded pairs. A pair present in a log has already cracked its hash and will not crack another, but a rule that worked on one baseword has usually never been tried against the others — so N basewords and M rules yield close to N x M untried candidates.

The menu first asks how to rank rules — choices 1-3 below, plus a fourth, unrelated mode:

* Rules can be ranked by application frequency, by how many distinct basewords each one worked on, or by how many unique candidates each one generated. Frequency is the default; baseword spread is the better choice when the goal is a rule set that generalizes past the specific words it was learned from
* Only after one of those three is picked does hate_crack list the logs found in `hcatDebugLogPath` newest-first with their sizes; pick one, pick all of them (up to 20), or type a path to a log from elsewhere
* Prompts for how many top rules to keep and how many top basewords. Both default to all — a blank answer keeps every winning rule the logs contain, and zero means the same thing. Enter a number to cap either. The keyspace is the product of the two and is printed before hashcat starts
* Output is written beside the hash file in `<hash file>.rosetta/` as `basewords.txt` and `rules.rule`, alongside the other ephemeral wordlists, and the directory is removed on exit by the temp-file cleanup
* Reading stops at 1,000,000 debug lines, since the analyzer needs the whole batch in memory at once. Truncation is reported on the console rather than assumed harmless — logs from a long run routinely exceed this, in which case the newest log is the one worth selecting
* **LLM Mask Attack** (4) - a different mode entirely, and the only one that needs no debug logs. Prompts for a natural-language description of the passwords you expect (length, character patterns, symbols, etc.), sends it to the locally configured Ollama model, writes the returned masks to `<hash file>.hcmask`, and runs a `-a 3` hashcat mask attack against them

#### Corporate Masks Brute Force
Statistical masks (8-14 characters) derived from analysis of 3.2M NTLM hashes cracked on real engagements. Powered by [Corporate_Masks](https://github.com/golem445/Corporate_Masks), these masks encode realistic password patterns from successful penetration tests.

* Prompts for minimum and maximum mask length (default 8-10)
* Longer lengths cost exponentially more keyspace—start with 8-10 for speed, or 8-12 for thoroughness
* Each mask file is run as a separate hashcat invocation in ascending length order
* Gracefully handles missing mask files (skips them) and absent submodule (prints warning and returns)
* Supports optimized kernels (`-O` flag) for faster cracking
* Ctrl-C during one length aborts remaining lengths

#### Wordlist Tools (option 80)
A submenu of wordlist preprocessing utilities using hashcat-utils binaries. All tools read from and write to files on disk. All file and directory path prompts support tab completion.

| Key | Tool | Description |
|-----|------|-------------|
| 1 | Filter by Length | Keep only words between a min and max length (`len.bin`) |
| 2 | Require Char Classes | Keep words that include all char classes in mask (`req-include.bin`). Mask: 1=lower, 2=upper, 4=digit, 8=symbol (additive) |
| 3 | Exclude Char Classes | Remove words containing any char class in mask (`req-exclude.bin`). Same mask encoding |
| 4 | Extract Substring | Cut bytes from each word at a given offset and optional length (`cutb.bin`) |
| 5 | Split by Length | Create per-length files in an output directory (`splitlen.bin`) |
| 6 | Subtract Wordlist | Remove lines from a wordlist that appear in one or more remove files. Mode 1 uses `rli2.bin` (single file); mode 2 uses `rli.bin` (multiple files) |
| 7 | Shard Wordlist | Split a wordlist into N equal, interleaved parts in one run, written as `base.001`…`base.00N` for distributed cracking (`gate.bin`) |
| 8 | Optimize Wordlists | Dedupe and split the selected wordlists into per-length files under an output directory |
| 9 | Download from Hashmob.net | Browse and download wordlists from Hashmob.net into the configured wordlist directory |
| 10 | Download from Weakpass | Browse and download Weakpass wordlist torrents, with automatic extraction |
| 11 | Hashmob Downloads | Access a submenu for downloading Hashmob archives (yearly full-found corpora) and combined-left lists (per-mode uncracked hashes) |

All binaries are in `hate_crack/hashcat-utils/bin/`.

#### Rule File Tools (option 81)
Preprocesses hashcat rule files using `cleanup-rules.bin` and `rules_optimize.bin` from hashcat-utils, and downloads rule files from Hashmob.net.

* **Clean** (1) - removes invalid syntax and duplicate rules using `cleanup-rules.bin`. Useful after combining rule files or downloading rules from external sources.
* **Optimize** (2) - consolidates redundant operations using `rules_optimize.bin`. Reduces rule file size and improves cracking speed.
* **Clean and optimize** (3) - runs both operations in sequence via a temporary file, then writes the final result.
* **Download rules from Hashmob.net** (4) - fetches rule files into the configured `rulesDirectory`.
* **Analyze Hashcat rules** (5) - opcode frequency analysis of a rule file, powered by HashcatRosetta.

The three preprocessing operations read from an input file and write to a separate output file (original is never modified).

#### Download Rules from Hashmob.net (Rule File Tools option 4)
Downloads the latest rule files from Hashmob.net's rule repository. These rules are curated and optimized for password cracking and can be used with the Quick Crack and Loopback Attack modes.

* Downloads rule sets in parallel using a thread pool (up to 4 concurrent downloads)
* Skips rules already downloaded locally
* Reports download summary with success/failure counts
* Stores rules in the configured rules directory

#### Analyze Hashcat Rules (Rule File Tools option 5)
Powered by HashcatRosetta (https://github.com/bandrel/HashcatRosetta), this feature analyzes hashcat rule files to provide detailed insights into rule composition and complexity.

* Prompts for a rule file path
* Displays frequency analysis of rule opcodes (operations)
* Helps understand what transformations a rule set performs
* Useful for rule debugging and optimization

#### Mask Tools (option 83)
Downloads mask files from Hashmob.net. This is a minimal submenu today — masks
have no local file-tooling counterpart to the rule/wordlist cleanup and
optimization utilities, only a download capability.

* **Download masks from Hashmob.net** (1) - fetches mask files into the hate_crack masks directory.

#### Download Masks from Hashmob.net (Mask Tools option 1)
Downloads mask files from Hashmob.net's mask repository into the hate_crack masks directory for use with mask-based attacks.

* Downloads mask sets in parallel using a thread pool (up to 4 concurrent downloads)
* Skips masks already downloaded locally
* Reports download summary with success/failure counts
* Stores masks in the configured masks directory used by the Ad-hoc Mask Attack
* Supports interactive listing, range selection, and browsing of available mask files

#### Download Wordlists from Hashmob.net (Wordlist Tools option 9)
Downloads wordlists from Hashmob.net's collection of cracked passwords and commonly used wordlists.

* Interactive menu for browsing available wordlists
* Progress tracking for large downloads
* Stores wordlists in configured wordlist directory

#### Weakpass Wordlist Menu (Wordlist Tools option 10)
Interactive menu for downloading and managing wordlists from Weakpass.com via BitTorrent.

* Browse available Weakpass wordlist torrents
* Download specific wordlists or entire collections
* Automatic extraction of compressed archives
* Progress tracking for torrent downloads

#### Hashmob Downloads (Wordlist Tools option 11)
Access a submenu for downloading large-scale password corpora and specialized wordlists from Hashmob.net.

**Archives** - Downloads yearly full-found password corpora (multi-GB archives containing all cracked passwords from a given year)
* Requires confirmation before downloading -- these archives are large (the listing may show "(unknown size)" since Hashmob's API doesn't currently report a file size per archive)
* Lists all available archives across every year as one globally-numbered list to browse and pick from by index, rather than a per-year picker
* Accepts `a` (or `all`) at the selection prompt to download every listed archive, one at a time. A single confirmation naming the archive count and the summed size covers the whole batch; an archive already on disk at its listed size is skipped, one whose size does not match is re-downloaded, and a failure is counted rather than aborting the rest
* Stores archives in the configured wordlist directory for extraction and use

**Combined Left Lists** - Downloads per-hashcat-mode combined lists of uncracked ("left") hashes from Hashmob.net
* Each list is a set of hashes, not plaintexts, still awaiting a crack for that hashcat mode
* Useful for spotting overlap between your own hash list and hashes the community hasn't cracked yet
* Supports mode selection from the listed hash counts per algorithm

-------------------------------------------------------------------
### Version History

The full, per-release changelog now lives in [CHANGELOG.md](https://github.com/trustedsec/hate_crack/blob/main/CHANGELOG.md).

分类