> 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/dockerlabs/medium/chocolatefire.md).

# ChocolateFire

## Información de la máquina

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

ChocolateFire es una maquina de dificultad media en el que explotaremos un servidor Openfire corriendo en la versión 4.7.4. que nos permitió hacer bypass de autenticación en la consola administrativa de Openfire. A partir de ahí, pudimos escalar nuestra intrusión utilizando credenciales obtenidas y un ataque por fuerza bruta exitoso sobre SSH. Finalmente, realizamos una escalada de privilegios mediante la explotación de un script vulnerable ejecutado con permisos elevados, consiguiendo así acceso completo como root al sistema.

***

## 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/SlQNDC2S0I9tVvdVjQnd" 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 **64**, lo que indica que es un sistema **Linux** (normalmente, los sistemas Windows tienen un TTL de 128).&#x20;

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

#### **. `-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 puerto 22,5222,5223,5262,5263,5269,5270,5275,5276,7070,7777,9090 están abierto. Ahora realizamos un escaneo más detallado:

```bash
nmap -p22,5222,5223,5262,5263,5269,5270,5275,5276,7070,7777,9090 -sCV 10.88.0.2 -oN targeted
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-04-07 16:40 CEST
Nmap scan report for 10.88.0.2
Host is up (0.0000080s latency).
PORT     STATE SERVICE        VERSION
22/tcp   open  ssh            OpenSSH 8.4p1 Debian 5+deb11u3 (protocol 2.0)
| ssh-hostkey: 
|   3072 9c:7c:e5:ea:fe:ac:f5:bc:21:54:87:66:70:ed:df:75 (RSA)
|   256 b2:1a:b1:05:0e:7e:94:18:98:19:8f:60:d7:04:7a:1c (ECDSA)
|_  256 c1:81:ba:4f:1a:99:9f:32:10:4a:6a:d9:f4:aa:40:de (ED25519)
5222/tcp open  jabber
| xmpp-info: 
|   STARTTLS Failed
|   info: 
|     unknown: 
|     xmpp: 
|       version: 1.0
|     capabilities: 
|     compression_methods: 
|     stream_id: h0z7mhjqg
|     errors: 
|       invalid-namespace
|       (timeout)
|     auth_mechanisms: 
|_    features: 
|_ssl-cert: ERROR: Script execution failed (use -d to debug)
| fingerprint-strings: 
|   RPCCheck: 
|_    <stream:error xmlns:stream="http://etherx.jabber.org/streams"><not-well-formed xmlns="urn:ietf:params:xml:ns:xmpp-streams"/></stream:error></stream:stream>
5223/tcp open  ssl/hpvirtgrp?
|_ssl-date: TLS randomness does not represent time
5262/tcp open  jabber         Ignite Realtime Openfire Jabber server 3.10.0 or later
| xmpp-info: 
|   STARTTLS Failed
|   info: 
|     unknown: 
|     xmpp: 
|       version: 1.0
|     capabilities: 
|     compression_methods: 
|     stream_id: u4dc87zyg
|     errors: 
|       invalid-namespace
|       (timeout)
|     auth_mechanisms: 
|_    features: 
5263/tcp open  ssl/unknown
|_ssl-date: TLS randomness does not represent time
5269/tcp open  xmpp           Wildfire XMPP Client
| xmpp-info: 
|   STARTTLS Failed
|   info: 
|     xmpp: 
|     capabilities: 
|     compression_methods: 
|     unknown: 
|     errors: 
|       (timeout)
|     auth_mechanisms: 
|_    features: 
5270/tcp open  xmp?
5275/tcp open  jabber
| xmpp-info: 
|   STARTTLS Failed
|   info: 
|     unknown: 
|     xmpp: 
|       version: 1.0
|     capabilities: 
|     compression_methods: 
|     stream_id: 2s83qat24o
|     errors: 
|       invalid-namespace
|       (timeout)
|     auth_mechanisms: 
|_    features: 
| fingerprint-strings: 
|   RPCCheck: 
|_    <stream:error xmlns:stream="http://etherx.jabber.org/streams"><not-well-formed xmlns="urn:ietf:params:xml:ns:xmpp-streams"/></stream:error></stream:stream>
5276/tcp open  ssl/unknown
|_ssl-date: TLS randomness does not represent time
7070/tcp open  realserver?
| fingerprint-strings: 
|   DNSStatusRequestTCP, DNSVersionBindReqTCP: 
|     HTTP/1.1 400 Illegal character CNTL=0x0
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 69
|     Connection: close
|     <h1>Bad Message 400</h1><pre>reason: Illegal character CNTL=0x0</pre>
|   GetRequest: 
|     HTTP/1.1 200 OK
|     Date: Mon, 07 Apr 2025 14:40:24 GMT
|     Last-Modified: Wed, 16 Feb 2022 15:55:03 GMT
|     Content-Type: text/html
|     Accept-Ranges: bytes
|     Content-Length: 223
|     <html>
|     <head><title>Openfire HTTP Binding Service</title></head>
|     <body><font face="Arial, Helvetica"><b>Openfire <a href="http://www.xmpp.org/extensions/xep-0124.html">HTTP Binding</a> Service</b></font></body>
|     </html>
|   HTTPOptions: 
|     HTTP/1.1 200 OK
|     Date: Mon, 07 Apr 2025 14:40:29 GMT
|     Allow: GET,HEAD,POST,OPTIONS
|   Help: 
|     HTTP/1.1 400 No URI
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 49
|     Connection: close
|     <h1>Bad Message 400</h1><pre>reason: No URI</pre>
|   RPCCheck: 
|     HTTP/1.1 400 Illegal character OTEXT=0x80
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 71
|     Connection: close
|     <h1>Bad Message 400</h1><pre>reason: Illegal character OTEXT=0x80</pre>
|   RTSPRequest: 
|     HTTP/1.1 505 Unknown Version
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 58
|     Connection: close
|     <h1>Bad Message 505</h1><pre>reason: Unknown Version</pre>
|   SSLSessionReq: 
|     HTTP/1.1 400 Illegal character CNTL=0x16
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 70
|     Connection: close
|_    <h1>Bad Message 400</h1><pre>reason: Illegal character CNTL=0x16</pre>
7777/tcp open  socks5         (No authentication; connection failed)
| socks-auth-info: 
|_  No authentication
9090/tcp open  zeus-admin?
| fingerprint-strings: 
|   GetRequest: 
|     HTTP/1.1 200 OK
|     Date: Mon, 07 Apr 2025 14:40:24 GMT
|     Last-Modified: Wed, 16 Feb 2022 15:55:03 GMT
|     Content-Type: text/html
|     Accept-Ranges: bytes
|     Content-Length: 115
|     <html>
|     <head><title></title>
|     <meta http-equiv="refresh" content="0;URL=index.jsp">
|     </head>
|     <body>
|     </body>
|     </html>
|   HTTPOptions: 
|     HTTP/1.1 200 OK
|     Date: Mon, 07 Apr 2025 14:40:29 GMT
|     Allow: GET,HEAD,POST,OPTIONS
|   JavaRMI, drda, ibm-db2-das, informix: 
|     HTTP/1.1 400 Illegal character CNTL=0x0
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 69
|     Connection: close
|     <h1>Bad Message 400</h1><pre>reason: Illegal character CNTL=0x0</pre>
|   SqueezeCenter_CLI: 
|     HTTP/1.1 400 No URI
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 49
|     Connection: close
|     <h1>Bad Message 400</h1><pre>reason: No URI</pre>
|   WMSRequest: 
|     HTTP/1.1 400 Illegal character CNTL=0x1
|     Content-Type: text/html;charset=iso-8859-1
|     Content-Length: 69
|     Connection: close
```

**1.** `-p22,5222,5223,5262,5263,5269,5270,5275,5276,7070,7777,9090` **→ Escaneo de puertos específicos**

Con este parámetro, le indicamos que **solo** escanee los puertos 22,5222,5223,5262,5263,5269,5270,5275,5276,7070,7777,9090.

**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**.

Lo único destacable que tenemos es el puerto 9090.&#x20;

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

Tenemos un inicio de sesión en openfire.

{% hint style="success" %}
Openfire (anteriormente llamado Wildfire y Jive Messenger) es un sistema de mensajería instantánea, hecho en java y que utiliza el protocolo [XMPP](https://es.wikipedia.org/wiki/Extensible_Messaging_and_Presence_Protocol), con él podrás tener tu propio servidor de mensajería, puedes administrar a tus usuarios, compartir archivos, auditar mensajes, mensajes offline, mensajes broadcast, grupos, etc y además contiene plugins gratuitos con diferentes funciones extras.
{% endhint %}

***

## Enumeración y búsqueda de vulnerabilidades

Hemos identificado que el servicio Openfire que corre en la máquina víctima está usando la versión **4.7.4**. Esto es importante porque versiones específicas de software pueden contener vulnerabilidades conocidas. El siguiente paso lógico es buscar en Google (o alguna base de datos de exploits como Exploit-DB o GitHub) si existe algún **CVE (Common Vulnerabilities and Exposures)** documentado para esta versión de Openfire.

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

Durante la búsqueda, encontramos un **CVE aplicable a la versión 4.7.4**, el cual permite un **bypass de autenticación**. Esto significa que, sin necesidad de credenciales válidas, se puede acceder a áreas restringidas del sistema (como el panel de administración de Openfire), lo que nos abre la puerta a la explotación.

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

***

## Explotación de las vulnerabilidades

Clonamos el repositorio del exploit en nuestra máquina atacante usando `git clone`, descargando así el código necesario para ejecutar el exploit del CVE de Openfire.

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

Al ejecutar el script que explota la vulnerabilidad, conseguimos hacer el ByPass y obetener un usuario administrador de OpenFire.

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

Probamos esas credenciales en la interfaz de administración de Openfire y confirmamos que funcionan. Ya tenemos acceso al panel de administración del servicio, lo que nos da visibilidad (y posiblemente control) sobre otros usuarios y configuraciones del sistema.

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

Desde el panel, accedemos a la sección de "Users/Groups", donde podemos ver una lista de todos los usuarios del sistema. Esto es muy útil porque nos revela posibles objetivos para intentar acceder al sistema por otros vectores, como SSH.

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

Decidimos utilizar **Hydra**, una herramienta para ataques de fuerza bruta, con el objetivo de probar contraseñas comunes (o una lista personalizada) contra el servicio SSH, utilizando alguno de los usuarios descubiertos anteriormente.

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

Después de probar varias combinaciones, encontramos una contraseña válida. Con ella, intentamos establecer una conexión SSH con la máquina víctima.

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

La autenticación SSH fue exitosa y ahora tenemos **acceso interactivo al sistema** con los privilegios del usuario objetivo.

***

## Post Explotación y escalada de privilegios

Con el acceso inicial conseguido, pasamos a la etapa de post-explotación, en la que enumeramos los permisos y configuraciones del sistema para buscar una forma de **escalar privilegios** hasta obtener acceso como root o a un usuario con más privilegios.

Al ejecutar `sudo -l`, vemos que el usuario tiene permisos para ejecutar el binario `dpkg` como root sin necesidad de contraseña. Este binario es parte del sistema de gestión de paquetes de Debian y, si está mal configurado, puede ser explotado para escalar privilegios.

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

Utilizamos el comando `sudo -u pinguinacio /usr/bin/dpkg -l`, que lista los paquetes instalados. Este comando abre una especie de "paginador" (como `less` o `more`) para mostrar los resultados.

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

Dentro del paginador, si este es `less` o `more`, se puede ejecutar un comando del sistema anteponiendo `!`. Escribimos `!/bin/bash` para invocar una shell como root, ya que `dpkg` se está ejecutando con privilegios elevados. Así conseguimos acceso a una shell con **del usuario pinguinacio**

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

Después de la fase inicial de explotación, hemos logrado entrar al sistema como el usuario `pinguinacio`. Es un usuario estándar (no root), así que nuestro objetivo ahora es **escalar privilegios** para tomar control completo del sistema.

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

Ejecutamos el comando `sudo -l`, que nos muestra los comandos que `pinguinacio` puede ejecutar como superusuario (root) sin necesidad de introducir contraseña.\
Entre los resultados aparece un **script en Bash** al que `pinguinacio` tiene acceso con `sudo`.

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

Si vemos el script.

```bash
#!/bin/bash
read -rp "Ingrese el número 1 para hacer un backup de tus archivos: " numero
if [[ "$numero" -eq 1 ]]
then
    echo "El número ingresado es igual a 1"
    echo "Intentando copiar archivos al directorio /opt..."
    cp * /opt
    echo "Copia completada."
else
    echo "El número ingresado no es igual a 1. No se realizará ninguna operación."
fi
```

#### `read -rp "Ingrese el número 1...":`

Es una entrada por teclado. Guarda lo que escribas en la variable `numero`.

#### `if [[ "$numero" -eq 1 ]]`

Aquí está la clave.

**¿Qué hace `-eq`?**

`-eq` es un operador **aritmético** en Bash, usado para comparar números enteros.\
Ejemplo válido:

```bash
if [[ 1 -eq 1 ]]; then echo "Son iguales"; fi
```

Pero si pones algo que **no es un número**, como `hola`, `a[1]`, o `$(whoami)`, el script va a fallar.

#### **¿Dónde está la vulnerabilidad?**

Bash permite **inyección de comandos** cuando el intérprete intenta evaluar expresiones **no numéricas con `-eq`**.

Entonces si escribes algo como:

```bash
a[$(/bin/bash >&2)]+1
```

&#x20;El `-eq` tratará de **evaluar esto como una expresión aritmética**, y ejecutará lo que hay dentro del `$()`.

* `$(/bin/bash >&2)` ejecuta **una nueva shell interactiva** y la redirige al canal de error estándar (`stderr`), lo que **permite que se muestre en pantalla**.
* El resto (`a[...]+1`) solo está para **simular que es una expresión válida** para Bash y no lanzar un error de sintaxis inmediata.

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

Ya tenemos privilegios máximos en la máquina.

{% hint style="success" %}
En este recurso lo explican paso a paso
{% endhint %}

{% embed url="<https://exploit-notes.hdks.org/exploit/linux/privilege-escalation/bash-eq-privilege-escalation/>" %}

***

## Conclusión

Con la máquina ChocolateFire identificamos una versión vulnerable de Openfire y una correcta explotación de la misma, obtuvimos acceso inicial al sistema. Posteriormente, usando fuerza bruta con Hydra y una mala configuración de permisos en `sudo`, conseguimos escalar privilegios hasta obtener una shell como root.
