Saltar la navegación

Más sobre John The Ripper

Como ya se ha mencionado, John The Ripper es una herramienta de seguridad muy popular, ya que permite a los administradores de sistemas comprobar que las contraseñas de los usuarios son suficientemente buenas. Es capaz de autodetectar el tipo de cifrado de entre muchos disponibles, y se puede personalizar su algoritmo de prueba de contraseñas. Eso ha hecho que sea uno de los más usados en este campo.

El funcionamiento de JtR consiste en utilizar un conjunto de palabras como posibles contraseñas, y para cada una de ellas, la cifra y la compara con el hash a descifrar. Si coinciden, es que la palabra era la contraseña correcta.

Esto funciona bien porque la mayor parte de las contraseñas que usa la gente son palabras de diccionario. Pero JtR también prueba con variaciones de estas palabras: les añade números, signos de puntuación, mayúsculas y minúsculas, intercambia letras, combina palabras, etc. Además, ofrece el típico sistema de fuerza bruta en el que se prueban todas las combinaciones posibles, sean palabras o no. Este es el sistema más lento, y usado por los administradores, solo en casos concretos, dado que los otros modos de trabajo que tiene, single crash y wordlist, permiten descubrir muy rápidamente las contraseñas débiles.

Para hacer uso de JtR podemos instalar en Debian la versión libre o compilar la versión Jumbo que trabaja con más algoritmos de cifrado. En los puntos anteriores se explicó cómo disponer de ambas versiones del programa.

Una vez instalado, la configuración se encuentra en el fichero john.conf (también puede trabajar con john.ini, pensado más para windows):

  • Si se ha instalado en Debian a través del paquete john, la configuración se busca en el directorio ~/.john y si no se encuentra, en /etc/john, y si tampoco se encuentra, por último la busca en el directorio /usr/share/john.
  • Si se ha instalado la versión Jumbo de JtR a través de la compilación del código fuente, la configuración está en el directorio run dentro del directorio donde se compiló.

En el fichero john.conf se pueden establecer valores para opciones globales, definir reglas para los modos single y wordlist, asignar valores a los parámetros del modo incremental e incluso definir nuevos modos externos de craqueo.

Este fichero está constituido por secciones, cada una de las cuales comienza por una línea donde está el nombre de la sección entre corchetes. Además se tiene que tener en cuenta lo siguiente:

  • Los nombres de las variables y de las secciones no diferencian entre mayúsculas y minúsculas.
  • Las líneas de comentarios comienzan por una almohadilla ( # ) o un punto y coma ( ; ).

La sección general se llama [Options], y se utiliza para asignar valores a ciertas variables que utiliza JtR, por ejemplo:

  • Wordlist: Con esta opción se indica cuál será el diccionario que utilizará JtR en el modo wordlist cuando no se especifique ninguno en la línea de comando. Por defecto es el fichero password.lst.
  • Idle: Se utiliza para indicar si JtR utilizará únicamente ciclos inactivos de las CPU o no.
  • Save: Indica el número de segundos tras los cuales se guarda el estado en el que se encuentra el proceso de descifrado, y así, si el ordenador se bloqueara, se podría continuar a partir de ese punto y no se tendría que empezar de nuevo todo el proceso. Por defecto son 600 segundos.
  • Beep: Indica si se quiere que JtR emita un pitido cada vez que se descifre una contraseña.

Por ejemplo:

[Options]
# Wordlist file name, to be used in batch mode
Wordlist = $JOHN/password.lst
# Use idle cycles only
Idle = Y
# Crash recovery file saving delay in seconds
Save = 600
# Beep when a password is found (who needs this anyway?)
Beep = N

Las reglas que utilizan los modos wordlist y single crack para generar las palabras que se utilizarán para descubrir las contraseñas, se especifican en secciones independientes, concretamente en las secciones [List.Rules.Wordlist] y [List.Rules.Single], respectivamente. Estas reglas, una por línea, se aplican a cada una de las palabras del diccionario en el modo wordlist, y a la información extraída del fichero /etc/passwd en el modo single crack.

Estas reglas que usa JtR están basadas en la sintaxis de las reglas del programa Crack, y también hay otros programas que hacen lo mismo, como por ejemplo Hashcat, por lo que, con algunas pequeñas diferencias a tener en cuenta, entre estos tres programas pueden intercambiarse las reglas de transformación. Pero una mejora importante, que incorporan tanto JtR como Hashcat, es la introducción de un preprocesador, de forma que usando determinados símbolos, el preprocesador puede convertir una regla en varias.

# "Single crack" mode rules
[List.Rules:Single]
:
-s x**
-c (?a c Q
-c l Q
-s-c x** /?u l

# Wordlist mode rules
[List.Rules:Wordlist]
:
-c >3 !?X l Q
-c (?a >2 !?X c Q
<* >2 !?A l p

Para definir los parámetros del modo incremental, es necesario crear una sección usando [Incremental:NAME], donde NAME es el nombre del modo incremental que se está parametrizando. En el fichero de configuración de JtR ya existen algunos modos incrementales creados y pueden utilizarse como plantillas.

Algunas de las variables que pueden asignarse son las siguientes:

  • File: Especifica el fichero que contiene el conjunto o juego de caracteres con el que se formarán las contraseñas.
  • MinLen: Indica la longitud de la contraseña más pequeña. Por defecto 0 (cadena vacía).
  • MaxLen: Indica la longitud de la contraseña más larga. Por defecto 8.
  • CharCount: Establece la cantidad de caracteres distintos como mínimo que poseerá el juego de caracteres. Si tiene menos, se producirá un error.
  • Extra = Caracteres: Especifica algunos caracteres extra, distintos a los del juego de caracteres, que podrán ser usados para formar las potenciales contraseñas, aunque JtR tendrá en cuenta que estos caracteres aparecen con menos frecuencia en las contraseñas.
# Incremental modes
[Incremental:ASCII]
File = $JOHN/ascii.chr
MinLen = 0
MaxLen = 13
CharCount = 95

[Incremental:Alnum]
File = $JOHN/alnum.chr
MinLen = 1
MaxLen = 13
CharCount = 62

[Incremental:Alpha]
File = $JOHN/alpha.chr
MinLen = 1
MaxLen = 13
CharCount = 52

Otra posibilidad que da el fichero de configuración de JtR es la de deshabilitar algoritmos de cifrado concretos para la autodetección, es decir, algoritmos que JtR no tendrá en cuenta cuando analiza el fichero de claves para ver con qué algoritmo están cifradas. Para hacer esto hay que crear la sección [Disabled:Formats]:

[Disabled:Formats]
LM = Y
md5crypt = Y

Hay que tener en cuenta que si un algoritmo se ha deshabilitado para la autodetección, no significa que no se pueda utilizar explícitamente con la opción --format.

En la versión Jumbo de JtR, el fichero de configuración se puede dividir en varios ficheros e incluirse estos, en john.conf, con la instrucción .include "fichero":

...
.include "$JOHN/mis-reglas.conf"
...

Y también, pueden crearse nuevas secciones copiando el contenido de otras, usando para esto la instrucción .include [sección], por ejemplo:

# For Single Mode against fast hashes
[List.Rules:Single-Extra]
.include [List.Rules:Single]
.include [List.Rules:Extra]
.include [List.Rules:OldOffice]

JtR trabaja también en un cuarto modo denominado externo, para lo cual se debe crear la sección [List.External:NAME], donde NAME será el nombre del modo externo que se esté creando. En esta sección lo que hay que hacer es definir completamente el funcionamiento del modo mediante el desarrollo de las funciones init(), filter(), generate() y restore(), que son la base del funcionamiento de JtR, aunque no tienen que estar siempre todas presentes. Estas funciones se deben codificar utilizando un lenguaje C reducido que el propio JtR incorpora y que puede compilar.

# A simple cracker for LM hashes
[List.External:LanMan]
int length;                             // Current length
int maxlength;

void init()
{
        if (req_minlen)
                length = req_minlen;
        else
                length = 1;
        if (req_maxlen)
                maxlength = req_maxlen;
        else                                    // the format's limit
                maxlength = cipher_limit;
        word[0] = 'A' - 1;              // Start with "A"
        word[length] = 0;
}

void generate()
{
        int i;

        i = length - 1;                 // Start from the last character
        while (++word[i] > 'Z')         // Try to increase it
        if (i)                          // Overflow here, any more positions?
                word[i--] = 'A';        // Yes, move to the left, and repeat
        else                            // No

        if (length < maxlength) {
                word[i = ++length] = 0; // Switch to the next length
                while (i--)
                        word[i] = 'A';
                return;
        } else {
                word = 0; return;       // We're done
        }
}

void restore()
{
        length = 0;                     // Calculate the length
        while (word[length]) length++;
}

Una vez que JtR está configurado como queremos, ya podemos utilizarlo y para ello debemos dominar las opciones de línea de comando que posee. Vamos a ver a continuación las más importantes, aunque algunas ya se han comentado en puntos anteriores.

En primer lugar, para consultar cuáles son estas opciones, debemos ejecutar el comando sin opciones:

# john
John the Ripper password cracker, version 1.8.0
Copyright (c) 1996-2013 by Solar Designer
Homepage: http://www.openwall.com/john/

Usage: john [OPTIONS] [PASSWORD-FILES]
--single                   "single crack" mode
--wordlist=FILE --stdin    wordlist mode, read words from FILE or stdin
--rules                    enable word mangling rules for wordlist mode
--incremental[=MODE]       "incremental" mode [using section MODE]
--external=MODE            external mode or word filter
--stdout[=LENGTH]          just output candidate passwords [cut at LENGTH]
--restore[=NAME]           restore an interrupted session [called NAME]
--session=NAME             give a new session the NAME
--status[=NAME]            print status of a session [called NAME]
...

Si ejecutamos el comando john sin opciones con uno o varios ficheros de claves (todas las claves con el mismo algoritmo de cifrado):

# john claves

ejecutará los modos configurados en el primer fichero john.conf que encuentre en los siguientes directorios:

  1. ~/.john
  2. /etc/john
  3. /usr/share/john

Si no hemos cambiado nada desde la instalación, ejecutará lo especificado en /etc/john/john.conf, que consiste en lo siguiente:

  1. Comienza con el modo single crack, aplicando las reglas especificadas en dicha sección a las palabras que obtiene de la información de /etc/passwd.
  2. Ejecuta el modo wordlist, aplicando sus reglas a cada una de las palabras del fichero que indique la variable Wordlist. Si dicha variable no contiene ningún valor, usa el fichero /usr/share/john/password.lst.
  3. Aplica el modo incremental de nombre ASCII, y si no estuviera definido, muestra un mensaje de error.

Si especificamos opciones hay que tener en cuenta lo siguiente:

  1. Se tiene en cuenta la diferencia entre mayúsculas y minúsculas. Por ejemplo: --single es correcto, --Single es incorrecto.
  2. Se pueden abreviar las opciones tanto como se quiera, siempre que no haya ambigüedad con otra opción. Por ejemplo: --single y --si es lo mismo y correcto, -s es incorrecto.
  3. Pueden ir con un guión o con dos. Por ejemplo: --single y -single es lo mismo y correcto.
  4. Los argumentos de las opciones se pueden separar con : o con =. Por ejemplo, -w:palabras.lst y -w=palabras.lst es lo mismo y correcto.

La opción --single[=SECCIÓN] se utiliza para lanzar solo el modo single crack. Si no se especifica ninguna sección se utilizan las reglas de la sección [List.Rules:Single].

# john --single=Single-2 claves

El ejemplo anterior ejecuta sobre el fichero claves el modo single crack con las reglas de la sección [List.Rules:Single-2].

Para activar solo el modo wordlist se debe usar la opción --wordlist[=DICCIONARIO], donde DICCIONARIO es el fichero con las palabras que se utilizarán como potenciales contraseñas. Si no se indica ningún diccionario se utilizará el especificado en la variable Wordlist de john.conf, y si tampoco existe dicha variable, se utilizará /usr/share/john/password.lst.

Esta opción, está íntimamente relacionada con la opción --rules[=SECCIÓN], pues si acompaña a --wordlist, las potenciales contraseñas que se utilizarán serán las generadas al aplicar a cada una de las palabras del diccionario las reglas de la sección de --rules, o de [List.Rules:Wordlist] si no se ha dado ninguna sección.

En el caso de que --wordlist no vaya con la opción --rules, solo se usarán las palabras del diccionario sin transformación alguna.

La posibilidad de indicar una sección con --rules, solo la ofrece la versión Jumbo de JtR, la versión libre no tiene esta posibilidad y por lo tanto, --rules se refiere siempre a las reglas de la sección [List.Rules:Wordlist].

El siguiente ejemplo aplica al fichero claves solo el modo wordlist utilizando las palabras del diccionario lista.lst, cuyas palabras se transformarán con las reglas de la sección [List.Rules:Wordlist]:

# john -w:lista.lst --rules claves

Activar solo el modo incremental requiere de la opción --incremental[=SECCIÓN], y si no se especifica SECCIÓN se asume por defecto ASCII (o LM_ASCII si se estuviera utilizando el algoritmo LM de Windows), es decir, lo indicado en [Incremental:ASCII]. El siguiente ejemplo aplica al fichero claves, el método de fuerza bruta para contraseñas de solo números con una longitud que va desde 1 hasta 20.

# john -incremental:Digits claves

El modo Incremental:Digits está definido en john.conf de la siguiente manera:

[Incremental:Digits]
File = $JOHN/digits.chr
MinLen = 1
MaxLen = 20
CharCount = 10

Para aplicar un modo externo se debe usar la opción --external=SECCIÓN, donde SECCIÓN, en este caso, es obligatorio. Así, por ejemplo, para aplicar el modo externo LanMan que se puso como ejemplo anteriormente, ejecutaríamos:

# john --external:LanMan claves

Los modos de craqueo, excepto single crack, pueden utilizarse solo para mostrar por la salida estándar las potenciales contraseñas, sin aplicarles el algoritmo de cifrado para obtener la cadena hash y comparar el resultado con el hash a descifrar. Es necesario para esto utilizar la opción --stdout[=LENGTH], donde LENGTH indica la longitud de la contraseña más larga a mostrar, truncando el texto que exceda.

Con la opción --stdout nunca se debe especificar un fichero de contraseñas a descifrar.

Veamos algunos ejemplos:

# cat .john/john.conf
......
[List.Rules:Wordlist]
# Añade 1 al final
$1
# Añade 2 al final
$2
......
# cat lista.lst
usuario
coche
root
# john -w:lista.lst --stdout
Press 'q' or Ctrl-C to abort, almost any other key for status
usuario
coche
root
3p 0:00:00:00 100% 300.0p/s root
# john -w:lista.lst --rules --stdout
Press 'q' or Ctrl-C to abort, almost any other key for status
usuario1
coche1
root1
usuario2
coche2
root2
6p 0:00:00:00 100% 600.0p/s root2
#

# ./john -incremental:Digits --stdout
12345
123456
11111
121288
123444
121290
010189
010190
012222
012233
22222
21234
12123
11234
......
#

# ./john -external:LanMan --stdout
A
B
C
D
E
F
......
#

Como ya se mencionó, cuando se ejecuta JtR y se pulsa una tecla cualquiera que no sea q o Ctrl+C, se muestra el estado en el que se encuentra el proceso de descifrado. Si se pulsan q o Ctrl+C se suspende la ejecución, la cual puede ser reanudada con la opción --restore[=NAME] en el punto en el que se interrumpió. Para conseguir esto, JtR usa los ficheros ~/.john/john.log y ~/.john/john.rec.

Es posible ejecutar varias instancias de JtR de forma simultánea, y para que podamos interrumpirlas y posteriormente reanudarlas sin que JtR se líe, necesitamos ejecutar cada instancia en una sesión independiente, que hará que se creen ficheros .log y .rec distintos, de forma que así sí es factible diferenciar las distintas ejecuciones.

Para ejecutar JtR en una instancia concreta, se debe usar la opción --session=NAME, donde NAME será el nombre de la sección y NAME.log y NAME.rec, serán los ficheros que lleven el control de lo que va sucediendo en dicha sección.

Por ejemplo, en una terminal se puede ejecutar:

# john --session:s1 claves1

y en otra terminal:

# john --session:s2 claves2

Si detenemos la sesión s1 pulsando la tecla q, se crearán los ficheros s1.log y s1.rec, y su reanudación se haría así:

# john --restore:s1

Cuando una sesión está ejecutándose o detenida, podemos utilizar la opción --status[=NAME] para ver cuál es la situación en la que se encuentra el proceso:

# john --status:s1

Otras opciones de JtR que ya se han visto son: --show, --test, --users, --groups, --shells y --format. Existen otras, y la versión Jumbo de JtR tiene más opciones que la versión libre. Es aconsejable consultar la documentación para conocerlas y mejorar el uso de JtR.

Licencia: licencia de software libre GPL