
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 は 2 つの設定ファイルを使用し、それぞれが異なる設定群を管理します:
config.json— ワードリストのパス、マスク、ルール、チューニング、potfile、hashcat のパス、候補数制限、通知トグル、CLI 設定のデフォルト(35 設定)。.env— サードパーティ連携設定のみ:Hashview と Hashmob の認証情報、Pushover の認証情報、Ollama、および pipal(14 設定)。git では追跡されず、モード0600で作成されます。
この線引きがなされている理由は 1 つです:.env はシークレットを保持しうるファイルだからです。サードパーティサービスの認証情報と設定は、追跡されない 0600 のファイルに置かれ、hate_crack がローカルで行うことはすべて config.json に残ります。これは共有、差分比較、自分のノートへのチェックインが安全です。また、Pushover の認証情報が .env にあり、Pushover のオン/オフトグルが config.json にあるのも同じ理由です — トグルはローカルの設定であり、シークレットではありません。
各キーにはちょうど 1 つの置き場所があります。もう一方のファイルに置かれたキーは無視され、hate_crack はそれが属するファイル名を示す警告を出力します。どのキーも、その環境変数をエクスポートすることで単一実行時に上書きできます。デフォルトのパスはそのまま動作するため、ほとんどのユーザーはこの手順を省略できます。
config.json は恒久的かつ第一級です — 非推奨ではなく、削除の予定もありません。移動したのは連携設定のみです。
単一の config.json からアップグレードしますか? hate_crack は初回実行時に自動で移行します:連携設定は新しい 0600 の .env にコピーされ、その後 config.json から削除されるため、両方のファイルが同じ設定を主張することはありません。移動したキー(値は決して含めず)を出力し、変更を加える前に元のファイルを config.json.pre-split.bak として保存します。config.json のその他の内容は、キーの順序も含めてまったくそのまま残されます。
初回実行: hate_crack が両方のファイルを作成するため、何もする必要はありません。代わりに手動で .env を設定するには、追跡されているテンプレートをコピーします:```bash
cp .env.example .env
chmod 600 .env
`.env.example` はコミットされており、すべての認証情報キーが空の状態で同梱されています。`.env` 自体は**決して**コミットしてはいけません — これは gitignore されており、通常のバックアップ用の綴りも同様に除外され、hate_crack は常にモード `0600`(所有者のみ読み書き可能)でこれを作成します。`.env.example` はスキーマから生成されます。`hate_crack/config_schema.py` を変更した後は、`uv run python -m hate_crack.config_writer` で再生成してください。
### 3. 依存関係と hate_crack のインストール
最も簡単な方法は `make`(または `make install`)を実行することです。これは OS を自動検出し、以下をインストールします:
- 外部依存関係(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 バックエンド、クラックごとのテーラー)。hate_crack/username_detect.py:username:hash入力ファイルを検出し、hashcat の--usernameを決定。hate_crack/formatting.py、hate_crack/progress.py: 出力フォーマットと進捗表示のヘルパー。hate_crack/main.py: メイン CLI 実装。
トップレベルの hate_crack.py はメインエントリポイントとして残り、これらのモジュールを統括します。
参考文献と謝辞
このプロジェクトは、多くの外部プロジェクトやサービスに依存し、またそれらからインスピレーションを得ています。感謝します:
- Hashview (http://github.com/hashview/)
- Weakpass (https://weakpass.com)
- Hashmob (https://hashmob.net)
使用方法
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 シムを作成し、リポジトリディレクトリから実行されるため、現在の作業ディレクトリに関係なく、設定とアセットは常に見つかります。
設定は以下でも検索されます:
- リポジトリルートとパッケージディレクトリ
- `~/.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`**。最初に一致したものが優先される。2つのファイルが異なるディレクトリから取得されるのは正常である。
- 初回実行時、両方のファイルが作成される — `config.json` は `config.json.example` から、`.env` は組み込みのデフォルトから。古い `config.json` にまだ統合キーが含まれている場合、それらは新しい `.env` にコピーされ、hate_crack は `config.json` から削除すべきキーを通知する。hate_crack がそのファイル自体を編集することは決してない。
- 実行のたびに、hate_crack は実際に読み込んだ2つのファイルを出力する: ```
[*] config.json: /home/you/.hate_crack/config.json
[*] .env: /home/you/.hate_crack/.env
設定が「反映されていない」とデバッグする前に、この2行を読んでください。これらが存在するのは、検索順序における2つの罠のためです:
- チェックアウトはホームディレクトリより優先される。 リポジトリルートが最初に検索されるため、ツールを実行する任意のチェックアウト内にある
.envやconfig.jsonは~/.hate_crackにあるものより優先されます — そして、チェックアウトからツールを実行することが、そもそもそこにそれらのファイルが作成される原因そのものです。これが実際の~/.hate_crack設定を隠してしまう場合、hate_crack は両方のパスを明示する3番目の[!]行でその旨を通知します — その行は「以下のファイルは無視されている」という意味として扱い、2つ目の同等に有効な設定として扱わないでください。 - カレントワーキングディレクトリは決して検索されない。 たまたま現在いるディレクトリにある
.envは意図的に無視されます:エンゲージメントディレクトリは、誰も設定として意図していないファイルで溢れているからです。リポジトリルートか~/.hate_crackに置いてください。
エラー: ref 'refs/heads/master' とマージしようとしたが、そのような ref はフェッチされなかった
次のように表示される場合:``` 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
**アンインストール** - OS の依存関係とツールを削除します:```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
### リンターと型チェックの実行
変更をプッシュする前に、これらのチェックをローカルで実行してください。すべてを実行するには `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 フックは [prek](https://github.com/j178/prek) (v0.3.3+) によって管理されています。フックをインストールするには:```bash
prek install --hook-type pre-push --hook-type pre-commit
これは prek.toml で定義されたフックを、pre-commit の local-repo
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 を設定します。このモードでは1桁のショートカットキーのみが機能し、10番以上のオプションには矢印キーで到達する必要があります。矢印キーモードは TTY も必要とするため、出力がパイプされている場合はオフのままです。
開発用依存関係
オプションの [dev] グループには以下が含まれます:
- ty - 静的型チェッカー
- ruff - 高速な Python リンター兼フォーマッター
- pytest - テストフレームワーク
- pytest-cov - カバレッジレポート
一般的なオプション:
--download-hashview: クラッキング前に Hashview からハッシュをダウンロードします。--hashview: ハッシュ、ワードリスト、ジョブを管理するための対話型 Hashview メニュー。--hashview --help: Hashview のコマンドラインオプションを表示します。--weakpass: Weakpass からワードリストをダウンロードします。--hashmob: Hashmob.net からワードリストをダウンロードします。--hashmob-masks: Hashmob.net からマスクをダウンロードします。--download-torrent <FILENAME>: 特定の Weakpass トレントファイルをダウンロードします。--download-all-torrents: キャッシュから利用可能なすべての Weakpass トレントをダウンロードします。--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にあるため、別のブランチにある場合はチェックアウトをmainに切り替えます。--nightly: 代わりにnightly-devブランチから最新のナイトリービルドに更新します。ナイトリービルドは 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`)を入力すると、1つではなくリストされているすべてのルールをダウンロード
- **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
Download left hashes(クラッキング用の未クラックハッシュ):```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 は検証がオフのとき、プロセス開始のたびにホスト名を含む 1 行の警告を出力します。
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 トークンを消費するため、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% が使用するベースワードと、1 人だけが使用するベースワードを区別できず、これこそが推測を実行する価値のあるシグナルなのです。
- **`OLLAMA_NO_CLOUD`** — `true` の場合、3 つの LLM バックエンド(Ollama、vLLM、または汎用 OpenAI 互換サーバー)のいずれについても、このホストから何も送信することを拒否します。2 つのチェックがこの 1 つの設定で制御されます。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` に設定すると常に空のプロンプトになります(遅いモデルで便利です。調査は攻撃開始前に余分なラウンドトリップを 1 回消費するため)。
- **`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 を話すため、これはそれらが異なる 2 つのリクエスト形成の詳細のみを選択します。`ollama` は `options.num_ctx` を取得し、`vllm` は `chat_template_kwargs={"thinking": false}` を取得します — これがないと、推論パーサーを実行している vLLM サーバーは構造化応答全体を `message.reasoning` にルーティングし、`message.content` を空のままにして、JSON 解析を壊します。`openai` はどちらも送信しません。`num_ctx` に相当するものがないためです。これはホスト、モデル、タイムアウト、コンテキスト、またはサンプリング設定の取得元を変更し**ません** — それらは 3 つすべてについて上記の `OLLAMA_*` キーです。
- **`LLM_API_KEY`** — 設定されたバックエンドに送信される認証情報。デフォルトはリテラルの `ollama` で、Ollama 自身のサーバーが無視するプレースホルダーであるため、既存のインストールのリクエストは変更されません。空の値は同じプレースホルダーにフォールバックします。OpenAI SDK が `api_key=""` を拒否するためです。サーバーが認証情報を強制する場合は実際の値に設定してください — `--api-key` で起動された vLLM サーバーはそうでなければ 401 を返します。
- LLM Attack を使用する前に、Ollama が実行中でモデルがプルされていることを確認してください(`ollama pull qwen3:4b-instruct`) — hate_crack は不足しているモデルを自動プルしなくなりました。
この攻撃は 3 つの生成モードを提供します:
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 サーバーのみを使用するため、クライアント名がホスト外に出ることはありません。Web やサードパーティ API の呼び出しは一切ありません。モデルが組織を認識しない場合(小規模クライアントではよくあるケース)、何も返さず、単純な空のプロンプトが表示されます: ``` Company name: Acme Rail Services Industry: Location: Parent company / acquired by:
リサーチの失敗 — タイムアウト、Ollama が実行されていない、空の回答 — は攻撃を妨げることはなく、空のプロンプトにフォールバックするだけです。リサーチを完全にスキップするには `ollamaAutoResearch` を `false` に設定してください。
2. **Wordlist** — サンプルの wordlist から basewords を導出します。
3. **Cracked passwords** — このセッションで既に復元された平文 (`<hashfile>.out`) をモデルにフィードバックし、対象組織独自のパスワード慣習 (basewords、季節、年、サフィックス、leetspeak) を推測させ、同じスタイルの*新しい*候補を生成させます。このオプションは少なくとも1つのハッシュがクラックされた後にのみ表示され、ファイル全体が Wordlist モードと全く同様に統計的に分析されます (上記の `ollamaMaxSampleLines` を参照)。
#### PCFG Configuration
PCFG Attack (オプション 20) と PRINCE-LING Attack (オプション 21) は `pcfg_cracker` サブモジュールを使用します。これらは `config.json` で設定します:```json
{
"pcfgRuleset": "DEFAULT",
"pcfgMaxCandidates": 50000000,
"pcfgPrinceLingMaxCandidates": 10000000
}
pcfgRuleset— 使用する学習済み文法の名前(デフォルト:DEFAULT)。pcfg_cracker/Rules/<name>/に解決されます。pcfg_cracker のtrainer.pyで独自に学習させ、これをルールセット名に設定してください。pcfgMaxCandidates— PCFG 攻撃でpcfg_guesser.pyが出力する候補の最大数(デフォルト:50000000)。pcfgPrinceLingMaxCandidates—prince_ling.pyがキャッシュされた PRINCE ベースワードリストに書き込むベースワードの最大数(デフォルト:10000000)。
最適化カーネル (optimizedKernelAttacks)
hashcat の -O フラグは最適化カーネルを選択します。これは大幅に高速ですが、候補長に上限があり(おおよそ 31 文字、一部のモードではそれ以下)、それより長いものは黙ってスキップされます。config.json の optimizedKernelAttacks は -O で実行する攻撃を列挙します。リストから攻撃を省略すると、フルレングスカーネルで実行されます。config.json.example のリストは、config.json が存在しない場合に適用される組み込みのデフォルトと一致します。
4 つの攻撃はこの設定に従いますが、デフォルトでは最適化されません。これは -O の上限を超える可能性のある候補を供給するためです。オプトインするにはリストに追加してください:
hcatNgramX、hcatOllama、hcatOmen、hcatLMtoNT
設定を編集せずに 1 回の実行で -O をすべて無効にするには、--no-optimized-kernel(短縮形 --no-optimize)を渡します。これはすべての攻撃に対してリストを上書きし、hcatTuning に書かれた -O も削除します。そうでなければリストに関係なく hashcat に到達してしまいます。
名前は完全一致で照合され、認識されないエントリは無視されるのではなく起動時に報告されます。別の攻撃に委譲する攻撃は、自身の名前ではなく委譲先の攻撃によって制御されることに注意してください: PRINCE-LING は hcatPrince に従い、Spoonman、Rosetta、および LLM パターンルールモードは hcatQuickDictionary に従います。
攻撃カバレッジの追跡 (coverage_enabled)
長期間のエンゲージメントでは、同じハッシュファイルが、ローテーションされるワードリスト、ルールファイル、マスクリストのセットを使って多くのセッションで攻撃され、すでにカバーした範囲を再実行して何時間も無駄にしがちです。特に同じルール行が複数のルールファイルに存在する場合はなおさらです。hate_crack は各ハッシュファイルに対してすでに実行した内容を記録し、重複をスキップすることを提案します。
カバレッジはファイル単位ではなくエントリ単位で記録されます: 個々のルール行と個々の .hcmask 行が、それぞれ実行対象のワードリストとペアで記録されます。これにより、今日実行するカスタムルールファイルが先週 best64.rule でカバー済みのルールのうち 40 個を繰り返していることを認識できます。また、ルールが「カバー済み」となるのは試行した特定のワードリストに対してのみである理由でもあります。同じルールでも異なるコーパスに対してはまったく異なる候補を試行します。
ハッシュファイルはその内容の sha256 で識別されるため、セッション間で名前を変更したり移動したりしてもカバレッジは維持されます。ワードリストも同様に識別され、ダイジェストはサイズと mtime に対してメモ化されるため、数ギガバイトのコーパスも攻撃ごとではなく一度だけハッシュ化されます。
スキップするものが本当にある場合にのみプロンプトが表示されます:``` [*] 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 はその1つのターゲットにのみ影響します — ストアは ~/.hate_crack/coverage/attack_coverage.sqlite3 にあり、ファイルを削除するとすべてのターゲットのカバレッジがリセットされます。
スクリプト実行
カバレッジが完全にスキップするスクリプト攻撃でも、デフォルトでは終了コード 0 で終了するため、カバレッジを有効にしても既存のハーネスが失敗し始めることはありません。何も起動されなかった場合に終了コード 3 を得るには、--exit-code-on-skip を渡してください:```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 は *何も* 実行されなかったことを意味する。部分的にフィルタリングされたパス — 一部のエントリはスキップされ、一部は試行された — はそれでも `0` で終了する。なぜなら、その攻撃は実際に処理を行ったからである。
### hashcat brain サポート (`brain_enabled`)
hashcat 自体には「brain」が同梱されている — 実行中の hashcat インスタンスが候補パスワードをストリーミングする小さなサーバーで、同じターゲットに対する2回目の実行が、1回目で既に試された候補をスキップできるようにする。hate_crack はこれを自動的に利用し、メニュー操作は不要である。hashcat が遅いと報告するハッシュモード(bcrypt、scrypt、その他の KDF ベースのモード — 候補生成ではなくハッシュ自体がボトルネックとなるもの)に対する攻撃を起動しようとするたびに、ローカルの brain サーバーを起動または再利用し、hashcat の呼び出しに `--brain-*` フラグを自動的に追加する。高速モードは、そのモード番号が `brain_modes_force` に記載されていない限り、そのままにされる。また、`brain_modes_exclude` に記載されたモードは、hashcat 自身の判定に関係なく brain を決して利用しない — exclude が常に優先される。
**Brain は攻撃カバレッジと同じものではなく、両者は冗長ではなく補完的である。** カバレッジ(上記)はルール全体、マスク行、ワードリストのレベルで重複を排除する — hashcat が実行される前に、そもそも何を起動するかを決定する。Brain は個々の候補パスワードのレベルで重複を排除し、それを単一の hashcat 呼び出しを超えて存続する永続サーバーを通じて行うため、カバレッジでは見えない重複を捕捉する。すなわち、同じ実行内で2つの異なるルールや2つの異なるワードリストを通じて到達可能な候補、そして — `tests/e2e/test_brain_e2e.py` のラウンドトリップが示すように — 同じターゲットに対する2回目の別個の hashcat 実行で再送される同じ候補である。両方を同時に有効にしても競合はない。
`config.json` の7つのキーがこれを制御し、すべて `brain_*` プレフィックスの下にある。`brain_enabled`(マスタースイッチ、デフォルトはオン)、`brain_host`(空なら hate_crack がループバック上でローカルサーバーを管理する。値があればそのホストにのみ接続する — hate_crack は管理を指示されていないサーバーを決して起動しない)、`brain_port`(デフォルト `6863`)、`brain_client_features`(`1` はハッシュ化パスワード、`2` は攻撃位置、`3` は両方 — `3` が最も重複を排除するが、サーバーは確認した候補ごとに約12バイトの RAM を消費する)、`brain_server_timer`(サーバーが `.ldmp`/`.admp` ダンプをディスクに書き込む頻度に関する hashcat 自身の設定、最小60秒、デフォルト `300`)、そして `brain_modes_force` / `brain_modes_exclude`(hashcat 自身の遅い/速い判定を上書きするカンマ区切りのハッシュモード番号で、exclude が優先される)。
**自動起動されたサーバーにはアイドルタイムアウトが一切ない。** `brain_server_timer` はサーバーがどれだけ稼働し続けるかを制御しない — 何も制御しない。それは起動したプロセスの存続期間中(または `shutdown()`/`atexit` が停止するまで)実行され、セッション内のすべての攻撃で再利用される。デフォルトの `300` では、hate_crack が実行されている限り、5分ごとに `~/.hate_crack/brain/` へのダンプ書き込みが行われることを意味する。
8番目のキー `BRAIN_PASSWORD` は、brain がサードパーティ統合だからではなく、共有シークレットであるため、`config.json` ではなく `.env` に存在する — これは既に運用しているリモート brain サーバーに接続する場合にのみ使用され、自動起動されたローカルサーバーはセッションごとに独自のランダムパスワードを生成するため設定は不要である。
**brain パスワードは hashcat 実行の存続期間中 `ps` から見える**。なぜなら hashcat はそれをコマンドライン引数としてのみ受け付け、環境変数の形式は存在しないからである。ローカルの自動起動サーバーではこれは小さな窓に過ぎない。パスワードはランダムでその1セッションにスコープされるため、別のローカルユーザーがそれを見られるのは攻撃が実際に実行されている間だけで、セッションが終われば無用である。共有リモート brain サーバーのパスワードにはそのような緩和策はない — それは呼び出しごとに同じ値であり、そのサーバーに対する hate_crack の実行が進行中である限り、マシン上の他のローカルユーザーから見える。共有またはマルチテナントのハードウェアではそれに応じて扱うこと。
`brain_enabled` に関係なく単一の実行で brain を無効にするには `--no-brain` を渡すか、`config.json` で `brain_enabled` を `false` に設定してどこでもオフにする。
**Brain は `~/.hate_crack/brain/` に状態を保持する** — hashcat バージョンごとの hashcat 自身の遅い/速い判定の小さな `slow_modes.json` キャッシュ、加えて自動起動サーバーの場合はその `.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にあります:
- Toggle Pushover Notifications [ON/OFF] — マスタースイッチ。
config.jsonにnotify_enabledとして永続化されます。 - Toggle Per-Crack Notifications [ON/OFF] — ONの場合、バックグラウンドのtailerが
.outファイルを監視し、クラックごとに通知をプッシュします(ティックごとのバースト集約あり)。config.jsonにnotify_per_crack_enabledとして永続化されます。マスタースイッチがOFFの間は有効にできません — 先にオプション1を有効にしてください。 - Send Test Pushover Notification — 定型のプッシュを送信するので、Pushoverのトークン/ユーザーのペアが機能することを確認できます。マスタースイッチがOFFでも機能します。
認証情報は.envにあり、残りの調整ノブはconfig.jsonの設定ファイル専用です:
NOTIFY_PUSHOVER_TOKEN、NOTIFY_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を参照してください。
Wordlist Tools(メニューオプション80)
Wordlist Toolsサブメニューは、hashcat-utilsバイナリをバックエンドとしたワードリスト前処理ユーティリティと、Hashmob.netおよびWeakpassからのワードリストダウンロードを提供します。メインメニューのオプション80からアクセスします。
| オプション | バイナリ | 機能 |
|---|---|---|
| 1 | len.bin | 長さでフィルタ - 最小長と最大長の間の単語のみを保持 |
| 2 | req-include.bin | 文字クラスを要求 - 必要なすべての文字タイプを含む単語のみを保持 |
| 3 | req-exclude.bin | 文字クラスを除外 - 除外された文字タイプを含む単語を削除 |
| 4 | cutb.bin | 部分文字列を抽出 - 各単語からバイト範囲を切り出す |
| 5 | splitlen.bin | 長さで分割 - 単語の長さごとに別々のファイルを作成(出力ディレクトリに01-64という名前のファイル) |
| 6 | rli.bin / rli2.bin | 単語を減算 - 1つ以上の他のファイルに現れるエントリを削除 |
| 7 | gate.bin | シャード - 複数のマシンに分散クラッキングするためにN番目ごとの単語を抽出 |
| 8 | - | ワードリストを最適化 - 重複排除し、最適化されたワードリストディレクトリの下で長さごとのファイルに分割 |
| 9 | - | Hashmob.netからワードリストをダウンロード |
| 10 | - | Weakpassからワードリストをダウンロード(BitTorrent経由) |
文字クラスマスクビット(オプション2と3で使用):1=小文字、2=大文字、4=数字、8=記号、16=その他。値を合計します:7 = 小文字+大文字+数字。
シャーディングの使用方法:シャーディングは1つのワードリストをN個の等しい、重複しない部分に分割し、複数のマシンやGPUに作業を分散できるようにします。各部分はインターリーブ(N番目ごとの行)されているため、各シャードは連続した前/後ろのチャンクではなく、リスト全体の代表的なサンプルです — 単一のノードが低確率のテールのみをクラックし続けることはありません。
オプション7を一度実行し、入力ワードリスト、出力ベースパス、シャード数(N)を指定します。1回のパスですべてのN個の部分を書き込み、ゼロ埋めされた部分番号で名前が付けられます(base.001、base.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 に従い、バンプは実際にバッチに含まれる内容から導出されます。2 番目のコンポーネントは**機能に対してのみ**動きます。`feat` コミットを 1 つでも含むサイクルは `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:` フッターは機能としてカウントされます。なぜなら、自動メジャーは 1 行の打ち間違えた件名で不可逆的な公開リリースになりかねないからです。メジャーは明示的な人間の行為です。手動でタグを付けてプッシュしてください。
ポリシーは `tools/next_version.py` にあり、両方のタグ付けワークフローで共有され、`tests/test_next_version.py` でユニットテストされています。
起動時チェックはリリースのみを提供します。なぜなら、nightly ビルドは GitHub リリースを一切公開せず、チェックは GitHub の「latest release」エンドポイントを読み取るからです — したがって `check_for_updates` を有効にしても nightly に引き込まれることはありません。現在、チャネルを分けているのは 2 つのことです。それと、候補が本物の PEP 440 プレリリースであるという事実であり、生のバージョン番号をランク付けするツールも、それが最終的になるリリースより古いものとして扱います。
どちらのフラグも、まずチェックアウトを対応するブランチに切り替えます(コミットされていない変更がある場合は切り替えを拒否します)。nightly を実行していてリリース済みコードに戻りたい場合は、`--update` で `main` に戻ります。
#### 自動 Found Hash マージ(Download Left Only)
left ハッシュ(未クラックのハッシュ)をダウンロードするとき、hate_crack は自動的に:
1. 補助操作として Hashview から found(クラック済み)ハッシュをダウンロードしようと試みます
2. found ハッシュをローカルの `.out` ファイル(例: pwdump 形式の場合は `left_1_123.txt.out` または `left_1_123.nt.txt.out`)とマージします
3. 重複エントリを削除します
4. マージ後に一時的な分割ファイルをクリーンアップします
これにより、未クラックのハッシュを扱う際に、ローカルのクラッキング結果が Hashview の集中データベースと同期した状態に保たれます。
**注:** download-found オプションは、参照目的で既にクラック済みのハッシュを別途ダウンロードするものであり、マージやクラッキングのプロンプトは行いません。
`<hash_type>` は `hashcat --help` を実行することで取得できます。
Example Hashes: 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
検出
検出ルール
- ルールは
rules/ディレクトリに配置されています。 - 各ルールは、検出ロジックを定義した YAML ファイルです。
- ルールは、疑わしい動作、ファイルの整合性、ネットワークアクティビティ、およびシステムコールを対象としています。
検出エンジン
- エンジンは、ルールをリアルタイムのシステムイベントと照合します。
- アラートは、重大度、タイムスタンプ、および関連するプロセスメタデータとともに生成されます。
アラート出力
-
アラートは、コンソール、ログファイル、または外部の SIEM に送信できます。
-
各アラートには、ルール名、説明、および影響を受けるリソースが含まれます。``` $ ./hate_crack.py 1000
/ | _____ / | ____ _ ___ ____________ ____ | | __
/ ~ __ \ / __ \ / \ /_ __ _ \ / | |/ /
\ Y // __ | | \ / \ _| | // __ \ _| <
___| /(__ /| _ >______ /|__| ( /___ >|_
/ / /___/ / / / /
Version 2.0
-------------------------------------------------------------------
## テスト
テストスイートはほとんどがオフラインで、モック/フィクスチャを使用します。ライブネットワークチェックと
システム依存関係チェックは、環境変数によるオプトインです。
### ローカルでのテスト実行```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—7z、transmission-daemon、またはtransmission-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 キー、顧客、ハッシュファイル、およびクラック済みの「effective task」データがシードされ、テストが読み取る HASHVIEW_* 環境変数がエクスポートされます。便利な環境変数:
HASHVIEW_TEST_LOCAL=1— ローカルスタックを有効化(それ以外では no-op)HASHVIEW_REPO=<path>— Hashview チェックアウト(デフォルト~/projects/hashview)HASHVIEW_KEEP=1— セッション後もコンテナを実行したままにする(再実行が高速化)HASHVIEW_LOCAL_PORT=5000— アプリが公開されるホストポート
hate_crack CLI は HASHVIEW_URL / HASHVIEW_API_KEY 環境変数を尊重し(これら 2 つのキーが存在する .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のみ):
前提条件:Limaとrsyncがインストールされている必要があります。```bash
brew install lima
テストVMは、すべての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 VM内でのインストールと実行を検証します。
テスト構成
- tests/test_hashview.py: モック化されたAPIレスポンスを使用したHashviewAPIクラスの包括的なテストスイート。以下を含みます:
- 顧客リストとデータ検証
- 認証および認可テスト
- ハッシュファイルのアップロード機能
- 完全なジョブ作成ワークフロー
すべてのテストはモック化された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 を2回連鎖して実行し、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).