Hoy recibí mi factura mensual de mi proveedor de internet y algo me pareció extraño.
La factura, incluida en el correo, venía en un archivo ZIP con contraseña.
Sin mencionar lo extraño que resulta en estos días recibir un adjunto en forma de archivo ZIP (spam, malware, phishing, etc.), la contraseña que eligieron me pareció muy débil.
Es la fecha de nacimiento del titular de la cuenta en el formato YYMMDD.
Hice un cálculo muy burdo mentalmente mientras estaba en el gimnasio y resultó en muy pocas combinaciones posibles. Después de usar una herramienta en línea para calcular cuántos días han pasado (ya que no todas las combinaciones resultarían en una fecha válida) desde el 1900-01-01, resulta que las combinaciones son solo 44,075 (hasta el 2020-09-14).
Sabiendo que las herramientas optimizadas que usan el poder de las GPU para descifrar hashes pueden hacer millones de intentos por segundo, quise ver qué tan rápido se podía adivinar la contraseña sin usarlas y utilizando solo la CLI de Linux/macOS (ya que solo tenía acceso a un VPS en el gimnasio).
Se me ocurrió el siguiente código que funciona en macOS:
echo {1..44000} | xargs -P 16 -n 1 -I{} date -v "-{}d" +"%y%m%d" | xargs -P 16 -I{} sh -c 'unzip -qqoP "{}" 0417160508.zip && echo "{}" && exit 255'
El comando es bastante simple en su funcionamiento, aunque parece complicado.
echo {1..44000} genera los números del 1 al 44,000 y los pasa al siguiente paso.
xargs -P 16 -n 1 -I{} date -v "-{}d" +"%y%m%d" – toma la entrada del primer paso y genera fechas en el formato YYMMDD aprovechando la funcionalidad de date para “aumentar” una fecha con una cantidad específica. En este caso tomaría X días a partir de la fecha actual, donde X es el número generado en el primer paso. De esta forma podemos generar fechas desde hoy hasta los años 1900.
El tercer paso es el más interesante, así que lo voy a dividir en dos partes:
xargs -P 16 -I{} sh -c '...'
Esto toma las fechas generadas en el paso 2 y ejecuta un comando sobre cada una de esas fechas. -P 16 aquí significa que va a ejecutar esto en 16 procesos paralelos, para hacer que el procesamiento de los datos sea más rápido. El mismo truco se aplica en el paso 2 para acelerar la generación de fechas.
La segunda parte es donde ocurren los intentos:
unzip -qqoP "{}" 0417160508.zip && echo "{}" && exit 255
Lo que hace esto es primero intentar descomprimir el archivo zip usando la contraseña generada en el paso 2. Si tiene éxito, imprime (echo) la contraseña adivinada y luego exit 255 obliga a xargs a detener la ejecución. No queremos seguir adivinando si ya se encontró la contraseña.
En resumen, fue una muy mala decisión elegir esto como contraseña para el archivo, porque ejecutar el comando anterior toma solo unos 10 segundos para adivinar la contraseña correcta de mi factura. No mucho más para cualquier otra persona.