Volver a actualizaciones
Nuevo releaseSep 4, 2026

hate_crack v2.36.1

Una herramienta para automatizar metodologías de cracking mediante Hashcat, del equipo de TrustedSec.

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

Instalación

Instalar desde el código fuente es la única vía soportada. hate_crack no se distribuye en PyPI: pip install hate-crack resuelve a un placeholder 0.0.0 que falla a propósito y apunta de vuelta aquí. El nombre se reserva únicamente para que nadie más pueda publicar un clon bajo él — consulta packaging/pypi-placeholder/.

1. Instalar hashcat

Hashcat debe estar instalado y disponible en tu PATH:

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

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

O descargue un binario precompilado desde https://hashcat.net/hashcat/ y configure hcatPath en config.json con su ubicación.

2. Descargar hate_crack

Clone con submódulos (requerido para hashcat-utils, princeprocessor, pcfg_cracker, Corporate_Masks y, opcionalmente, omen):```bash git clone --recurse-submodules https://github.com/trustedsec/hate_crack.git cd hate_crack

Si clonaste sin submódulos, inicialízalos:```bash
git submodule update --init --recursive

Luego personaliza la configuración si es necesario. hate_crack utiliza dos archivos de configuración, cada uno con un conjunto distinto de ajustes:

  • config.json — rutas de wordlists, máscaras, reglas, ajuste fino, potfile, ruta de hashcat, límites de candidatos, alternadores de notificación, valores predeterminados de preferencia de CLI (35 ajustes).
  • .env — solo ajustes de integración con terceros: credenciales de Hashview y Hashmob, credenciales de Pushover, Ollama y pipal (14 ajustes). No rastreado por git, creado con modo 0600.

La línea divisoria está ahí por una razón: .env es el archivo que puede contener secretos. Las credenciales y la configuración de servicios de terceros van en el archivo no rastreado con modo 0600; todo lo que hate_crack hace localmente permanece en config.json, que es seguro para compartir, comparar y guardar en tus propias notas. Esa es también la razón por la que las credenciales de Pushover están en .env mientras que los alternadores de activación/desactivación de Pushover están en config.json — los alternadores son preferencias locales, no secretos.

Cada clave tiene exactamente un hogar. Una clave colocada en el otro archivo se ignora, y hate_crack imprime una advertencia nombrando el archivo al que pertenece. Cualquier clave aún puede sobrescribirse para una sola ejecución exportando su variable de entorno. La mayoría de los usuarios pueden omitir este paso, ya que las rutas predeterminadas funcionan sin configuración adicional.

config.json es permanente y de primera clase — no está obsoleto y no hay un plazo de eliminación para él. Solo se movieron los ajustes de integración.

¿Actualizando desde un único config.json? hate_crack lo migra por ti en la primera ejecución: los ajustes de integración se copian a un nuevo .env con modo 0600, luego se eliminan de config.json para que ambos archivos no los reclamen. Imprime qué claves se movieron (nunca sus valores) y guarda tu original como config.json.pre-split.bak antes de tocarlo. Todo lo demás en config.json se deja exactamente como estaba, incluido el orden de las claves.

Primera ejecución: hate_crack crea ambos archivos por ti, así que no hay nada que hacer. Para configurar .env manualmente en su lugar, copia la plantilla rastreada:```bash cp .env.example .env chmod 600 .env

`.env.example` está comprometido y se distribuye con cada clave de credencial vacía. El propio `.env` **nunca** debe comprometerse — está en gitignore, junto con sus variantes habituales de respaldo, y hate_crack siempre lo crea con modo `0600` (solo lectura/escritura del propietario). `.env.example` se genera a partir del esquema; regenéralo después de cambiar `hate_crack/config_schema.py` con `uv run python -m hate_crack.config_writer`.

### 3. Instalar dependencias y hate_crack

La forma más sencilla es ejecutar `make` (o `make install`), que detecta automáticamente tu SO e instala:
- Dependencias externas (p7zip, transmission-daemon / transmission-remote)
- Compila submódulos (hashcat-utils, princeprocessor, pcfg_cracker y, opcionalmente, omen) y extrae el conjunto de máscaras Corporate_Masks de solo datos
- Dependencias de Python mediante uv y un shim de CLI en `~/.local/bin/hate_crack````bash
make

Esto es idempotente: omite las herramientas ya instaladas. Para forzar una reinstalación limpia:```bash make reinstall

**O instalar dependencias manualmente:**

### Dependencias externas
Estas son necesarias para ciertos flujos de descarga/extracción:

- `7z`/`7za` (p7zip) — se utiliza para extraer archivos `.7z`.
- `transmission-daemon` / `transmission-remote` — se utiliza para descargar torrents de Weakpass.

Comandos de instalación manual:

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

Luego instala las dependencias de Python y el shim de 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

Estructura del proyecto

La lógica principal ahora está dividida en módulos bajo hate_crack/:

  • hate_crack/cli.py: ayudantes de argparse y anulaciones de configuración.
  • hate_crack/api.py: integraciones con Hashview, Weakpass y Hashmob (descargas/menús/ayudantes).
  • hate_crack/attacks.py: manejadores de ataques del menú.
  • hate_crack/corpus_stats.py: estadísticas de contraseñas de todo el corpus utilizadas para describir un corpus al LLM.
  • hate_crack/plaintext.py: recupera la contraseña de una línea del corpus (eliminación del prefijo de hash, decodificación de $HEX[...]); compartido por los modos LLM, corpus_stats y rulegen.
  • hate_crack/llm.py: generación estructurada (JSON) de candidatos LLM mediante Atomic Agents.
  • hate_crack/menu.py: renderizador de menú compartido, incluida la navegación opcional con teclas de flecha.
  • hate_crack/noninteractive.py: despachador para los subcomandos de ataque programados.
  • hate_crack/notify/: paquete de notificaciones (backend Pushover, tailer por crack).
  • hate_crack/username_detect.py: detecta archivos de entrada username:hash para decidir sobre --username de hashcat.
  • hate_crack/formatting.py, hate_crack/progress.py: ayudantes de formato de salida y visualización de progreso.
  • hate_crack/main.py: implementación principal de la CLI.

El hate_crack.py de nivel superior sigue siendo el punto de entrada principal y orquesta estos módulos.


Referencias y agradecimientos

Este proyecto depende de y está inspirado en una serie de proyectos y servicios externos. Gracias a:


Uso

Después de instalar con make, ejecuta hate_crack desde cualquier lugar:```bash hate_crack

or with arguments:

hate_crack <hash_file> <hash_type> [options]

Alternativamente, ejecútalo mediante `uv`:```bash
uv run hate_crack.py <hash_file> <hash_type>

Ejecutar como herramienta (recomendado)

Instalar usando make desde la raíz del repositorio - esto compila los submódulos y empaqueta los recursos:```bash cd /path/to/hate_crack make hate_crack

El comando `make install` crea un shim de bash en `~/.local/bin/hate_crack` que se ejecuta desde el directorio del repositorio, por lo que la configuración y los recursos siempre se encuentran independientemente de tu directorio de trabajo actual.

La configuración también se busca en:
- La raíz del repositorio y el directorio del paquete
- `~/.hate_crack`

**Nota:** El `hcatPath` en `config.json` es solo para la ubicación del binario de hashcat (opcional si hashcat está en el PATH). Los recursos de Hate_crack (hashcat-utils, princeprocessor, pcfg_cracker, Corporate_Masks, omen) se cargan desde el directorio del repositorio y se incluyen automáticamente mediante `make install`.

### Ejecutar como script
El script usa un shebang de `uv`. Hazlo ejecutable y ejecuta:```bash
chmod +x hate_crack.py
./hate_crack.py

También puedes usar Python directamente:```bash python hate_crack.py

### Uso no interactivo / con scripts

Para la automatización, puedes lanzar un único ataque directamente, omitiendo el menú. El nombre del ataque es el primer argumento, seguido del archivo de hashes y el tipo de hash de hashcat. Los avisos de preprocesamiento (filtrado de cuentas de equipo, fuerza bruta con LM primero, deduplicación de cuentas duplicadas) aceptan automáticamente sus valores predeterminados en este modo. El proceso sale con `0` en caso de éxito y con un valor distinto de cero en caso de error (archivo de hashes faltante, tipo de hash no numérico, lista de palabras faltante o un nombre de archivo de reglas desconocido).```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

Solución de problemas

Error: "would clobber existing tag" al actualizar

Un clon antiguo puede negarse a actualizarse, imprimiendo una larga lista de líneas como:``` ! [rejected] v2.5.0 -> v2.5.0 (would clobber existing tag)

Esto afecta a los clones creados antes de julio de 2026. El historial publicado se reescribió
entonces para eliminar algunos archivos que nunca debieron haberse confirmado, lo que dio
a cada commit un nuevo ID; por lo tanto, las etiquetas de un clon más antiguo apuntan a objetos que este
repositorio ya no contiene, y git se niega a mover una etiqueta que ya tiene.
No hay nada malo con tu copia de trabajo y ningún dato de cracking está en riesgo.

Recupera con un restablecimiento único. Esto descarta los commits y ediciones locales en la
copia de trabajo, así que si has personalizado algo rastreado por git (a diferencia de
`config.json`, que no está rastreado), confírmalo a una rama primero:```bash
cd /path/to/hate_crack
git fetch --tags --force origin
git checkout -B main origin/main
make install

--force aquí solo actualiza las etiquetas; no puede tocar tus commits. Después, el actualizador integrado funciona con normalidad. Las versiones anteriores a la 2.18 no podían realizar esta recuperación por sí mismas, por lo que debe hacerse manualmente una vez.

Error: El directorio de compilación no existe

Si ves un error como:``` Error: Build directory /opt/hashcat/hashcat-utils does not exist. Expected to find expander at /opt/hashcat/hashcat-utils/bin/expander.

Esto significa que los recursos de hate_crack no se incluyeron en el paquete instalado.

**Entendiendo las rutas:**
- `hcatPath` en config.json → apunta a la **ubicación del binario de hashcat** (opcional, puede estar en PATH)
- `hashcat-utils/` y `princeprocessor/` → incluidos en el paquete por `make install`

**Solución:**
Reinstalar usando el Makefile, que compila los submódulos e instala la herramienta:```bash
cd /path/to/hate_crack  # the repository checkout
make install

Configuración predeterminada (config.json.example):

La mayoría de los usuarios pueden usar los valores predeterminados sin personalización:

  • hcatWordlists: ./wordlists (relativo a la raíz del repositorio o HOME/.hate_crack)
  • hcatOptimizedWordlists: ./optimized_wordlists (directorio usado por Quick Crack; recurre a hcatWordlists si no se encuentra)
  • rules_directory: ./hashcat/rules (incluye reglas del submódulo)
  • hcatTuning: `` (cadena vacía - sin flags de tuning predeterminados)

Ejemplos de personalizaciones 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) ... }

**Carga de configuración:**
- Precedencia para cada clave: `os.environ` > el propio archivo de inicio de esa clave (`.env` o `config.json`) > valor predeterminado integrado
- Las claves faltantes recurren a los valores predeterminados integrados; `config.json.example` documenta cada clave de `config.json`
- Ambos archivos se buscan, de forma independiente entre sí, en este orden: **raíz del repositorio**, luego el **directorio del paquete instalado**, luego **`~/.hate_crack`**. Gana la primera coincidencia; es normal que los dos archivos provengan de directorios diferentes.
- En la primera ejecución, se crean ambos: `config.json` a partir de `config.json.example`, `.env` a partir de los valores predeterminados integrados. Si un `config.json` más antiguo todavía contiene claves de integración, se copian al nuevo `.env` y hate_crack te indica cuáles eliminar de `config.json`; nunca edita ese archivo por sí mismo.
- En cada ejecución, hate_crack imprime los dos archivos que realmente cargó:  ```
  [*] config.json: /home/you/.hate_crack/config.json
  [*] .env:        /home/you/.hate_crack/.env

Lee esas dos líneas antes de depurar una configuración que "no surte efecto". Existen debido a dos trampas en el orden de búsqueda:

  • Un checkout tiene prioridad sobre tu directorio home. La raíz del repositorio se busca primero, por lo que un .env o config.json que esté en cualquier checkout desde el que ejecutes la herramienta prevalece sobre el de ~/.hate_crack — y ejecutar la herramienta desde un checkout es exactamente lo que crea esos archivos allí en primer lugar. Si esto llega a ocultar una configuración real de ~/.hate_crack, hate_crack ahora lo indica con una tercera línea [!] nombrando ambas rutas — trata esa línea como "el archivo de abajo se está ignorando", no como una segunda configuración igualmente válida.
  • El directorio de trabajo actual nunca se busca. Un .env en el directorio en el que estés situado se ignora, deliberadamente: los directorios de engagement están llenos de archivos que nadie pretendía que fueran configuración. Ponlo en la raíz del repositorio o en ~/.hate_crack.

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

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

La rama predeterminada se renombró de `master` a `main`. Solucionar con:```bash
git remote set-head origin -a
git branch -m master main
git branch --set-upstream-to=origin/main main
git pull

Objetivos del Makefile

Predeterminado (instalación completa) - compila los submódulos, instala las dependencias e instala la herramienta:```bash make

or explicitly:

make install

Esto es idempotente: omite las herramientas ya instaladas.

**Forzar reinstalación limpia:**```bash
make reinstall

Actualización rápida - reconstruye los submódulos y reinstala la herramienta (después de obtener los cambios):```bash make update

**Desinstalar** - elimina las dependencias del sistema operativo y la herramienta:```bash
make uninstall

Compilar solo hashcat-utils:```bash make hashcat-utils

**Ejecutar pruebas** - maneja automáticamente HATE_CRACK_SKIP_INIT cuando es necesario:```bash
make test

Informe de cobertura:```bash make coverage

**Limpiar artefactos de compilación/pruebas:**```bash
make clean

Desarrollo

Configuración del entorno de desarrollo

Instala el proyecto con las dependencias de desarrollo opcionales (incluye linters y herramientas de testing):```bash make dev-install

### Ejecución de linters y comprobaciones de tipos

Antes de subir cambios, ejecuta estas comprobaciones localmente. Usa `make lint` para todo, o ejecuta comprobaciones individuales:

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

Corregir problemas automáticamente:```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 (verificación de tipos):**```bash
make ty
# or manually:
uv run ty check hate_crack

Ejecutar todas las comprobaciones juntas:```bash make lint

### Ejecución de pruebas

Las pruebas detectan automáticamente cuando los submódulos no están compilados y establecen `HATE_CRACK_SKIP_INIT=1` de forma automática.```bash
make test

O ejecutar pytest directamente:```bash uv run pytest -v

Con cobertura:```bash
make coverage

O con pytest:```bash uv run pytest --cov=hate_crack

### Git Hooks (prek)

Los Git hooks se gestionan con [prek](https://github.com/j178/prek) (v0.3.3+). Instala los hooks con:```bash
prek install --hook-type pre-push --hook-type pre-commit

Esto instala los hooks definidos en prek.toml usando el esquema TOML de repositorio local de pre-commit:

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

Los autocorrectores de pre-commit reescriben los archivos en su lugar, así que vuelve a preparar y hacer commit de nuevo después de que se ejecuten.

Nota: prek 0.3.3 espera repos = [...] en el nivel superior. El formato antiguo [hooks.<stage>] commands = [...] no es compatible.

Los menús usan por defecto la selección clásica numerada con print() + input(), que acepta teclas de varios dígitos.

Para habilitar la navegación con teclas de flecha mediante simple-term-menu, establece HATE_CRACK_ARROW_MENU=1. En ese modo solo funcionan las teclas de atajo de un solo dígito; las opciones numeradas 10 y superiores deben alcanzarse con las teclas de flecha. El modo de teclas de flecha también requiere una TTY, por lo que permanece desactivado cuando la salida se canaliza.

Dependencias de desarrollo

El grupo opcional [dev] incluye:

  • ty - Verificador de tipos estático
  • ruff - Linter y formateador rápido de Python
  • pytest - Framework de pruebas
  • pytest-cov - Informes de cobertura

Opciones comunes:

  • --download-hashview: Descarga hashes desde Hashview antes del cracking.
  • --hashview: Menú interactivo de Hashview para gestionar hashes, wordlists y jobs.
  • --hashview --help: Muestra las opciones de línea de comandos de Hashview.
  • --weakpass: Descarga wordlists desde Weakpass.
  • --hashmob: Descarga wordlists desde Hashmob.net.
  • --hashmob-masks: Descarga masks desde Hashmob.net.
  • --download-torrent <FILENAME>: Descarga un archivo torrent específico de Weakpass.
  • --download-all-torrents: Descarga todos los torrents de Weakpass disponibles desde la caché.
  • --wordlists-dir <PATH> / --optimized-wordlists-dir <PATH>: Sobrescribe los directorios de wordlists.
  • --pipal-path <PATH>: Sobrescribe la ruta de pipal.
  • --restore-potfile: Reconstruye <hashfile>.out desde el archivo POT de hashcat al inicio, reemplazando cualquier contenido existente, y luego continúa al menú normal. Sin este flag, la búsqueda en el POT solo se ejecuta cuando .out no existe todavía. La opción 93 del menú hace lo mismo bajo demanda, con un aviso de confirmación.
  • --maxruntime <SECONDS>: Sobrescribe el tiempo máximo de ejecución.
  • --bandrel-basewords <PATH>: Sobrescribe el archivo de basewords de bandrel.
  • --update: Actualiza a la última versión y reinstala. Cambia el checkout a main si está en otra rama, ya que las etiquetas de versión residen allí.
  • --nightly: Actualiza a la última nightly en su lugar, desde la rama nightly-dev. Las nightlies han pasado CI pero no forman parte de una versión publicada. También se puede escribir --update --nightly.
  • --no-optimized-kernel (o --no-optimize): Nunca pasa -O a hashcat durante toda la ejecución. Sobrescribe optimizedKernelAttacks en config.json y elimina cualquier -O que hayas puesto en hcatTuning. No se escribe nada de vuelta en la config, por lo que se aplica solo a esta ejecución. Con un subcomando, colócalo antes del subcomando: ./hate_crack.py --no-optimize quick hashes.txt 1000 --wordlist words.txt.
  • --debug: Habilita el registro de depuración (escribe en stderr).

Integración con Hashview

hate_crack se integra con Hashview para la gestión centralizada de hashes y el cracking distribuido.

Accede al menú interactivo de Hashview:```bash hate_crack.py --hashview

Opciones del menú:
- **(1) Upload Cracked Hashes** - Subir resultados descifrados de la sesión actual a Hashview
- **(2) Upload Wordlist** - Subir un archivo de wordlist a Hashview
- **(3) Download Wordlist** - Descargar un wordlist desde Hashview
- **Download Rule** - Descargar un archivo de reglas desde Hashview (descomprimido a texto plano, listo para `hashcat -r`). Introduzca `a` (o `all`) en el prompt del ID de regla para descargar todas las reglas listadas en lugar de una sola
- **Download All Rules** - Descargar todos los archivos de reglas listados por Hashview en una sola pasada; los fallos por regla se reportan sin abortar el resto
- **(4) Download Left Hashes** - Descargar los hashes restantes sin descifrar (solicita cambiar para descifrar)
- **(5) Download Found Hashes** - Descargar los hashes ya descifrados con contraseñas en texto claro (para referencia/análisis)
- **(6) Upload Hashfile and Create Job** - Subir un nuevo archivo de hashes y crear un trabajo de descifrado
- **(99) Back to Main Menu** - Volver al menú principal

**Importante: Download Found vs Download Left**
- **Download Left Hashes (4)**: Descarga los hashes sin descifrar que necesitan ser descifrados. Se fusiona automáticamente con cualquier hash encontrado si está disponible, y solicita cambiar a este archivo de hashes para descifrar.
- **Download Found Hashes (5)**: Descarga los hashes ya descifrados en formato hash:cleartext. Estos son para referencia y no pueden ser descifrados más. No se muestra ningún prompt de cambio.

#### Interfaz de línea de comandos

Las operaciones de Hashview también se pueden realizar mediante línea de comandos:

Subir hashes descifrados:```bash
hate_crack.py --hashview upload-cracked --file <output_file>.out --hash-type 1000

Subir una lista de palabras:```bash hate_crack.py --hashview upload-wordlist --file .txt --name "My Wordlist"

Descargue un archivo de reglas (guardado descomprimido, listo para `hashcat -r`):```bash
hate_crack.py --hashview download-rules --rules-id 4 --output best64.rule

Descargar hashes restantes (hashes sin descifrar para descifrar):```bash hate_crack.py --hashview download-left --customer-id 1 --hashfile-id 123

Descargar hashes encontrados (hashes ya descifrados con texto claro):```bash
hate_crack.py --hashview download-found --customer-id 1 --hashfile-id 123

Subir archivo hash y crear trabajo:```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"

#### Configuración

Establezca las credenciales de Hashview en `.env` (son ajustes de integración, por lo que no residen en `config.json`):```
HASHVIEW_URL=https://hashview.example.com
HASHVIEW_API_KEY=your-api-key-here
HASHVIEW_VERIFY_TLS=true

HASHVIEW_VERIFY_TLS tiene como valor predeterminado true: hate_crack verifica el certificado TLS del servidor de Hashview, y la conexión a un Hashview con un certificado autofirmado o de una CA interna fallará hasta que ese certificado sea de confianza (agrégalo a tu almacén de confianza del sistema, o usa un certificado emitido por una CA en la que tu sistema ya confíe). Si eso no es posible, establece HASHVIEW_VERIFY_TLS=false -- hate_crack imprimirá una advertencia de una línea nombrando el host en cada inicio de proceso cuando la verificación esté desactivada, ya que desactivarla elimina la protección contra un servidor suplantado o un atacante en la ruta que intercepte la conexión.

Configuración del LLM

El LLM Attack (opción 12) y el Rosetta Mask Attack (opción 23) generan sus candidatos con un modelo local. Configura el modelo, la ventana de contexto y el tiempo de espera de solicitud en .env:``` LLM_BACKEND=ollama OLLAMA_MODEL=qwen3:4b-instruct OLLAMA_NUM_CTX=8192 OLLAMA_TIMEOUT=300

**Las claves `OLLAMA_*` a continuación se aplican a todos los backends, no solo a Ollama.** Conservan ese prefijo porque `OLLAMA_HOST` es la misma variable que lee la propia CLI de Ollama, y renombrarlas rompería todos los `.env` existentes sin ninguna ganancia funcional — un servidor vLLM o compatible con OpenAI quiere el mismo host, modelo, timeout, contexto y parámetros de muestreo bajo los mismos nombres. `LLM_BACKEND` solo selecciona cómo se da forma a la petición.

- **`OLLAMA_MODEL`** — El modelo de Ollama usado para la generación de candidatos (por defecto: `qwen3:4b-instruct`). El ataque LLM usa salida estructurada (JSON), así que elige un modelo con buen soporte de herramientas/JSON.
- **`OLLAMA_NUM_CTX`** — Tamaño de la ventana de contexto del modelo (por defecto: `8192`). Esto era `2048` antes de que se introdujeran las estadísticas del corpus, lo cual era demasiado pequeño para contener el prompt que se le estaba dando: 500 textos planos muestreados ocupan aproximadamente 2.000–3.500 tokens antes del system prompt y la respuesta, así que Ollama truncaba silenciosamente parte de la muestra que el muestreador había distribuido cuidadosamente por todo el archivo.
- **`OLLAMA_TIMEOUT`** — Segundos a esperar una respuesta de generación antes de rendirse (por defecto: `300`). Auméntalo si un modelo grande todavía se está cargando en la VRAM en la primera petición, lo que de otro modo puede superar el timeout; hate_crack imprime el timeout transcurrido y el nombre de esta configuración cuando se dispara.
- **`OLLAMA_MAX_SAMPLE_LINES`** — El umbral por debajo del cual los modos LLM también pegan los textos planos literales en el prompt (por defecto: `500`). Los valores ≤ 0 se tratan como 500.

  Los modos derivados del corpus (**Wordlist**, **Cracked passwords**, **Pattern rules**) siempre describen el corpus *entero* estadísticamente — proporciones de palabras base, máscaras, uso de mayúsculas/minúsculas, longitudes, dígitos y símbolos finales, años — en lugar de pegar una porción de él. La agregación está acotada, así que un volcado de 120.000 contraseñas cuesta aproximadamente el mismo espacio de prompt que uno de 500 líneas. Cuando el corpus entero cabe por debajo de este umbral, también se incluyen los textos planos sin procesar, ya que no se gana nada ocultando un corpus pequeño al modelo.

  Esto reemplaza el comportamiento anterior de pegar una muestra uniformemente espaciada de hasta `ollamaMaxSampleLines` contraseñas. Una muestra de un volcado grande no transmitía ninguna información de frecuencia: el modelo no podía distinguir una palabra base usada por el 8% de la organización de una usada por una sola persona, que es precisamente la señal que hace que una conjetura merezca la pena ejecutar.
- **`OLLAMA_NO_CLOUD`** — Cuando es `true`, se niega a enviar cualquier cosa fuera de este host, para cualquiera de los tres backends LLM (Ollama, vLLM o un servidor genérico compatible con OpenAI). Dos comprobaciones están controladas por esta única configuración: Ollama redirige un modelo etiquetado como `-cloud` (`gpt-oss:120b-cloud`, `deepseek-v3.1:671b-cloud`) a ollama.com a través del mismo endpoint local que usa un modelo local, así que nada en la petición parece diferente — eso se rechaza por nombre de modelo. También se comprueba la URL del backend configurado: un destino que no sea loopback, privado o link-local (y que no sea `localhost` ni un nombre `.local`/`.internal`/`.lan`/`.localdomain`) se rechaza por destino, y un nombre de host que esta comprobación no pueda resolver también se rechaza, fail-closed, en lugar de dejar pasar un destino no verificable. Los prompts de hate_crack llevan textos planos recuperados, estadísticas del corpus y el nombre, sector y ubicación del cliente, así que cualquiera de las dos comprobaciones que se dispare significa que la petición se rechaza antes de construirse. Por defecto es `false`, así que un modelo en la nube o servidor remoto configurado deliberadamente sigue funcionando; actívalo para encargos en los que los datos del cliente no deben salir del host.
- **`OLLAMA_AUTO_RESEARCH`** — Cuando es `true` (por defecto), el modo **Target info** pide al modelo local que sugiera el sector, la ubicación y la empresa matriz / historial de adquisiciones en cuanto hayas escrito el nombre de la empresa, y los ofrece como valores por defecto editables del prompt. Ponlo a `false` para obtener siempre prompts en blanco (útil con un modelo lento, ya que la investigación cuesta un round-trip extra antes de que empiece el ataque).
- **`OLLAMA_HOST`** — Dónde está escuchando el backend configurado. Acepta un `host:port` simple (`theplague.lan:11434`) o una URL completa con esquema (`https://ollama.example.com`); en cualquier caso la URL base se normaliza antes de usarse. Por defecto es `localhost:11434`, que es el puerto de Ollama — un servidor vLLM o compatible con OpenAI necesita que esto se ponga al suyo propio (vLLM normalmente escucha en `:8000`). Configúralo en `.env`, o expórtalo como variable de entorno real para sobrescribir eso en una sola ejecución — es el mismo nombre de variable que lee la propia CLI de Ollama.
- **`LLM_BACKEND`** — Con qué servidor compatible con OpenAI hablar: `ollama` (por defecto), `vllm`, u `openai` para uno genérico. Todos los backends hablan la misma API de chat-completions `/v1`, así que esto solo selecciona los dos detalles de conformación de la petición en los que difieren: `ollama` recibe `options.num_ctx`, y `vllm` recibe `chat_template_kwargs={"thinking": false}` — sin lo cual un servidor vLLM ejecutando un parser de razonamiento enruta toda la respuesta estructurada a `message.reasoning`, deja `message.content` vacío y rompe el parseo de JSON. `openai` no envía ninguno de los dos, ya que `num_ctx` no tiene equivalente ahí. **No** cambia de dónde vienen el host, el modelo, el timeout, el contexto o la configuración de muestreo — esas son las claves `OLLAMA_*` de arriba para los tres.
- **`LLM_API_KEY`** — La credencial enviada al backend configurado. Por defecto es el literal `ollama`, el marcador de posición que el propio servidor de Ollama ignora, así que las peticiones de una instalación existente no cambian; un valor vacío recurre a ese mismo marcador de posición porque el SDK de OpenAI rechaza `api_key=""`. Ponlo al valor real si el servidor exige uno — un servidor vLLM iniciado con `--api-key` devuelve 401 en caso contrario.
- Asegúrate de que Ollama está en ejecución y el modelo está descargado (`ollama pull qwen3:4b-instruct`) antes de usar el LLM Attack — hate_crack ya no descarga automáticamente los modelos que faltan.

El ataque ofrece tres modos de generación:

1. **Target info** — empresa / sector / ubicación / empresa matriz; el modelo deriva candidatos a partir de esos detalles.

   Después de que escribas el nombre de la empresa, hate_crack pregunta al mismo modelo local qué sabe ya sobre esa organización y rellena previamente los prompts de **Industry**, **Location** y **Parent Company** con las respuestas, mostradas entre paréntesis:   ```
   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:

Pulsa Enter para aceptar una sugerencia o escribe encima de ella. Estos valores son el recuerdo del modelo, no OSINT — trátalos como un punto de partida, no como inteligencia sobre el cliente. La búsqueda utiliza únicamente el servidor local de Ollama, por lo que el nombre del cliente nunca sale del host; no hay llamadas web ni a API de terceros. Si el modelo no reconoce la organización (el caso habitual con clientes pequeños), no devuelve nada y obtienes indicaciones en blanco: ``` Company name: Acme Rail Services Industry: Location: Parent company / acquired by:

Un fallo de investigación —timeout, Ollama no está en ejecución, respuesta vacía— nunca bloquea el ataque; simplemente recurre a prompts en blanco. Establece `ollamaAutoResearch` en `false` para omitir la investigación por completo.
2. **Wordlist** — deriva palabras base a partir de una wordlist de muestra.
3. **Contraseñas crackeadas** — alimenta los textos planos ya recuperados en esta sesión (`<hashfile>.out`) al modelo para que pueda inferir las convenciones de contraseñas de la propia organización objetivo (palabras base, estaciones, años, sufijos, leetspeak) y generar *nuevos* candidatos con el mismo estilo. Esta opción solo se lista una vez que se ha crackeado al menos un hash; el archivo completo se analiza estadísticamente exactamente igual que en el modo Wordlist (ver `ollamaMaxSampleLines` arriba).

#### Configuración de PCFG

El ataque PCFG (opción 20) y el ataque PRINCE-LING (opción 21) utilizan el submódulo `pcfg_cracker`. Configúralos en `config.json`:```json
{
"pcfgRuleset": "DEFAULT",
"pcfgMaxCandidates": 50000000,
"pcfgPrinceLingMaxCandidates": 10000000
}
  • pcfgRuleset — Nombre de la gramática entrenada a usar (predeterminado: DEFAULT), resuelto a pcfg_cracker/Rules/<name>/. Entrena la tuya con trainer.py de pcfg_cracker y establece este valor al nombre del conjunto de reglas.
  • pcfgMaxCandidates — Número máximo de candidatos que pcfg_guesser.py emite para el ataque PCFG (predeterminado: 50000000).
  • pcfgPrinceLingMaxCandidates — Número máximo de palabras base que prince_ling.py escribe en la lista de palabras base de PRINCE en caché (predeterminado: 10000000).

Kernels optimizados (optimizedKernelAttacks)

El flag -O de hashcat selecciona kernels optimizados, que son sustancialmente más rápidos pero limitan la longitud de los candidatos (aproximadamente 31 caracteres, menos para algunos modos) y omiten silenciosamente cualquier cosa más larga. optimizedKernelAttacks en config.json lista los ataques que se ejecutan con -O; omite un ataque de la lista para ejecutarlo con kernels de longitud completa. La lista en config.json.example coincide con el valor predeterminado integrado que se aplica cuando no existe config.json.

Cuatro ataques respetan la configuración pero no están optimizados por defecto, porque alimentan candidatos que pueden exceder el límite de -O — agrégalos a la lista para activarlos:

  • hcatNgramX, hcatOllama, hcatOmen, hcatLMtoNT

Para desactivar -O en todas partes para una sola ejecución sin editar la configuración, pasa --no-optimized-kernel (forma corta --no-optimize). Anula la lista para cada ataque y también elimina un -O escrito en hcatTuning, que de lo contrario llegaría a hashcat independientemente de la lista.

Los nombres se comparan exactamente, y una entrada no reconocida se reporta al inicio en lugar de ser ignorada. Ten en cuenta que los ataques que delegan a otro ataque están controlados por el ataque al que delegan, no por su propio nombre: PRINCE-LING sigue a hcatPrince, mientras que Spoonman, Rosetta y los modos de reglas de patrones LLM siguen a hcatQuickDictionary.

Seguimiento de cobertura de ataques (coverage_enabled)

A lo largo de un compromiso prolongado, el mismo archivo de hashes es atacado en muchas sesiones con un conjunto rotativo de listas de palabras, archivos de reglas y listas de máscaras, y es fácil perder horas re-ejecutando terreno que ya cubriste — especialmente porque la misma línea de regla vive en más de un archivo de reglas. hate_crack registra lo que ya ha ejecutado contra cada archivo de hashes y ofrece omitir la superposición.

La cobertura se registra por entrada, no por archivo: líneas de reglas individuales y líneas individuales de .hcmask, cada una emparejada con la lista de palabras contra la que se ejecutó. Eso es lo que le permite reconocer que un archivo de reglas personalizado que ejecutas hoy repite 40 de las reglas que best64.rule ya cubrió la semana pasada, y también es por lo que una regla solo está "cubierta" para la lista de palabras específica con la que se probó — las mismas reglas sobre un corpus diferente prueban candidatos completamente diferentes.

El archivo de hashes se identifica mediante un sha256 de su contenido, por lo que la cobertura sobrevive al renombrado o movimiento entre sesiones. Las listas de palabras se identifican de la misma manera, con el resumen memorizado contra el tamaño y la mtime para que un corpus de varios gigabytes se hashee una vez en lugar de en cada ataque.

Solo se te solicita cuando hay genuinamente algo que omitir:``` [*] 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]:

Responde `Y` y hate_crack construye un archivo de reglas temporal que contiene solo las entradas no probadas; responde `n` para ejecutar todo de todos modos. Si *cada* entrada es una repetición, se te pregunta si omitir el ataque por completo, de modo que volver a ejecutar deliberadamente terreno ya cubierto nunca requiere reiniciar la herramienta.

Los ataques que nunca se filtran igualmente se registran como ejecutados, lo que te permite responder "¿ya ejecuté PRINCE contra este objetivo?".

Un ataque que selecciona varios archivos de reglas a la vez (Quick Crack, Loopback) hace la pregunta de omisión **una vez para todo el lote, por adelantado**, antes de cualquier invocación de hashcat. Esa pregunta es deliberadamente barata — no lee ni calcula el hash de ninguno de los archivos de reglas seleccionados, ya que un lote YOLO puede llegar a millones de líneas y no deberías esperar a que termine para responder un sí/no. Solo le pregunta al almacén si este ataque ya se ejecutó contra este archivo de hashes **con una de estas wordlists**; el diff por entrada sigue ocurriendo de forma perezosa, un archivo de reglas a la vez, y decide qué se omite realmente. Así, un corpus nuevo nunca se marca, incluso cuando las reglas sobre él ya se ejecutaron todas contra uno diferente.

Tres límites deliberados:

- **La cobertura solo se registra cuando hashcat agota el espacio de claves** (salida 1). Un ctrl-C o un error no registra nada, y la salida 0 tampoco — eso significa que todos los hashes fueron crackeados, lo que hashcat reporta *sin* terminar el espacio de claves, y en el caso degenerado de "todos los hashes encontrados como entradas del potfile" sin probar un solo candidato. El subregistro solo cuesta una ejecución redundante más adelante.
- **Los generadores dinámicos de candidatos nunca se filtran.** PRINCE, PCFG, OMEN, la fuerza bruta de Markov y los modos LLM no tienen un conjunto fijo que diferenciar, así que se registran como ejecutados y por lo demás se dejan en paz. Los archivos de reglas encadenados (`-r a -r b`) se rastrean como una sola unidad en lugar de por entrada, porque hashcat aplica el *producto cartesiano* de los dos archivos y eliminar una línea individual eliminaría silenciosamente cada combinación en la que participó.
- **Las ejecuciones con `--loopback` se registran pero nunca se filtran.** hashcat reintroduce los textos planos recién crackeados como candidatos *extra*, así que tal ejecución prueba la wordlist y el conjunto de reglas completos más lo que alcancen esos textos planos reciclados. Eso hace que las dos direcciones sean asimétricas: registrarla es correcto, así que una ejecución ordinaria posterior de la misma wordlist y reglas se reconoce correctamente como una repetición, pero una segunda ejecución de loopback tiene más cracks que reciclar y nunca se omite.

Establece `coverage_enabled` en `false` en `config.json` para desactivar esto, o pasa `--no-coverage` para una sola ejecución — lo cual ni consulta ni actualiza el almacén.

#### Inspeccionar y restablecer la cobertura

La opción **85 — Attack Coverage** del menú principal muestra lo que se ha ejecutado contra el archivo de hashes cargado, su historial de ejecuciones, y puede borrarlo. Las mismas tres acciones son 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

El archivo de hash se identifica por contenido, por lo que estos funcionan independientemente de dónde se haya movido desde entonces. forget afecta solo a ese objetivo — el almacén vive en ~/.hate_crack/coverage/attack_coverage.sqlite3, y eliminar el archivo restablece la cobertura para todos los objetivos.

Ejecuciones con script

Un ataque con script que la cobertura omite por completo aún sale con 0 por defecto, por lo que habilitar la cobertura no puede empezar a fallar un arnés existente. Pasa --exit-code-on-skip para obtener el código de salida 3 en su lugar cuando no se lanzó nada:```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 significa que *nada* se ejecutó. Una pasada que fue parcialmente filtrada — algunas entradas omitidas, algunas intentadas — igual sale con `0`, porque el ataque sí hizo trabajo.

### Soporte de hashcat brain (`brain_enabled`)

hashcat en sí incluye un "brain" — un pequeño servidor al que una instancia de hashcat en ejecución transmite contraseñas candidatas, para que una segunda ejecución contra el mismo objetivo pueda omitir candidatos que la primera ya intentó. hate_crack lo activa automáticamente, sin necesidad de ningún paso en el menú: cada vez que está a punto de lanzar un ataque contra un modo de hash que hashcat reporta como lento (bcrypt, scrypt y otros modos respaldados por KDF, donde el hash en sí es el cuello de botella en lugar de la generación de candidatos), inicia o reutiliza un servidor brain local y añade los flags `--brain-*` a la invocación de hashcat por ti. Un modo rápido se deja en paz, a menos que su número de modo esté listado en `brain_modes_force`, y un modo listado en `brain_modes_exclude` nunca activa brain independientemente del veredicto de hashcat — exclude siempre gana.

**Brain no es lo mismo que la cobertura de ataque, y los dos son complementarios en lugar de redundantes.** La cobertura (arriba) deduplica a nivel de reglas completas, líneas de máscara y wordlists — decide qué lanzar en primer lugar, antes de que hashcat siquiera se ejecute. Brain deduplica a nivel de contraseñas candidatas individuales, y lo hace a través de un servidor persistente que sobrevive a cualquier invocación individual de hashcat, por lo que captura solapamientos que la cobertura no puede ver: un candidato alcanzable a través de dos reglas diferentes o dos wordlists diferentes dentro de la misma ejecución, y — como demuestra el viaje de ida y vuelta en `tests/e2e/test_brain_e2e.py` — los mismos candidatos reenviados en una segunda ejecución separada de hashcat contra el mismo objetivo. Ambos pueden habilitarse a la vez sin conflicto.

Siete claves en `config.json` lo controlan, todas bajo el prefijo `brain_*`: `brain_enabled` (interruptor maestro, activado por defecto), `brain_host` (vacío significa que hate_crack gestiona un servidor local en loopback; un valor significa conectarse solo a ese host — hate_crack nunca genera un servidor que no se le haya indicado gestionar), `brain_port` (por defecto `6863`), `brain_client_features` (`1` contraseñas hasheadas, `2` posiciones de ataque, `3` ambas — `3` deduplica más pero le cuesta al servidor aproximadamente 12 bytes de RAM por candidato visto), `brain_server_timer` (ajuste propio de hashcat para la frecuencia con la que el servidor escribe su volcado `.ldmp`/`.admp` a disco, mínimo 60 segundos, por defecto `300`), y `brain_modes_force` / `brain_modes_exclude` (números de modo de hash separados por comas que anulan el veredicto lento/rápido de hashcat, con prioridad para exclude).

**El servidor autogenerado no tiene ningún tiempo de espera por inactividad.** `brain_server_timer` no controla cuánto tiempo permanece activo — nada lo hace; se ejecuta durante toda la vida del proceso que lo generó (o hasta que `shutdown()`/`atexit` lo detenga) y se reutiliza en cada ataque de la sesión. Con el valor por defecto de `300`, eso significa una escritura de volcado en `~/.hate_crack/brain/` cada cinco minutos mientras hate_crack esté en ejecución.

Una octava clave, `BRAIN_PASSWORD`, vive en `.env` en lugar de `config.json` porque es un secreto compartido, no porque brain sea una integración de terceros — solo se usa al conectarse a un servidor brain remoto que ya ejecutas; el servidor local autogenerado genera su propia contraseña aleatoria por sesión y no necesita configuración.

**La contraseña de brain es visible para `ps` durante toda la vida de la ejecución de hashcat,** porque hashcat solo la acepta como argumento de línea de comandos — no existe una forma de variable de entorno. Para el servidor local autogenerado esta es una ventana pequeña: la contraseña es aleatoria y está limitada a esa única sesión, por lo que otro usuario local solo puede verla mientras un ataque está realmente en ejecución, y es inútil una vez que la sesión termina. La contraseña de un servidor brain remoto compartido no tiene tal mitigación — es el mismo valor en cada invocación, visible para cualquier otro usuario local de la máquina mientras cualquier ejecución de hate_crack contra ese servidor esté en curso. Trátala en consecuencia en hardware compartido o multiinquilino.

Pasa `--no-brain` para deshabilitar brain en una única ejecución independientemente de `brain_enabled`, o establece `brain_enabled` a `false` en `config.json` para desactivarlo en todas partes.

**Brain mantiene su estado en `~/.hate_crack/brain/`** — una pequeña caché `slow_modes.json` del veredicto lento/rápido propio de hashcat por versión de hashcat, más, para el servidor autogenerado, sus archivos de volcado `.ldmp`/`.admp`. Esos volcados son material derivado de candidatos: permiten que un servidor nuevo reanude sabiendo lo que ya se ha intentado contra un objetivo, lo que en un encargo significa datos derivados del cliente acumulándose en el directorio home del operador durante todo el tiempo que brain haya estado ejecutándose allí. Al igual que con el almacén de cobertura de arriba, eliminar el directorio reinicia brain — un candidato previamente rechazado deja de ser recordado, a costa de perder la deduplicación que ese volcado representaba. Si brain parece estar omitiendo trabajo que no debería (un volcado obsoleto de una ejecución previa con un alcance diferente), esta es la solución.

**Eliminar `~/.hate_crack/brain/` no limpia un servidor huérfano.** El servidor autogenerado se ejecuta en su propia sesión (`start_new_session=True`) para que sobreviva a un terminal cerrado o a un SIGHUP — solo un kill explícito, o que el proceso que lo generó salga limpiamente y ejecute su manejador `atexit`, lo detiene. Un huérfano sigue ocupando el puerto de loopback. Con el `BRAIN_PASSWORD` vacío por defecto, lo notarás como `"[!] ... no brain server could be reached; running without candidate de-duplication"` en cada ataque en modo lento: la contraseña del huérfano era efímera y murió con el proceso que la generó, así que hate_crack se niega a adoptar el puerto en el que está asentado en lugar de adivinar una contraseña que no puede verificarse. Encuéntralo y deténlo con:```bash
pgrep -f 'hashcat --brain-server'
kill <pid>

después de lo cual el siguiente ataque genera un servidor nuevo como de costumbre.

Notificaciones (opción de menú 82)

hate_crack puede enviar notificaciones push de Pushover cuando los ataques finalizan y, opcionalmente, cuando se descifran hashes individuales. Todos los controles están bajo la opción del menú principal 82 — Notifications:

  1. Toggle Pushover Notifications [ON/OFF] — interruptor maestro. Se guarda en config.json como notify_enabled.
  2. Toggle Per-Crack Notifications [ON/OFF] — cuando está ON, un tailer en segundo plano vigila el archivo .out y envía una notificación por cada crack (con agregación de ráfagas por tick). Se guarda en config.json como notify_per_crack_enabled. No se puede activar mientras el interruptor maestro está OFF — activa primero la opción 1.
  3. Send Test Pushover Notification — envía un push predefinido para que puedas confirmar que tu par token/usuario de Pushover funciona. Funciona incluso cuando el interruptor maestro está OFF.

Las credenciales viven en .env; los parámetros de ajuste restantes son solo de archivo de configuración en config.json:

  • NOTIFY_PUSHOVER_TOKEN, NOTIFY_PUSHOVER_USER (en .env) — necesarios para que se dispare cualquier push. Nada en el menú escribe estos valores; edita .env tú mismo.
  • notify_attack_allowlist — nombres de ataques que dan consentimiento automático sin el prompt [y/N/always]. Se rellena automáticamente cuando respondes always.
  • notify_suppress_in_orchestrators (por defecto true) — silencia los ataques individuales encadenados por Extensive Crack, que en su lugar dispara un único resumen. Establécelo en false para recibir una notificación por cada ataque encadenado. Otras entradas del menú que ejecutan varias pasadas (por ejemplo Quick Crack con múltiples cadenas de reglas) no son orquestadores y siempre notifican por pasada.
  • notify_max_cracks_per_burst (por defecto 5), notify_poll_interval_seconds (por defecto 5.0) — ajuste del tailer por crack. Consulta hate_crack/notify/tailer.py para la lógica de agregación de ráfagas.

Wordlist Tools (opción de menú 80)

El submenú Wordlist Tools proporciona utilidades de preprocesamiento de wordlists respaldadas por los binarios de hashcat-utils, además de descargas de wordlists desde Hashmob.net y Weakpass. Accede mediante la opción 80 en el menú principal.

OpciónBinarioQué hace
1len.binFiltrar por longitud - conserva solo las palabras entre una longitud mínima y máxima
2req-include.binRequerir clases de caracteres - conserva solo las palabras que contienen todos los tipos de caracteres requeridos
3req-exclude.binExcluir clases de caracteres - elimina las palabras que contienen cualquier tipo de carácter excluido
4cutb.binExtraer subcadena - recorta un rango de bytes de cada palabra
5splitlen.binDividir por longitud - crea archivos separados por longitud de palabra (archivos nombrados 01-64 en un directorio de salida)
6rli.bin / rli2.binRestar palabras - elimina las entradas que aparecen en uno o más archivos
7gate.binShard - extrae cada N-ésima palabra para cracking distribuido entre múltiples máquinas
8-Optimizar wordlists - deduplica y divide en archivos por longitud bajo el directorio de wordlists optimizadas
9-Descargar wordlists desde Hashmob.net
10-Descargar wordlists desde Weakpass (vía BitTorrent)

Bits de máscara de clase de caracteres (usados por las opciones 2 y 3): 1=minúscula, 2=mayúscula, 4=dígito, 8=símbolo, 16=otro. Suma los valores: 7 = minúscula+mayúscula+dígito.

Cómo se pretende usar el sharding: el sharding divide una wordlist en N partes iguales y no solapadas para que el trabajo pueda repartirse entre múltiples máquinas o GPUs. Cada parte está intercalada (cada N-ésima línea), por lo que cada shard es una muestra representativa de toda la lista en lugar de un fragmento contiguo de principio/final — ningún nodo queda atascado descifrando solo la cola de baja probabilidad.

Ejecuta la opción 7 una vez, dale una wordlist de entrada, una ruta base de salida y un número de shards (N). Escribe las N partes en una sola pasada, nombradas con números de parte rellenados con ceros (base.001, base.002, … hasta base.00N). Copia una parte a cada nodo y apunta la ejecución de hashcat de ese nodo a ella. En un sistema con una sola GPU el sharding no aporta ninguna mejora de velocidad, pero una sola parte sigue siendo una muestra rápida y representativa para una pasada de triaje rápido antes de comprometerse con la lista completa.

Comprobaciones automáticas de actualizaciones

hate_crack puede comprobar automáticamente en GitHub si hay versiones más recientes al iniciarse. Esta función se controla mediante la opción de configuración check_for_updates:```json { "check_for_updates": true }

- **`check_for_updates`** — Habilita las comprobaciones automáticas de versión al inicio (predeterminado: `true`).
- Cuando está habilitado, hate_crack obtiene la información de la última versión desde GitHub y muestra un aviso si hay una actualización disponible.
- La comprobación se ejecuta de forma asíncrona y no bloquea el inicio. Los errores de red se ignoran silenciosamente.

##### Canales de actualización

| Canal | Flag | Origen | Qué obtienes |
|---------|------|--------|--------------|
| Release | `--update` | `main` | La última versión publicada. Este es el predeterminado y lo que ofrece la comprobación de inicio. |
| Nightly | `--nightly` | `nightly-dev` | Trabajo que ha pasado CI pero que aún no se ha publicado. |

Las versiones siguen el semver habitual, con el incremento derivado de lo que realmente hay en
el lote. El segundo componente se mueve **solo por funcionalidades**: un ciclo que contiene
cualquier commit `feat` se dirige a `X.(Y+1).0`, y un ciclo de solo correcciones,
documentación y tareas se dirige a `X.Y.(Z+1)`.

`nightly-dev` etiqueta release candidates para la versión hacia la que se dirige
el lote — `v2.20.1rc1`, `v2.20.1rc2`, … — y fusionar hacia `main` promueve ese
mismo objetivo a su versión final. Los candidatos son pre-releases reales de PEP 440, por lo que
se ordenan correctamente en ambos extremos:

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

El objetivo puede cambiar a mitad de ciclo: el primer `feat` que llegue lo mueve de
`X.Y.(Z+1)` a `X.(Y+1).0`, y la numeración de candidatos se reinicia para el nuevo objetivo.
El número siempre nombra lo que el lote enviaría hoy.

El componente mayor nunca se incrementa automáticamente — un asunto con `!` o un
pie de página `BREAKING CHANGE:` cuenta como una funcionalidad, porque un incremento mayor automático está a una
línea de asunto mal escrita de una versión publicada irreversible. Un incremento mayor es un
acto humano explícito: etiquétalo y súbelo a mano.

La política vive en `tools/next_version.py`, compartida por ambos flujos de trabajo de etiquetado y
probada unitariamente en `tests/test_next_version.py`.

La comprobación de inicio solo ofrece releases, porque las compilaciones nightly no publican ninguna
release de GitHub y la comprobación lee el endpoint de "latest release" de GitHub — por lo que
habilitar `check_for_updates` nunca te llevará a una nightly. Dos cosas mantienen
los canales separados ahora: eso, y el hecho de que un candidato es una
pre-release genuina de PEP 440, por lo que una herramienta que clasifique números de versión sin procesar también lo trata como anterior a
la release en la que se convierte.

Cualquiera de los dos flags cambia tu checkout a la rama correspondiente primero (y
se niega a hacerlo si tienes cambios sin confirmar). Si estás ejecutando una nightly
y quieres volver al código publicado, `--update` te devuelve a `main`.

#### Fusión automática de hashes encontrados (solo descarga de left)

Al descargar hashes left (hashes no crackeados), hate_crack automáticamente:
1. Intenta descargar cualquier hash encontrado (crackeado) desde Hashview como una operación auxiliar
2. Fusiona los hashes encontrados con los archivos `.out` locales (por ejemplo, `left_1_123.txt.out` o `left_1_123.nt.txt.out` para el formato pwdump)
3. Elimina las entradas duplicadas
4. Limpia los archivos divididos temporales después de la fusión

Esto garantiza que tus resultados de cracking locales se mantengan sincronizados con la base de datos centralizada de Hashview cuando trabajas con hashes no crackeados.

**Nota:** La opción de descarga de encontrados descarga los hashes ya crackeados por separado con fines de referencia y no realiza ninguna fusión ni solicita cracking.

El <hash_type> se obtiene ejecutando `hashcat --help`

Hashes de ejemplo: 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 del servidor | | -t | --token | TOKEN | | Token de autenticación | | -o | --output | FILE | stdout | Archivo de salida | | -f | --format | FORMAT | json | Formato de salida | | -v | --verbose | | | Salida detallada | | -q | --quiet | | | Modo silencioso | | -h | --help | | | Mostrar ayuda | | -V | --version | | | Mostrar versión |

Ejemplos

# Escanear un objetivo
scanner scan --target example.com

# Escanear con opciones específicas
scanner scan --target example.com --format json --output results.json

# Escanear múltiples objetivos
scanner scan --target example.com,test.com

# Escanear desde un archivo
scanner scan --file targets.txt

# Escanear con hilos personalizados
scanner scan --target example.com --threads 20

# Escanear con tiempo de espera
scanner scan --target example.com --timeout 30

# Escanear con proxy
scanner scan --target example.com --proxy http://proxy:8080

# Escanear con encabezados personalizados
scanner scan --target example.com --header "Authorization: Bearer token"

# Escanear con cookies
scanner scan --target example.com --cookie "session=abc123"

# Escanear con agente de usuario personalizado
scanner scan --target example.com --user-agent "Custom Agent"

# Escanear con seguimiento de redirecciones
scanner scan --target example.com --follow-redirects

# Escanear con verificación SSL deshabilitada
scanner scan --target example.com --no-verify-ssl

# Escanear con salida detallada
scanner scan --target example.com --verbose

# Escanear con salida silenciosa
scanner scan --target example.com --quiet

Configuración

La configuración se puede proporcionar a través de:

  1. Argumentos de línea de comandos (mayor prioridad)
  2. Variables de entorno
  3. Archivo de configuración
  4. Valores predeterminados (menor prioridad)

Variables de entorno

export SCANNER_SERVER=http://localhost:8080
export SCANNER_TOKEN=your-token
export SCANNER_OUTPUT=results.json
export SCANNER_FORMAT=json
export SCANNER_VERBOSE=true
export SCANNER_QUIET=false

Archivo de configuración

server: http://localhost:8080
token: your-token
output: results.json
format: json
verbose: true
quiet: false
threads: 10
timeout: 30
proxy: http://proxy:8080
headers:
  Authorization: Bearer token
cookies:
  session: abc123
user_agent: Custom Agent
follow_redirects: true
verify_ssl: false

Desarrollo

Requisitos previos

  • Go 1.21 o superior
  • Make
  • Docker (opcional)

Compilación

# Clonar el repositorio
git clone https://github.com/example/scanner.git
cd scanner

# Compilar el binario
make build

# Compilar para múltiples plataformas
make build-all

# Ejecutar pruebas
make test

# Ejecutar pruebas con cobertura
make test-coverage

# Ejecutar linter
make lint

# Formatear código
make fmt

# Limpiar artefactos de compilación
make clean

Estructura del proyecto

scanner/
├── cmd/
│   └── scanner/
│       └── main.go
├── internal/
│   ├── config/
│   ├── scanner/
│   ├── output/
│   └── utils/
├── pkg/
│   ├── api/
│   └── models/
├── docs/
├── scripts/
├── tests/
├── Makefile
├── go.mod
├── go.sum
└── README.md

Pruebas

# Ejecutar todas las pruebas
go test ./...

# Ejecutar pruebas con cobertura
go test -cover ./...

# Ejecutar pruebas con salida detallada
go test -v ./...

# Ejecutar pruebas de referencia
go test -bench=. ./...

# Ejecutar pruebas con detector de carreras
go test -race ./...

Contribución

  1. Hacer un fork del repositorio
  2. Crear una rama de funcionalidad (git checkout -b feature/amazing-feature)
  3. Confirmar los cambios (git commit -m 'Add amazing feature')
  4. Enviar a la rama (git push origin feature/amazing-feature)
  5. Abrir una solicitud de extracción

Directrices de contribución

  • Seguir las convenciones de código de Go
  • Escribir pruebas para código nuevo
  • Actualizar la documentación según sea necesario
  • Ejecutar pruebas y linter antes de enviar
  • Mantener las solicitudes de extracción enfocadas y pequeñas

Licencia

Este proyecto está licenciado bajo la Licencia MIT - consulte el archivo LICENSE para más detalles.

Agradecimientos

Soporte

Descargo de responsabilidad

Esta herramienta está destinada únicamente a fines educativos y de pruebas de seguridad autorizadas. Los usuarios son responsables de cumplir con todas las leyes y regulaciones aplicables. Los autores no se hacen responsables de ningún uso indebido o daño causado por esta herramienta.

Registro de cambios

Consulte CHANGELOG.md para obtener un historial detallado de cambios.

Hoja de ruta

  • Agregar soporte para más protocolos
  • Implementar escaneo distribuido
  • Agregar interfaz web
  • Mejorar el rendimiento
  • Agregar más formatos de salida
  • Implementar sistema de plugins

Descargo de responsabilidad: Esta herramienta está destinada únicamente a fines educativos y de pruebas de seguridad autorizadas. Los usuarios son responsables de cumplir con todas las leyes y regulaciones aplicables. Los autores no se hacen responsables de ningún uso indebido o daño causado por esta herramienta.``` $ ./hate_crack.py 1000


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

-------------------------------------------------------------------
## Pruebas

La suite de pruebas es mayormente offline y utiliza mocks/fixtures. Las comprobaciones de red en vivo y las comprobaciones de dependencias del sistema son opcionales mediante variables de entorno.

### Ejecución de pruebas localmente```bash
# Run all tests
uv run pytest -v

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

También puedes ejecutar la suite completa con make test.

Pruebas en vivo (opcionales)

Configura cualquiera de las siguientes opciones para habilitar las comprobaciones en vivo:

  • HASHMOB_TEST_REAL=1 — comprobación de conectividad/menú CLI de Hashmob en vivo
  • HASHVIEW_TEST_REAL=1 — comprobación del menú CLI de Hashview en vivo
  • WEAKPASS_TEST_REAL=1 — comprobación del menú CLI de Weakpass en vivo
  • HATE_CRACK_REQUIRE_DEPS=1 — falla si falta 7z, transmission-daemon o transmission-remote

Prueba de carga en vivo de Hashview

La prueba de carga en vivo de Hashview se omite de forma predeterminada. Para ejecutarla, configura la variable de entorno y proporciona credenciales válidas en .env:```bash HATE_CRACK_RUN_LIVE_TESTS=1 uv run pytest tests/test_upload_cracked_hashes.py -v

### Pruebas en vivo de Hashview contra una pila local de Docker

En lugar de apuntar las pruebas en vivo a un servidor remoto de Hashview, puedes hacer que
la suite levante una pila local de Docker de [Hashview](https://github.com/hashview/hashview),
la inicialice, ejecute las pruebas en vivo contra ella y la desmonte. Establece
`HASHVIEW_TEST_LOCAL=1` y apunta `HASHVIEW_REPO` a una copia local de 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

Esto levanta docker compose en el repositorio de Hashview, siembra una clave de API de administrador, un cliente, un archivo de hashes y datos de "tarea efectiva" crackeados, luego exporta las variables de entorno HASHVIEW_* que leen las pruebas. Variables de entorno útiles:

  • HASHVIEW_TEST_LOCAL=1 — habilita el stack local (no-op en caso contrario)
  • HASHVIEW_REPO=<path> — checkout de Hashview (por defecto ~/projects/hashview)
  • HASHVIEW_KEEP=1 — deja los contenedores en ejecución después de la sesión (re-ejecuciones más rápidas)
  • HASHVIEW_LOCAL_PORT=5000 — puerto del host en el que se publica la aplicación

La CLI de hate_crack respeta las variables de entorno HASHVIEW_URL / HASHVIEW_API_KEY (anulando el .env en el que viven esas dos claves), lo que permite que la suite apunte la CLI al stack local sin editar tu configuración persistida.

Pruebas de Instalación de Extremo a Extremo (Local + Docker)

Instalación local de la herramienta uv + ejecución de script (usa un HOME temporal):```bash HATE_CRACK_RUN_E2E=1 uv run pytest tests/test_e2e_local_install.py -v

Instalación/ejecución de extremo a extremo basada en Docker (en caché mediante `Dockerfile.test`):```bash
HATE_CRACK_RUN_DOCKER_TESTS=1 uv run pytest tests/test_docker_script_install.py -v

La prueba E2E de Docker también descarga un pequeño subconjunto de rockyou y ejecuta un crackeo básico con hashcat para validar la integración con herramientas externas.

Prueba de extremo a extremo con la VM de Lima (solo macOS):

Requisitos previos: Lima y rsync deben estar instalados.```bash brew install lima

La VM de prueba se aprovisiona automáticamente con todas las dependencias de 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

Esta prueba valida la instalación y ejecución dentro de una VM Linux ligera en macOS.

Estructura de las pruebas

  • tests/test_hashview.py: Suite de pruebas completa para la clase HashviewAPI con respuestas de API simuladas, que incluye:
    • Listado de clientes y validación de datos
    • Pruebas de autenticación y autorización
    • Funcionalidad de carga de archivos hash
    • Flujo de trabajo completo de creación de trabajos

Todas las pruebas utilizan llamadas a la API simuladas, por lo que pueden ejecutarse sin conectividad a un servidor Hashview.


(1) Quick Crack (2) Extensive Pure_Hate Methodology Crack (3) Brute Force Attack (4) Top Mask Attack (5) Fingerprint Attack (6) Combinator Attacks (7) Hybrid Attack (8) Pathwell Top 100 Mask Brute Force Crack (9) PRINCE Attack (10) Bandrel Methodology (11) Loopback Attack (12) LLM Attack (13) OMEN Attack (14) Ad-hoc Mask Attack (15) Markov Brute Force Attack (16) N-gram Attack (17) Permutation Attack (18) Random Rules Attack (19) Combipow Passphrase Attack (20) PCFG Attack (21) PRINCE-LING Attack (22) Spoonman Attack (23) Rosetta Attack (24) Corporate Masks Brute Force (25) Smart Mask Attack

(80) Wordlist Tools (81) Rule File Tools (82) Notifications (83) Mask Tools

(93) Regenerate .out from POT file (94) Hashview API (95) Analyze hashes with Pipal (96) Export Output to Excel Format (97) Display Cracked Hashes (98) Display README (99) Quit

Select a task:```

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.

¿Qué regla(s) te gustaría ejecutar?
(1) best64.rule
(2) d3ad0ne.rule
(3) T0XlC.rule
(4) dive.rule
(99) YOLO...ejecutar todas las reglas
Introduce una lista de reglas separadas por comas que te gustaría ejecutar. Para ejecutar reglas encadenadas usa el símbolo +.
Por ejemplo, 1+1 ejecutará best64.rule encadenada dos veces y 1,2 ejecutará best64.rule y luego d3ad0ne.rule secuencialmente.
Elige sabiamente:```




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

Categorías