Webshells in Report Exports via String Replacement

We are back again with another fun finding from a recent assessment. During this assessment, one of our Ninjas found an interesting way to acquire remote code execution.

In actuality, to get to this point there were a host of factors and utilizations of other findings that are usually considered lower severity. The lesson I am hoping everyone takes away from this blog is that all findings matter, even those that are considered lower severity. The next time you get a report with Low and Medium severity findings, don’t just ignore them. Please take the time to remediate these issues as well.

With that out of the way, let’s start from the beginning. The application we were testing is a reporting application. It’s functionality centers around gathering data from multiple other applications and compiling it into digestible reports. To perform this functionality, it queries multiple databases, formats the report, and exports it in several different formats.

While looking through the export page, the first thing we noticed was a field named “Export Location”.  Using this, we thought there may be a way to export the report to any location on the server we want. We made note of this for later use.

The next finding is something that we find on 90% of our assessments.  It is usually rated as a medium severity finding due to its information disclosure. Performing certain actions on the web page caused an error. The error code shown contains a stack trace with a wealth of information. Upon reviewing this stack trace, we learned the local directory the application is running from.

The next thing we noticed was that the directory listing had been left on for the root directory. We located this directory by messing with the URL after learning the application directory from the above finding. Navigating here via the URL would display a list of files.

Now, let’s combine these findings and try writing a report to the inbox directory we found above and see what we get. Success! We also noticed that the report was being exported as an .xml file. What happens if we attempt to change the export file type to .aspx?

Success!!

Okay, we can now export to a location we can access. How can we get a web shell from here? The answer to this question lies in the export functionality itself. Turns out the application contains a field called “Export Modifiers”. These modifiers allow certain fields to be altered or modified during the export process. After messing with these, we settled on attempting to use a function that alters the default value of a filed in the report. So, if a field is blank it will set our supplied default value. We tried this with some JavaScript and got some success.

This works great, but web shells tend to be rather lengthy, so we need a field that is long. The current field we were testing with had a maximum length of 20 characters. We spent about 45 minutes checking fields from different databases until we found one that allowed over 100 characters. Hint: description fields are usually a good bet.

Using burp suite to bypass the arbitrary client-side character limit, we saved our shell as the default value for this field.

Now let’s navigate to where we saved the report and see what we get.

Success!!!

Now, we just use the web shell to connect back to our machine for a fully interactive shell and we are done.

So, what did we learn today? Even small findings can contribute to a major issue within an application. Information disclosure findings are an issue and should be remediated along with High and Critical findings. 

That’s it for today.  Hope you had as fun reading this one as we had writing it. Until next time.

Scroll to Top