Spider - Hack The Box

Spider is a complex machine with two SSTI vulnerabilities, and a really interesting method to get cookies with its private key. To escalate privileges we take advantage of the fact that we are allowed to enter input in an XML file, of which a parameter is displayed in a web service.

Nmap

The first we do is add the main host of the machine to our /etc/hosts file.

There are only 2 open ports in the machine.

Here, we can see that the port 80 hosts a nginx web server. The machine is a Linux OS and has Secure Shell Connection enabled.

With whatweb we can see that same information about the web server.

Web page

The page seems to be a furniture shop. We can look carefully and see the login, admin and register pages in the left.

To login we are asked for an UUID and a password. We will have to register first.

I checked for SQL injections in there parameters but they are not vulnerable.

Then, we proceed to register. We need a username and a password.

When we click the register button, we are given a UUID. With this UUID we can try to login.

SSTI

As nothing happened, I thought about a SSTI, a vulnerability I have seen in a recent machine. A SSTI (Server side template injection) plays with the response of the server to execute what we want, as we will see.

To check if it was vulnerable, I registered with 9 as my username. If it was vulnerable, the output of the operation will be shown as the username.

Now, our username is 81, so it worked.

We can try to run `` to get configuration information.

Now, in our username there is a lot of information about the web server.

If we read all the string, we will see a key. This “SECRET_KEY” is used for cookie encoding. With this, we will be able to get the session cookie of the user we want.

Session cookies with Flask Unsign

It is possible to craft the cookie we want using the tool Flask Unsign, available in Github.

With flask-unsign --sign --cookie, the vulnerable field and the key, we will get a cookie.

If we replace our cookie with this one, our user will change.

We are chiv at this point. As the admin board is empty, we can suppose that there will be a board that is not empty. So we now need to move to another user.

This phase is the most difficult one of the machine. We can only get to this by trying everything we know. And I thought about a simple Python oneliner to use flask unsign and the key. With this oneliner, I could test for SQL injections and is shown below.

The “script” is the following one.

from flask_unsign import session as s;
session = s.sign({'uuid': session}, secret = '(SecretKey)')

And the SQLmap command to detect SQL injections is:

Luckily, the parameter Cookie is injectable.

Now we know chiv’s password and uuid.

We can also see a really interesting message in its dashboard.

I saved the information retrieved in my content folder.

With the credentials, we can login.

And in the dashboard, there is the message we have seen before.

If we navigate to that URL, we will see a support portal.

From SSTI to RCE

This part is also hard, because we have to get a reverse shell from the SSTI vulnerability available in this kind of forms. The full explanation can be read in the following image.

In internet there are many tutorials to get command execution with SSTI. The problem is that the page has a lot of filters, so we can not use many restricted characters and symbols. So we need to bypass them, and I found this guide.

Here, we can see that the curly brackets are forbidden… Then, we have to bypass that restriction.

In this first bypass, we can replace the inner curly brackets of ”“ with ”% %”

But again, we are told that ”.”, the point, is a forbidden character.

We can encode the whole payload with echo -n (base64) | base64 -d | bash and pass our payload encoded to bypass the restrictions.

Our bash payload will be this one.

And the final payload, with the encoding thechnique, is this one.

At first, it seems that it does not like it.

But we finally get a reverse shell in our nc listener!

User SSH

We are now user in the system.

To make it easier for us, we will get the chiv id_rsa, and use it to connect with SSH.

We have now a SSH connection as the chiv user.

System enumeration

With netstat -tunlp we can see the listening ports in the victim machine. The 8080 one seems interesting, as it is normally associated with HTTPS services.

We can port forward it with SSH so we can get access to the port from our local machine.

In the webpage hosted in that port there is a “Beta login” form.

When we enter a username, a similar page as the first one is shown. And more important, our input is reflected.

XXE

If we intercept the POST request with Burpsuite, we will see a hidden parameter, version.

We can deduce from here that the application is parsing XML documents. This is vulnerable to XXE (External XML Entity).

Let’s see if we can get something else about the XML document fetched. We can retrieve our session cookie from the logout request.

If we decode this cookie, and then the base64, we will see a XML syntax with our username and the provided version. We know that the username part is reflected in the web, and we can write in the 1.0.0 part. We can play with that.

Our XML file is the following one:

<!-- API Version 1.0.0 -->
<root>
  <data>
    <username>bimo</username>
    <is_admin>0</is_admin>
  </date>
</root>

Therefore, we can close the API Version comment from our input, and then inject a malicious entity to read whatever we want. And, from our username, we can make a reference to that entity with a pointer.

The payload for the version input parameter will be:

With this, our XML will look as:

<!-- API Version 1.0.0 -->
<!DOCTYPE foo> [
  <!ELEMENT foo ANY>
  <!ENTITY bimo SYSTEM "file:///etc/passwd" >
]> <!-- -->
<root>
  <data>
    <username>&bimo;</username>
    <is_admin>0</is_admin>
  </date>
</root>

I injected it using burpsuite, because of the URL encoding.

If everything worked as intended, we will see the file in the webpage.

With CTRL+U we can see read it better.

Now, we can use this vulnerability to read every file we want. For example, the RSA Private key of the root user (/root/.ssh/id_rsa).

Using this private key, we can connect with SSH as the privileged user of the victim machine.