Exploiting File Uploads Pt. 2 – A Tale of a $3k worth RCE.

#TL;DR;

In this post I show how I was able to find a Remote Code Execution vulnerability on a private program through exploiting a file upload functionality, and leveraging XSSHunter to prove it. I also expand more on my mentality in exploiting file uploads and bug bounty in general, as well as give a few tips on communicating vulnerability impact to triagers.

#Approaching a new target

Feel free to just skip over to the #VerifyMyShell section if you just want to read about the exploit write up itself, but before I get into it I want to share my thought process / methodology when I start looking at a new target. On my last post I briefly touched on a few of these concepts, check out Exploiting File Uploads Pt. 1 if you are interested.

Something I tend to always check before jumping into and focusing on a new program is some of the program’s statistics, like how many bounties were found/paid, or for how long the program has been running. However, you can miss a lot of good programs if you get discouraged by these. This bug was a great example. I got invited to the program in question on May of 2019, and it had been running since 2016 with over 150+ bugs. Luckily, I decided to look into it regardless. Since the program was running for a while the first thing I checked was the Updates tab on it’s HackerOne Program page. It showed which endpoints were recently added to the policy as well as it had a description which part of the program the organization was interested in receiving bugs for.

Takeaway 1: There are always bugs to be found. Old programs can have just as many bugs as new programs! Hack the planet!

#Understanding the Target

The program’s description mentioned they were interested in vulnerabilities in the partner.program.com subdomain. Visiting the subdomain it seemed to be an application that allowed users to become partners and affiliates to the target. I usually like to focus on the authenticated part of the application, therefore a practice that I usually have is signing up with at least 2 accounts. Two accounts allow me to test for IDOR as I move along each of the application features. HackerOne e-mail aliases are great for this. After signing up and logging in to the app, one thing immediately called my attention.

This was one of the first steps required to use the app. As this is a trading company, partners and users are required to have their identities verified before using the site by uploading their passport/id pictures.

Have I mentioned how much I love File Uploads? 🙂

Takeaway 2: Don't overlook things. You never know when that search bar does have "that" XSS or SQLi that all the other 1337 hackers skipped over.

#Vulnerability Discovery

I’ve discussed a lot of my thought process and the things I try when testing File Uploads on Part 1, but the short version is: I try to understand how the upload process works. What are the limitations, the restrictions, and more importantly what are the sinks. As this was an identity verification functionality it usually has one of two sinks: an automated program that will test my file, or an actual person/employee approving user’s identities. The file upload it self looked like this:

Selecting any file that was not PNG, JPG, PDF, or BMP caused the application to do nothing. I looked over the request history in Burp to see if there were any type of file restrictions being caught. However, there were no new requests. Uploading a JPG did create a request to upload the file.

What does this tell us?

It showed there was a client side check. Client side checks are usually useless, and we can easily bypass it by selecting a JPG file to upload and intercepting the request to change it to whatever we want.

The request above gave me a “201 Created” response.

{"file_id":16xxxxx1}

So far so good. But where did our file go ? Looking back at the app, things don’t look so good.

However, refreshing the page and visiting the identity file upload page again we have a pleasant surprise. The file was listed under the files list to be uploaded with a hashed name and the .foo extension. It looked something like 34beduc…….3dfed.foo . Uploading the same file again, gave us a different hash like: fd33d3f……38338999dee.foo. As you may notice the extension was kept intact, but the file name was hashed and not fully disclosed. Finding the file to access it directly was not possible for me at the time. So how can we exploit this? What would you have tried?

#VerifyMyShell

With the possible sinks in mind, I tried to think what could be the best file to upload that would possibly be executed in most contexts. If my file upload is reaching an employee, there are things that I don’t know that could cause my file to not be executed. Is the employee using a linux machine? Windows? Mac? That could break my payload. What if it is an automated program? Also I need to have something that will communicate back to me somehow so I can tell when it is executed. I was pretty blind.

In comes XSS Hunter….

If you never heard of XSS Hunter, please make sure you visit the project’s page and read about it. In short XSS Hunter is a tool created by @IAmMandatory , and used for hunting for blind Cross Site Scripting bugs.

I decided to leverage this awesome tool to find out what my sink was. HTML files are executed in most of the contexts mentioned above, and using XSS Hunter I could get a tremendous amount of information sent back to me without much work.

Creating a very simple html file and uploading to the program, worked just as expected.

A day or two later we get a ping back, and it was better than expected. In XSS Hunter we see our HTML file was opened 3 times, and also pinged back to the XSS hunter server successfully.

BINGO! Our file was executed by what seems to be an employee from their Downloads folder. Looking at the full report we can even see more information such as User Agent which revealed the employee’s OS.

Takeaway 3: There are several ways to leverage a tool, be creative! The best tool you have is your unique view and perspective!

#Getting Paid

Finding the vulnerability, and exploiting is great, however reporting it correctly, is just as important when it comes to getting paid. If someone does not have the hacker/attacker mindset, they may have read up to this point and still thought there is no big vulnerability here. All we did was get the employee to open a html file. What’s the big deal?

Well that’s where explaining the impact and sometimes escalating it comes in. Here is an example how I reported this.

An attacker can easily bypass the client side check by simply choosing a correct JPEG and then modifying the actual request later as demonstrated. It is also shown from the Proof of Concept above the user(s) responsible for verifying the identity files are not checking the validity of the file before executing it OR there is an automated check that is executing files regardless of extension. Either or, it can very easily result in Remote Code Execution if the attacker sends for example an ELF or EXE file. I did not want to send any file with malware, but an malicious actor can easily upload a reverse shell for example and wait for personnel to execute.

Which resulted in one of my favorite things to receive back from triagers.

We were able to confirm this issue...[redacted] ... BTW. Very cool finding :)

And finally more importantly….