DevOops Writeup w/o Metasploit

Reconnaissance

Run the nmapAutomatoarrow-up-rightr script to enumerate open ports and services running on those ports.

  • All: Runs all the scans consecutively.

We get back the following result.

We have two ports open.

  • Port 22: running OpenSSH 7.2p2

  • Port 5000: running Gunicorn 19.7.1

Before we move on to enumeration, let’s make some mental notes about the scan results.

  • The OpenSSH version that is running on port 22 is not associated with any critical vulnerabilities, so it’s unlikely that we gain initial access through this port, unless we find credentials.

  • The Gobuster scan found two directories: feed and upload. The upload directory sounds interesting, we’ll check it out to see if we can get initial access through it.

Enumeration

Visit the application in the browser.

The index page makes mention of a feed.py page. This page didn’t show up in our gobuster scan. Visit the page in the application.

We get a 404 error. Next, let’s visit the upload directory.

It seems to be taking in XML files. When I see an XML upload functionality, the first thing I test for is an XML External Entity (XXE) injection. This is a type of attack that exploits how the backend XML parser processes XML data. If successful, it can allow an attacker to view files on the server, conduct a server side request forgery attack, etc.

To test this out, let’s first create an empty test.xml file and upload it. Intercept the request in Burp and send it to Repeater. Then send the request.

We get an internal server error, which probably means that there is a certain XML structure that the backend is expecting. The page did make mention of three XML elements: Author, Subject and Content. So after a bit of trail and error, we find that the following payload generated a 200 status code.

Now that we have a working request, let’s see if it is vulnerable to XXE injection. Visit the PayloadAllTheThings XXEarrow-up-right section and perform the basic entity test that detects if this vulnerability exists.

The above payload includes the entity “example” in the DOCTYPE element. If the XML parser parses this entity, it will display the string “Doe” in the “Author” element.

As can be seen in the response, we now have confirmation that this upload functionality is vulnerable to an XXE injection.

Initial Foothold

Let’s take this exploit a step further and retrieve the content of the /etc/passwd file.

Filter the result on users that have a /bin/bash shell assigned to them.

The user.txt file is probably in the roosa home directory. Since SSH is the only other port that is open, let’s check if roosa has an SSH private key in her home directory.

Perfect! Save the content of the private key in file roosa_id_rsa.

Change the permissions of the file.

SSH into roosa’s account.

Grab the user.txt flag.

Privilege Escalation

View the content of the home directory.

Let’s look into the .bash_history file.

Roosa made a commit that contained a key. To view the commit history run the following command.

We get an error that the folder we’re in is not a git repository. To find the git repository, locate the .git file.

It’s in the directory /blogfeed directory.

We get a commit id for the commit that reverted the proper key. Use the commit ID to show the difference between that commit and the previous one.

We get back the following result.

So it seems that Roosa deleted an RSA private key and replaced it with her own RSA private key. We don’t know who the deleted key belongs to so let’s add it in the file unknown_id_rsa.

Change the permissions on the file.

Try to log into the git account with it.

It doesn’t work. Let’s try the root account.

We’re in! Grab the root.txt flag.

Extra Content

After rooting this machine, I watched ippsec’s videoarrow-up-right and discovered an alternative way to gain initial access.

In the index page, there was a mention of a feed.py script that gave us a 404 error when we tried to access it through the application. We can use the XXE injection vulnerability to view the content of the script.

We get back the following result in the response.

We see that there is a newpost directory that takes in user input (request data) in a POST method and loads it using the pickle module.

A quick search on the module tells us what it does.

The picklearrow-up-right module implements binary protocols for serializing and de-serializing a Python object structure.

The page also include the following warning.

This is a HUGE red flag! The above warning states that you should never take in data from an untrusted source, however, in the script above, we can see that it takes in request data (which is client side data that can be tampered with) and doesn’t do any validation on that data. So we definitely have an arbitrary code execution vulnerability here.

Do a google search on “pickle exploit” to find the following github pagearrow-up-right. Download the exploit code and change the command to a bash reverse shell with the correct IP address and port.

Run the exploit.

We need to insert the above base64 encoded string into the the POST request to /newpost. To do that, intercept the request to the index page, send it to Repeater, right click and select the option Change Request Method. Then add the path /newpost, change the Content-Type to ‘text’ and include the base64 string our exploit generated.

Send the request and we get a shell!

Lessons Learned

To gain an initial foothold on the box we exploited two vulnerabilities.

  1. XML External Entity (XXE) injection that allowed us to enumerate users on the box and obtain the SSH private key of the user roosa. Remediations for this vulnerability include input validation and properly configuring XML parsers to disable the resolution of external entities.

  2. Lack of input validation that allowed us to run arbitrary commands on the system. The application was taking in untrusted user input and unpacking it using the pickle python deserialization library. Since the input was not properly validated, we generated a string of malicious input that sent a reverse shell back to our attack machine. Remediations for this vulnerability include input validation and using secure libraries that have built in input validation checks.

To escalate privileges we exploited one vulnerability.

  1. Sensitive information disclosure. The developer had previously committed the root RSA private key in a Github repository. Although the key was replaced with the correct one, we were still able to access the original key in the commit history. Remediation for this vulnerability would be to remove the file from the repository’s history. For more information on how to do that, refer to this linkarrow-up-right.

Last updated