HTB - Quick

Zweilosec's write-up on the hard difficulty Linux machine Quick from https://hackthebox.eu

Overview

Short description to include any strange things to be dealt with

Useful Skills and Tools

Connecting to HTTPS through UDP (QUIC protocol)

  • quiche [link]

  • experimental curl features [link]

  • can also change settings in-browser experimental settings [link]

Upgrading a limited shell to a full TTY

  1. Determine the installed version of python with which python.

  2. Spawn a Bash shell through python's PTY with python -c 'import pty;pty.spawn("/bin/bash")'.

  3. Hit CTRL+Z to background the shell.

  4. Type stty raw -echo to enable all input to be sent raw through your reverse shell.

  5. Type fg to return your shell to the foreground.

  6. Enable screen clearing and colors with export TERM=xterm-256color

Creating an SSH tunnel for port forwarding

  • -L flag

  • link

  • example

Enumeration

Nmap scan

I started my enumeration with an nmap scan of 10.10.10.186. The options I regularly use are: -p-, which is a shortcut which tells nmap to scan all ports, -sC is the equivalent to --script=default and runs a collection of nmap enumeration scripts against the target, -sV does a service scan, and -oN <name> saves the output with a filename of <name>.

Based on my Nmap scan of TCP ports, there were only two open: SSH on the default port 22 and an Apache website being served over HTTP on the non-standard port 9001.

I opened a browser to see that was hosted on HTTP, and got a website which appeared to belong to a business selling broadband internet.

There was also a list of currently subscribed clients at /clients.php.

The main site says "Upto 17MBps - £18 | Upto 50MBps - £27" and because the price is in pounds it indicates that this might be a UK service provider. Correlating the countries of the clients, the company names, and the names on the Testimonials section gave me a potential list of users. I also noted that only two clients (Tim from Qconsulting and Elisa from Wink) were from the UK and rated them as higher priority targets for potential access.

My shortlist of potential usernames had four entries on it.

Clicking on the "Get Started" link led to a login page at http://10.10.10.186:9001/login.php. I attempted to see if any of these names would give me a positive error indicating a valid username, but the form required email addresses rather than usernames so it yielded nothing.

According to my dirbuster scan there was an exposed db.php, though I was not sure how to interact with it. Navigating to that site only brought up a blank page.

On the main page, there was a link to portal.quick.htb, which I added to my hosts file. It seemed to be an exact copy of the first page, except for the link that led to portal.quick.htb was an HTTPS site that did not connect.

I did notice something interesting while viewing the requests in Burp though: there was an HTTP header that said X-Powered-By: Esigate. Some research revealed that this was a webapp integration backend for the site. My research also found that there were some vulnerabilities that could be exploited in this software, though they required an exposed form where specifically crafted requests could bypass security controls. Unfortunately I didn't have anywhere to test for this vulnerability yet. http://www.esigate.org/security/security-01.html https://www.gosecure.net/blog/2019/05/02/esi-injection-part-2-abusing-specific-implementations/

I also noted that the apache server-status page was accessible, which could lead to a serious data disclosure vulnerability. I found some exploit code to take advantage of this at https://github.com/mazen160/server-status_PWN, but this site didn't seem to have any data exposed that could help me.

Nmap redux

Unfortunately this next part was spoiled for me a bit by someone mentioning that TCP was the only protocol that Nmap scanned by default and further enumeration was required. This was enough of a clue for my to try a UDP scan to see if there were any more ports open.

UDP scans take much, much longer to complete due to the way enumeration has to be done. Potential open UDP ports are determined by not receiving a response back from a probe, as opposed to TCP where a TCP - ACK is generally indicative of an open port, and a RST means the port is closed. UDP does not use flags in the same way as TCP, and relies on ICMP port unreachable messages to relay closed ports.

I recommend not scanning all 65536 ports at a time if you ever need to scan UDP, and do it in chunks. This scan also requires root privileges to run.

There was one UDP port that seemed to be open. Next I did some research on HTTPS over UDP port 443 and found some articles on the new protocol HTTP/3. I remember reading about the new HTTPS protocol over UDP which used a protocol called QUIC, but I didn't expect it to already by implemented in a Hack the Box challenge (kudos to MrR3boot!).

Resources:

The QUIC protocol is used in HTTP/3 and utilizes UDP for a fast connectionless "session". Since most websites are simple requests and responses, UDP works fine, because the extra overhead from TCP just slows everything down. Supposedly QUIC will be much faster (pun intended?).

This explains why the portal.quick.htb site had a link to an https:// site that didn't work, since the browser expects TCP:443, and most browsers do not currently support the new protocol which uses UDP. I did some looking around to see if any browsers did have support, and found https://caniuse.com/#feat=http3. It seems that some browers such as Google Chrome (or Chromium) can enable quic in the experimental settings page at chrome://flags. https://docs.google.com/document/d/1lmL9EF6qKrk7gbazY8bIdvq3Pno2Xj_l_YShP40GLQE/edit#

It seems that some browsers such as Google Chrome (or Chromium) can enable QUIC in the experimental settings page at chrome://flags. https://docs.google.com/document/d/1lmL9EF6qKrk7gbazY8bIdvq3Pno2Xj_l_YShP40GLQE/edit#

Building an HTTP/3 version of cURL

While reading up on HTTP/3 and determining if a site supports it or not I found the site https://geekflare.com/http3-test/. It mentioned a version of cURL that can be built from source that supports this protocol, so I downloaded the code from the GitHub repository at https://github.com/curl/curl/blob/master/docs/HTTP3.md#quiche-version and followed the instructions.

https://unix.stackexchange.com/questions/360434/how-to-install-libtoolize

After installing the Rust language (and many other dependencies) I had a shiny new experimental version of curl to play with that had HTTP/3 support.

Since I didn't want to just live in the install directory I created an alias of curl3 to the new curl with alias curl3=</install_path/>curl

With this new tool I was able to download the page at https://portal.quick.htb. There were four pages listed: index.php, contact, about, and docs.

The /contact page looked like a work in progress and had no useful information.

The /about page contained three potential users and useful email addresses: Jane Doe jane@quick.htb, Mike Ross mike@quick.htb, and John Doe john@quick.htb.

The /docs page contained references to two PDF files. I downloaded them to see if I could find more juicy information.

Both PDFs downloaded with no issues using the new cURL tool. The document Connectivity.pdf contained some interesting information!

Apparently this broadband provider gives their customers a default password to use to log into their accounts. I hoped that one of the clients was lazy enough to use the same password to log into the portal, and then not change it later.

The file Connectivity.pdf also had a link that led back to the first site: http://quick.htb, while the other document linked back to the HTTPS version. I thought that maybe this was a clue to log into the first site.

It took a little bit of guesswork to figure out how to log into the site since I couldn't see any clues that pointed to any email addresses other than the three @quick.htb ones. I first tried iterating through all of the names I had found while adding @quick.htb on the the end, but that wasn't successful. Next I decided that since they provided the company names and countries for each of the users, I could make potential email addresses out of those.

I loaded my potential email address list into wfuzz and used it to username-spray the website. My hunch seemed to be right! That 302 HTTP response above meant I had found a successful login for elisa@wink.co.uk! I'm actually surprised there was only one user that used the default password provided to log in! :P

I made sure to capture the login credentials in Burp so I could easily resend them any time I needed.

Initial Foothold

Now that I was logged into the portal, I had access to the /home, /ticket, and /search pages I had seen in my dirbuster output earlier.

The ticketing page had an entry field that gave me a ticket number when I submitted it.

Since I now had access to some fields that I could send input through, I decided to test out that Esigate vulnerability I had read about earlier to see if it could be exploited. It was assigned as CVE-2018-1000854. https://www.gosecure.net/blog/2019/05/02/esi-injection-part-2-abusing-specific-implementations/ https://github.com/esigate/esigate/issues/209

I followed the instructions in the blog and crafted an XSL file, which contained specially formed XML code that would be read and executed by Esigate when reflected into an XML file.

I submitted the above code into the ticketing system, which caused Esigate to load the evil.xml file with my code from the evil.xsl code reflected into it as a "stylesheet".

After some testing I found that the vulnerability indeed existed in the ticket search function! After submitting my "ticket" to the system searching for the ticket number caused the code in the malicious XML file to be read and executed by Esigate.

After quite a bit of head-scratching and testing, I found that I could only use a specific filename once. After that it caused a 404 error for even files that definitely exist on my locally hosted python server. I wasn't sure what was going on but it must have been something the server was doing.

During some of my testing, I tried to get the server to send me /etc/passwd, but unfortunately the file was blank. After testing it again a different way, I concluded that this command was being blocked so nothing was being sent. The important thing was that I could see that my test exploit worked.

Next I created a python script to automate the file upload and ticket search activation process.

I ran the script with three separate ESL files. Each were loaded with commands that would enable me to get a reverse shell. The first send a version of nc that had the ability to execute commands upon connection. The second ran chmod +x nc to ensure it was executable. The third contained my reverse shell command that would connect back to my machine. I loaded up all of my files with different filenames, executed my script, and crossed my fingers hoping that everything would work.

Everything looked like it completed without errors...

All of my files were uploaded successfully...

And... I was in. I received a limited shell at my waiting listener that I quickly upgraded to a fully interactive Bash shell using python.

User.txt

The first thing to do after gaining access was to claim my proof.

Path to Power (Gaining Administrator Access)

Enumeration as sam

The first thing I do after gaining an account on a machine is to find out what kind of privileges are available by using sudo -l. Unfortunately there was nothing I could run without the password.

I started looking though all of the Esigate files since that was what got me in, but there wasn't anything useful there.

I printed out /etc/passwd to see what users and services were available, and found three users with login capability: root, sam, and srvadm.

Netstat identified a few extra ports open from the inside that I couldn't reach from my machine. On port 8081 I found a Jetty server version 9.1.z-SNAPSHOT, and found vulnerabilities related to this at https://www.cvedetails.com/vulnerability-list/vendor_id-10410/product_id-34824/Eclipse-Jetty.html, but nothing that led anywhere.

There were quite a few processes running related to containers...in fact, it looked like the UDP 443 port I connected to was running from a container. There was even an interface visible in ifconfig.

I tried connecting to the docker container on that IP, but was rebuffed since I had no credentials.

Next I started looking through the website files in /var/www to see if there were any credentials left around, and found the email address srvadm@quick.htb in the index.php file. This file also mentioned db.php which sounded like it might contain useful information.

I was not disappointed. I now had credentials to a MySQL database which I had seen running on port 3306 earlier.

In the folder /var/www/ I found a writeable folder jobs that was owned by root. This is always a good indication of a privilege escalation route. In /var/www/printers I also found the file job.php which looked promising.

This looked to me like I could make a file in the /jobs folder (where I was able to write), write to the file my IP and port, then the jobs.php will make a connection to my computer thinking it is trying to print. The only catch is that whoever triggers the print needs to be logged in. I felt that I needed to check the database to check for further credentials.

I found the users table which potentially had new creds in it, but I wasn't sure what type of hash or encryption had been used on it.

I also found a list of the tickets that I submitted earlier...the lazy admin still hadn't gotten around to helping me with my issues!

for the password "hash" I found, the login.php contained this line which explained it:

wrote a script to crack the password using: https://stackoverflow.com/questions/13246597/how-to-read-a-large-file-line-by-line

then I ran it and didn't have to wait long

from github - https://github.com/mike42/escpos-php

While poking around in the /etc/apache2 directory I noticed the ports.conf file referenced a listener on port 80. Since this was not exposed outside the box, this must be an internal page only. The file said to check /etc/apache2/sites-enabled/000-default.conf for virtual hosts, so I did.

Here was the information I was looking for! There was a virtual host on port 80 at printerv2.quick.htb running under user srvadm. This may allow me exploit that jobs folder I had found in /var/www/html.

I added the page to my /etc/hosts file, but I was still blocked from accessing the page since it was on port 80 (which was still not open to the world).

Apparently this domain name was not in the quick.htb machine's hosts file, so I used the IP and port to try to connect instead.

This page looks exactly the same as the virtual hosted page http://portal.quick.htb. However, since I needed to specify the virtual host's domain name to connect, this was expected. If I could edit the local hosts file, I would be fine, but since I couldn't, I would have to connect from my machine.

I decided to try to create an authorized_keys folder for sam and see if I could use ssh port redirection to allow me to use my browser to navigate the printer page.

SSH worked, after that it I set up my port redirection tunnel. The -L option allows you to forward a local port to a port on the remote machine with the syntax: -L local_socket:host:hostport.

I logged in successfully, now to test my port forwarding in the browser. Unfortunately it didn't work, though I quickly spotted the problem. I was trying to connect to 10.10.10.186 on port 80, just from the quick.htb machine, which I already knew was blocked. I needed to access the site the same way I had with curl earlier, with 127.0.0.1:80.

After fixing the IP, I was able to connect to the virtual hosted page.

This led me to a login page. Since I knew that the page was running as srvadm, I figured the credentials must be the ones I had found for that user in the MySQL database earlier. http://pentestmonkey.net/tools/web-shells/php-reverse-shell

Getting a shell

As soon as I clicked the print button I got a connection, but when went to the jobs page it closed. I reopened the listener, and sent myself a test message, which appeared in my nc listener, then the connection ended again. It looked like I was not going to be able to send a shell through this, but would have to send data that srvadm could access.

this user did have a .ssh folder, so I hoped that he had an id_rsa key that I could try to steal. I searched for files that srvadm had access to but there wasn't anything else that looked useful.

I looked back at the code of the jobs page to see exactly what it was doing. It looked like it was creating a file with a name derived from the php date("Y-m-d_H:i:s") funtion, then writing to the file the contents of the 'Bill Details' field from the 'Print Jobs' page. After that it sends the file to the IP and port specified in the 'Bill & Receipt Printer' field.

So...now I had to try to figure how to trick this into printing the SSH key of srvadm. The only way I could think to do it was to create a link to the key file, replacing the file the print job expected (we are able to do this since job.php sets the file permissions to 0777) before it sends it to the "printer". I would have to be ...quick. https://stackoverflow.com/questions/12198844/replace-a-whole-file-with-another-file-in-bash

So that didn't work...probably because I don't have read permissions of the file. This does tell me, however, that the file exists and that I am on the right track!

This time, instead of trying to put the contents of the SSH key in the print file, I swapped the print file with a symlink to the key. This way when the file is sent to my waiting "printer" (nc listener), it would send the SSH key using the permissions of srvadm.

After a lot of troubleshooting I arrived at the script above and was able to retrieve the SSH key. I ended up having to remove the print job file job.php made, copy its filename to a variable, then symlink the id_rsa file to a file with the same name as the print job file. This all had to happen before the print job was sent to my waiting nc listener.

Enumeration as srvadm

forgot to change the permissions of the private key to 600

I found that srvadm was a member of the printers group, so I searched for files that that group could access...and came up with nothing.

https://www.cvedetails.com/cve/CVE-2017-7658/

https://www.cvedetails.com/vulnerability-list/vendor_id-10410/product_id-34824/Eclipse-Jetty.html

https://portswigger.net/web-security/request-smuggling

I thought &ftQ4K3SGde8? looked like it was being used as a password, so I tested it to see if I could use sudo as srvadm, but it didn't work. I decided to try something crazy, and tried to su to root...and it worked!

Root.txt

Thanks to <box_creator> for something interesting or useful about this machine.

If you like this content and would like to see more, please consider buying me a coffee!

Last updated

Was this helpful?