Fortress - TryHackMe

SUMMARY

Primero a partir del escaneo de puertos de Nmap pude saber qué servicios se ejecutaban en los puertos abiertos. Luego, enumerando los recursos compartidos del servidor FTP, pude obtener un bytecode que había sido compilado con Python 2.7, logrando decompilarlo con uncompyle2, y obteniendo el script Python que implementaba un servidor que escuchaba conexiones en el puerto 5752, y que tenía un método de autenticación, logrando omitirlo y obtener la ruta de dos recursos. Uno de ellos era un script PHP, donde genere la colisión hash SHA-1 con el fin de obtener la ruta de un recurso que contenía la clave privada SSH del usuario h4rdy. Luego, omití la shell rbash asignado al usuario h4rdy, y en la escalada horizontal, aproveché que h4rdy podía ejecutar el comando cat con los privilegios de j4x0n con el fin de obtener su clave privada SSH. Luego, en la escalada vertical, encontré la credencial de j4x0n en un script en Bash, logrando saber que podía ejecutar cualquier comando con los privilegios de root mediante sudo.

FASE RECONOCIMIENTO ACTIVO

En este caso debemos acceder al sistema destino y obtener dos banderas Luego, 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 vulnerables.

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

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 SSH que se ejecuta en el puerto 22.
  • Un programa servidor FTP que se ejecuta en el puerto 5581. Ademas, las conexiones anonimas estan permitidas, es decir, sin proveer credenciales.
  • Un programa servidor HTTP que se ejecuta en el puerto 7331.
  • Un servicio desconocido que se ejecuta en el puerto 5752.

Ahora accederemos al servidor FTP mediante una conexión anonima con el fin de enumerar los recursos compartidos.

Podemos observar que logramos encontrar dos recursos compartido donde uno viene a ser un archivo de texto, que contiene el username de un usuario local en elsistema destino, y otro viene a ser un archivo bytecode que ha sido compilado con Python 2.7. Ademas, debemos saber que cuando se ejecuta un sciprt en Python, el interprete de Python compila el codigo fuente a un formato intermedio llamado bytecode.

Ahora buscaremos en el motor de busqueda de Google una herramienta en linea para decompilar este bytecode

Podemos observar que con la herramienta uncompyle2 podemos decompilar bytecode compilados en Python 2.7, y obtener el script en Python original. Luego, en el script en Python original, podemos observar que se ha implementado un servidor que puede atender hasta un maximo de 10 conexiones en el puerto 5752. Luego de establecer conexión con el servidor, se nos enviaran dos mensajes que nos indican que ingresemos un username valido. Luego, debemos ingresar un username valido con una longitud maxima de 1024 bytes. Luego, debemos ingresar un password valido con una longitud maxima de 1024 bytes. Luego, estos dos strings ingresados seran convertidos a bytes y van a ser uitlizados en condicionales. En el condicional if tenemos la funcion bytes_to_long que convertira el valor del username y password ingresado en numeros enteros largos y los comparara con dos numeros enteros largos preestablecidos, y si la coincidencia es exacta, se nos enviara el contenido de un archivo de texto llamado secret. En el caso de else, se nos enviara un mensaje diciendo que la autenticacion fallo,y se cerrara la conexión.

Ahora que hemos analizado el codigo del script en Python, podemos concluir que luego de establecer conexión con el servidor, se establece un mecanismo de autenticacion como un login donde debemos ingresar un username y password valido. Ademas, estos valores, lo podemos obtener al utilizaR la funcion long_to_byes, que viene a tener una funcionalidad contraria a la funcion bytes_to_long, sobre los valores preestablecidos en las variables userm y passw.

Podemos observar que logramos establecer una conexión con el servidor a traves del servicio Telnet. Luego, nos autenticamos exitosamente, y recibimos el mensaje contenido en el archivo secret.txt. Ademas, este mensaje puede ser la ruta de un endpoint de una API o un recurso escondido en el directorio razi del servidor web. Para comprobar esto, utilizaremos la herramienta gobuster con el fin de realizar fuerza bruta de directorios teniendo en cuenta la posible ruta encontrada anteriormente.

Podemos observar que logramos encontrar dos recursos escondidos. Aunque uno de ellos viene a ser un archivo PHP por lo que su contenido va ser ejecutado por el servidor web y solo el resultado HTML sera mostrado en nuestro navegador web.

Ahora observaremos el recurso t3mple_0f_y0ur_51n5.html a traves de mi navegador web.

Podemos obsrvar que el recurso viene a ser una pagina web con cierto formulario HTML. Ademas, si observamos el codigo fuente de la pagina web, observaremos varios comentarios que vienen a formar un codigo de un script PHP. Ademas, nos daremos cuenta que ese script PHP no viene a ser el codigo implementado en el login de la pagina web ya que si enviamos la solicitud GET que le corresponde al formulario HTML, no obtendremos ningun cambio y solo seremos redirrecionado a la misma pagina web. Ademas, esto lo podemos deducir con la frae del ultimo comentario, que nos dice que no viene a ser la puerta actual para acceder al templo o fortaleza.

Ahora accederemos al otro recurso PHP para observar su respuesta HTML en nuestro navegador web.

Podemos observar que solo obtenemos un fondo negro en la salida HTML del recurso PHP, pero si revisamos el codigo fuente nos topamos con unos comentarios que vienen a ser codigo HTML de un formulario HTML que consta de dos parametros GET llamados user y pass.

Ahora comprobaremos si se el codigo del script PHP anterior le corresponde a este recurso PHP. Para ello agregaremos los parametros GET user y pass a la URL, y le asignaremos cualquier valor.

Podemos observar que si logramos obtener el mensaje de texto dentro de la etiqueta HTML pre del segundo condicional if del script PHP. De esta manera comprobar que el script PHP le pertenece al recurso PHP. Ademas, lo que nos interesa obtener viene a ser el valor de la variable $spot ya que puede contener el valor de una ruta de un endpoint.

FASE GANAR ACCESSO

Ahora buscaremos en el motor de busqueda de google formas o tecnicas de colision de hash SHA-1, que consiste en que dos conjuntos de datos diferentes produzcan el mismo hash SHA-1 luego de haberles aplicado la funcion SHA-1 sobre ellos.

En un writeup de otro reto, almacenado en el respitorio: https://github.com/bl4de/ctf/blob/master/2017/BostonKeyParty_2017/Prudentialv2/Prudentialv2_Cloud_50.md, logre encontrar dos archivos HTML que vienen a ser prueba de una colision de hash SHA-1 ya que se obtiene el mismo hash SHA-1 en ambos.

Ahora realizaremos la solicitud GET utilizando estos archivos como parametros GET, para ello implementaremos un script en Python que automatize este proceso.

De esta manera logramos obtener la ruta del endpoint esperado.

Ahora accederemos al endpoint a traves de mi navegador web.

Podemos observar que se trata de la clave privada SSH del usuario local h4rdy, con la cual podemos autenticarnos para acceder al sistema destino mediante el servicio SSH.

De esta manera logramos obtener acceso al sistema destino siendo el usuario h4rdy. Ademas, nos damos cuenta que al usuario h4rdy le han asignado un shell rbash que viene a ser una variante de la shell bash, y que nos proporciona un entorno restringido, limitandonos el uso de muchos comando. Ademas, observamos que la variable de entorno PATH solo contiene un directorio por lo que no apunta a los directorios donde estan los archivos binarios ejecutables de los comandos basicos, pero no podemos modificar su valor.

Ahora buscamos en el motor de busqueda de Google, tecnicas de como omitir las restricciones de esta shell rbash.

En el paper (https://www.exploit-db.com/docs/english/44592-linux-restricted-shell-bypass-guide.pdf?rss) escrito por @n4ckhcker & @h4d3sw0rm. Podemos observar algunos comandos ssh que podemos utilizar para obtener una shell bash o zsh interactiva en el sistema remoto cuando iniciemos sesion en el.

Podemos observar que logramos tener una shell bash interactiva, y modificando el valor del PATH podremos ejecutar cualquier comando.

FASE ESCALADA DE PRIVILEGIOS

Ahora buscaremos vectores de escalada de privilegios en el sistema de archivos del usuario h4rdy.

Podemos observar que el usuario h4rdy pùede utilizar el comando cat con los privilegios del usuario j4x0n, y sin tener que ingresar sus credenciales. Ademas, en el directorio home de j4x0n nos topamos con el directorio oculto .ssh con una clave privada SSH, pero no podemos observar su contenido ya que no tenemos el permiso de lectura sobre el siendo el usuario h4rdy.

Ahora utilizaremos el comando cat con los privilegos de j4x0n para observar el contenido de la clave privada, y poder iniiciar sesion en el sistema destino mediante el servicio SSH y siendo el usuario j4x0n.

De esta manera logramos realizar una escalda de privlegio vertical llegando a ser el usuario j4x0n.

Ahora buscaremos vectores de escalada privilegios en el sistema de archivos de este nuevo usuario.

Podemos observar que en el directorio opt, logre encontrar un archivo binario ejecutable con el bit SUID habilitado pero al ejecutarlo solo resulto ser un rabbit hole. Ademas, logramos encontrar un directorio inusual en el directorio raiz, y que contenia un script sh con diversos comandos relacionados con la creacion de los uaurios locales en el sistema destino, logrando observar sus credenciales.

Ahora utilizando la contraseña del usuario local j4x0n, podremos enumerar los comandos o programas que podemos ejecutar con el comando sudo.

Podemos observar que el usuario j4x0n puede ejecutar cualquier comando con los privilegios de root, y por esta razon utilizamos el comando su para ser el usuario root. De esta manera logramos una escalada de privilegio vertical siendo el usuario root.

Ahora buscaremos las dos banderas en los archivos root.txt y user.txt en el sistema de archivos del sistema destino.

Por ultimo, el script en Python y los archivos HTML utilizados en la colision de hash SHA-1, lo puedes encontrar en mi repositorio Github.