Para descifrar contraseñas, a veces es útil combinar listas de palabras de manera que se concatenen palabras de múltiples listas. Este artículo muestra tres formas de hacerlo.
Descripción del problema
El descifrado de contraseñas consiste en realizar muchos intentos para adivinar la contraseña correcta. El éxito de esto depende en gran medida de la calidad del diccionario que se utilice como base de las suposiciones. A veces es útil combinar dos listas de palabras, de manera que las contraseñas consistan en concatenaciones de palabras de una lista con palabras de una segunda lista.
Por ejemplo, una lista de palabras puede contener estaciones del año:
- primavera
- verano
- otoño
- invierno
La segunda lista de palabras puede contener años:
- 2023
- 2024
- 2025
Al combinar ambas, se pueden obtener contraseñas comunes:
- primavera2023
- verano2023
- …
- otoño2025
- invierno2025
#1. Combinator de Hashcat
Hashcat tiene una utilidad llamada combinator, que hace exactamente lo que se busca:
Cada palabra de archivo2
se agrega al final de cada palabra de archivo1
y luego se imprime en la salida estándar (STDOUT).
$ ./combinator.bin
uso: ./combinator.bin archivo1 archivo2
En lugar de leer ambos archivos completamente en memoria, lee uno de los archivos varias veces. La ventaja es que esto funciona con archivos muy grandes que no cabrían en memoria. Sin embargo, es cuestionable si este es un escenario realista; combinar dos archivos de 1 GB resultaría en un archivo de aproximadamente 200 petabytes, por lo que se acabaría el espacio en disco antes que la memoria.
Combinator.bin
funciona bien. Hace lo que se supone que debe hacer y funciona en múltiples plataformas.
#2. Utilidad join de la shell
El comando join
de la shell también puede combinar listas de palabras. Sin embargo, está pensado para unir archivos según una clave. Si se tienen dos archivos con datos tabulados separados por tabuladores, puede realizar algo similar a un join en SQL. Pero aquí no hay una clave, y se necesitan algunos trucos para realizar la combinación más simple que se busca.
Primero, se quiere unir todas las líneas, sin importar cuál sea el valor de la clave. Para hacer esto, se indica a join
que use una clave inexistente; como el valor de una clave inexistente siempre es vacío, todas las líneas coinciden. La opción -j 2
usa la segunda columna, que presumiblemente no existe.
Sin embargo, algunas líneas pueden tener una segunda columna si la línea contiene espacios en blanco. Para asegurarse de que no haya una segunda columna, se indica a join que divida las líneas no por espacios en blanco, sino por algún carácter que sea poco probable que aparezca en las listas de palabras, como el byte nulo. La opción -t $'\0'
le dice a join que divida las líneas en campos usando el byte nulo.
Al unir, join
no concatena las palabras, sino que las coloca en campos separados. Así que entre cada par de palabras combinadas está el separador de campos, que en este caso es el byte nulo. Para solucionar esto, simplemente se usa tr
para eliminar todos los bytes nulos. El comando completo queda así:
join -j 2 -t $'\0' archivo1.txt archivo2.txt | tr -d '\000'
Esto funciona. Es más complicado de lo necesario, pero la ventaja es que estas herramientas ya están presentes en la mayoría de los sistemas.
#3. Uso de itertools.product de Python
Por supuesto, esta tarea simple también se puede realizar con un pequeño script en Python o cualquier otro lenguaje adecuado para scripts rápidos y pequeños. Python ya tiene una funcionalidad para combinar listas como se desea: itertools.product. Se leen los archivos en listas, se llama a itertools.product y se convierte la lista resultante nuevamente en cadenas de texto:
import sys
import itertools
lists = []
for filename in sys.argv[1:]:
words = []
with open(filename) as fp:
for line in fp:
words.append(line.rstrip())
lists.append(words)
for element in itertools.product(*lists):
print("".join(element))
Conclusión
Este artículo presentó tres herramientas para combinar listas de palabras como un producto cartesiano. La utilidad de hashcat está hecha para esta tarea y funciona bien. El comando de la shell también funciona, pero es más complicado de lo que se esperaría para una tarea tan sencilla. Finalmente, usando un script en Python, cualquier tarea es solucionable.
Lee también: 5 Formas de Crear Diccionario Hacking para Fuerza Bruta