viernes, mayo 22, 2020

Aplicaciones prácticas de Docker en ciberseguridad: Contenedores para “crackear” passwords utilizando GPU

Continuamos con nuestra serie de artículos donde vamos publicando diferentes herramientas relacionadas con la ciberseguridad, eso sí, siempre con Docker como eje principal. En el primer artículo de esta serie contamos cómo crear nuestro propio Proxy para poder navegar por la red TOR. En esta ocasión, vamos a sacar partido a los contenedores Docker que también utilizan la GPU del equipo para romper o crackear contraseñas. 

Figura 1: Aplicaciones prácticas de Docker en ciberseguridad:
Contenedores para “crackear” passwords utilizando GPU


De esta forma, de una manera limpia y sencilla, puedes desplegar este tipo de herramientas en tu ordenador durante un Ethical Hacking. Recuerda que un buen punto de partida para comenzar en el maravilloso mundo de Docker es nuestro libro Docker:SecDevOps ;)

Figura 2: Libro de Docker:SecDevOps

Como ya hemos comentado más de una vez, la gran ventaja de Docker es el poder desplegar en pocos segundos, cualquier aplicación que necesitemos sin tener que realizar cambios en nuestro ordenador principal. Vamos con el caso de hoy.

Creando la imagen con doig (Docket Image Generator)

Para crear la colección de herramientas que necesites puedes utilizar la herramienta de Tuxotron, llamada doig, que ya presentamos en el anterior artículo. Para preparar la imagen que vamos a utilizar, ejecutaremos el siguiente comando:
doig -i mytools -t hashcat hashid seclists johntheripper

    Step 1/7 : FROM ubuntu:18.04
    ---> c3c304cb4f22
    ...
    ...
    Step 7/7 : COPY tools.txt .
    ---> 6d818093f1f0
    Successfully built 6d818093f1f0
    Successfully tagged mytools:latest

    Tools added to the image:
    [-] johntheripper: All john tools are under /opt/john/run
    [-] hashcat
    [-] hashid
    [-] seclists
Y ahora, lo primero que necesitamos saber a la hora de crackear una contraseña, asumiendo siempre que le tengamos en forma de hash, es precisamente saber que tipo de algoritmo de generación de hash es el que tenemos entre manos.: md5, sha1, bcrypt, etcétera. 

Identificando el tipo de Hash

Para ello, si no sabemos qué tipo de hash tenemos, la herramienta hashid (que hemos añadido antes en nuestra imagen) es nuestra amiga. En nuestro caso vamos a crear un fichero de texto llamado samples.txt con varios hashes. Estos no tienen porque ser del mismo tipo. Vamos a utilizar hashid para que nos identifique los tipos. 

Figura 3: Libro de Cifrado de las comunicaciones digitales:
De la cifra clásica a RSA (2ª Edición) de 0xWord.

Por supuesto, no podemos dejar de recomendar el libro de Cifrado de las comunicaciones digitales: de la cifra clásica a RSA (2ª Edición) que explica en detalle el cifrado y el hashing. Asumiendo que tenemos nuestro fichero samples.txt en el directorio en el que nos encontramos, podemos ejecutar nuestro contenedor montando dicho fichero dentro del mismo a modo de volumen:
docker run -it --rm -v $(pwd)/samples.txt:/opt/samples.txt mytools
Veamos el contenido de nuestro fichero samples.txt:
cat samples.txt
8743b52063cd84097a65d1633f5c74f5
b89eaac7e61417341b710b727768294d0e6a277b
fcf7c1b8749cf99d88e5f34271d636178fb5d130
b4b9b02e6f09a9bd760f388b67351e2b
127e6fbfe24a750e72930c220a8e138275656b8e5d8f48a98c3c92df2caba935
Como podemos ver tenemos 5 hashes en dicho fichero. Veamos que nos dice hashid:
hashid samples.txt
    --File 'samples.txt'--
    Analyzing '8743b52063cd84097a65d1633f5c74f5'
    [+] MD2
    [+] MD5
    [+] MD4
    ...
    ...
    [+] RAdmin v2.x
    Analyzing '127e6fbfe24a750e72930c220a8e138275656b8e5d8f48a98c3c92df2caba935'
    [+] Snefru-256
    [+] SHA-256
    [+] RIPEMD-256
    [+] Haval-256
    [+] GOST R 34.11-94
    [+] GOST CryptoPro S-Box
    [+] SHA3-256
    [+] Skein-256
    [+] Skein-512(256)
    --End of file 'samples.txt'—
Con hashid, se analiza cada hash y nos da una lista de posibles algoritmos correspondientes a cada hash. hashid también nos puede proporcionar el tipo de hash en formato john the ripper o hashcat. La opción *-j* nos ofrece el format jonh:
    hashid -j samples.txt
    --File 'samples.txt'--
    Analyzing '8743b52063cd84097a65d1633f5c74f5'
    [+] MD2 [JtR Format: md2]
    [+] MD5 [JtR Format: raw-md5]
    [+] MD4 [JtR Format: raw-md4]
    ...
    ...
Figura 4: Ejemplo de ejecución de hascat desde un contenedor
 buscando una contraseña usando fuerza bruta y utilizando GPU.
En el vídeo al final del artículo se detalla su ejecución.

Y la opción -m para el formato hashcat:
    hashid -m samples.txt
    --File 'samples.txt'--
    Analyzing '8743b52063cd84097a65d1633f5c74f5'
    [+] MD2
    [+] MD5 [Hashcat Mode: 0]
    [+] MD4 [Hashcat Mode: 900]
    [+] Double MD5 [Hashcat Mode: 2600]
    ...
    ...
Hashcat

Ahora vamos a ver un poco de información sobre hashcat. Para ver todas las opciones de esta herramienta, podemos ejecutarlo con la opción --help. Una de las opciones más importantes de hashcat son los tipos de hash, el cual podemos averiguar con el comando anteriormente visto hashid. Con la opción -m podemos especificar qué tipo de hash queremos usar. Mirando la ayuda podemos ver que la lista de modos es bastante amplia. Los modos más usados son:
      900 - MD4
        0 - MD5
     1000 - NTLM
     5500 - NetNTLMv1
     5600 - NetNTLMv2
     1100 - mscache1 (xp, w2k3)
     2100 - mscache2 (v, w7, w8, w10,w2k8+)
     3000 - LanManager
     1700 - SHA512
     7500 - Kerberos REQ
    13100 - Kerberos TGS-REP
      400 - Wordpress
     2500 - WPA
     2501 - WPA PMK
Otra opción importante a tener en cuenta es el tipo de ataque:
    0 - Straight (ataques basados en lista o diccionario de palabras)
    1 - Combination (ataques basados en varias listas o diccionarios de palabras)
    3 - Brute-force (fuerza bruta o con máscara)
    6 - Hybrid Wordlist + Mask (lista de palabras + fuerza bruta/máscara)
    7 - Hybrid Mask + Wordlist (fuerza bruta/máscara + lista de palabras)
Veamos un ejemplo de como crackear un hash md5 usando un diccionario:
    echo -n iloveu | md5sum
    edbd0effac3fcc98e725920a512881e0  -

    hashcat -m 0 -a 0 edbd0effac3fcc98e725920a512881e0
            /opt/SecLists/Passwords/Common-Credentials/10k-most-common.txt


    OpenCL API (OpenCL 1.2 LINUX) - Platform #1 [Intel(R) Corporation]
    ==================================================================
    * Device #1: Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz, 15953/16017 
                                       MB (4004 MB allocatable), 8MCU
    ...
    ...
    Dictionary cache built:
    * Filename..: /opt/SecLists/Passwords/Common-Credentials/10k-most-common.txt
    * Passwords.: 10000
    * Bytes.....: 83017
    * Keyspace..: 10000
    * Runtime...: 0 secs

    edbd0effac3fcc98e725920a512881e0:iloveu

    Session..........: hashcat
    ...
    ...
Como se puede apreciar, el hash edbd0effac3fcc98e725920a512881e0 ha sido encontrado:
edbd0effac3fcc98e725920a512881e0:iloveu
Con el parámetro -m especificamos el tipo de hash (0 - MD5), con -a el tipo de ataque, en este caso por diccionario, usando:

 /opt/SecLists/Passwords/Common-Credentials/10k-most-common.txt

Es posible usar varios diccionarios, en cuyo caso usaríamos la opción -a 1:
hashcat -a 1 -m 0 hash-to-crack diccionario1.txt diccionario2.txt ...
Es posible pasar un fichero de hashes también en vez de hashes individuales. Y por supuesto se pueden hacer ataques por fuerza bruta basado en patrones con ataques del tipo 3, y mezclando la fuerza bruta con patrones usando los ataques del tipo 6 y 7

Figura 5: Cracking Passwords con Docker

Incrementando la potencia de cálculo con contenedores y GPU

Hasta ahora, lo que hemos visto es el crackeo basado en CPU, pero realmente donde sacaremos más partido a todo este proceso será cuando usemos GPUs o FPGAs. Y esto también podemos hacerlo activando el acceso a la GPU del ordenador host por parte de los contenedores. Para poder usar la/s GPU/s dentro de contenedores Docker, tienes que instalar dentro de tu contenedor los drivers de tu GPU, y en el caso de NVIDIA tienes que instalar en tu host el paquete nvidia-docker2, como se especifica en este enlace


Pero para que te sea más sencillo de utilizar en un Ethical Hacking, nosotros hemos preparado una imagen de hashcat ya con todos estos requisitos instalados (excepto nvidia-docker2, eso lo tienes que instalar en el host) que hemos llamado hashcat-nvidia y que puedes añadir en la construcción con doig como puedes ver a continuación:
doig -u -i mytools -t seclists hashcat-nvidia hashid johntheripper
Una vez creada la imagen, levantamos el contenedor. Aún estamos perfeccionando la imagen, pero todavía tenemos que pasar algunas variables de entorno desde la misma línea de comandos cuando ejecutamos el docker run:
docker run -it --gpus all --rm -e NVIDIA_VISIBLE_DEVICES=all 
  -e LD_LIBRARY_PATH=/usr/local/nvidia/lib:/usr/local/nvidia/lib64:
  -e PATH=/usr/local/nvidia/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
  -e  NVIDIA_DRIVER_CAPABILITIES=compute,utility mytools
Aquí es importante introducir el comando –gpus all para que, de esta forma, podamos utilizar todas las GPUs disponibles en el host. En el siguiente vídeo podéis ver una prueba de crackeo por fuerza bruta de la misma contraseña (“iloveyou”) que utilizamos antes:


Figura 7: Cracking password con Docker usando GPUs

El viejo rockero, John the Ripper

Hasta ahora hemos hablado de hashcat que es quizás actualmente la herramienta más usada para estos menesteres. Pero hablemos también de un viejo rockero: John The Ripper (JtR), protagonista sin duda de muchas de las anécdotas de la historia de la informática y los hackers.

Figura 8: Libro de "Microhistorias: anécdotas y curiosidades
de la historia de la informática (y los hackers)"

Como hemos visto al inicio de esta entrada, creamos una imagen Docker en la que incluíamos JtR, así que si has seguido los pasos descritos hasta ahora debes de tener en tu contenedor dicha herramienta bajo el directorio /opt/john/run. Desde dicho directorio podemos invocar el comando john. Veamos la lista de tipos de hashes que JtR soporta:
    ./john --list=formats

    descrypt, bsdicrypt, md5crypt, md5crypt-long, bcrypt, scrypt, LM, AFS,
    tripcode, AndroidBackup, adxcrypt, agilekeychain, aix-ssha1, aix-ssha256,
    aix-ssha512, andOTP, ansible, argon2, as400-des, as400-ssha1, asa-md5,
    AxCrypt, AzureAD, BestCrypt, bfegg, Bitcoin, BitLocker, bitshares, Bitwarden,
    BKS, Blackberry-ES10, WoWSRP, Blockchain, chap, Clipperz, cloudkeychain,
    ...
El uso de JtR es muy sencillo, al igual que hashcat podemos usar diccionarios y fuerza bruta con patrones. Así que no vamos a entrar en más detalles sobre el propio JtR. Pero sí queremos añadir que la versión de JtR que instala doig es la versión Jumbo comunitaria, la cual viene cargada con utilidades que nos permite la conversión de ficheros en formato que JtR entiende. Por ejemplo:
    # En salida tendríamos los usuarios con sus hashes listo para ser crackeados con JtR
    ./unshadow /etc/passwd /etc/shadow > salida

    # Para convertir ficheros ssh con clave encriptada
    python3 ssh2john.py fichero-ssh-clave-encriptada > salida

    # Pone en salida el hash de la contreseña de una base de datos de keepass
    ./keepass2john fichero.kdb > salida
Si ejecutamos un ls -l en el directorio /opt/john/run veremos que existen muchas más herramientas de conversión.

Restricción a los contenedores

Si ejecutamos un ls -l en el directorio /opt/john/run veremos que existen muchas más herramientas de conversión. Para finalizar, es importante destacar que la utilización en GNU/Linux de los contenedores no hay límites en el uso de memoria o CPU (en cambio en Windows y MacOS sí que existen). Por lo tanto, es importante limitarlos para evitar llevar al colapso el host. Por ejemplo, para limitar la memoria, podrías utilizar el parámetro –memory durante la ejecución del docker run:
docker run -it --gpus all --rm --memory="256m" mytools
En este enlace encontrarás más información sobre cómo aplicar estas restricciones. De todas formas, para el caso que nos ocupa, seguramente no quieras restringir los recursos para romper las contraseñas los más rápido posible.

Happy Hacking Hackers!!! Autores:

Fran Ramírez, (@cyberhadesblog) es investigador de seguridad y miembro del equipo de Ideas Locas en CDO en Telefónica, co-autor del libro "Microhistorias: Anécdotas y Curiosidades de la historia de la informática (y los hackers)", del libro "Docker: SecDevOps", también de "Machine Learning aplicado a la Ciberseguridad” además del blog CyberHades. Puedes contactar con Fran Ramirez en MyPublicInbox.


 Contactar con Fran Ramírez en MyPublicInbox

Rafael Troncoso
(@tuxotron) es Senior Software Engineer en SAP Concur, co-autor del libro "Microhistorias: Anécdotas y Curiosidades de la historia de la informática (y los hackers)", del libro "Docker: SecDevOps" además del blog CyberHades. Puedes contactar con Rafael Troncoso en MyPublicInbox.



Contactar con Rafael Troncoso en MyPublicInbox

2 comentarios:

  1. Un pequeño aporte:

    A la hora de identificar el tipo de hash, hashid no es tan fiable como hash-identifier la verdad, y ¿Por qué no usar las famosas rainbow tables?
    https://project-rainbowcrack.com/table.htm

    Inclusive sin descargar nada se podrían usar webs como https://md5decrypt.net/en/ para md5 la cual tiene 15.000.000.000 hash y los prueba todos en cuestión de segundos.

    Saludos ;)

    ResponderEliminar