
CobaltStrike BOF zum Starten von Beacons mittels DLL Application Directory Hijacking
DropSpawn ist ein CobaltStrike BOF, das verwendet wird, um zusätzliche Beacons über eine relativ unbekannte Methode des DLL-Hijacking zu spawnen. Funktioniert x86-x86, x64-x64 und x86-x64/umgekehrt. Verwenden Sie es als Alternative zur Prozessinjektion.
Windows-ausführbare Dateien folgen der DLL-Suchreihenfolge, wenn sie versuchen, DLLs zu laden, deren absolute Pfade nicht angegeben wurden:

DLL-Hijacking erfordert typischerweise, dass entweder:
A. Ein Benutzer Schreibberechtigungen in einem Ordner hat, der eine höhere Suchreihenfolge als der Ort hat, an dem sich die echte DLL befindet
oder
B. Die betreffende DLL an keinem Ort im System existiert, in welchem Fall sie in einen benutzerbeschreibbaren Ordner in der %PATH%-Variable des Benutzers (wie %USERPROFILE%\appdata\local\microsoft\windowsapps) platziert werden kann.
Diese Anforderungen schließen DLL-Hijacking für ausführbare Dateien in C:\Windows\System32 aus, da fast alle DLLs, die diese ausführbaren Dateien laden, ebenfalls in System32 residieren. Das Kopieren einer System32-Ausführungsdatei an einen benutzerbeschreibbaren Ort und deren Ausführung dort ist eine Option, aber nicht sehr OPSEC-sicher, da System32-Binärdateien, die von alternativen Orten ausgeführt werden, leicht zu identifizieren sind.
DropSpawn ermöglicht DLL-Hijacking unter Verwendung von System32-Ausführbaren (und anderen, die in zusätzlichen nicht benutzerbeschreibbaren Ordnern gefunden werden), indem es 'Das Verzeichnis, aus dem die Anwendung geladen wird' auf ein beliebiges benutzerdefiniertes fälscht.
Die öffentliche Version von DropSpawn unterscheidet sich geringfügig von der nicht-öffentlichen. Die nicht-öffentliche Version nutzt einen proprietären Payload-Generator, was die Erfahrung für den Bediener viel nahtloser macht. Die öffentliche Version wurde leicht angepasst, um der Tatsache Rechnung zu tragen, dass Benutzer ihre eigenen Wege haben, DLL-Hijack-kompatible Payloads zu generieren. Ein Python3-Skript sowie Quellcode für eine Demonstrations-DLL wurden hinzugefügt, um Benutzern bei der Integration und Waffeneinsatz von DropSpawn zu helfen.
Identifizieren Sie einige Ziel-Ausführbare, die versuchen, DLLs zu laden, ohne ihre absoluten Pfade anzugeben. Sie können dies tun, indem Sie die exe in ein benutzerbeschreibbares Verzeichnis kopieren und sie ausführen, während Sie sie mit Procmon überwachen. In diesem Beispiel verwenden wir WerFault.exe, das sich normalerweise unter C:\Windows\System32\WerFault.exe befindet.

Im obigen Beispiel sind cryptsp.dll, wer.dll, dbghelp.dll und bcrypt.dll alle geeignete Kandidaten, da ihre absoluten Pfade nicht innerhalb von WerFault angegeben wurden; als Ergebnis wird WerFault versuchen, sie zuerst aus seinem Anwendungsverzeichnis zu laden, bevor es auf den Rest der DLL-Suchreihenfolge zurückgreift. Beachten Sie, dass dies normalerweise kein Problem darstellt, da das Anwendungsverzeichnis von WerFault System32 ist.
Laden Sie eine der hijackbaren DLLs vom Zielsystem herunter.
Dies ist notwendig, damit wir seine Exporte extrahieren und in unsere Payload-DLL aufnehmen können. Es ist wichtig, die hijackbare DLL von demselben Rechner zu holen, auf dem Sie DropSpawn verwenden möchten, da sich DLLs zwischen Windows-Versionen ändern. Wenn Sie außerdem einen x86-Beacon ausführen und mit DropSpawn einen x64-Beacon spawnen möchten, stellen Sie sicher, dass Sie die x64-Version der echten DLL herunterladen, indem Sie 'C:\windows\sysnative...' anstelle von 'C:\windows\system32...' angeben.
Führen Sie generate_dll.py aus und übergeben Sie die heruntergeladene DLL und die gewünschte Payload-Architektur. Generate_dll.py ist eine modifizierte Version von diesem Skript. Es wird die bereitgestellte DLL parsen, eine .def-Datei mit den Exporten der DLL erstellen und MingW aufrufen, um unsere Demonstrations-Payload-DLL zu kompilieren. Wenn der gespawnte Prozess versucht, eine echte Funktion innerhalb der gefälschten DLL aufzurufen, leitet unsere Payload-DLL den Aufruf an die echte DLL in System32 weiter, damit der Hostprozess nicht abstürzt.

Rufen Sie dropspawn mit der generierten Payload-DLL auf.
dropspawn <payload DLL> <x86|x64> <program to spawn> [writable target folder] [parent]
payload DLL - der vollständige Pfad zur generierten DLL-Payload.
architecture - die Architektur des Prozesses, den Sie spawnen möchten
program to spawn - der Name/Pfad des Prozesses, den Sie spawnen möchten. Wenn dieser Prozess in System32 (oder syswow64) residiert, können Sie einfach den Namen angeben. Andernfalls geben Sie den vollständigen Pfad an. Sie können dem Prozess auch Befehlszeilenargumente übergeben. Wenn der Pfad Leerzeichen enthält oder Sie Argumente verwenden, setzen Sie das Ganze in Anführungszeichen.
writable target folder - Optional. Wenn leer gelassen, versucht dropspawn das aktuelle Verzeichnis des Beacons zu verwenden. Verwenden Sie Anführungszeichen, wenn der Pfad Leerzeichen enthält.
parent - Optional. Der Name des Prozesses, der für PPID-Spoofing mit dem neu gespawnten Prozess verwendet werden soll. Wenn ein Prozess angegeben wird, der mehrere laufende Instanzen mit unterschiedlichen Berechtigungsstufen hat (z.B. svchost.exe), versucht dropspawn einen zu identifizieren, der für PPID-Spoofing verwendet werden kann.
Beispiel: dropspawn /root/gitlab/DropSpawn_BOF/dist/dbgcore.dll x64 "WerFault.exe -u -p 4352 -s 160" C:\users\user\appdata\local\temp explorer.exe
Dies wird die Payload-DLL 'dbgcore.dll' auf die Festplatte unter 'c:\users\user\appdata\local\temp\dbgcore.dll' ablegen und einen x64 WerFault.exe-Prozess mit den Befehlszeilenargumenten '-u -p 4352 -s 160' und explorer.exe als Elternprozess spawnen.


Die Bereinigung ist einfach. Durch die Aufnahme der Self-Deletion-Funktion in die Payload-DLL, die auf die Festplatte abgelegt wird, wird diese gelöscht, sobald unser neuer Prozess gestartet und sie geladen hat. Dies ist ein Game-Changer, da normalerweise die DLL auf der Festplatte gesperrt wäre, solange unser Prozess, der sie geladen hat, weiterläuft. Wenn die Self-Deletion-Technik aus irgendeinem Grund fehlschlägt (oder der Prozess nicht gestartet werden kann), versucht DropSpawn, die Payload-DLL von der Festplatte zu löschen und informiert den Benutzer in jedem Fall über das Ergebnis der Operation.
Prozessinjektion folgt typischerweise der Kette: Remote-Prozess öffnen -> Remote-Speicher zuweisen -> Remote-Speicher schreiben -> Remote-Speicher ausführen, mit der Option, am Anfang einen neuen Prozess zu starten anstatt einen vorhandenen zu verwenden. DropSpawn erstellt nur einen neuen Prozess; der neu gespawnte Prozess ist für das Zuweisen, Schreiben und Ausführen von Shellcode verantwortlich, sodass wir viele der IOCs vermeiden können, die typischerweise mit Remote-Prozessinjektion verbunden sind.
Diese Technik ist natürlich von der Güte Ihrer DLL-Payloads abhängig. Aber wir können uns ansehen, was Windows sieht (dieser nächste Abschnitt verwendet die private Version von DropSpawn und spawned Beacons).
Was die Ereignisanzeige betrifft, sieht alles normal aus:

In MDE gibt es sehr wenig zu sehen.
Ausführen von dropspawn:

MDE-Protokolle:
Mit PPID-Spoofing:

Ohne PPID-Spoofing:

In beiden Fällen sehen wir unseren ursprünglichen Beacon-Prozess (ebenfalls eine WerFault-Instanz), der dbgcore.dll auf die Festplatte ablegt, einen neuen WerFault.exe-Prozess erstellt, der neu gespawnte Prozess dbgcore.dll lädt und diese dann umbenennt (löscht). Kritisch ist, dass es keine zusätzliche Überprüfung von dbgcore.dll gibt, die oft mit DLL-Hijacks einhergeht, da wir sie nicht an einen häufig gehijackten Ort schreiben, und WerFault.exe (oder welchen Prozess Sie auch immer verwenden) wird nicht wirklich mit DLL-Hijacks in Verbindung gebracht, wie es bei Dingen wie WmiPrvSE.exe der Fall ist.
Interessanterweise ist es fast sichtbarer, dies mit PPID-Spoofing zu tun als ohne. Dies kann jedoch je nach Sicherheitsprodukt variieren.
Wie erwähnt, ist es unerlässlich, dass Benutzer die echten DLLs von dem Zielrechner herunterladen, auf dem sie DropSpawn verwenden möchten. Die Verwendung der falschen Version einer DLL kann dazu führen, dass der gespawnte Prozess abstürzt, wenn er versucht, eine Funktion aufzurufen, die nicht existiert.
DropSpawn kann mit ausführbaren Dateien außerhalb von System32 verwendet werden; seien Sie jedoch gewarnt, dass Probleme auftreten können, wenn der Prozess versucht, zusätzliche DLLs aus dem tatsächlichen Anwendungsverzeichnis des Prozesses zu laden. Da wir das Anwendungsverzeichnis woanders hin gefälscht haben, wird der Prozess abstürzen/fehlschlagen, wenn das reale Anwendungsverzeichnis nicht anderweitig über die DLL-Suchreihenfolge erreichbar ist, da er essentielle DLLs nicht finden kann. Testen Sie potenzielle Hijacks immer auf Entwicklungsmaschinen, bevor Sie sie in der Produktion einsetzen!
Diese Forschung entstand, als ich untersuchte, wie Prozesse ihre endgültige DLL-Suchreihenfolge zusammenstellen (da sie zur Laufzeit bestimmt werden muss, da ausführbare Dateien in verschiedenen Verzeichnissen liegen, das aktuelle Verzeichnis Teil des Suchpfads ist usw.). Meine Forschung führte mich zu diesem Forumsbeitrag, der den Ursprung der beiden kritischen undokumentierten APIs darstellt, die für diese Technik zentral sind.
Sie wurden bereits früher verlinkt, aber dieser Beitrag zur Vermeidung von Loader Lock, dieses Skript zur Erstellung einer .def-Datei für DLL-Proxying und diese Forschung zur Selbstlöschung laufender Ausführbarer sind wesentlich für die Erstellung effektiver, waffenfähiger DLL-Payloads, die für DropSpawn geeignet sind.
Als ich diese Technik zum ersten Mal auf Twitter veröffentlichte, schlossen sich mehrere andere der Diskussion an und erstellten POCs. SecurityAndStuff erstellte dieses, während Snovvcrash seines hier hat