Ghost AcademyGhostOffensive · Ghost Academy
GhostOffensiveMódulo 12Con laboratorio

Ataques a contraseñas

La contraseña sigue siendo la puerta más atacada. Este módulo separa las dos grandes familias: los ataques offline (tienes los hashes y los rompes en tu equipo, sin límite de intentos) y los ataques online (pruebas credenciales contra un servicio vivo, con todas las restricciones que eso impone).

Objetivos de la unidad

1. Cómo se guardan las contraseñas (y por qué importa)

Una aplicación bien hecha no guarda tu contraseña: guarda su hash. Un hash es una función de un solo sentido: es fácil calcular hash("Verano2024"), pero computacionalmente inviable ir del hash a la contraseña. Al hacer login, la aplicación hashea lo que escribes y compara hashes. Esto significa que quien roba la base de datos no obtiene contraseñas, sino hashes, y por eso el ataque offline consiste en adivinar: probar candidatas, hashearlas y ver cuál produce el hash robado. No se "descifra" un hash; se acierta la entrada.

Aquí entra la sal (salt): un valor aleatorio único que se añade a cada contraseña antes de hashearla y se guarda junto al hash. Su función es doble: que dos usuarios con la misma contraseña tengan hashes distintos, y —clave— derrotar las rainbow tables (tablas precalculadas de hash→contraseña para millones de claves comunes). Con sal, esas tablas precalculadas no sirven: habría que rehacerlas para cada sal posible. Por eso un hash sin sal (MD5, SHA-1, NTLM crudos) es tan débil, y uno con sal única obliga a atacar cada contraseña por separado.

2. Credenciales por defecto

Antes de romper nada, lo más barato: muchos equipos y aplicaciones se instalan con usuario y contraseña de fábrica (admin/admin, root/root, admin/password) que nadie cambia. Es lo primero que se prueba y funciona a menudo, sobre todo en dispositivos de red, cámaras, paneles y bases de datos. Hay listas públicas de credenciales por defecto por fabricante (DefaultCreds, SecLists). Coste cero, impacto a veces total.

3. Identificar el hash antes de romperlo

No se puede atacar lo que no se sabe qué es: cada algoritmo tiene su modo en hashcat, y elegir mal el modo no crackea nada. Se reconoce por longitud y formato:

AlgoritmoLongitud / formatoModo hashcat¿Sal?
MD532 caracteres hex-m 0No
SHA-140 caracteres hex-m 100No
SHA-25664 caracteres hex-m 1400No
NTLM32 caracteres hex (Windows)-m 1000No
bcrypt$2a$/$2y$ + coste + sal-m 3200Sí

hashid o hashcat --identify ayudan, pero fíjate: MD5 y NTLM tienen la misma longitud (32 hex), así que la longitud no basta y hay que usar el contexto (¿viene de un volcado de Windows? entonces NTLM). El prefijo $2y$ de bcrypt, en cambio, es inconfundible, y además codifica su factor de coste (el 08 en $2y$08$...): cada +1 duplica el tiempo de cálculo.

4. Los modos de ataque de hashcat

La fuerza bruta pura (probar todas las combinaciones) es inviable salvo para contraseñas cortísimas. Lo rentable es ser listo con las candidatas. Los modos, de más a menos rentable en la práctica:

ModoQué pruebaCuándo
Diccionario (-a 0)Palabras de una lista de contraseñas reales filtradasSiempre lo primero
Diccionario + reglas (-a 0 -r)Cada palabra con mutaciones: Verano → Verano1, V3r4no!...Cubre las "casi débiles"; enorme rendimiento
Máscara (-a 3)Un patrón conocido: 4 dígitos, o Mayúscula+5 letras+2 dígitosCuando conoces la política de contraseñas
Híbrido (-a 6/7)Diccionario pegado a una máscara (palabra+2024)Patrones tipo "palabra + año"

El diccionario de referencia es rockyou.txt (14 millones de contraseñas de una brecha real), incluido en Kali. Las reglas son la clave del rendimiento: aplican mutaciones humanas típicas (añadir año, capitalizar, sustituir a→@) a cada palabra, cubriendo el espacio de contraseñas "que la gente cree seguras" sin el coste de la fuerza bruta.

kali@lab
$ sudo gunzip -k /usr/share/wordlists/rockyou.txt.gz   # en Kali viene comprimido
kali@lab
$ hashcat -m 0 -a 0 hash.txt /usr/share/wordlists/rockyou.txt   # diccionario
kali@lab
$ hashcat -m 0 -a 0 hash.txt rockyou.txt -r /usr/share/hashcat/rules/best64.rule   # con reglas
kali@lab
$ hashcat -m 0 -a 3 hash.txt '?d?d?d?d'   # máscara: 4 dígitos

5. Hashes rápidos frente a lentos: por qué importa tanto

La diferencia entre un algoritmo y otro no es académica: decide si una contraseña cae en segundos o en siglos. MD5, SHA-1 y NTLM se diseñaron para ser rápidos, lo que los hace pésimos para guardar contraseñas: una sola GPU moderna prueba miles de millones de candidatas por segundo contra MD5. bcrypt se diseñó al revés, para ser deliberadamente lento y con sal única, de modo que esa misma GPU baja a unos pocos miles por segundo: seis o siete órdenes de magnitud menos.

La consecuencia práctica. Contra MD5 sin sal, un diccionario de 14 millones se agota en una fracción de segundo, y hasta la fuerza bruta de contraseñas medianas es viable. Contra bcrypt, solo es realista el ataque de diccionario + reglas: probar contraseñas probables, porque no da tiempo a probar todas. Por eso una contraseña del top de rockyou cae en ambos casos (está entre las primeras que se prueban), pero una contraseña larga y aleatoria es prácticamente irrompible bajo bcrypt y sigue siendo atacable bajo MD5. La sal y la lentitud compran tiempo, no dan invulnerabilidad: lo que de verdad salva es una contraseña que no esté en ningún diccionario ni siga un patrón predecible.

6. Ataques online: fuerza bruta y rociado

Cuando no tienes los hashes, atacas el servicio vivo. Aquí el mundo cambia: hay bloqueos de cuenta, limitación de intentos, y cada intento queda registrado. La velocidad ya no la pones tú, la pone el servidor, y el sigilo importa. Dos enfoques opuestos:

kali@lab
$ hydra -l kiosko -P pins.txt objetivo http-post-form "/login:usuario=^USER^&clave=^PASS^:incorrectos"   # fuerza bruta de PIN
kali@lab
$ hydra -L usuarios.txt -p "Primavera2024" objetivo http-post-form "/login:usuario=^USER^&clave=^PASS^:incorrectos"   # rociado

En el http-post-form de hydra, la sintaxis es ruta:parámetros:condición_de_fallo. La condición de fallo (aquí incorrectos) es el texto que aparece cuando el login falla; hydra asume acierto cuando ese texto no está en la respuesta. Elegir mal esa cadena es la causa nº 1 de que hydra "no encuentre nada" aunque las credenciales sean correctas: si el texto aparece también en las respuestas de éxito, nunca detecta el acierto.

7. Defensas

Cerrar el círculo, porque el informe lo exige: (1) almacenar con un hash lento y con sal (bcrypt, scrypt o Argon2, nunca MD5/SHA crudos); (2) MFA, que hace que una contraseña robada no baste por sí sola —la defensa más eficaz contra el rociado—; (3) limitación de intentos y bloqueo temporal contra los ataques online; (4) política de contraseñas que empuje a claves largas y no reutilizadas (y comprobación contra listas de contraseñas filtradas); y (5) desactivar o cambiar todas las credenciales por defecto.

Para profundizar
🧰 Herramientas relacionadas (Ghost Academy)

Guías y laboratorios ya publicados en Ghost Academy sobre las herramientas de este módulo:

Hashcat · Hashcat (lab) · John the Ripper · John the Ripper (lab) · Cracking de contraseñas Windows · Crunch (wordlists) · Responder / LLMNR

Laboratorio: Lumen Tech

⬇ Descargar laboratorio (ZIP)

Descomprime, lee el LEEME.md y lanza startlab.sh. Combina crackeo offline (un volcado con 4 algoritmos distintos) y ataques online (rociado y fuerza bruta contra el login). 8 flags GO{...}, verificables en http://localhost:8989/verificador.

Necesitas hashcat/john con rockyou para los retos 3-6, y hydra para los retos 7-8.

¿Atascado o ya terminado? La solución paso a paso muestra cada ataque. Úsala cuando lo hayas intentado.

Autoevaluación

  1. ¿Por qué se dice que un hash no se "descifra" sino que se "adivina"?
  2. ¿Qué hace la sal exactamente y por qué derrota a las rainbow tables?
  3. Diferencia entre los modos diccionario, reglas y máscara de hashcat. ¿Cuándo usarías cada uno?
  4. ¿Qué hace que bcrypt sea mucho más costoso de atacar que MD5, y por qué aun así cae una contraseña del top de rockyou?
  5. ¿Por qué el rociado de contraseñas evita los bloqueos de cuenta y la fuerza bruta clásica no?
  6. ¿Cómo distingue hydra en un http-post-form un intento correcto de uno fallido, y qué error rompe esa detección?
  7. Tienes un hash de 32 caracteres hexadecimales. ¿Qué dos algoritmos podría ser y cómo decides cuál?
  8. ¿Cuál es la defensa más eficaz contra el rociado de contraseñas y por qué?