> For the complete documentation index, see [llms.txt](https://4lec4st.gitbook.io/4lec4st/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://4lec4st.gitbook.io/4lec4st/writes-ups/hack-the-box/medium/strutted.md).

# Strutted

## Información de la máquina

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

`Strutted` es una máquina Linux de dificultad media que incluye el sitio web de una empresa que ofrece soluciones de alojamiento de imágenes. El sitio web proporciona un contenedor Docker con la versión de Apache Struts vulnerable a `[CVE-2024-53677](https://nvd.nist.gov/vuln/detail/CVE-2024-53677)`, que se aprovecha para establecerse en el sistema. Una enumeración más detallada revela el archivo `tomcat-users.xml` con una contraseña de texto plano utilizada para autenticarse como `james`. Para la escalada de privilegios, abusamos de `tcpdump` mientras se usa con `sudo` para crear una copia del binario `bash` con el bit `SUID` activado, lo que nos permite obtener un shell `root`.

***

## Reconocimiento

La fase de **reconocimiento** es el primer paso a la hora de resolver una máquina. Su objetivo es recopilar la mayor cantidad de información posible sobre el sistema objetivo, permitiendo entender su estructura, tecnología y posibles vectores de ataque.&#x20;

Empezaremos haciendo un ping a la máquina víctima para ver si está encendida y ante que nos enfrentamos.

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

Si recibimos respuesta, significa que la máquina está en línea. Además, observamos que el **TTL** (Time To Live) es **63**, lo que indica que es un sistema **Linux** (normalmente, los sistemas Windows tienen un TTL de 127).&#x20;

{% hint style="success" %}
Esto sucede porque Hack The Box virtualiza las máquinas, lo que a menudo reduce el TTL en un punto respecto al valor estándar.

En entornos reales tendrían los siguientes valores:

TTL Linux **→** 64

TTL Windows **→** 128
{% endhint %}

Empezaremos haciendo un primer reconocimiento para ver los puertos abiertos en el sistema.

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

**1. `-p-` → Escaneo de todos los puertos (1-65535)**

Por defecto, `nmap` solo escanea los **1000 puertos más comunes**.\
Con `-p-`, forzamos a que escanee **los 65,535 puertos** de la máquina objetivo, lo que puede ser útil para encontrar servicios que corren en puertos poco convencionales.

**2. `--open` → Filtrar solo los puertos abiertos**

Cuando escaneamos un sistema, muchos puertos pueden estar cerrados o filtrados por un firewall.\
Este parámetro hace que `nmap` **solo muestre los puertos abiertos**, reduciendo el ruido y facilitando el análisis.

**3. `-sS` → Stealth Scan (Escaneo Sigiloso con SYN)**

Es conocido como **"TCP SYN Scan"**, y funciona de la siguiente manera:

* `nmap` envía un paquete **SYN** (solicitud de conexión).
* &#x20;Si el puerto está abierto, el servidor responde con **SYN-ACK**.
* En lugar de completar la conexión con un **ACK**, `nmap` responde con un **RST (Reset)**, interrumpiendo la comunicación.

**4. `--min-rate 5000` → Velocidad mínima de paquetes (5000 por segundo)**

Por defecto, `nmap` ajusta dinámicamente la velocidad de los paquetes según la respuesta de la red.\
Con `--min-rate 5000`, obligamos a `nmap` a **no enviar menos de 5000 paquetes por segundo**, acelerando el escaneo.

**5. `-n` → Deshabilitar resolución DNS**

Normalmente, `nmap` intenta resolver el nombre de dominio de las IPs escaneadas (DNS lookup).\
Con `-n`, evitamos esta resolución de nombres, lo que **acelera el escaneo** y evita que los servidores DNS registren nuestra actividad.

**6. `-Pn` → Omitir detección de host (Host Discovery Off)**

Por defecto, `nmap` envía paquetes ICMP (ping) para ver si un host está activo antes de escanearlo.\
Si un firewall bloquea los pings, `nmap` puede marcarlo como "host down" y no escanearlo.

**7. `-oG`** **→ Exportar el contenido en formato grepeable**

Todo el resultado del escaneo lo exportaremos en un archivo llamado **`puertos` .**

El escaneo revela que los puertos **22 (SSH)** y 80 **(HTTP)** están abiertos. Ahora realizamos un escaneo más detallado:

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

**1. `-p22,80` → Escaneo de puertos específicos**

Con `-p22,80`, le indicamos que **solo** escanee los puertos **22 (SSH)** y 80 (HTTP).

**2. `-sCV` → Escaneo de versiones y scripts básicos**

Este parámetro en realidad es **dos combinaciones en una**:

* **`-sC`** → Activa los **NSE scripts por defecto** en `nmap` (similar a usar `--script=default`).\
  🔹 Ejecuta scripts básicos para enumerar información del servicio detectado, como banners, versiones, etc.
* **`-sV`** → Realiza **fingerprinting de versiones**, intentando identificar la versión exacta del software en cada puerto abierto.

**3. `-oN` → Guardar el resultado en formato Normal**

Por defecto, `nmap` muestra los resultados en pantalla, pero con **`-oN targeted`**, guardamos el resultado en un archivo en **formato legible para humanos**.

Cambiaremos el /etc/host ya que se aplica una redirección al dominio `strutted.htb` .

<figure><img src="/files/7H0AwB8lqjECw3s23b3Y" alt=""><figcaption></figcaption></figure>

## Enumeración web

Antes de visitar la web, useremos la herramienta `whatweb`, para saber que tecnologías usa esta página, u otra información relevante.

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

Encontramos información como el `título de la página (Strutted - Instant Image Upload)`, que se usa java y la `version 1.18.0 de nginx`.

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

Esta es la página web. Nos ofrece una subida de archivos, posible vector de entrada y una página para descargar algo.

Si pulsamos el botón de `Download` podemos ver que podemos descargar en un principio la aplicación.

<figure><img src="/files/6Ogi3udh7rVLU4RQrpYb" alt=""><figcaption></figcaption></figure>

La guardamos en nuestro equipo y procedemos a descomprimir el archivo .zip

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

Con la utilidad 7z, podemos descomprimir fácilmente el archivo.

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

Esto es lo que contiene el archivo. Observamos un archivo tomcat-users.xml. Estos archivos expuestos normalmente contienen credenciales en texto claro:

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

Probando estas credenciales con SSH(puerto 22 expuesto) no nos dejará acceder a la máquina, pero está bien siempre guardarlas por si en algún momento hacen falta.

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

## Apache Struts

Al revisar el proyecto, encontramos un archivo `pom.xml`, característico de proyectos escritos en Java. Esto indica que se está utilizando **Maven** como gestor de dependencias. En este archivo, podemos ver las versiones de los plugins utilizados, incluyendo **Apache Struts**, entre otros.

{% hint style="success" %}
Struts es una herramienta de soporte para el desarrollo de aplicaciones Web del patrón MVC bajo la plataforma Java EE. Struts se desarrollaba como parte del proyecto Jakarta de la Apache Software Foundation, pero actualmente es un proyecto conocido como Apache Struts. Struts permite reducir el tiempo de desarrollo.
{% endhint %}

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

Si buscamos vulnerabilidades de apache struts, vemos que hay una vulnerabilidad al subir archivos.

Apache Struts presenta una debilidad en su mecanismo de carga de archivos. Un atacante puede manipular los parámetros de carga para realizar un **cruce de rutas**, lo que en ciertas condiciones permite subir un archivo malicioso. Este archivo puede luego utilizarse para **ejecutar código de manera remota (RCE)**.\
Este problema afecta a **Apache Struts desde la versión 2.0.0 hasta la 6.4.0**.

Para comprender mejor esta vulnerabilidad, debemos conocer algunos componentes clave de Struts:

1. **Interceptors en Struts**
   * Struts utiliza una serie de **clases interceptoras** que se ejecutan por defecto.
   * Una de ellas es **FileUploadInterceptor**, encargada de gestionar la carga de archivos.
2. **Uso de OGNL en Struts**
   * Struts implementa la **Object Graph Navigation Library (OGNL)**, un sistema que gestiona valores en una pila.
   * Si hay múltiples objetos en la pila y se hace referencia a una propiedad (por ejemplo, `name`), OGNL recorre la pila y devuelve el primer objeto que tenga esa propiedad.
3. **Explotación de la vulnerabilidad**
   * Si una solicitud **POST** activa el objeto **FileUploadInterceptor**, es posible incluir **otros parámetros POST** que hagan referencia a partes del objeto a través de la pila OGNL.
   * Esto permite **modificar propiedades de forma no autorizada**, lo que, en la práctica, facilita la ejecución de código malicioso.

Ahora que ya conocemos mejor como funciona esta vulnerabilidad, buscaremos un PoC para ver como se produce:

<figure><img src="/files/0ySkexkk7nAjVtKkZmtT" alt=""><figcaption></figcaption></figure>

Este PoC en la máquina no sirve, pero nos hace comprender como se podría acontecer esta vulnerabilidad, añadiendo un nuevo campo a la imagen.

## RCE via exploit vulnerable version Apache Struts - CVE-2024-53677

Subiremos una imagen y la interceptaremos con Caido o con BurpSuite. En mi caso usaré BurpSuiite

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

Si probamos a cambiar el nombre a .jsp(ya que sabemos que utiliza java), en un principio no nos dejará. De tal forma que ahora se acontece el `CVE-2024-53677` .

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

Si añadimos un segundo parámetro con el nombre que nos da el PoC visto anteriormente, vemos que tenemos capacidad de modificar el nombre de nuestro archivo.

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

De tal forma, tambien se acontece el Directory Path Traversal que nos comentaban, pudiendo retroceder directorios. Ahora, buscaremos una WebShell para poder ejecutar comandos desde ella.

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

Como acontecemos esta vulnerabilidad, si ahora nos vamos a la raiz y ponemos test.jsp, nos deberia mostrar una página con la WebShell:

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

De esta forma, ya tenemos el RCE. Ahora falta entablarnos una ReverShell para acceder al sistema.

Si probamos con el OneLiner típico para entablarnos la conexión, nos va a dar un error, por lo que haremos lo siguiente:

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

Nos crearemos un archivo index.html que contenga el código para entablarnos la Shell.

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

Abriré un servidor HTTP con python por el puerto 80 y aprovecharé tambien para ponerme en escucha por el puerto 443, que es el que hemos puesto en el archivo index.html.

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

En nuestra WebShell, ejecutaremos el comando curl para hacer una petición a nuestro servidor que contiene el archivo para la shell y lo exportaremos a una carpeta /tmp/shell (podeis ponerle el nombre que queráis).&#x20;

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

Ahora si ejecutamos la siguiente instrucción, nos otorgará la ReverShell:

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

***

## Shell usuario James

Si nos vamos al directorio home, vemos que hay un usuario llamado `james` . Tenemos que buscar la forma de migrar a este usuario.

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

Anteriormente, vimos que había un archivo llamado tomcar-users.xml cuando descargamos el .zip

Si probamos a buscar dentro de la máquina archivos que se llamen asi vemos los siguientes:

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

Si le hechamos un vistazo al primer archivo, podemos ver que las credenciales que se muestran son distintas al que vimos:&#x20;

<figure><img src="/files/9P7GNjQvIIbZ93ZaMV1M" alt=""><figcaption></figcaption></figure>

Ahora, si probamos a usar estas credenciales para meternos con el usuario james:

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

Vemos que no tenemos acceso y que no podemos entrar. Entonces, ¿cómo podríamos entrar como el usuario james?.

{% hint style="success" %}
Siempre hay que probar las credenciales en todos los sitios que podamos, de tal forma que como el servicio SSH(puerto 22) está abierto, usaremos la contraseña para entrar.
{% endhint %}

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

Y como vemos, podemos acceder por SSH con la contraseña que vimos anteriormente. Y con ello, poder ver la primera flag:

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

## Shell root via misconfigured sudo privileges - tcpdump

Ahora tenemos que ver como podemos escalar nuestros privilegios para estar como root.

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

Si enumeramos el sistema, vemos que podemos ejecutar tcpdump como root.

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

Si buscamos en GTFObins si se pueden escalar privilegios con este binario, podemos ver que podemos escalar a root. De tal forma que pegamos los comandos en la terminal, y modificaremos la variable COMMAND para que otorgue permisos SUID a la /bin/bash:

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

Vemos que los privilegios de la bash han cambiado

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

Conseguimos escalar privilegios como root. Por último vemos la flag última flag.

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

***

## Conclusión

La máquina **Strutted** demuestra cómo una combinación de vulnerabilidades en software desactualizado, configuraciones inseguras y abuso de permisos puede llevar a la **comprometización total de un sistema Linux**.

El punto de entrada es una vulnerabilidad en **Apache Struts (CVE-2024-53677)** dentro de un contenedor **Docker**, que permite obtener acceso inicial al sistema.

Posteriormente, la enumeración revela un archivo **tomcat-users.xml** con **credenciales en texto plano**, facilitando la autenticación como el usuario **james**.

Para escalar privilegios, se aprovecha la ejecución de **tcpdump con sudo**, lo que permite crear una copia de **bash con el bit SUID activado**. Esto concede la capacidad de ejecutar comandos como **root**, logrando el control total de la máquina.
