
Freeze is a payload toolkit for bypassing EDRs using suspended processes, direct syscalls, and alternative execution methods
Um die neueste Version von Freeze zu sehen oder ein Issue einzureichen, siehe https://github.com/Tylous/Freeze.
Wenn Sie mehr über die in diesem Framework verwendeten Techniken erfahren möchten, werfen Sie einen Blick auf den SourceZero Blog
Freeze ist ein Tool zur Erstellung von Payloads, das verwendet wird, um EDR-Sicherheitskontrollen zu umgehen und Shellcode auf eine unauffällige Weise auszuführen. Freeze nutzt mehrere Techniken, um nicht nur Userland-EDR-Hooks zu entfernen, sondern auch Shellcode so auszuführen, dass andere Endpunktüberwachungskontrollen umgangen werden.
Wenn ein Prozess erstellt wird, ist Ntdll.dll die erste DLL, die geladen wird. Dies geschieht, bevor EDR-DLLs geladen werden. Das bedeutet, dass es eine kleine Verzögerung gibt, bevor eine EDR geladen werden kann und beginnt, die Assembly von System-DLLs zu hooken und zu modifizieren. Bei der Betrachtung der Windows-Syscalls in Ntdll.dll sehen wir, dass noch nichts gehooked ist. Wenn wir einen Prozess im angehaltenen Zustand (einen in der Zeit eingefrorenen) erstellen, sehen wir, dass außer Ntdll.dll keine anderen DLLs geladen sind. Man sieht auch, dass keine EDR-DLLs geladen sind, was bedeutet, dass die Syscalls in Ntdll.dll unverändert sind.
Um diesen sauberen angehaltenen Prozess zu verwenden, um Hooks aus dem Freeze-Loader zu entfernen, benötigen wir eine Möglichkeit, programmatisch den Speicher des sauberen angehaltenen Prozesses zu finden und zu lesen. Hier kommt die Adressraum-Layout-Randomisierung (ASLR) ins Spiel. ASLR ist ein Sicherheitsmechanismus, um Schwachstellen basierend auf Stack-Speicherkorruption zu verhindern. ASLR randomisiert den Adressraum innerhalb eines Prozesses, um sicherzustellen, dass alle speicherzugeordneten Objekte, der Stack, der Heap und das ausführbare Programm selbst eindeutig sind. Nun wird es interessant, denn während ASLR funktioniert, funktioniert es nicht für positionsunabhängigen Code wie DLLs. Bei DLLs (insbesondere bekannten System-DLLs) wird der Adressraum einmal beim Booten randomisiert. Das bedeutet, dass wir keine Informationen eines entfernten Prozesses auflisten müssen, um die Basisadresse seiner ntdll.dll zu finden, da sie in allen Prozessen gleich ist, einschließlich des von uns kontrollierten. Da die Adresse jeder DLL pro Bootvorgang an derselben Stelle liegt, können wir diese Informationen aus unserem eigenen Prozess abrufen und müssen nie den angehaltenen Prozess auflisten, um die Adresse zu finden.
Mit diesen Informationen können wir die API ReadProcessMemory verwenden, um den Speicher eines Prozesses zu lesen. Dieser API-Aufruf wird häufig mit dem Lesen von LSASS im Rahmen von credential-basierten Angriffen in Verbindung gebracht; allein ist er jedoch grundsätzlich nicht bösartig, insbesondere wenn wir nur einen beliebigen Speicherbereich lesen. Das einzige Mal, dass ReadProcessMemory als verdächtig markiert wird, ist, wenn man etwas liest, das man nicht lesen sollte (wie den Inhalt von LSASS). EDR-Produkte sollten die Tatsache, dass ReadProcessMemory aufgerufen wurde, niemals als verdächtig markieren, da es legitime betriebliche Verwendungen für diese Funktion gibt und dies zu vielen Fehlalarmen führen würde.
Wir können dies noch einen Schritt weiterführen, indem wir nur einen Abschnitt von Ntdll.dll lesen, in dem alle Syscalls gespeichert sind – den .text-Abschnitt, anstatt die gesamte DLL zu lesen.
Durch die Kombination dieser Elemente können wir programmatisch eine Kopie des .text-Abschnitts von Ntdll.dll erhalten, um unseren vorhandenen gehookten .text-Abschnitt vor der Ausführung des Shellcodes zu überschreiben.
ETW nutzt eingebaute Syscalls, um diese Telemetrie zu generieren. Da ETW auch eine native Funktion von Windows ist, müssen Sicherheitsprodukte die ETW-Syscalls nicht "hooken", um auf die Informationen zuzugreifen. Um ETW zu verhindern, patcht Freeze daher zahlreiche ETW-Syscalls, spült die Register aus und gibt den Ausführungsfluss an die nächste Anweisung zurück. Das Patchen von ETW ist jetzt standardmäßig in allen Loadern enthalten.
Da nur Ntdll.dll wiederhergestellt wird, müssen alle nachfolgenden Aufrufe zur Ausführung von Shellcode in Ntdll.dll residieren. Mit Go (beachten Sie, dass Sie dies auch in anderen Sprachen tun können, aber in Go ist es recht einfach zu implementieren) können wir die NT-Syscalls definieren und aufrufen, die zum Allozieren, Schreiben und Schützen des Shellcodes erforderlich sind, und so die Standardaufrufe in kernel32d.dll und Kernelbase.dll effektiv überspringen, da diese möglicherweise noch gehooked sind.
Freeze wurde in Golang entwickelt.
Um Freeze zu installieren, führen Sie die folgenden Befehle aus, oder verwenden Sie die kompilierte Binärdatei:
go build Freeze.go
___________
\_ _____/______ ____ ____ ________ ____
| __) \_ __ \_/ __ \_/ __ \\___ // __ \
| \ | | \/\ ___/\ ___/ / /\ ___/
\___ / |__| \___ >\___ >_____ \\___ >
\/ \/ \/ \/ \/
(@Tyl0us)
Soon they will learn that revenge is a dish... best served COLD...
Verwendung von ./Freeze:
-I string
Pfad zum rohen 64-Bit-Shellcode.
-O string
Name der Ausgabedatei (z.B. loader.exe oder loader.dll). Abhängig von der definierten Dateierweiterung wird bestimmt, ob Freeze eine DLL oder eine EXE erstellt.
-console
Nur für binäre Payloads - Generiert ausführliche Konsoleninformationen, wenn die Payload ausgeführt wird. Dies deaktiviert die Funktion des versteckten Fensters.
-encrypt
Verschlüsselt den Shellcode mit AES-256-Verschlüsselung
-export string
Nur für DLL-Loader - Geben Sie eine bestimmte Exportfunktion an, die ein Loader haben soll.
-process string
Der Name des zu startenden Prozesses. Dieser Prozess muss in C:\Windows\System32\ vorhanden sein. Beispiel 'notepad.exe' (Standard "notepad.exe")
-sandbox
Aktiviert die Sandbox-Umgehung durch Überprüfung:
Ist der Endpunkt mit einer Domäne verbunden?
Hat der Endpunkt mehr als 2 CPUs?
Hat der Endpunkt mehr als 4 GB RAM?
-sha256
Gibt den SHA256-Wert der Loader an (Dies ist nützlich für die Nachverfolgung)
Freeze kann entweder eine .exe- oder .dll-Datei generieren. Um dies anzugeben, stellen Sie sicher, dass die -O-Befehlszeilenoption entweder mit .exe für Binärdateien oder .dll für DLLs endet. Andere Dateitypen werden derzeit nicht unterstützt. Im Falle von DLL-Dateien kann Freeze auch zusätzliche Exportfunktionen hinzufügen. Verwenden Sie dazu -export mit einem bestimmten Exportfunktionsnamen.
Freeze verwendet eine Technik, bei der zuerst der Prozess erstellt und dann in den Hintergrund verschoben wird. Dies hat zwei Auswirkungen: Erstens hilft es, den Prozess versteckt zu halten, und zweitens vermeidet es die Erkennung durch EDR-Produkte. Das sofortige Starten eines Prozesses im Hintergrund kann sehr verdächtig sein und ein Indikator für Bösartigkeit sein. Freeze erreicht dies, indem es die Windows-Funktionen 'GetConsoleWindow' und 'ShowWindow' aufruft, nachdem der Prozess erstellt und die EDR-Hooks geladen wurden, und dann die Fensterattribute auf "versteckt" ändert. Freeze verwendet diese APIs anstelle des traditionellen -ldflags -H=windowsgui, da dies stark signiert und in den meisten Sicherheitsprodukten als Indikator für eine Kompromittierung eingestuft wird.
Wenn die Befehlszeilenoption -console ausgewählt ist, wird Freeze den Prozess nicht im Hintergrund verstecken. Stattdessen wird Freeze mehrere Debug-Meldungen hinzufügen, die anzeigen, was der Loader tut.
Besonderer Dank gilt aahmad097 für die Entwicklung von AlternativeShellcodeExec
Besonderer Dank gilt mvdan für die Entwicklung von Garble