Dieser Artikel ist Teil der Reihe „Powershell Verschleierung“. Sehen Sie sich den Rest an:
Um sich auf diesen Post einzustimmen, können Sie sich kurz die ersten Folien aus dieser Präsentation von Daniel Bohannon und Le Holmes von der Black Hat 2017 ansehen. Wer hätte gedacht, dass man eine Präsentation mit einer Folienzahl im dreistelligen Bereich benötigt, um PowerShell-Befehle unlesbar aussehen zu lassen?
PowerShell ist das Werkzeug der Wahl für die Ernte nach dem Eindringen, mit dem die Angreifer das System beackern und sich die Früchte schmecken lassen. Lesen Sie sich unsere Reihe über Pen-Tests für das Active Directory durch, wenn Sie hieran noch Zweifel haben.
Allerdings besteht IT-Sicherheit theoretisch darin, die Benutzeraktivität zu überwachen (etwa in einem Security Operations Center/SOC), weshalb es einfach sein sollte, die Ausführung eines „nicht normalen“ Befehls zu erkennen.
Tatsächlich wissen wir, dass ein Hinweis auf einen PowerShell-Angriff darin besteht, dass ein Benutzer ein WebClient-Objekt erstellt, dessen Downloadstring-Methode aufruft und dann den in einer externen Webseite enthaltenen String ausführt. Das kann folgendermaßen aussehen:
Warum würde ein gewöhnlicher Benutzer oder sogar ein Administrator so etwas tun?
Dieser „Klartext“ ist zwar durch eine Betrachtung der richtigen Protokolle in Windows und Scannen nach den passenden Stichwörtern leicht zu erkennen. Sobald aber die verschleierte Version ins Spiel kommt, sieht die Sache ganz anders aus. Am Ende dieses Posts werden wir zeigen, wie diese einfache, von Hackern verwendete „Launch Cradle“ so gestaltet werden kann, dass sie wie ein komplett unentzifferbarer Wortsalat aussieht.
Bevor wir unseren ersten Ausflug in die Verschleierung unternehmen, wollen wir einen Blick darauf werfen, wie Ereignisse – insbesondere für PowerShell – tatsächlich von Windows protokolliert werden. Sobald Sie die Protokolle gesehen haben, werden Sie besser verstehen, was die Hacker zu verbergen versuchen.
Man muss Microsoft zugute halten, dass sie die Gefahren erkannt haben, die von PowerShell ausgehen können, und die Befehlprotokollierung in Windows 7 verbessert haben. Diese Verbesserungen sind in den Powershell-Versionen 4 und 5 zu erkennen.
In meiner eigenen AWS-Umgebung war das von mir verwendete Windows Server 2012 mit Version 4 ausgestattet. Diese Version verfügt anscheinend über die meisten erweiterten Protokollierungsfunktionen – bei Version 5 sind diese aber am umfassendsten und besten.
Soweit ich die großartige Präsentation von Bohannon und einige andere Quellen bei Microsoft verstanden habe, muss man das Ereignis 4688 (Prozesserstellung) aktivieren und dann die Überprüfung für die PowerShell-Befehlszeile einstellen. Mehr darüber erfahren Sie in diesem Microsoft-Dokument.
Um die Protokollierung noch umfangreicher zu machen, können Sie Richtlinien in der GPO-Konsole einrichten um z. B. eine vollständige Transkriptionsprotokollierung für eine PowerShell zu aktivieren (siehe unten).
Nein, für meine eigenen Tests habe ich das nicht getan! Ich habe (wie viele andere Sicherheitsexperten) gemerkt, dass die Dinge bei der Arbeit mit dem Windows-Ereignisanzeige sehr schnell verwirrend werden. Ich brauche die volle Leistungsfähigkeit der Transkriptionsprotokollierung nicht.
Zum Spaß habe ich eine einfache Pipeline ausgeführt – Get-Process | %{Write-Host $_.Handles} – um Prozess-Handles auszudrucken – und dabei die erstaunliche Menge von 114 Ereignissen im PowerShell-Protokoll erzeugt. Es gibt übrigens einen guten Post von Ofer, in dem er dass größere Problem, die separaten Ereignisse miteinander in Verbindung zu setzen, um das Gesamtbild zu erkennen, erklärt.
Die gute Nachricht ist, dass ich in der Ereignis-Anzeige die grundlegende Befehlszeile erkennen konnte, von der die Ereignisflut ausgelöst wurde (oben).
Der Angreifer verfolgt das Ziel, es für die Sicherheitsverantwortlichen, die sich die Protokolle ansehen, schwierig bis unmöglich zu machen, offenkundige Hacking-Aktivitäten zu erkennen, oder – noch wahrscheinlicher – Analyseprogramme zu überlisten, so dass diese beim Laden von Malware keinen Alarm auslösen.
In der zuvor erwähnten Präsentation gibt es ein langes und ausführliches Beispiel dafür, wie Malware durch Ausnutzen der Fähigkeit von PowerShell, in einen String eingebettete Befehle auszuführen, verschleiert werden kann.
Wussten Sie, dass das möglich ist?
Oder – noch bösartiger – dies hier:
Oder schauen Sie sich das hier an, was ich nach eigenem Rezept zusammengebraut habe:
Ja, PowerShell ist ungemein flexibel, und Hacker sind sehr gut darin, sich seine Funktionen zunutze zu machen, um Verwirrung zu stiften.
Sie können sich auch dieses Beispiel anschauen, indem Umweltvariablen in einer herkömmlichen Windows-Shell verwendet werden, um bösartigen Code zu verbergen und danach in PowerShell zu übertragen:
Sie sollten bedenken, dass in einer PowerShell-Pipeline jedes Segment einen separaten Prozess ausführt, der eigene Ereignisse auslöst, um für maximale Verwirrung zu sorgen. Ziel im vorstehenden Beispiel ist es, den bösartigen Code mit der %cmd%-Variable zu verbergen.
In meiner Windows-Ereignisanzeige konnte ich allerdings die vollständige ursprüngliche Befehlszeile aufspüren – es hat allerdings etwas gedauert.
Theoretisch könnte man in den Windows-Protokollen durch Scannen der Befehlszeilen nach der tatsächlichen Malware-Signatur suchen, für die in meinem Beispiel „write-host evil malware“ steht.
Aber Hacker haben inzwischen gelernt, die Malware-Signatur selbst geschickt unsichtbar zu machen. Das ist tatsächlich das Beispiel, mit dem ich zunächst angefangen habe.
Die Idee war, das WebClient .Net-Objekt zum Lesen der Malware zu nutzen, die in einer externen Seite enthalten ist, und sie dann mit Invoke-Expression von PowerShell auszuführen. In der Ereignisanzeige taucht der tatsächliche Code niemals auf!
Diese Vorgehensweise ist als dateilose Malware bekannt und ist unter Hackern mittlerweile sehr beliebt. Wie ich eingangs erwähnt habe, können Sicherheitsexperten darauf reagieren, indem sie stattdessen nach WebClient und Downloadstring in der Befehlszeile suchen. Das ist einfach kein normaler Benutzerbefehl, jedenfalls nicht für mich.
An dieser Stelle kommt das Tool von Bohannon für die Invoke-Verschleierung ins Spiel. Er hat ein Jahr lang alle möglichen Techniken zur Verschleierung der PowerShell-Befehlszeile ausprobiert, mit denen es nahezu unmöglich wird, nach offenkundigen Stichwörtern zu scannen.
Seine Verschleierungen basieren auf Escape-Sequenzen und gerissener PowerShell-Programmierung zum Manipulieren der Befehle.
Ich habe seine Invoke-Expression-App in meinen AWS-Server geladen und es selbst ausprobiert. Wir werden uns beim nächsten Mal ausführlicher mit diesem Tool beschäftigen, aber das hier ist passiert, als ich den dateilosen Webclient.Downloadstring-Befehl eingegeben habe:
Sehr verwirrend! Und ich konnte in seiner App die verschleierte PowerShell testen.
Nächstes Mal werden wir uns die Fähigkeiten der Invoke-Verschleierung genauer anschauen und erste Schritte unternehmen, um diese verwirrenden, aber brandgefährlichen PowerShell-Skripte aufzuspüren.