
CobaltWhispers is an aggressor script that utilizes a collection of Beacon Object Files (BOF) for Cobalt Strike to perform process injection, persistence and more, leveraging direct syscalls (SysWhispers2) to bypass EDR/AV
Autor: @Cerbersec
CobaltWhispers ist ein Aggressor-Skript, das eine Sammlung von Beacon Object Files für Cobalt Strike verwendet, um Prozessinjektion, Persistenz und mehr durchzuführen, indem es direkte Syscalls nutzt, um EDR/AV zu umgehen.
CobaltWhispers nutzt SysWhispers2 und InlineWhispers2
CobaltWhispers basiert auf StayKit sowie Arbeiten von Hasherezade und Forrest Orr.
CobaltWhispers wurde im Rahmen eines Praktikums im Red Team von NVISO Security erstellt. Die zugehörigen Blogbeiträge finden Sie hier (Prozessinjektion) und hier (Kernel Karnage).
CobaltWhispers erfordert mehrere Werkzeuge zum Kompilieren:
apt install mingw-w64apt install makeJedes Projekt benötigt 3 Dateien, die von SysWhispers2 / InlineWhispers2 generiert werden, um zu funktionieren:
Diese Dateien können gemäß der InlineWhispers2-Dokumentation generiert werden, dies ist jedoch nicht die optimale Methode, da eine Menge ungenutzter Code enthalten sein wird:
git clone https://github.com/Sh0ckFR/InlineWhispers2 && cd InlineWhispers2
cd SysWhispers2/ && python3 syswhispers.py --preset all -o syscalls_all && cd ..
python3 InlineWhispers2.py
Verwenden Sie stattdessen SysWhispers2, um die Ausgabedateien nur für die erforderlichen APIs zu generieren, und stellen Sie sie dann manuell (oder per Skript) InlineWhispers2 zur Verfügung, das sie in das richtige Format konvertiert. Weitere Informationen finden Sie im mitgelieferten Makefile, oder verwenden Sie die mitgelieferten Dateien auf eigenes Risiko.
| Payload-Typ | Ziel | Zuverlässigkeit (0-5) | Erweiterte Rechte | Bemerkungen |
|---|---|---|---|---|
| - | - | 5 | Nein | Erbt Berechtigungen vom übergeordneten Prozess |
Startet einen neuen angehaltenen Prozess mit aktiviertem Code Integrity Guard (CIG), um nicht von Microsoft signierte Binärdateien zu blockieren. Spooft den angegebenen übergeordneten Prozess. Die PID wird zurückgegeben.
Übergeordneter Prozess: Der Name des Prozesses, der als übergeordneter Prozess festgelegt werden soll
Speicherort der ausführbaren Datei: Vollständiger Pfad zur ausführbaren Datei auf der Festplatte, die zum Starten eines neuen Prozesses verwendet wird
| Payload-Typ | Ziel | Zuverlässigkeit (0-5) | Erweiterte Rechte | Bemerkungen |
|---|---|---|---|---|
| Shellcode/Raw | PID | 5 | Nein | - |
Injiziert einen Payload in einen entfernten Prozess mithilfe von NtCreateThreadEx
Prozess-PID: Die Prozess-ID des entfernten Prozesses
Payload-Speicherort: Speicherort des Payloads in binärer Form auf der Festplatte (Bedingt | Optional)
Payload b64: Roher Shellcode im Base64-kodierten String-Format (Bedingt | Optional)
Listener: Listener, für den ein Payload generiert werden soll (Bedingt)
Ein Listener sollte angegeben werden, um einen Beacon-Payload zu generieren. Wenn ein manueller Payload gewünscht ist, sollte er über einen Pfad zur rohen Binärdatei auf der Festplatte oder als Base64-kodierten Shellcode bereitgestellt werden.
| Payload-Typ | Ziel | Zuverlässigkeit (0-5) | Erweiterte Rechte | Bemerkungen |
|---|---|---|---|---|
| Shellcode/Raw | PID | 2 | Nein | Kann den Zielprozess möglicherweise zum Absturz bringen |
Injiziert einen Payload in einen entfernten Prozess mithilfe von NtQueueApcThread
Prozess-PID: Die Prozess-ID des entfernten Prozesses
Threads: Anzahl der Threads, zu denen ein APC-Aufruf hinzugefügt werden soll
Payload-Speicherort: Speicherort des Payloads in binärer Form auf der Festplatte (Bedingt | Optional)
Payload b64: Roher Shellcode im Base64-kodierten String-Format (Bedingt | Optional)
Listener: Listener, für den ein Payload generiert werden soll (Bedingt)
Ein Listener sollte angegeben werden, um einen Beacon-Payload zu generieren. Wenn ein manueller Payload gewünscht ist, sollte er über einen Pfad zur rohen Binärdatei auf der Festplatte oder als Base64-kodierten Shellcode bereitgestellt werden.
| Payload-Typ | Ziel | Zuverlässigkeit (0-5) | Erweiterte Rechte | Bemerkungen |
|---|---|---|---|---|
| Shellcode/Raw | Surrogate-Prozess | 5 | Nein | - |
Injiziert einen Payload in einen Surrogate-Prozess mithilfe von NtMapViewOfSection
Übergeordneter Prozess: Der Name des Prozesses, der als übergeordneter Prozess festgelegt werden soll
Speicherort der ausführbaren Datei: Der Speicherort der ausführbaren Datei auf der Festplatte, die zum Starten eines neuen Prozesses verwendet wird
Payload-Speicherort: Speicherort des Payloads in binärer Form auf der Festplatte (Bedingt | Optional)
Payload b64: Roher Shellcode im Base64-kodierten String-Format (Bedingt | Optional)
Listener: Listener, für den ein Payload generiert werden soll (Bedingt)
Ein Listener sollte angegeben werden, um einen Beacon-Payload zu generieren. Wenn ein manueller Payload gewünscht ist, sollte er über einen Pfad zur rohen Binärdatei auf der Festplatte oder als Base64-kodierten Shellcode bereitgestellt werden.
| Payload-Typ | Ziel | Zuverlässigkeit (0-5) | Erweiterte Rechte | Bemerkungen |
|---|---|---|---|---|
| PE | Surrogate-Prozess | 5 | Nein | Erfordert x64-PE-Payload |
Injiziert einen Payload in einen Surrogate-Prozess mithilfe transaktionaler Sektionen und gemappter Ansichten. Der entfernte Einstiegspunkt und die PEB werden aktualisiert, keine anomalen Speichersektionen oder Speicherberechtigungen. Weitere Informationen finden Sie hier.
Übergeordneter Prozess: Der Name des Prozesses, der als übergeordneter Prozess festgelegt werden soll
Speicherort der ausführbaren Datei: Der Speicherort der ausführbaren Datei auf der Festplatte, die zum Starten eines neuen Prozesses verwendet wird
Payload-Speicherort: Speicherort des x64-PE-Payloads auf der Festplatte (Bedingt | Optional)
Payload b64: x64-PE-Payload im Base64-kodierten String-Format (Bedingt | Optional)
Listener: Listener, für den ein Payload generiert werden soll (Bedingt)
Ein Listener sollte angegeben werden, um einen Beacon-Payload zu generieren. Wenn ein manueller Payload gewünscht ist, sollte er über einen Pfad zur x64-PE-Datei auf der Festplatte oder als Base64-kodierte x64-PE bereitgestellt werden.
DERZEIT NICHT IMPLEMENTIERT
| Payload-Typ | Ziel | Zuverlässigkeit (0-5) | Erweiterte Rechte | Bemerkungen |
|---|---|---|---|---|
| Positionsunabhängiger Shellcode (PIC) | Surrogate-Prozess | 5 | Ja | Erweiterte Berechtigungen sind erforderlich, um System-DLLs mit Schreibberechtigung zu öffnen |
Injiziert einen Payload in einen Surrogate-Prozess mithilfe transaktionaler Sektionen in Kombination mit DLL-Hollowing. Weitere Informationen finden Sie hier.
Übergeordneter Prozess: Der Name des Prozesses, der als übergeordneter Prozess festgelegt werden soll
Speicherort der ausführbaren Datei: Der Speicherort der ausführbaren Datei auf der Festplatte, die zum Starten eines neuen Prozesses verwendet wird
Payload-Speicherort: Speicherort des Payloads in binärer Form auf der Festplatte (Bedingt | Optional)
Payload b64: Roher Shellcode im Base64-kodierten String-Format (Bedingt | Optional)
Listener: Listener, für den ein Payload generiert werden soll (Bedingt)
Ein Listener sollte angegeben werden, um einen Beacon-Payload zu generieren. Wenn ein manueller Payload gewünscht ist, sollte er über einen Pfad zur rohen Binärdatei auf der Festplatte oder als Base64-kodierten Shellcode bereitgestellt werden.
Erstellt oder ändert einen Registrierungsschlüssel an der angegebenen Position.
Schlüsselname: Wertname
Befehl: Befehl, der ausgeführt wird, wenn die Registrierung verwendet wird
Registrierungsschlüssel: Speicherort, an dem der Registrierungsschlüssel erstellt wird
Versteckt: Stellt dem Schlüsselnamen ein Nullbyte voran; führt in regedit zu Fehlern
Bereinigung: Entfernt den erstellten Schlüssel
Für die Bereinigung sind der Schlüsselname und der Registrierungsschlüssel (Speicherort) erforderlich.
Erstellt oder ändert einen Registrierungsschlüssel an der angegebenen Position.
Schlüsselname: Wertname
Befehl: Befehl, der ausgeführt wird, wenn die Registrierung verwendet wird
Registrierungsschlüssel: Speicherort, an dem der Registrierungsschlüssel erstellt wird
Versteckt: Stellt dem Schlüsselnamen ein Nullbyte voran; führt in regedit zu Fehlern
Bereinigung: Entfernt den erstellten Schlüssel
Für die Bereinigung sind der Schlüsselname und der Registrierungsschlüssel (Speicherort) erforderlich.
UserInit: Legt 'Schlüsselname' und 'Registrierungsschlüssel' automatisch fest.
Erstellt oder ändert einen Registrierungsschlüssel an der angegebenen Position.
Schlüsselname: Wertname
Befehl: Befehl, der ausgeführt wird, wenn die Registrierung verwendet wird
Registrierungsschlüssel: Speicherort, an dem der Registrierungsschlüssel erstellt wird
Versteckt: Stellt dem Schlüsselnamen ein Nullbyte voran; führt in regedit zu Fehlern
Bereinigung: Entfernt den erstellten Schlüssel
Für die Bereinigung sind der Schlüsselname und der Registrierungsschlüssel (Speicherort) erforderlich.
Erstellt oder ändert einen Registrierungsschlüssel an der angegebenen Position.
Schlüsselname: Wertname
Befehl: Befehl, der ausgeführt wird, wenn die Registrierung verwendet wird
Registrierungsschlüssel: Speicherort, an dem der Registrierungsschlüssel erstellt wird
Versteckt: Stellt dem Schlüsselnamen ein Nullbyte voran; führt in regedit zu Fehlern
Bereinigung: Entfernt den erstellten Schlüssel
Für die Bereinigung sind der Schlüsselname und der Registrierungsschlüssel (Speicherort) erforderlich.
UserInitMprLogonScript: Legt 'Schlüsselname' und 'Registrierungsschlüssel' automatisch fest.
Übernimmt den COM-Handler einer geplanten Aufgabe. Erstellt einen Registrierungsschlüssel unter HKCU:\Software\Classes\CLSID\\InprocServer32, der auf eine DLL verweist.
Klassen-ID: Die CLSID, die der COM-Handler-CLSID der Aufgabe entspricht
DLL-Pfad: Pfad zur DLL, die geladen werden soll
Bereinigung: Entfernt den erstellten Schlüssel
| Zuverlässigkeit (0-5) | Erweiterte Rechte | Bemerkungen |
|---|---|---|
| 4 | Ja | Kann das Zielsystem möglicherweise zum Absturz bringen (BSOD) |
Lädt einen verwundbaren signierten Treiber mit beliebigem Kernel-Speicher-Lesen/Schreiben (NalDrv/iqvm64.sys). Ändert das g_CiEnabled-Flag von ntoskrnl.exe oder das g_CiOptions-Flag von CI.dll, um die Treibersignaturerzwingung (Driver Signature Enforcement, DSE) zu deaktivieren.
Lädt einen nicht signierten Treiber (Interceptor/Interceptor.sys) und stellt dann die DSE-Flag-Werte wieder her. Sowohl der signierte Treiber als auch der nicht signierte Treiber werden auf die Festplatte geschrieben.
| Treiber | MD5-Prüfsumme |
|---|---|
| iqvm64.sys | 1898ceda3247213c084f43637ef163b3 |
| Interceptor.sys | 508c8943359717cfa0c77b61ebea2118 |
Speicherort des verwundbaren Treibers: Speicherort des verwundbaren signierten Treibers in binärer Form auf der Festplatte
Speicherort des schädlichen Treibers: Speicherort des schädlichen, nicht signierten Treibers in binärer Form auf der Festplatte
Name des verwundbaren Treibers: Name, der zum Erstellen des Registrierungsschlüssels '\Registry\Machine\System\CurrentControlSet\Services\' verwendet wird
Gerätename des verwundbaren Treibers: Name, der zum Kontaktieren des Treibers '\DosDevices\' verwendet wird
Name des schädlichen Treibers: Name, der zum Erstellen des Registrierungsschlüssels '\Registry\Machine\System\CurrentControlSet\Services\' verwendet wird
Gerätename des schädlichen Treibers: Name, der zum Kontaktieren des Treibers '\DosDevices\' verwendet wird
Zielpfad: Temporärer Pfad, in den die Dateien des verwundbaren und des schädlichen Treibers geschrieben werden
| Zuverlässigkeit (0-5) | Erweiterte Rechte | Bemerkungen |
|---|---|---|
| 5 | Ja | - |
Entlädt einen Treiber auf dem Zielsystem mithilfe des angegebenen Registrierungsschlüssels und löscht die Binärdatei von der Festplatte unter dem angegebenen Pfad.
Registrierungsschlüssel des Treibers: Registrierungsschlüssel, der zum Entladen des Treibers verwendet wird '\Registry\Machine\System\CurrentControlSet\Services\'
Installationspfad des Treibers: Speicherort des Treibers auf der Festplatte
| Zuverlässigkeit (0-5) | Erweiterte Rechte | Bemerkungen |
|---|---|---|
| 4 | Nein | Kann das Zielsystem möglicherweise zum Absturz bringen (BSOD) |
Information: Fragt den Interceptor-Treiber ab
Hook: Hookt die Hauptfunktionen (IRP) des Zieltreibers
Unhook: Stellt die Hauptfunktionen des Zieltreibers wieder her
Patch: Patcht die Kernel-Callbacks des Ziels
Restore: Stellt die Kernel-Callbacks des Ziels wieder her
Anbieter: Unterstützte Anbieter anzeigen
Module: Alle geladenen Treiber abfragen
Gehookte Module: Alle gehookten Treiber anzeigen
Callbacks: Alle registrierten Callbacks abfragen
Index: Einen Treiber per Index hooken (siehe: Informationen – Module)
Name: Einen Treiber per Gerätenamen hooken (\Device\Name)
Werte: Kommagetrennte Liste von Indizes (bedingt)
Name: Gerätename des Zieltreibers (bedingt)
Werte sind erforderlich, wenn 'Index' ausgewählt ist. Name ist erforderlich, wenn 'Name' ausgewählt ist.
Index: Einen Treiber per Index unhooken (siehe: Informationen – gehookte Module)
Alle: Alle gehookten Treiber unhooken
Werte: Kommagetrennte Liste von Indizes (bedingt)
Werte sind erforderlich, wenn 'Index' ausgewählt ist.
Anbieter: Alle Callbacks patchen, die mit Anbietermodul(en) verknüpft sind
Modul: Alle Callbacks patchen, die mit Modul(en) verknüpft sind
Prozess: Prozess-Callback(s) patchen
Thread: Thread-Callback(s) patchen
Image: Image-Callback(s) patchen
Registrierung: Registrierungs-Callback(s) patchen
Objektprozess: Objektprozess-Callback(s) patchen
Objektthread: Objektthread-Callback(s) patchen
Werte: Kommagetrennte Liste von Indizes (siehe: Informationen – Callbacks) (bedingt)
Name: Kommagetrennte Liste von Modulnamen oder ein einzelner Anbietername (siehe: Informationen – Anbieter) (bedingt)
Werte sind erforderlich, wenn 'Prozess', 'Thread', 'Image', 'Registrierung', 'Objektprozess' oder 'Objektthread' ausgewählt ist. Name ist erforderlich, wenn 'Anbieter' oder 'Modul' ausgewählt ist.
Anbieter: Alle Callbacks wiederherstellen, die mit Anbietermodul(en) verknüpft sind
Modul: Alle Callbacks wiederherstellen, die mit Modul(en) verknüpft sind
Prozess: Prozess-Callback(s) wiederherstellen
Thread: Thread-Callback(s) wiederherstellen
Image: Image-Callback(s) wiederherstellen
Registrierung: Registrierungs-Callback(s) wiederherstellen
Objektprozess: Objektprozess-Callback(s) wiederherstellen
Objektthread: Objektthread-Callback(s) wiederherstellen
Alle: Alle Callbacks wiederherstellen
Werte: Kommagetrennte Liste von Indizes (siehe: Informationen – Callbacks) (bedingt)
Name: Kommagetrennte Liste von Modulnamen oder ein einzelner Anbietername (siehe: Informationen – Anbieter) (bedingt)
Werte sind erforderlich, wenn 'Prozess', 'Thread', 'Image', 'Registrierung', 'Objektprozess' oder 'Objektthread' ausgewählt ist. Name ist erforderlich, wenn 'Anbieter' oder 'Modul' ausgewählt ist.