So umgehen Sie AMSI mithilfe von DLL-Hijacking
Aktie
Sehr gut an alle! Heute kommt mit einer (vorerst) letzten Folge über die Welt von AMSI. Bei dieser Gelegenheit werden wir herausfinden, wie wir AMSI mithilfe einer Technik namens DLL-Hijacking umgehen können.
Wenn eine Binärdatei mit dynamischen Links kompiliert wird, sucht das Betriebssystem nach der spezifischen DLL, um eine Laufzeitfunktionalität abzudecken. In vielen Fällen wird der Link zur DLL nicht über den vollständigen Pfad, sondern nur über den Namen definiert.
Dadurch kann Windows über seinen Suchmodus erkennen, welche DLL die Binärdatei in diesen Link laden wollte. Die Suchreihenfolge ist wie folgt:
- Das Verzeichnis, in dem sich die ausgeführte Anwendung befindet
- C:\Windows\System32
- C:\Windows\System
- C:\Windows
- Das Verzeichnis, in dem es sich befindet
- Alles in der Umgebungsvariablen %PATH%
Aufgrund dieser Funktionsweise von Windows kann daher jeder mit Schreibzugriff irgendwo auf der Festplatte AMSI umgehen. Weil? Denn wenn wir die PowerShell kopieren können, um sie an einem Ort zu haben, an dem wir Schreibrechte haben, und wir eine Datei namens amsi.dll erstellen, wird diese DLL beim Öffnen dieser PowerShell bevorzugt geladen.
Im folgenden Beispiel können wir sehen, wie wir durch die Platzierung der PowerShell an einem Ort wie dem Desktop dafür sorgen können, dass amsi.dll von demselben Ort geladen wird.
Die einzige Voraussetzung für die Verwendung dieser Technik ist eine DLL (erstellt in C/C++), deren Funktionen auf die gleiche Weise wie die eigentliche DLL definiert sind. Das heißt, es ist nicht notwendig, dass die Funktionalität dieselbe ist, aber für PowerShell muss der Aufruf der Funktion auf dieselbe Weise erfolgen: mit demselben Namen und denselben Argumenten.
64-Bit PowerShell finden Sie im folgenden Verzeichnis:
- C:\Windows\System32\WindowsPowerShell\v1.0
Während 32-Bit PowerShell im folgenden Verzeichnis zu finden ist:
- C:\Windows\SysWOW64\WindowsPowerShell\v1.0
Eine einfache Möglichkeit, diese Aufgabe zu erfüllen, besteht darin, die Original-DLL zu patchen. Mit anderen Worten: Wir könnten amsi.dll nehmen und die entsprechenden Anweisungen ändern, sodass die ursprüngliche Funktionalität verloren geht und niemals Malware zurückgegeben wird.
Zuvor haben wir im Beitrag AMSI-Funktionen erklärt, wozu jede AMSI-Funktion dient.
Wir wissen, dass AmsiScanBuffer ein HRESULT zurückgibt, einen Code, der angibt, ob die Funktion erfolgreich ausgeführt wurde oder nicht. Wenn wir AmsiScanBuffer so ändern, dass immer 0x80070057 zurückgegeben wird, funktioniert AMSI nicht mehr und wir haben es umgangen.
Das folgende Bild ist Teil der AmsiScanBuffer-Funktion.
Das erste if führt eine Reihe grundlegender Validierungen durch und wenn es erfolgreich ist, bedeutet dies, dass die Argumente ungültig bereitgestellt wurden und der Scan nicht möglich ist. Daher wird uVar2 auf 0x80070057 gesetzt.
Aber was würde passieren, wenn im else uVar2 auch auf 0x80070057 gesetzt wäre? Die Antwort ist, dass AMSI nicht mehr richtig funktionieren würde, denn obwohl AMSI mit Windows Defender kommuniziert, um den Puffer zu senden, wird der Befehl normal ausgeführt, wenn die Funktion INVALIDARG zurückgibt.
Um in Assembler einen Wert in einer Rückgabe zurückzugeben, müssen wir den Inhalt in ein Rückgaberegister laden. Um INVALIDARG zurückzugeben, könnten wir daher Folgendes hinzufügen:
- MOV EAX,0x80070057
Wenn Sie ghidra verwenden und im Teil decompile den Teil auswählen, der uns interessiert, können wir sehen, wo sich der entsprechende Assembler befindet. Um diese Funktion so zu patchen, dass sie immer INVALIDARG zurückgibt, können wir den letzten Aufruf ändern
Daher würde die Funktion wie folgt aussehen:
Abschließend müsste noch die DLL als PE exportiert werden und das wäre es.