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

# Grooti

### **1. Despliegue de la máquina:**

#### **1.1. Descarga:**

Accedemos a la web oficial de [DockerLabs](https://dockerlabs.es/), buscamos la máquina Grooti y pulsamos el botón de descarga.

Esto nos redirige a un enlace de Mega, desde donde descargamos un archivo comprimido que incluye tanto la imagen de la máquina como el script necesario para su ejecución.

#### **1.2. Descompresión:**

Utilizamos `7z` para extraer el contenido del archivo:

```bash
7z x grooti.zip
```

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

#### **1.3. Ejecución en Docker:**

Ejecutamos el script de despliegue, indicando el archivo comprimido como argumento:

```bash
bash auto_deploy.sh grooti.tar
```

Con esto, la máquina queda levantada en el entorno Docker y se le asigna una IP interna (en nuestro caso, `172.17.0.2`).

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

### **2. Reconocimiento:**

#### **2.1. Verificación de conectividad:**

Comprobamos que la máquina está activa mediante un `ping`:

```bash
ping -c 1 172.17.0.2
```

La respuesta confirma que el host está accesible.

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

#### **2.2. Escaneo de puertos (Nmap - escaneo inicial):**

Realizamos un escaneo completo de puertos con `nmap`:

```bash
nmap -p- --open -sS --min-rate 5000 -vvv -n -Pn -oN escaneo_inicial.txt 172.17.0.2
```

{% hint style="info" %}
**Explicación de los parámetros**

`-p-`: Escanea todos los puertos, del 1 al 65535.

`--open`: Muestra solo los puertos que están abiertos, omitiendo los cerrados o filtrados.

`-sS`: Realiza un escaneo SYN (stealth scan) que no completa la conexión TCP.

`--min-rate 5000`: Fuerza una velocidad mínima de 5000 paquetes por segundo, acelerando el escaneo.

`-vvv`: Activa el nivel máximo de verbosidad, mostrando información detallada del proceso.

`-n`: Evita la resolución DNS, usando solo direcciones IP.

`-Pn`: Omite la detección de host activo, asumiendo que el host está disponible.

`-oN escaneo_inicial.txt`: Guarda los resultados del escaneo en formato normal, en el archivo `escaneo_inicial.txt`.
{% endhint %}

Puertos abiertos detectados:

* 22 - SSH.
* 80 - HTTP.
* 3306 - MYSQL.

<figure><img src="/files/1KIbQqztcvTK6gUOYLBW" alt=""><figcaption></figcaption></figure>

#### **2.3. Escaneo detallado de servicios:**

Realizamos un escaneo más exhaustivo sobre los puertos detectados:

```bash
nmap -sCV -p22,80,3306 -oN escaneo_final.txt 172.17.0.2
```

{% hint style="info" %}
**Explicación de los parámetros**

`-sCV`: Combina la ejecución de scripts básicos de reconocimiento (`-sC`) con el escaneo de versiones (`-sV`).

`-p22,80,3306`: Especifica los puertos a escanear.

`-oN escaneo_final.txt`: Guarda los resultados del escaneo en formato normal, en el archivo `escaneo_final.txt`.
{% endhint %}

Servicios y versiones:

* 22/tcp - OpenSSH 9.6p1 Ubuntu 3ubuntu13.12 (Ubuntu Linux; protocol 2.0).
* 80/tcp - Apache/2.4.58 (Ubuntu).
* 3306/tcp - MySQL 8.0.42-0ubuntu0.24.04.2.

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

### **3. Enumeración del servicio web:**

#### **3.1. Análisis de la página principal:**

Accedemos a `http://172.17.0.2/` desde el navegador.

La página principal es sencilla y contiene varios hiperenlaces:

* Mis Fotos (`http://172.17.0.2/imagenes/`).
* Mi base de datos (`http://172.17.0.2/documentos/`).
* Facturas de la nave (`http://172.17.0.2/archives/`).

<figure><img src="/files/86nmZbQDYbYG5ueuwAIs" alt=""><figcaption></figcaption></figure>

Revisamos cada uno, pero el que resulta más interesante es Mis Fotos (`http://172.17.0.2/imagenes/`).

En este directorio encontramos:

* `README.txt`.
* `grooti.jpg`.

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

Al acceder a `README.txt`, vemos el siguiente texto: `(password1) Encuentra donde ponerla ;)`.

Esto sugiere que `password1` es una contraseña que deberá utilizarse en algún punto concreto.

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

#### **3.2. Descubrimiento de rutas ocultas (Gobuster):**

Para localizar rutas no enlazadas en la página principal, utilizamos `gobuster` en modo directorios:

```bash
gobuster dir -u http://172.17.0.2 -w /usr/share/wordlists/seclists/Discovery/Web-Content/DirBuster-2007_directory-list-2.3-medium.txt
```

{% hint style="info" %}
**Explicación de los parámetros**

`dir`: Indica el modo de búsqueda de directorios.

`-u http://172.17.0.2`: Indica la dirección URL objetivo.

`-w /usr/share/wordlists/seclists/Discovery/Web-Content/DirBuster-2007_directory-list-2.3-medium.txt`: Indica la wordlist que Gobuster usará.
{% endhint %}

Directorios encontrados:

* `/archives`.
* `/imagenes`.
* `/secret`.
* `/server-status`.

El directorio que más nos interesa es `/secret`.

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

#### **3.3. Análisis del directorio `/secret`:**

Accedemos a `/secret` desde el navegador (`http://172.17.0.2/secret/`).

En esta página se muestran:

* Varios nombres de usuario.
* Tipo de permisos de cada usuario.
* Estado de las cuentas.
* Un botón: Descargar archivo de instrucciones.

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

Al pulsar el botón, se descarga el archivo `instrucciones.txt`.

Visualizamos su contenido:

```bash
cat instrucciones.txt
```

El archivo contiene el mensaje: `look carefully here ;)`.

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

Y, al final, aparece el siguiente comando:

```bash
mysql -u rocket -p -h 172.17.0.2 --ssl=0
```

Este comando indica cómo conectarse al servicio MySQL que ya habíamos detectado en el puerto 3306.

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

#### **3.4. Conexión a MySQL con el usuario `rocket`:**

Probamos el comando anterior y, cuando nos solicita la contraseña, introducimos la que vimos en `README.txt` (`password1`).

La autenticación es correcta y obtenemos acceso al servicio MySQL como el usuario `rocket`.

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

#### **3.5. Enumeración de bases de datos:**

Listamos las bases de datos disponibles:

```sql
show databases;
```

Se muestran:

* `files_secret`.
* `information_schema`.
* `performance_schema`.

Las dos últimas son bases de datos internas de MySQL, por lo que nos centramos en `files_secret`.

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

Seleccionamos esta base de datos:

```sql
use files_secret;
```

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

#### **3.6. Enumeración de tablas y contenido:**

Listamos las tablas:

```sql
show tables;
```

Aparece una tabla: `rutas`.

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

Consultamos su contenido:

```sql
select * from rutas;
```

La tabla contiene varias rutas, la que nos interesa es la última (`/unprivate/secret`).

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

### **4. Explotación del panel de logs oculto:**

#### **4.1. Acceso a `/unprivate/secret`:**

Accedemos a la ruta descubierta (`http://172.17.0.2/unprivate/secret/`).

Encontramos un panel de registros de logs con dos campos:

* Mensaje de acceso (texto libre).
* Número (entre 1 y 100).

Al enviar un mensaje y un número, el sistema genera un archivo descargable.

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

#### **4.2. Pruebas manuales:**

Probamos con un mensaje cualquiera y el número 1.

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

Se descarga un archivo: `password1.txt`.

Su contenido coincide con el mensaje que hemos introducido.

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

Repetimos el proceso con el número 2.

Se descarga `password2.txt`.

Su contenido es: `Prueba otra vez`.

Esto nos indica que, dependiendo del número, el sistema realiza operaciones distintas y que alguno de ellos podría generar un archivo con información relevante.

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

#### **4.3. Configuración de BurpSuite y FoxyProxy:**

Para automatizar las pruebas sobre el campo `number`, configuramos BurpSuite como proxy interceptador.

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

El navegador para que todo el tráfico pase por BurpSuite (en nuestro caso, mediante la extensión FoxyProxy).

Con el proxy activo, volvemos al panel de logs, introducimos un mensaje y un número cualquiera, y pulsamos "Transmitir a Groot".

La página queda cargando mientras BurpSuite intercepta la petición.

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

#### **4.4. Envío de la petición al Intruder:**

En BurpSuite, con la petición interceptada enviamos la petición al Intruder (`Ctrl + I`).

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

En el apartado Positions, marcamos el parámetro correspondiente al campo `number` como posición de ataque.

Configuramos el tipo de payload como lista de valores desde un archivo de texto que contiene los números del 1 al 100.

Una vez configurado, iniciamos el ataque con Start attack.

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

#### **4.5. Análisis de respuestas:**

Al finalizar el ataque, revisamos la longitud de las respuestas para cada número.

Observamos que:

* La mayoría de números generan respuestas con longitudes repetidas.
* El número 16 produce una longitud de respuesta diferente y única.

Esto indica que, para el número 16, el servidor realiza una operación distinta.

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

#### **4.6. Descarga y análisis de `password16.zip`:**

Volvemos al navegador, accedemos de nuevo al panel de logs y:

* Introducimos un mensaje cualquiera.
* En el campo número, ponemos 16.
* Pulsamos "Transmitir a Groot".

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

Se descarga un archivo comprimido: `password16.zip`.

Listamos su contenido:

```bash
7z l password16.zip
```

Vemos que contiene: `password16.txt`.

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

Descomprimimos el archivo:

```bash
7z x password16.zip
```

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

Visualizamos el contenido de `password16.txt`:

```bash
cat password16.txt
```

El archivo contiene varias posibles contraseñas, que utilizaremos posteriormente para un ataque de diccionario.

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

### **5. Ataque de diccionario sobre SSH:**

#### **5.1. Creación del diccionario de usuarios:**

Recordamos que en `http://172.17.0.2/secret/` se mostraban varios nombres de usuario.

Creamos un archivo de texto con estos usuarios, por ejemplo `usuarios.txt`.

En `password16.txt` ya disponemos de una lista de contraseñas potenciales, que utilizaremos directamente como wordlist.

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

#### **5.2. Ejecución de Hydra:**

Realizamos un ataque de diccionario contra el servicio SSH (puerto 22) utilizando `hydra`:

```bash
hydra -L usuarios.txt -P password16.txt ssh://172.17.0.2
```

{% hint style="info" %}
**Explicación de los parámetros**

`-L usuarios.txt`: Indica el archivo que contiene la lista de usuarios a probar.

`-P password16.txt`: Indica el archivo que contiene la lista de contraseñas a probar.

`ssh://172.17.0.2`: Indica el servicio (SSH) y la dirección objetivo donde Hydra intentará iniciar sesión.
{% endhint %}

Credenciales validas:

* Usuario: `grooti`.
* Contraseña: `YoSoYgRo0t`.

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

#### **5.3. Acceso al sistema vía SSH:**

Nos conectamos a la máquina:

```bash
ssh grooti@172.17.0.2
```

La autenticación es correcta y obtenemos acceso al sistema como el usuario `grooti`.

<figure><img src="/files/90rMI2WnkNbu9qI2aO0Z" alt=""><figcaption></figcaption></figure>

### **6. Escalada de privilegios:**

#### **6.1. Revisión de tareas programadas (cron):**

Revisamos las tareas programadas del sistema (`crontab -l`) y observamos que se ejecuta cada minuto el siguiente script: `/opt/cleanup.sh`.

<figure><img src="/files/8VJ8DokBXzNg6KUcTYOB" alt=""><figcaption></figcaption></figure>

Visualizamos su contenido:

```bash
cat /opt/cleanup.sh
```

El script `cleanup.sh` ejecuta otro script ubicado en `/tmp` llamado `malicious.sh`.

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

#### **6.2. Análisis del script `malicious.sh`:**

Consultamos el contenido de `malicious.sh`:

```bash
cat /tmp/malicious.sh
```

El script original:

* Crea un archivo temporal en `/tmp` llamado `mi_log_temporal.log` con un texto y la fecha del sistema.
* Elimina dicho archivo a los dos segundos.

Aunque su funcionalidad no es útil directamente para escalar privilegios, sí lo es el hecho de que se ejecuta periódicamente con permisos de `root`.

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

#### **6.3. Comprobación de permisos sobre `malicious.sh`:**

Verificamos los permisos del archivo:

```bash
ls -l /tmp/malicious.sh
```

Comprobamos que el usuario `grooti` tiene permisos de lectura y escritura sobre `malicious.sh`.

Esto significa que podemos modificar el script que será ejecutado automáticamente por cron con privilegios de `root`.

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

#### **6.4. Modificación del script para escalar privilegios:**

Editamos el archivo `malicious.sh`:

```bash
nano /tmp/malicious.sh
```

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

Reemplazamos su contenido por:

```bash
#!/bin/bash

chmod u+s /bin/bash
```

Con este cambio, cada vez que cron ejecute `malicious.sh`, se asignará el bit SUID a `/bin/bash`.

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

#### **6.5. Verificación del bit SUID en `/bin/bash`:**

Antes de que se ejecute la tarea programada, comprobamos los permisos de `/bin/bash`:

```bash
ls -l /bin/bash
```

Inicialmente, no tiene el bit SUID activado.

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

Esperamos aproximadamente un minuto (tiempo de ejecución del cron) y volvemos a comprobar:

```bash
ls -l /bin/bash
```

Ahora observamos que `/bin/bash` tiene el bit SUID asignado, lo que indica que el script se ha ejecutado correctamente con privilegios de `root`.

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

#### **6.6. Obtención de shell como `root`:**

Para aprovechar el bit SUID en `/bin/bash`, ejecutamos:

```bash
bash -p
```

Con este comando obtenemos una shell con privilegios de `root`, completando la escalada de privilegios y, por tanto, la resolución completa de la máquina Grooti.

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