Retour aux mises à jour
New releaseSep 4, 2026

hate_crack v2.36.1

Un outil pour automatiser les méthodologies de craquage via Hashcat, développé par l'équipe TrustedSec.

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

Installation

L'installation depuis les sources est la seule voie prise en charge. hate_crack n'est pas distribué sur PyPI : pip install hate-crack renvoie vers un placeholder 0.0.0 qui échoue volontairement et redirige ici. Le nom est réservé uniquement pour que personne d'autre ne puisse publier un homonyme sous celui-ci — voir packaging/pypi-placeholder/.

1. Installer hashcat

Hashcat doit être installé et disponible dans votre PATH :

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

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

Ou téléchargez un binaire précompilé depuis https://hashcat.net/hashcat/ et définissez hcatPath dans config.json vers son emplacement.

2. Télécharger hate_crack

Clonez avec les sous-modules (requis pour hashcat-utils, princeprocessor, pcfg_cracker, Corporate_Masks, et éventuellement omen) :```bash git clone --recurse-submodules https://github.com/trustedsec/hate_crack.git cd hate_crack

Si vous avez cloné sans les sous-modules, initialisez-les :```bash
git submodule update --init --recursive

Ensuite, personnalisez la configuration si nécessaire. hate_crack utilise deux fichiers de configuration, chacun possédant un ensemble distinct de paramètres :

  • config.json — chemins des wordlists, masques, règles, réglages, potfile, chemin hashcat, limites de candidats, bascules de notification, préférences par défaut de la CLI (35 paramètres).
  • .env — paramètres d'intégration tiers uniquement : identifiants Hashview et Hashmob, identifiants Pushover, Ollama et pipal (14 paramètres). Non suivi par git, créé avec le mode 0600.

La séparation se fait à cet endroit pour une raison : .env est le fichier susceptible de contenir des secrets. Les identifiants et la configuration des services tiers vont dans le fichier non suivi en 0600 ; tout ce que hate_crack fait localement reste dans config.json, qui peut être partagé, comparé et consigné dans vos propres notes sans risque. C'est aussi pourquoi les identifiants Pushover sont dans .env tandis que les bascules d'activation/désactivation de Pushover sont dans config.json — les bascules sont des préférences locales, pas des secrets.

Chaque clé a exactement un emplacement. Une clé placée dans l'autre fichier est ignorée, et hate_crack affiche un avertissement nommant le fichier auquel elle appartient. N'importe quelle clé peut toujours être remplacée pour une seule exécution en exportant sa variable d'environnement. La plupart des utilisateurs peuvent ignorer cette étape car les chemins par défaut fonctionnent immédiatement.

config.json est permanent et de premier ordre — il n'est pas obsolète et aucune date de suppression n'est prévue. Seuls les paramètres d'intégration ont été déplacés.

Vous migrez depuis un seul config.json ? hate_crack le migre pour vous au premier lancement : les paramètres d'intégration sont copiés dans un nouveau .env en 0600, puis supprimés de config.json afin que les deux fichiers ne les revendiquent pas tous les deux. Il indique quelles clés ont été déplacées (jamais leurs valeurs) et sauvegarde votre original sous config.json.pre-split.bak avant d'y toucher. Tout le reste dans config.json est laissé exactement tel quel, ordre des clés inclus.

Premier lancement : hate_crack crée les deux fichiers pour vous, il n'y a donc rien à faire. Pour configurer .env manuellement à la place, copiez le modèle suivi :```bash cp .env.example .env chmod 600 .env

`.env.example` est versionné et est livré avec chaque clé d'identification vide. `.env` lui-même ne doit **jamais** être versionné — il est ignoré par git, tout comme ses orthographes de sauvegarde habituelles, et hate_crack le crée toujours avec le mode `0600` (lecture/écriture propriétaire uniquement). `.env.example` est généré à partir du schéma ; régénérez-le après avoir modifié `hate_crack/config_schema.py` avec `uv run python -m hate_crack.config_writer`.

### 3. Installer les dépendances et hate_crack

La méthode la plus simple consiste à exécuter `make` (ou `make install`), qui détecte automatiquement votre OS et installe :
- Les dépendances externes (p7zip, transmission-daemon / transmission-remote)
- Compile les sous-modules (hashcat-utils, princeprocessor, pcfg_cracker, et éventuellement omen) et récupère l'ensemble de masques Corporate_Masks (données uniquement)
- Les dépendances Python via uv et un shim CLI à `~/.local/bin/hate_crack````bash
make

Ceci est idempotent - cela ignore les outils déjà installés. Pour forcer une réinstallation propre :```bash make reinstall

**Ou installez les dépendances manuellement :**

### Dépendances externes
Celles-ci sont requises pour certains flux de téléchargement/extraction :

- `7z`/`7za` (p7zip) — utilisé pour extraire les archives `.7z`.
- `transmission-daemon` / `transmission-remote` — utilisé pour télécharger les torrents Weakpass.

Commandes d'installation manuelle :

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

Installez ensuite les dépendances Python et le shim 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

Structure du projet

La logique principale est désormais répartie en modules sous hate_crack/ :

  • hate_crack/cli.py : assistants argparse et substitutions de configuration.
  • hate_crack/api.py : intégrations Hashview, Weakpass et Hashmob (téléchargements/menus/assistants).
  • hate_crack/attacks.py : gestionnaires d'attaques du menu.
  • hate_crack/corpus_stats.py : statistiques de mots de passe sur l'ensemble du corpus utilisées pour décrire un corpus au LLM.
  • hate_crack/plaintext.py : récupère le mot de passe à partir d'une ligne de corpus (suppression du préfixe de hash, décodage $HEX[...]) ; partagé par les modes LLM, corpus_stats et rulegen.
  • hate_crack/llm.py : génération structurée (JSON) de candidats par LLM via Atomic Agents.
  • hate_crack/menu.py : moteur de rendu de menu partagé, incluant la navigation optionnelle par touches fléchées.
  • hate_crack/noninteractive.py : répartiteur pour les sous-commandes d'attaque scriptées.
  • hate_crack/notify/ : paquet de notification (backend Pushover, tailer par crack).
  • hate_crack/username_detect.py : détecte les fichiers d'entrée username:hash pour décider de l'option --username de hashcat.
  • hate_crack/formatting.py, hate_crack/progress.py : assistants de formatage de sortie et d'affichage de progression.
  • hate_crack/main.py : implémentation principale de la CLI.

Le fichier hate_crack.py à la racine reste le point d'entrée principal et orchestre ces modules.


Références et remerciements

Ce projet dépend de et s'inspire de plusieurs projets et services externes. Merci à :


Utilisation

Après l'installation avec make, lancez hate_crack depuis n'importe où :```bash hate_crack

or with arguments:

hate_crack <hash_file> <hash_type> [options]

Vous pouvez également exécuter via `uv` :```bash
uv run hate_crack.py <hash_file> <hash_type>

Exécuter en tant qu'outil (recommandé)

Installez en utilisant make depuis la racine du dépôt - cela compile les sous-modules et regroupe les ressources :```bash cd /path/to/hate_crack make hate_crack

La commande `make install` crée un shim bash à l'emplacement `~/.local/bin/hate_crack` qui s'exécute depuis le répertoire du dépôt, de sorte que la configuration et les ressources sont toujours trouvées quel que soit votre répertoire de travail actuel.

La configuration est également recherchée dans :
- La racine du dépôt et le répertoire du paquet
- `~/.hate_crack`

**Remarque :** Le `hcatPath` dans `config.json` concerne uniquement l'emplacement du binaire hashcat (facultatif si hashcat est dans le PATH). Les ressources de Hate_crack (hashcat-utils, princeprocessor, pcfg_cracker, Corporate_Masks, omen) sont chargées depuis le répertoire du dépôt et intégrées automatiquement par `make install`.

### Exécution en tant que script
Le script utilise un shebang `uv`. Rendez-le exécutable et lancez :```bash
chmod +x hate_crack.py
./hate_crack.py

Vous pouvez également utiliser Python directement :```bash python hate_crack.py

### Utilisation non interactive / scriptée

Pour l'automatisation, vous pouvez lancer une attaque unique directement, en contournant le menu. Le nom de l'attaque est le premier argument, suivi du fichier de hash et du type de hash hashcat. Les invites de prétraitement (filtrage des comptes informatiques, force brute LM en premier, déduplication des comptes en double) acceptent automatiquement leurs valeurs par défaut dans ce mode. Le processus se termine avec `0` en cas de succès et une valeur non nulle en cas d'erreur (fichier de hash manquant, type de hash non numérique, liste de mots manquante ou nom de fichier de règles inconnu).```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

Dépannage

Erreur : « would clobber existing tag » lors de la mise à jour

Un clone plus ancien peut refuser de se mettre à jour, en affichant une longue liste de lignes comme :``` ! [rejected] v2.5.0 -> v2.5.0 (would clobber existing tag)

Cela affecte les clones créés avant juillet 2026. L'historique publié a été réécrit
à ce moment-là pour supprimer certains fichiers qui n'auraient jamais dû être commités, ce qui a donné
à chaque commit un nouvel ID ; les tags d'un clone plus ancien pointent donc vers des objets que ce
dépôt ne contient plus, et git refuse de déplacer un tag qu'il possède déjà.
Rien ne cloche dans votre copie de travail et aucune donnée de cracking n'est en danger.

Récupérez avec une réinitialisation ponctuelle. Cela écarte les commits et modifications locaux dans la
copie de travail, donc si vous avez personnalisé quoi que ce soit suivi par git (par opposition à
`config.json`, qui n'est pas suivi), committez-le d'abord sur une branche :```bash
cd /path/to/hate_crack
git fetch --tags --force origin
git checkout -B main origin/main
make install

--force ici ne met à jour que les tags ; il ne peut pas toucher à vos commits. Ensuite, le programme de mise à jour intégré fonctionne normalement. Les versions antérieures à 2.18 ne pouvaient pas effectuer cette récupération elles-mêmes, c'est pourquoi elle doit être faite manuellement une fois.

Erreur : Le répertoire de build n'existe pas

Si vous voyez une erreur comme :``` Error: Build directory /opt/hashcat/hashcat-utils does not exist. Expected to find expander at /opt/hashcat/hashcat-utils/bin/expander.

Cela signifie que les ressources de hate_crack n'ont pas été intégrées dans le paquet installé.

**Comprendre les chemins :**
- `hcatPath` dans config.json → pointe vers **l'emplacement du binaire hashcat** (facultatif, peut être dans le PATH)
- `hashcat-utils/` et `princeprocessor/` → intégrés dans le paquet par `make install`

**Solution :**
Réinstallez en utilisant le Makefile, qui compile les sous-modules et installe l'outil :```bash
cd /path/to/hate_crack  # the repository checkout
make install

Configuration par défaut (config.json.example) :

La plupart des utilisateurs peuvent utiliser les valeurs par défaut sans personnalisation :

  • hcatWordlists : ./wordlists (relatif à la racine du dépôt ou HOME/.hate_crack)
  • hcatOptimizedWordlists : ./optimized_wordlists (répertoire utilisé par Quick Crack ; revient à hcatWordlists s'il n'est pas trouvé)
  • rules_directory : ./hashcat/rules (inclut les règles des sous-modules)
  • hcatTuning : `` (chaîne vide - aucun indicateur de réglage par défaut)

Exemples de personnalisations de 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) ... }

**Chargement de la configuration :**
- Priorité pour chaque clé : `os.environ` > le fichier personnel de cette clé (`.env` ou `config.json`) > valeur par défaut intégrée
- Les clés manquantes reviennent aux valeurs par défaut intégrées ; `config.json.example` documente chaque clé de `config.json`
- Les deux fichiers sont recherchés, indépendamment l'un de l'autre, dans cet ordre : **racine du dépôt**, puis le **répertoire du paquet installé**, puis **`~/.hate_crack`**. La première correspondance l'emporte ; il est normal que les deux fichiers proviennent de répertoires différents.
- Au premier lancement, les deux sont créés — `config.json` à partir de `config.json.example`, `.env` à partir des valeurs par défaut intégrées. Si un ancien `config.json` contient encore des clés d'intégration, elles sont copiées dans le nouveau `.env` et hate_crack vous indique lesquelles supprimer de `config.json` ; il ne modifie jamais ce fichier lui-même.
- À chaque exécution, hate_crack affiche les deux fichiers qu'il a réellement chargés :  ```
  [*] config.json: /home/you/.hate_crack/config.json
  [*] .env:        /home/you/.hate_crack/.env

Lisez ces deux lignes avant de déboguer un paramètre qui « ne prend pas effet ». Elles existent à cause de deux pièges dans l'ordre de recherche :

  • Un checkout prime sur votre répertoire personnel. La racine du dépôt est recherchée en premier, donc un .env ou config.json présent dans n'importe quel checkout depuis lequel vous lancez l'outil l'emporte sur celui de ~/.hate_crack — et lancer l'outil depuis un checkout est précisément ce qui crée ces fichiers à cet endroit en premier lieu. Si cela masque un véritable fichier de configuration ~/.hate_crack, hate_crack le signale désormais avec une troisième ligne [!] nommant les deux chemins — considérez cette ligne comme « le fichier ci-dessous est ignoré », et non comme un second fichier de configuration tout aussi valide.
  • Le répertoire de travail courant n'est jamais recherché. Un .env dans le répertoire où vous vous trouvez est ignoré, délibérément : les répertoires d'engagement sont remplis de fichiers que personne n'a voulus comme configuration. Placez-le à la racine du dépôt ou dans ~/.hate_crack.

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

Si vous voyez :``` Your configuration specifies to merge with the ref 'refs/heads/master' from the remote, but no such ref was fetched.

La branche par défaut a été renommée de `master` à `main`. Corrigez avec :```bash
git remote set-head origin -a
git branch -m master main
git branch --set-upstream-to=origin/main main
git pull

Cibles Makefile

Par défaut (installation complète) - compile les sous-modules, installe les dépendances et installe l'outil :```bash make

or explicitly:

make install

Ceci est idempotent - cela ignore les outils déjà installés.

**Forcer une réinstallation propre :**```bash
make reinstall

Mise à jour rapide - reconstruit les sous-modules et réinstalle l'outil (après avoir récupéré les modifications) :```bash make update

**Désinstaller** - supprime les dépendances du système d'exploitation et l'outil :```bash
make uninstall

Compiler uniquement hashcat-utils :```bash make hashcat-utils

**Exécuter les tests** - gère automatiquement HATE_CRACK_SKIP_INIT lorsque nécessaire :```bash
make test

Rapport de couverture :```bash make coverage

**Nettoyer les artefacts de build/test :**```bash
make clean

Développement

Configuration de l'environnement de développement

Installez le projet avec les dépendances de développement optionnelles (inclut les linters et les outils de test) :```bash make dev-install

### Exécution des linters et des vérifications de types

Avant de pousser des modifications, exécutez ces vérifications localement. Utilisez `make lint` pour tout, ou exécutez les vérifications individuelles :

**Ruff (linting et formatage) :**```bash
make ruff
# or manually:
uv run ruff check hate_crack tests tools packaging hate_crack.py

Correction automatique des problèmes :```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 (vérification de type) :**```bash
make ty
# or manually:
uv run ty check hate_crack

Exécuter toutes les vérifications ensemble :```bash make lint

### Exécution des tests

Les tests détectent automatiquement lorsque les sous-modules ne sont pas compilés et définissent automatiquement `HATE_CRACK_SKIP_INIT=1`.```bash
make test

Ou exécutez pytest directement :```bash uv run pytest -v

Avec couverture :```bash
make coverage

Ou avec pytest :```bash uv run pytest --cov=hate_crack

### Git Hooks (prek)

Les hooks Git sont gérés par [prek](https://github.com/j178/prek) (v0.3.3+). Installez les hooks avec :```bash
prek install --hook-type pre-push --hook-type pre-commit

Cela installe les hooks définis dans prek.toml en utilisant le schéma TOML local-repo de pre-commit :

  • pre-push (hooks locaux) : ruff, ruff-format, ty, pytest, pytest-lima, bandit
  • pre-commit (depuis pre-commit/pre-commit-hooks) : trailing-whitespace, end-of-file-fixer, check-yaml, check-merge-conflict, check-added-large-files, detect-private-key

Les auto-correcteurs de pre-commit réécrivent les fichiers sur place, donc réindexez et committez à nouveau après leur exécution.

Remarque : prek 0.3.3 attend repos = [...] au niveau supérieur. L'ancien format [hooks.<stage>] commands = [...] n'est pas pris en charge.

Les menus utilisent par défaut la sélection classique numérotée print() + input(), qui accepte les touches complètes à plusieurs chiffres.

Pour activer la navigation avec les touches fléchées via simple-term-menu, définissez HATE_CRACK_ARROW_MENU=1. Dans ce mode, seules les touches de raccourci à un seul chiffre fonctionnent ; les options numérotées 10 et au-delà doivent être atteintes avec les touches fléchées. Le mode touches fléchées nécessite également un TTY, il reste donc désactivé lorsque la sortie est redirigée.

Dépendances de développement

Le groupe optionnel [dev] inclut :

  • ty - Vérificateur de types statique
  • ruff - Linter et formateur Python rapide
  • pytest - Framework de tests
  • pytest-cov - Rapport de couverture

Options courantes :

  • --download-hashview : Télécharge les hashes depuis Hashview avant le cracking.
  • --hashview : Menu interactif Hashview pour gérer les hashes, les wordlists et les jobs.
  • --hashview --help : Affiche les options en ligne de commande de Hashview.
  • --weakpass : Télécharge les wordlists depuis Weakpass.
  • --hashmob : Télécharge les wordlists depuis Hashmob.net.
  • --hashmob-masks : Télécharge les masks depuis Hashmob.net.
  • --download-torrent <FILENAME> : Télécharge un fichier torrent Weakpass spécifique.
  • --download-all-torrents : Télécharge tous les torrents Weakpass disponibles depuis le cache.
  • --wordlists-dir <PATH> / --optimized-wordlists-dir <PATH> : Remplace les répertoires de wordlists.
  • --pipal-path <PATH> : Remplace le chemin de pipal.
  • --restore-potfile : Reconstruit <hashfile>.out à partir du fichier POT de hashcat au démarrage, en remplaçant tout contenu existant, puis continue vers le menu normal. Sans ce flag, la recherche dans le POT ne s'exécute que lorsque .out n'existe pas déjà. L'option de menu 93 fait la même chose à la demande, avec une invite de confirmation.
  • --maxruntime <SECONDS> : Remplace la durée d'exécution maximale.
  • --bandrel-basewords <PATH> : Remplace le fichier de basewords bandrel.
  • --update : Met à jour vers la dernière version et réinstalle. Bascule le checkout sur main s'il est sur une autre branche, car les tags de version s'y trouvent.
  • --nightly : Met à jour vers la dernière nightly à la place, depuis la branche nightly-dev. Les nightlies ont passé la CI mais ne font pas partie d'une version publiée. Peut aussi s'écrire --update --nightly.
  • --no-optimized-kernel (ou --no-optimize) : Ne jamais passer -O à hashcat pour toute l'exécution. Remplace optimizedKernelAttacks dans config.json et supprime tout -O que vous avez mis dans hcatTuning. Rien n'est réécrit dans la config, donc cela ne s'applique qu'à cette exécution. Avec une sous-commande, placez-le avant la sous-commande : ./hate_crack.py --no-optimize quick hashes.txt 1000 --wordlist words.txt.
  • --debug : Active la journalisation de débogage (écrit sur stderr).

Intégration Hashview

hate_crack s'intègre avec Hashview pour la gestion centralisée des hashes et le cracking distribué.

Accéder au menu interactif Hashview :```bash hate_crack.py --hashview

Options du menu :
- **(1) Upload Cracked Hashes** - Télécharge les résultats craqués de la session en cours vers Hashview
- **(2) Upload Wordlist** - Télécharge un fichier wordlist vers Hashview
- **(3) Download Wordlist** - Télécharge une wordlist depuis Hashview
- **Download Rule** - Télécharge un fichier de règles depuis Hashview (décompressé en texte brut, prêt pour `hashcat -r`). Saisissez `a` (ou `all`) à l'invite de l'ID de règle pour télécharger toutes les règles listées au lieu d'une seule
- **Download All Rules** - Télécharge en une seule passe tous les fichiers de règles listés par Hashview ; les échecs par règle sont signalés sans interrompre le reste
- **(4) Download Left Hashes** - Télécharge les hashes non craqués restants (propose de basculer pour le craquage)
- **(5) Download Found Hashes** - Télécharge les hashes déjà craqués avec les mots de passe en clair (pour référence/analyse)
- **(6) Upload Hashfile and Create Job** - Télécharge un nouveau fichier de hashes et crée une tâche de craquage
- **(99) Back to Main Menu** - Retour au menu principal

**Important : Download Found vs Download Left**
- **Download Left Hashes (4)** : Télécharge les hashes non craqués qui doivent être craqués. Fusionne automatiquement avec les hashes trouvés s'ils sont disponibles, et propose de basculer vers ce fichier de hashes pour le craquage.
- **Download Found Hashes (5)** : Télécharge les hashes déjà craqués au format hash:cleartext. Ceux-ci sont destinés à la référence et ne peuvent pas être craqués davantage. Aucune invite de bascule n'est affichée.

#### Interface en ligne de commande

Les opérations Hashview peuvent également être effectuées via la ligne de commande :

Télécharger les hashes craqués :```bash
hate_crack.py --hashview upload-cracked --file <output_file>.out --hash-type 1000

Téléchargez une liste de mots :```bash hate_crack.py --hashview upload-wordlist --file .txt --name "My Wordlist"

Téléchargez un fichier de règles (enregistré décompressé, prêt pour `hashcat -r`) :```bash
hate_crack.py --hashview download-rules --rules-id 4 --output best64.rule

Télécharger les hashes restants (hashes non craqués à craquer) :```bash hate_crack.py --hashview download-left --customer-id 1 --hashfile-id 123

Télécharger les hashes trouvés (hashes déjà cassés avec le texte en clair) :```bash
hate_crack.py --hashview download-found --customer-id 1 --hashfile-id 123

Téléchargez le fichier de hachage et créez la tâche :```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"

#### Configuration

Définissez les identifiants Hashview dans `.env` (ce sont des paramètres d'intégration, ils ne se trouvent donc pas dans `config.json`) :```
HASHVIEW_URL=https://hashview.example.com
HASHVIEW_API_KEY=your-api-key-here
HASHVIEW_VERIFY_TLS=true

HASHVIEW_VERIFY_TLS vaut true par défaut : hate_crack vérifie le certificat TLS du serveur Hashview, et la connexion à un Hashview avec un certificat auto-signé ou émis par une AC interne échouera tant que ce certificat n'est pas approuvé (ajoutez-le à votre magasin de confiance système, ou utilisez un certificat émis par une AC déjà approuvée par votre système). Si cela n'est pas possible, définissez HASHVIEW_VERIFY_TLS=false -- hate_crack affichera un avertissement d'une ligne nommant l'hôte à chaque démarrage de processus lorsque la vérification est désactivée, car la désactiver supprime la protection contre un serveur usurpé ou un attaquant sur le chemin interceptant la connexion.

Configuration LLM

L'Attaque LLM (option 12) et l'Attaque par Masque Rosetta (option 23) génèrent leurs candidats avec un modèle local. Configurez le modèle, la fenêtre de contexte et le délai d'expiration des requêtes dans .env :``` LLM_BACKEND=ollama OLLAMA_MODEL=qwen3:4b-instruct OLLAMA_NUM_CTX=8192 OLLAMA_TIMEOUT=300

**Les clés `OLLAMA_*` ci-dessous s'appliquent à tous les backends, pas seulement à Ollama.** Elles conservent ce préfixe parce que `OLLAMA_HOST` est la même variable que lit le CLI d'Ollama lui-même, et les renommer casserait chaque `.env` existant sans gain fonctionnel — un serveur vLLM ou compatible OpenAI veut le même hôte, modèle, timeout, contexte et paramètres d'échantillonnage sous les mêmes noms. `LLM_BACKEND` ne sélectionne que la façon dont la requête est formée.

- **`OLLAMA_MODEL`** — Le modèle Ollama utilisé pour la génération de candidats (par défaut : `qwen3:4b-instruct`). L'attaque LLM utilise une sortie structurée (JSON), donc choisissez un modèle avec un bon support des outils/JSON.
- **`OLLAMA_NUM_CTX`** — Taille de la fenêtre de contexte pour le modèle (par défaut : `8192`). C'était `2048` avant l'introduction des statistiques de corpus, ce qui était trop petit pour contenir le prompt qui lui était donné : 500 textes en clair échantillonnés représentent environ 2 000 à 3 500 tokens avant le prompt système et la réponse, donc Ollama tronquait silencieusement une partie de l'échantillon que l'échantillonneur avait soigneusement réparti sur le fichier.
- **`OLLAMA_TIMEOUT`** — Secondes d'attente pour une réponse de génération avant d'abandonner (par défaut : `300`). Augmentez cette valeur si un grand modèle est encore en cours de chargement dans la VRAM lors de la première requête, ce qui peut sinon dépasser le timeout ; hate_crack affiche le timeout écoulé et le nom de ce paramètre lorsqu'il se déclenche.
- **`OLLAMA_MAX_SAMPLE_LINES`** — Le seuil en dessous duquel les modes LLM collent également les textes en clair littéraux dans le prompt (par défaut : `500`). Les valeurs ≤ 0 sont traitées comme 500.

  Les modes dérivés du corpus (**Wordlist**, **Cracked passwords**, **Pattern rules**) décrivent toujours l'*intégralité* du corpus statistiquement — parts de mots de base, masques, casse, longueurs, chiffres et symboles finaux, années — plutôt que d'en coller un extrait. L'agrégation est bornée, donc un dump de 120 000 mots de passe coûte à peu près le même espace de prompt qu'un de 500 lignes. Lorsque tout le corpus tient sous ce seuil, les textes en clair bruts sont également inclus, puisqu'il n'y a rien à gagner à cacher un petit corpus au modèle.

  Cela remplace le comportement précédent qui consistait à coller un échantillon régulièrement espacé d'au plus `ollamaMaxSampleLines` mots de passe. Un échantillon d'un grand dump ne transmettait aucune information de fréquence : le modèle ne pouvait pas distinguer un mot de base utilisé par 8 % de l'organisation d'un mot utilisé par une seule personne, ce qui est précisément le signal qui rend une supposition digne d'être tentée.
- **`OLLAMA_NO_CLOUD`** — Lorsque `true`, refuse d'envoyer quoi que ce soit hors de cet hôte, pour l'un des trois backends LLM (Ollama, vLLM, ou un serveur générique compatible OpenAI). Deux vérifications sont contrôlées par ce seul paramètre : Ollama proxyfie un modèle étiqueté `-cloud` (`gpt-oss:120b-cloud`, `deepseek-v3.1:671b-cloud`) vers ollama.com via le même endpoint local qu'utilise un modèle local, donc rien dans la requête ne semble différent — c'est refusé par nom de modèle. L'URL du backend configuré est également vérifiée : une destination qui n'est pas loopback, privée ou link-local (et qui n'est pas `localhost` ni un nom `.local`/`.internal`/`.lan`/`.localdomain`) est refusée par destination, et un nom d'hôte que cette vérification ne peut pas résoudre est également refusé, en mode fail-closed, plutôt que de laisser passer une destination non vérifiable. Les prompts de hate_crack contiennent des textes en clair récupérés, des statistiques de corpus, ainsi que le nom, le secteur et la localisation du client, donc le déclenchement de l'une ou l'autre vérification signifie que la requête est refusée avant d'être construite. Par défaut à `false`, donc un modèle cloud ou un serveur distant délibérément configuré continue de fonctionner ; activez-le pour les missions où les données du client ne doivent pas quitter l'hôte.
- **`OLLAMA_AUTO_RESEARCH`** — Lorsque `true` (par défaut), le mode **Target info** demande au modèle local de suggérer le secteur, la localisation et la société mère / l'historique des acquisitions dès que vous avez saisi le nom de l'entreprise, et les propose comme valeurs par défaut éditables du prompt. Mettez à `false` pour toujours obtenir des prompts vides (utile avec un modèle lent, car la recherche coûte un aller-retour supplémentaire avant le début de l'attaque).
- **`OLLAMA_HOST`** — Là où le backend configuré écoute. Accepte un simple `host:port` (`theplague.lan:11434`) ou une URL complète avec un schéma (`https://ollama.example.com`) ; dans les deux cas l'URL de base est normalisée avant utilisation. Par défaut à `localhost:11434`, qui est le port d'Ollama — un serveur vLLM ou compatible OpenAI a besoin que ceci soit réglé sur le sien (vLLM écoute couramment sur `:8000`). Définissez-le dans `.env`, ou exportez-le comme variable d'environnement réelle pour remplacer cela pour une seule exécution — c'est le même nom de variable que lit le CLI d'Ollama lui-même.
- **`LLM_BACKEND`** — À quel serveur compatible OpenAI parler : `ollama` (par défaut), `vllm`, ou `openai` pour un serveur générique. Chaque backend parle la même API de complétions de chat `/v1`, donc ceci ne sélectionne que les deux détails de formation de requête sur lesquels ils diffèrent : `ollama` reçoit `options.num_ctx`, et `vllm` reçoit `chat_template_kwargs={"thinking": false}` — sans quoi un serveur vLLM exécutant un parseur de raisonnement route toute la réponse structurée vers `message.reasoning`, laisse `message.content` vide, et casse l'analyse JSON. `openai` n'envoie ni l'un ni l'autre, car `num_ctx` n'a pas d'équivalent là-bas. Cela ne change **pas** l'origine de l'hôte, du modèle, du timeout, du contexte ou des paramètres d'échantillonnage — ce sont les clés `OLLAMA_*` ci-dessus pour les trois.
- **`LLM_API_KEY`** — Le justificatif envoyé au backend configuré. Par défaut à la valeur littérale `ollama`, le placeholder que le serveur d'Ollama lui-même ignore, donc les requêtes d'une installation existante sont inchangées ; une valeur vide retombe sur ce même placeholder car le SDK OpenAI refuse `api_key=""`. Définissez-le sur la valeur réelle si le serveur en impose une — un serveur vLLM démarré avec `--api-key` renvoie 401 sinon.
- Assurez-vous qu'Ollama est en cours d'exécution et que le modèle est téléchargé (`ollama pull qwen3:4b-instruct`) avant d'utiliser l'LLM Attack — hate_crack ne télécharge plus automatiquement les modèles manquants.

L'attaque propose trois modes de génération :

1. **Target info** — entreprise / secteur / localisation / société mère ; le modèle dérive des candidats à partir de ces détails.

   Après que vous avez saisi le nom de l'entreprise, hate_crack demande au même modèle local ce qu'il sait déjà sur cette organisation et pré-remplit les prompts **Industry**, **Location** et **Parent Company** avec les réponses, affichées entre parenthèses :   ```
   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:

Appuyez sur Entrée pour accepter une suggestion ou saisissez par-dessus. Ces valeurs sont la recollection du modèle, pas de l'OSINT — traitez-les comme un point de départ, et non comme du renseignement sur le client. La recherche utilise uniquement le serveur Ollama local, donc le nom du client ne quitte jamais l'hôte ; il n'y a aucun appel web ou à des API tierces. Si le modèle ne reconnaît pas l'organisation (le cas courant pour les petits clients), il ne renvoie rien et vous obtenez de simples invites vides : ``` Company name: Acme Rail Services Industry: Location: Parent company / acquired by:

Un échec de recherche — timeout, Ollama non démarré, réponse vide — ne bloque jamais l'attaque ; il revient simplement à des prompts vides. Définissez `ollamaAutoResearch` sur `false` pour ignorer complètement la recherche.
2. **Wordlist** — dériver des mots de base à partir d'un échantillon de wordlist.
3. **Mots de passe craqués** — renvoyer les textes en clair déjà récupérés durant cette session (`<hashfile>.out`) au modèle afin qu'il puisse inférer les conventions de mots de passe propres à l'organisation cible (mots de base, saisons, années, suffixes, leetspeak) et générer de *nouveaux* candidats dans le même style. Cette option n'est listée qu'une fois qu'au moins un hash a été craqué ; le fichier entier est analysé statistiquement exactement comme en mode Wordlist (voir `ollamaMaxSampleLines` ci-dessus).

#### Configuration PCFG

L'attaque PCFG (option 20) et l'attaque PRINCE-LING (option 21) utilisent le sous-module `pcfg_cracker`. Configurez-les dans `config.json` :```json
{
"pcfgRuleset": "DEFAULT",
"pcfgMaxCandidates": 50000000,
"pcfgPrinceLingMaxCandidates": 10000000
}
  • pcfgRuleset — Nom de la grammaire entraînée à utiliser (par défaut : DEFAULT), résolu vers pcfg_cracker/Rules/<name>/. Entraînez la vôtre avec trainer.py de pcfg_cracker et définissez ce paramètre sur le nom du jeu de règles.
  • pcfgMaxCandidates — Nombre maximal de candidats que pcfg_guesser.py émet pour l'attaque PCFG (par défaut : 50000000).
  • pcfgPrinceLingMaxCandidates — Nombre maximal de mots de base que prince_ling.py écrit dans la liste de mots de base PRINCE mise en cache (par défaut : 10000000).

Noyaux optimisés (optimizedKernelAttacks)

L'option -O de hashcat sélectionne des noyaux optimisés, qui sont nettement plus rapides mais limitent la longueur des candidats (environ 31 caractères, moins pour certains modes) et ignorent silencieusement tout ce qui est plus long. optimizedKernelAttacks dans config.json liste les attaques qui s'exécutent avec -O ; omettez une attaque de la liste pour l'exécuter avec des noyaux pleine longueur. La liste dans config.json.example correspond à la valeur par défaut intégrée qui s'applique lorsqu'aucun config.json n'existe.

Quatre attaques respectent le paramètre mais ne sont pas optimisées par défaut, car elles fournissent des candidats qui peuvent dépasser le plafond de -O — ajoutez-les à la liste pour les activer :

  • hcatNgramX, hcatOllama, hcatOmen, hcatLMtoNT

Pour désactiver -O partout pour une seule exécution sans modifier la configuration, passez --no-optimized-kernel (forme courte --no-optimize). Cela remplace la liste pour chaque attaque et supprime également un -O écrit dans hcatTuning, qui atteindrait sinon hashcat indépendamment de la liste.

Les noms sont mis en correspondance exactement, et une entrée non reconnue est signalée au démarrage plutôt qu'ignorée. Notez que les attaques qui délèguent à une autre attaque sont contrôlées par l'attaque à laquelle elles délèguent, et non par leur propre nom : PRINCE-LING suit hcatPrince, tandis que Spoonman, Rosetta et les modes de règles de motif LLM suivent hcatQuickDictionary.

Suivi de la couverture des attaques (coverage_enabled)

Au cours d'un long engagement, le même fichier de hachages est attaqué dans de nombreuses sessions avec un ensemble rotatif de listes de mots, de fichiers de règles et de listes de masques, et il est facile de brûler des heures à refaire un terrain déjà couvert — d'autant plus que la même ligne de règle existe dans plus d'un fichier de règles. hate_crack enregistre ce qu'il a déjà exécuté contre chaque fichier de hachages et propose d'ignorer le chevauchement.

La couverture est enregistrée par entrée, et non par fichier : les lignes de règles individuelles et les lignes .hcmask individuelles, chacune associée à la liste de mots contre laquelle elle a été exécutée. C'est ce qui lui permet de reconnaître qu'un fichier de règles personnalisé que vous exécutez aujourd'hui répète 40 des règles que best64.rule a déjà couvertes la semaine dernière, et c'est aussi pourquoi une règle n'est « couverte » que pour la liste de mots spécifique avec laquelle elle a été essayée — les mêmes règles sur un corpus différent essaient des candidats entièrement différents.

Le fichier de hachages est identifié par un sha256 de son contenu, de sorte que la couverture survit au renommage ou au déplacement entre les sessions. Les listes de mots sont identifiées de la même manière, avec le condensé mémorisé en fonction de la taille et de la mtime afin qu'un corpus de plusieurs gigaoctets soit haché une seule fois plutôt qu'à chaque attaque.

Vous n'êtes invité à le faire que lorsqu'il y a réellement quelque chose à ignorer :``` [*] 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]:

Répondez `Y` et hate_crack construit un fichier de règles temporaire contenant uniquement les entrées non essayées ; répondez `n` pour tout exécuter quand même. Si *chaque* entrée est un doublon, il vous est demandé si vous souhaitez ignorer complètement l'attaque, de sorte que réexécuter délibérément un terrain déjà couvert ne nécessite jamais de redémarrer l'outil.

Les attaques qui ne sont jamais filtrées sont tout de même enregistrées comme ayant été exécutées, ce qui vous permet de répondre à « ai-je déjà exécuté PRINCE contre cette cible ? ».

Une attaque qui sélectionne plusieurs fichiers de règles à la fois (Quick Crack, Loopback) pose la question d'ignorance **une seule fois pour tout le lot, au préalable**, avant toute invocation de hashcat. Cette question est délibérément peu coûteuse — elle ne lit ni ne hache aucun des fichiers de règles sélectionnés, car un lot YOLO peut atteindre des millions de lignes et vous ne devriez pas attendre cela pour répondre par oui ou non. Elle demande uniquement au store si cette attaque a déjà été exécutée contre ce fichier de hachage **avec l'une de ces wordlists** ; le diff par entrée se produit toujours paresseusement, un fichier de règles à la fois, et décide de ce qui est réellement ignoré. Ainsi, un corpus frais n'est jamais signalé, même lorsque les règles qu'il contient ont toutes été exécutées contre un autre.

Trois limites délibérées :

- **La couverture n'est enregistrée que lorsque hashcat épuise l'espace de clés** (sortie 1). Un ctrl-C ou une erreur n'enregistre rien, et la sortie 0 non plus — cela signifie que tous les hachages ont été cassés, ce que hashcat rapporte *sans* terminer l'espace de clés, et dans le cas dégénéré « tous les hachages trouvés comme entrées potfile » sans essayer un seul candidat. La sous-enregistrement ne coûte qu'une exécution redondante plus tard.
- **Les générateurs de candidats dynamiques ne sont jamais filtrés.** PRINCE, PCFG, OMEN, la force brute Markov et les modes LLM n'ont pas d'ensemble fixe à différencier, ils sont donc journalisés comme ayant été exécutés et autrement laissés tranquilles. Les fichiers de règles chaînés (`-r a -r b`) sont suivis comme une seule unité plutôt que par entrée, car hashcat applique le *produit cartésien* des deux fichiers et supprimer une ligne individuelle retirerait silencieusement chaque combinaison à laquelle elle a participé.
- **Les exécutions `--loopback` sont enregistrées mais jamais filtrées.** hashcat réinjecte les textes en clair fraîchement cassés comme candidats *supplémentaires*, de sorte qu'une telle exécution essaie la wordlist et l'ensemble de règles complets plus tout ce que ces textes en clair recyclés atteignent. Cela rend les deux directions asymétriques : l'enregistrer est judicieux, de sorte qu'une exécution ordinaire ultérieure de la même wordlist et des mêmes règles est correctement reconnue comme un doublon, mais une seconde exécution loopback a plus de cassages à recycler et n'est jamais ignorée.

Définissez `coverage_enabled` sur `false` dans `config.json` pour désactiver cela, ou passez `--no-coverage` pour une seule exécution — ce qui ne consulte ni ne met à jour le store.

#### Inspection et réinitialisation de la couverture

L'option du menu principal **85 — Attack Coverage** montre ce qui a été exécuté contre le fichier de hachage chargé, son historique d'exécution, et peut l'effacer. Les trois mêmes actions sont scriptables :```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

Le fichier de hachage est identifié par son contenu, donc cela fonctionne quel que soit l'endroit où il a été déplacé depuis. forget n'affecte que cette cible — le stockage se trouve dans ~/.hate_crack/coverage/attack_coverage.sqlite3, et supprimer le fichier réinitialise la couverture pour toutes les cibles.

Exécutions scriptées

Une attaque scriptée que la couverture ignore entièrement se termine toujours par 0 par défaut, donc activer la couverture ne peut pas faire échouer un harnais existant. Passez --exit-code-on-skip pour obtenir le code de sortie 3 à la place lorsque rien n'a été lancé :```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 signifie que *rien* n'a été exécuté. Une passe partiellement filtrée — certaines entrées ignorées, d'autres tentées — se termine quand même par `0`, car l'attaque a bien effectué du travail.

### Prise en charge du brain hashcat (`brain_enabled`)

hashcat lui-même embarque un « brain » — un petit serveur vers lequel une instance hashcat en cours transmet les mots de passe candidats, afin qu'une seconde exécution contre la même cible puisse ignorer les candidats déjà essayés par la première. hate_crack l'active automatiquement, sans étape de menu requise : chaque fois qu'il s'apprête à lancer une attaque contre un mode de hash que hashcat signale comme lent (bcrypt, scrypt et autres modes reposant sur un KDF, où le hash lui-même est le goulot d'étranglement plutôt que la génération de candidats), il démarre ou réutilise un serveur brain local et ajoute les flags `--brain-*` à l'invocation hashcat pour vous. Un mode rapide est laissé de côté, sauf si son numéro de mode figure dans `brain_modes_force`, et un mode listé dans `brain_modes_exclude` n'active jamais le brain quel que soit le verdict de hashcat — l'exclusion l'emporte toujours.

**Le brain n'est pas la même chose que la couverture d'attaque, et les deux sont complémentaires plutôt que redondants.** La couverture (ci-dessus) déduplique au niveau des règles entières, des lignes de masque et des wordlists — elle décide quoi lancer au départ, avant même que hashcat ne s'exécute. Le brain déduplique au niveau des mots de passe candidats individuels, et il le fait via un serveur persistant qui survit à toute invocation hashcat, ce qui lui permet de détecter les chevauchements que la couverture ne peut pas voir : un candidat atteignable via deux règles différentes ou deux wordlists différentes au sein d'une même exécution, et — comme le démontre l'aller-retour dans `tests/e2e/test_brain_e2e.py` — les mêmes candidats renvoyés lors d'une seconde exécution hashcat distincte contre la même cible. Les deux peuvent être activés simultanément sans conflit.

Sept clés dans `config.json` le contrôlent, toutes sous le préfixe `brain_*` : `brain_enabled` (interrupteur principal, activé par défaut), `brain_host` (vide signifie que hate_crack gère un serveur local sur loopback ; une valeur signifie se connecter uniquement à cet hôte — hate_crack ne lance jamais un serveur qu'on ne lui a pas demandé de gérer), `brain_port` (par défaut `6863`), `brain_client_features` (`1` mots de passe hachés, `2` positions d'attaque, `3` les deux — `3` déduplique le plus mais coûte au serveur environ 12 octets de RAM par candidat vu), `brain_server_timer` (le propre réglage de hashcat pour la fréquence à laquelle le serveur écrit son dump `.ldmp`/`.admp` sur disque, minimum 60 secondes, par défaut `300`), et `brain_modes_force` / `brain_modes_exclude` (numéros de mode de hash séparés par des virgules qui remplacent le verdict lent/rapide de hashcat, l'exclusion étant prioritaire).

**Le serveur auto-lancé n'a aucun délai d'inactivité.** `brain_server_timer` ne contrôle pas combien de temps il reste actif — rien ne le fait ; il tourne pendant toute la durée de vie du processus qui l'a lancé (ou jusqu'à ce que `shutdown()`/`atexit` l'arrête) et est réutilisé pour chaque attaque de la session. À la valeur par défaut de `300`, cela signifie une écriture de dump dans `~/.hate_crack/brain/` toutes les cinq minutes tant que hate_crack est en cours d'exécution.

Une huitième clé, `BRAIN_PASSWORD`, réside dans `.env` plutôt que dans `config.json` parce qu'il s'agit d'un secret partagé, et non parce que le brain est une intégration tierce — elle n'est utilisée que lors de la connexion à un serveur brain distant que vous exécutez déjà ; le serveur local auto-lancé génère son propre mot de passe aléatoire par session et ne nécessite aucune configuration.

**Le mot de passe du brain est visible par `ps` pendant toute la durée de l'exécution hashcat,** car hashcat ne l'accepte que comme argument en ligne de commande — il n'existe pas de forme via variable d'environnement. Pour le serveur local auto-lancé, la fenêtre est réduite : le mot de passe est aléatoire et limité à cette seule session, donc un autre utilisateur local ne peut le voir que pendant qu'une attaque est réellement en cours, et il est inutile une fois la session terminée. Le mot de passe d'un serveur brain distant partagé n'a pas cette atténuation — c'est la même valeur à chaque invocation, visible par tout autre utilisateur local de la machine tant qu'une exécution hate_crack contre ce serveur est en cours. Traitez-le en conséquence sur du matériel partagé ou multi-locataire.

Passez `--no-brain` pour désactiver le brain pour une seule exécution quel que soit `brain_enabled`, ou mettez `brain_enabled` à `false` dans `config.json` pour le désactiver partout.

**Le brain conserve son état dans `~/.hate_crack/brain/`** — un petit cache `slow_modes.json` du verdict lent/rapide de hashcat par version de hashcat, plus, pour le serveur auto-lancé, ses fichiers de dump `.ldmp`/`.admp`. Ces dumps sont des données dérivées de candidats : ils permettent à un serveur frais de reprendre en sachant ce qui a déjà été essayé contre une cible, ce qui, lors d'une mission, signifie que des données dérivées du client s'accumulent dans le répertoire personnel de l'opérateur tant que le brain y a tourné. Comme pour le stockage de couverture ci-dessus, supprimer le répertoire réinitialise le brain — un candidat précédemment rejeté cesse d'être mémorisé, au prix de la perte de la déduplication que ce dump représentait. Si le brain semble ignorer du travail qu'il ne devrait pas (un dump obsolète d'une exécution précédente à périmètre différent), c'est la solution.

**Supprimer `~/.hate_crack/brain/` ne supprime pas un serveur orphelin.** Le serveur auto-lancé s'exécute dans sa propre session (`start_new_session=True`) afin de survivre à la fermeture d'un terminal ou à un SIGHUP — seul un kill explicite, ou la sortie propre du processus qui l'a lancé avec l'exécution de son gestionnaire `atexit`, l'arrête. Un orphelin continue d'occuper le port loopback. Avec la valeur par défaut vide de `BRAIN_PASSWORD`, vous le remarquerez sous la forme `"[!] ... no brain server could be reached; running without candidate de-duplication"` à chaque attaque en mode lent : le mot de passe de l'orphelin était éphémère et est mort avec le processus qui l'a généré, donc hate_crack refuse d'adopter le port qu'il occupe plutôt que de deviner un mot de passe qui ne peut pas être vérifié. Trouvez-le et arrêtez-le avec :```bash
pgrep -f 'hashcat --brain-server'
kill <pid>

après quoi l'attaque suivante lance un nouveau serveur comme d'habitude.

Notifications (option de menu 82)

hate_crack peut envoyer des notifications push Pushover lorsque les attaques se terminent et, en option, lorsque des hashes individuels sont cassés. Tous les contrôles se trouvent sous l'option 82 — Notifications du menu principal :

  1. Toggle Pushover Notifications [ON/OFF] — interrupteur principal. Persisté dans config.json sous notify_enabled.
  2. Toggle Per-Crack Notifications [ON/OFF] — lorsqu'activé, un tailer en arrière-plan surveille le fichier .out et envoie une notification par crack (avec agrégation des rafales par tick). Persisté dans config.json sous notify_per_crack_enabled. Ne peut pas être activé tant que l'interrupteur principal est désactivé — activez d'abord l'option 1.
  3. Send Test Pushover Notification — envoie une notification prédéfinie pour vous permettre de confirmer que votre paire token/utilisateur Pushover fonctionne. Fonctionne même lorsque l'interrupteur principal est désactivé.

Les identifiants se trouvent dans .env ; les autres paramètres de réglage sont uniquement dans le fichier de configuration config.json :

  • NOTIFY_PUSHOVER_TOKEN, NOTIFY_PUSHOVER_USER (dans .env) — requis pour qu'une notification soit envoyée. Rien dans le menu ne les écrit ; modifiez .env vous-même.
  • notify_attack_allowlist — noms d'attaques qui donnent leur consentement automatiquement sans l'invite [y/N/always]. Rempli automatiquement lorsque vous répondez always.
  • notify_suppress_in_orchestrators (par défaut true) — réduit au silence les attaques individuelles enchaînées par Extensive Crack, qui envoie à la place un seul résumé. Mettez à false pour recevoir une notification par attaque enchaînée. Les autres entrées de menu qui exécutent plusieurs passes (par exemple Quick Crack avec plusieurs chaînes de règles) ne sont pas des orchestrateurs et notifient toujours par passe.
  • notify_max_cracks_per_burst (par défaut 5), notify_poll_interval_seconds (par défaut 5.0) — réglage du tailer par crack. Voir hate_crack/notify/tailer.py pour la logique d'agrégation des rafales.

Wordlist Tools (option de menu 80)

Le sous-menu Wordlist Tools fournit des utilitaires de prétraitement de wordlists reposant sur les binaires hashcat-utils, ainsi que des téléchargements de wordlists depuis Hashmob.net et Weakpass. Accessible via l'option 80 du menu principal.

OptionBinaireCe qu'il fait
1len.binFiltrer par longueur - ne conserver que les mots entre une longueur min et max
2req-include.binExiger des classes de caractères - ne conserver que les mots contenant tous les types de caractères requis
3req-exclude.binExclure des classes de caractères - supprimer les mots contenant un type de caractère exclu
4cutb.binExtraire une sous-chaîne - découper une plage d'octets de chaque mot
5splitlen.binSéparer par longueur - créer des fichiers distincts par longueur de mot (fichiers nommés 01-64 dans un répertoire de sortie)
6rli.bin / rli2.binSoustraire des mots - supprimer les entrées qui apparaissent dans un ou plusieurs autres fichiers
7gate.binSharding - extraire un mot sur N pour répartir le cracking sur plusieurs machines
8-Optimiser les wordlists - dédupliquer et séparer en fichiers par longueur dans le répertoire des wordlists optimisées
9-Télécharger des wordlists depuis Hashmob.net
10-Télécharger des wordlists depuis Weakpass (via BitTorrent)

Bits de masque de classe de caractères (utilisés par les options 2 et 3) : 1=minuscule, 2=majuscule, 4=chiffre, 8=symbole, 16=autre. Additionnez les valeurs : 7 = minuscule+majuscule+chiffre.

Comment le sharding est censé être utilisé : le sharding divise une wordlist en N parties égales et non chevauchantes afin que le travail puisse être réparti sur plusieurs machines ou GPU. Chaque partie est entrelacée (un mot sur N), de sorte que chaque shard est un échantillon représentatif de la liste entière plutôt qu'un bloc contigu début/fin — aucun nœud n'est bloqué à ne casser que la queue à faible probabilité.

Exécutez l'option 7 une fois, fournissez-lui une wordlist d'entrée, un chemin de base de sortie et un nombre de shards (N). Elle écrit les N parties en une seule passe, nommées avec des numéros de partie complétés par des zéros (base.001, base.002, … jusqu'à base.00N). Copiez une partie sur chaque nœud et pointez l'exécution hashcat de ce nœud dessus. Sur un système mono-GPU, le sharding n'apporte aucun gain de vitesse, mais une seule partie reste un échantillon rapide et représentatif pour une passe de triage rapide avant de s'engager sur la liste complète.

Vérifications automatiques de mise à jour

hate_crack peut vérifier automatiquement sur GitHub la présence de versions plus récentes au démarrage. Cette fonctionnalité est contrôlée par l'option de configuration check_for_updates :```json { "check_for_updates": true }

- **`check_for_updates`** — Active la vérification automatique de version au démarrage (par défaut : `true`).
- Lorsqu'elle est activée, hate_crack récupère les informations de la dernière release depuis GitHub et affiche une notification si une mise à jour est disponible.
- La vérification s'exécute de manière asynchrone et ne bloque pas le démarrage. Les erreurs réseau sont ignorées silencieusement.

##### Canaux de mise à jour

| Canal | Option | Source | Ce que vous obtenez |
|---------|------|--------|--------------|
| Release | `--update` | `main` | La dernière release publiée. C'est le comportement par défaut et ce que propose la vérification au démarrage. |
| Nightly | `--nightly` | `nightly-dev` | Le travail qui a passé la CI mais qui n'a pas encore été publié. |

Les versions suivent le semver ordinaire, avec l'incrément dérivé de ce qui se trouve réellement dans
le lot. Le deuxième composant n'évolue **que pour les fonctionnalités** : un cycle contenant
un commit `feat` se dirige vers `X.(Y+1).0`, et un cycle composé uniquement de correctifs,
de documentation et de tâches se dirige vers `X.Y.(Z+1)`.

`nightly-dev` étiquette des release candidates pour la version vers laquelle le lot se dirige
— `v2.20.1rc1`, `v2.20.1rc2`, … — et la fusion vers `main` promeut cette
même cible en version finale. Les candidates sont de véritables pré-versions PEP 440, elles
s'ordonnent donc correctement aux deux extrémités :

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

La cible peut changer en cours de cycle : le premier `feat` à être intégré la fait passer de
`X.Y.(Z+1)` à `X.(Y+1).0`, et la numérotation des candidates redémarre pour la nouvelle cible.
Le numéro nomme toujours ce que le lot publierait aujourd'hui.

Le composant majeur n'est jamais incrémenté automatiquement — un sujet avec `!` ou un
pied de page `BREAKING CHANGE:` compte comme une fonctionnalité, car un majeur automatique est à une
ligne de sujet mal saisie d'une release publiée irréversible. Un majeur est un
acte humain explicite : étiquetez et poussez-le à la main.

La politique réside dans `tools/next_version.py`, partagée par les deux workflows d'étiquetage et
testée unitairement dans `tests/test_next_version.py`.

La vérification au démarrage ne propose jamais que des releases, car les builds nightly ne publient aucune
release GitHub et la vérification lit le point de terminaison « latest release » de GitHub — donc
activer `check_for_updates` ne vous amènera jamais sur une nightly. Deux choses maintiennent
les canaux séparés désormais : cela, et le fait qu'une candidate est une véritable pré-version PEP 440,
donc un outil classant les numéros de version bruts la traite également comme plus ancienne que
la release qu'elle deviendra.

Chaque option bascule d'abord votre copie de travail vers la branche correspondante (et
refuse de le faire si vous avez des modifications non validées). Si vous exécutez une nightly
et souhaitez revenir au code publié, `--update` vous ramène sur `main`.

#### Fusion automatique des hashes trouvés (téléchargement des restants uniquement)

Lors du téléchargement des hashes restants (hashes non cassés), hate_crack effectue automatiquement :
1. Tente de télécharger tout hash trouvé (cassé) depuis Hashview en tant qu'opération auxiliaire
2. Fusionne les hashes trouvés avec les fichiers `.out` locaux (par exemple, `left_1_123.txt.out` ou `left_1_123.nt.txt.out` pour le format pwdump)
3. Supprime les entrées en double
4. Nettoie les fichiers fractionnés temporaires après la fusion

Cela garantit que vos résultats de cassage locaux restent synchronisés avec la base de données centralisée de Hashview lorsque vous travaillez avec des hashes non cassés.

**Remarque :** L'option de téléchargement des hashes trouvés télécharge séparément les hashes déjà cassés à des fins de référence et n'effectue aucune fusion ni invite de cassage.

Le <hash_type> est obtenu en exécutant `hashcat --help`

Exemples de 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

| -s | --server | SERVER | http://localhost:8080 | URL du serveur cible | | -t | --token | TOKEN | | Jeton d'authentification | | -o | --output | FILE | stdout | Fichier de sortie | | -v | --verbose | | | Activer la sortie détaillée | | -q | --quiet | | | Supprimer toute la sortie | | -f | --format | FORMAT | json | Format de sortie (json, yaml, csv) | | -c | --config | FILE | ~/.config/tool/config.yaml | Chemin du fichier de configuration | | -d | --debug | | | Activer le mode débogage | | -h | --help | | | Afficher le message d'aide | | -V | --version | | | Afficher la version |

Exemples

# Exécution de base
tool --server http://localhost:8080 --token abc123

# Avec fichier de sortie
tool -s http://localhost:8080 -t abc123 -o results.json

# Mode détaillé
tool -v -s http://localhost:8080

# Format de sortie personnalisé
tool -f yaml -o results.yaml

Configuration

Le fichier de configuration est recherché dans les emplacements suivants :

  1. --config chemin spécifié sur la ligne de commande
  2. ./config.yaml répertoire courant
  3. ~/.config/tool/config.yaml répertoire personnel de l'utilisateur
  4. /etc/tool/config.yaml configuration système

Exemple de fichier de configuration :

server: http://localhost:8080
token: your-token-here
output: results.json
format: json
verbose: false

Variables d'environnement

VariableDescription
TOOL_SERVERURL du serveur cible
TOOL_TOKENJeton d'authentification
TOOL_OUTPUTFichier de sortie
TOOL_FORMATFormat de sortie
TOOL_DEBUGActiver le mode débogage

Codes de sortie

CodeDescription
0Succès
1Erreur générale
2Mauvaise utilisation de la ligne de commande
3Erreur de configuration
4Erreur d'authentification
5Erreur réseau

Dépannage

Le serveur ne répond pas

Vérifiez que le serveur est en cours d'exécution et que l'URL est correcte :

curl -v http://localhost:8080/health

Échec de l'authentification

Vérifiez que votre jeton est valide et qu'il dispose des autorisations nécessaires :

tool --token YOUR_TOKEN --server http://localhost:8080

Permission refusée

Assurez-vous de disposer des permissions d'écriture pour le fichier de sortie :

chmod +w results.json

Contribution

  1. Forkez le dépôt
  2. Créez une branche de fonctionnalité (git checkout -b feature/amazing-feature)
  3. Validez vos modifications (git commit -m 'Add amazing feature')
  4. Poussez vers la branche (git push origin feature/amazing-feature)
  5. Ouvrez une Pull Request

Licence

Ce projet est sous licence MIT - voir le fichier LICENSE pour plus de détails.

Remerciements

  • Merci à tous les contributeurs

  • Inspiration issue de projets similaires

  • Communauté open source``` $ ./hate_crack.py 1000


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

-------------------------------------------------------------------
## Tests

La suite de tests est principalement hors ligne et utilise des mocks/fixtures. Les vérifications réseau en direct et les vérifications des dépendances système sont optionnelles via des variables d'environnement.

### Exécution des tests en local```bash
# Run all tests
uv run pytest -v

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

Vous pouvez également exécuter la suite complète avec make test.

Tests en direct (opt-in)

Définissez l'une des variables suivantes pour activer les vérifications en direct :

  • HASHMOB_TEST_REAL=1 — vérification de la connectivité et du menu CLI Hashmob en direct
  • HASHVIEW_TEST_REAL=1 — vérification du menu CLI Hashview en direct
  • WEAKPASS_TEST_REAL=1 — vérification du menu CLI Weakpass en direct
  • HATE_CRACK_REQUIRE_DEPS=1 — échoue si 7z, transmission-daemon ou transmission-remote est manquant

Test d'envoi Hashview en direct

Le test d'envoi Hashview en direct est ignoré par défaut. Pour l'exécuter, définissez la variable d'environnement et fournissez des identifiants valides dans .env :```bash HATE_CRACK_RUN_LIVE_TESTS=1 uv run pytest tests/test_upload_cracked_hashes.py -v

### Tests Live Hashview contre une pile Docker locale

Au lieu de pointer les tests live vers un serveur Hashview distant, vous pouvez faire en sorte que la suite lance une pile Docker [Hashview](https://github.com/hashview/hashview) locale, l'initialise, exécute les tests live contre elle, puis la démonte. Définissez `HASHVIEW_TEST_LOCAL=1` et pointez `HASHVIEW_REPO` vers un checkout 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

Cela lance docker compose dans le dépôt Hashview, initialise une clé API admin, un client, un fichier de hash et des données de « tâche effective » craquées, puis exporte les variables d'environnement HASHVIEW_* que les tests lisent. Variables d'environnement utiles :

  • HASHVIEW_TEST_LOCAL=1 — active la pile locale (sans effet sinon)
  • HASHVIEW_REPO=<path> — copie de travail Hashview (par défaut ~/projects/hashview)
  • HASHVIEW_KEEP=1 — laisse les conteneurs en cours d'exécution après la session (ré-exécutions plus rapides)
  • HASHVIEW_LOCAL_PORT=5000 — port hôte sur lequel l'application est publiée

La CLI hate_crack respecte les variables d'environnement HASHVIEW_URL / HASHVIEW_API_KEY (écrasant le .env dans lequel ces deux clés résident), ce qui permet à la suite de pointer la CLI vers la pile locale sans modifier votre configuration persistée.

Tests d'installation de bout en bout (local + Docker)

Installation locale de l'outil uv + exécution du script (utilise un HOME temporaire) :```bash HATE_CRACK_RUN_E2E=1 uv run pytest tests/test_e2e_local_install.py -v

Installation/exécution de bout en bout basée sur Docker (mise en cache via `Dockerfile.test`) :```bash
HATE_CRACK_RUN_DOCKER_TESTS=1 uv run pytest tests/test_docker_script_install.py -v

Le test E2E Docker télécharge également un petit sous-ensemble de rockyou et exécute un crack hashcat basique pour valider l'intégration d'outils externes.

Test de bout en bout de la VM Lima (macOS uniquement) :

Prérequis : Lima et rsync doivent être installés.```bash brew install lima

La VM de test s'approvisionne automatiquement avec toutes les dépendances 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

Ce test valide l'installation et l'exécution dans une VM Linux légère sur macOS.

Structure des tests

  • tests/test_hashview.py : Suite de tests complète pour la classe HashviewAPI avec des réponses API simulées, incluant :
    • Listage des clients et validation des données
    • Tests d'authentification et d'autorisation
    • Fonctionnalité de téléversement de fichiers de hash
    • Flux complet de création de tâche

Tous les tests utilisent des appels API simulés, ils peuvent donc s'exécuter sans connectivité à un serveur Hashview.


(1) Crack rapide (2) Crack extensif selon la méthodologie Pure_Hate (3) Attaque par force brute (4) Attaque par masque principal (5) Attaque par empreinte (6) Attaques par combinaison (7) Attaque hybride (8) Crack par force brute avec masque Pathwell Top 100 (9) Attaque PRINCE (10) Méthodologie Bandrel (11) Attaque en boucle (12) Attaque LLM (13) Attaque OMEN (14) Attaque par masque ad hoc (15) Attaque par force brute Markov (16) Attaque par N-grammes (17) Attaque par permutation (18) Attaque par règles aléatoires (19) Attaque par phrase secrète Combipow (20) Attaque PCFG (21) Attaque PRINCE-LING (22) Attaque Spoonman (23) Attaque Rosetta (24) Force brute par masques d'entreprise (25) Attaque par masque intelligent

(80) Outils de listes de mots (81) Outils de fichiers de règles (82) Notifications (83) Outils de masques

(93) Régénérer le .out à partir du fichier POT (94) API Hashview (95) Analyser les hashs avec Pipal (96) Exporter la sortie au format Excel (97) Afficher les hashs craqués (98) Afficher le README (99) Quitter

Sélectionnez une tâche :```

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.

Quelle(s) règle(s) souhaitez-vous exécuter ?
(1) best64.rule
(2) d3ad0ne.rule
(3) T0XlC.rule
(4) dive.rule
(99) YOLO...exécuter toutes les règles
Entrez une liste de règles séparées par des virgules que vous souhaitez exécuter. Pour exécuter des règles enchaînées, utilisez le symbole +.
Par exemple, 1+1 exécutera best64.rule enchaînée deux fois et 1,2 exécutera best64.rule puis d3ad0ne.rule séquentiellement.
Choisissez judicieusement :```




#### 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).

Catégories