Cobalt Strike 4.9 ist jetzt verfügbar. In dieser Version wurden die Post-Exploitation-Fähigkeiten von Cobalt Strike überarbeitet, um benutzerdefinierte Reflective Loader (UDRLs) zu unterstützen. Außerdem wurde die Möglichkeit geschaffen, Beacon ohne Reflective Loader zu exportieren, was eine offizielle Unterstützung für Prepend-Style UDRLs mit sich bringt, sowie Unterstützung für Callbacks in einer Reihe von eingebauten Funktionen, einen neuen In-Beacon-Datenspeicher und mehr.
Post-Exploitation Verbesserung
Die Post-Exploitation-Fähigkeiten von Cobalt Strike wurden überarbeitet, wobei die folgenden Post-Exploitation-DLLs Unterstützung für benutzerdefinierte Reflective Loader im Prepend-Stil erhalten haben:
browserpivot
hashdump
invokeassembly
Keylogger
mimikatz
netview
portscan
powershell
bildschirmfoto
sshagent
Ein neuer Aggressor-Skript-Hook, POSTEX_RDLL_GENERATE, wurde hinzugefügt, um diese Änderung zu implementieren und den standardmäßigen reflektiven Lader durch einen UDRL zu ersetzen. Ausführliche Informationen zu diesem neuen Hook und seiner Verwendung finden Sie in der Dokumentation.
Es ist wichtig zu beachten, dass UDRLs für Beacon-Nutzlasten und Post-Exploitation-Nutzlasten sehr ähnlich sind, aber einige feine Unterschiede aufweisen. Informationen zu diesen Unterschieden, die sich auf die Loader-Eingabefunktion, den DLL-Eingabepunkt, das Zeigerargument RDATA_SECTION und den Startoffset der Verschleierung beziehen, finden Sie in der Dokumentation und sollten sorgfältig geprüft werden, bevor Sie Ihre eigenen Änderungen in diesem Bereich vornehmen.
Eine Beispielimplementierung eines Post-Exploitation-Laders finden Sie im UDRL-VS-Kit im Cobalt Strike Arsenal Kit.
Eine neue Malleable C2-Option, post-ex.cleanup, wurde hinzugefügt, um anzugeben, ob der Speicher des Post-Exploitation-Reflective-Loaders beim Laden der DLL bereinigt werden soll oder nicht. Wir haben auch die Blöcke post-ex.transform-x64 und post-ex.transform-x86 zum post-ex Malleable C2-Block hinzugefügt. Beide neuen Blöcke unterstützen die Option strrep, die eine Zeichenkette in allen post-exploitation-DLLs ersetzt, und strrepex, die eine Zeichenkette innerhalb einer bestimmten post-exploitation-DLL ersetzt. Gültige DLL-Namen sind BrowserPivot, ExecuteAssembly, Hashdump, Keylogger, Mimikatz, NetView, PortScanner, PowerPick, Screenshot und SSHAgent.
Zum Beispiel:
post-ex {
# cleanup the post-ex UDRL memory when the post-ex DLL is loaded
set cleanup "true";
transform-x64 {
# replace a string in the port scanner dll
strrepex "PortScanner" "Scanner module is complete" "Scan is complete";
# replace a string in all post exploitation dlls
strrep "is alive." "is up.";
}
transform-x86 {
# replace a string in the port scanner dll
strrepex "PortScanner" "Scanner module is complete" "Scan is complete";
# replace a string in all post exploitation dlls
strrep "is alive." "is up.";
}
}
Weitere Informationen zu dieser Änderung finden Sie in der Dokumentation.
Beacon ohne reflektierenden Loader exportieren
Beacon kann nun ohne die exportierte reflektierende Ladefunktion verwendet werden, wenn UDRLs verwendet werden. Diese Änderung verbessert auch die Unterstützung für UDRLs im Prepend-Stil.
Der BEACON_RDLL_SIZE Aggressor Script Hook wird aufgerufen, wenn Beacon vorbereitet wird und kann nun verwendet werden, um den gesamten Reflective Loader Space aus der Beacon DLL zu entfernen. Durch die Rückgabe des Wertes „0“ wird ein Beacon ohne den Reflective Loader an die Hooks BEACON_RDLL_GENERATE und BEACON_RDLL_GENERATE_LOCAL übergeben.
Zum Beispiel:
# ------------------------------------
# $1 = DLLfilename
# $2 = arch
# ------------------------------------
set BEACON_RDLL_SIZE {
warn("Running 'BEACON_RDLL_SIZE' for DLL " .$1. " with architecture " .$2);
return"0";
}
Als Ergebnis dieser Änderung wurde der Standardrückgabewert BEACON_RDLL_SIZE von 0 auf 5 geändert.
Callback Support
Fortra hatte eine Reihe von Anfragen von CS Benutzern bekommen, um die Verarbeitung der Ergebnisse bestimmter Funktionsaufrufe zu erleichtern. Dies ist aufgrund der asynchronen Natur der Kommunikation von Cobalt Strike eine Herausforderung, die in dieser Version durch das Hinzufügen von Rückrufen für eine Reihe von eingebauten Funktionen gelöst wurde. Callbacks werden ausgelöst, wenn Beacon auf einen Befehl antwortet, und auch, wenn benutzerdefinierte Dialoge über Dialogeingaben und Klicks auf Aktionsschaltflächen bearbeitet werden.
Die folgenden Aggressor-Script-Funktionen unterstützen nun Callbacks:
bnet
beacon_inline_execute
binline_ausführen
bdllspawn
bexecute_assembly
bhashdump
bmimikatz
bmimikatz_small
bportscan
bpowerpick
bpowershell
bpsinject
Im Allgemeinen gibt es drei Arten von Techniken, die für den Umgang mit Rückrufen verwendet werden können – anonyme Schließung, benannte Schließung und Lambda-Schließung.
Eine anonyme Schließung ist nützlich, wenn Sie einen kleinen Teil des Codes inline mit dem Aufrufer halten möchten. Die Protokollierung der Ausgabe eines BOFs auf der Beacon-Konsole würde zum Beispiel so aussehen:
alias cs_example {
# User setup code removed for brevity
beacon_inline_execute($bid, $data, "go", $args, { blog($1, $2); });
}
Eine benannte Closure ist nützlich, wenn Sie eine Menge Code haben, den Sie wiederverwenden möchten. In diesem Beispiel erstellen wir eine Closure mit dem Namen „bof_cb“, die ausgeführt wird, wenn Daten vom BOF zurückgegeben werden:
$1 - bid, $2 - result, $3 - info map
sub bof_cb {
# User defined code removed for brevity
}
alias cs_example {
local('$bid $data $args');
# User setup code removed for brevity
beacon_inline_execute($bid, $data, "go", $args, &bof_cb);
}
Eine Lambda-Schließung ist nützlich, wenn Sie Variablen übergeben wollen, die bei den vorherigen Beispielen nicht in den Geltungsbereich fallen würden. In diesem Beispiel wird gezeigt, wie Sie auf die Variable $test_num zugreifen können, die sich im Geltungsbereich des Alias cs_example befindet:
# $1 - bid, $2 – result, $3 - infomap, $4 - test_num
sub bof_cb{
# User defined code removed for brevity
}
alias cs_example {
local('$bid $file $test_num');
# User setup code removed for brevity
binline_execute($bid, $file, $test_num, lambda({ bof_cb($1, $2, $3, $test_num); }, \$test_num);
}
Beispiele finden Sie auch in einem öffentlichen Cobalt Strike GitHub-Repository, das Sie hier finden.
Beacon-Datenspeicher
Ähnlich wie der Token-Speicher in der Version 4.8 haben wir einen Beacon-Datenspeicher hinzugefügt, der es Ihnen ermöglicht, BOFs und .NET-Assemblies im Speicher von Beacon zu speichern, so dass die gespeicherten Objekte mehrfach ausgeführt werden können, ohne dass das Objekt erneut gesendet werden muss. Der Cobalt Strike Client erkennt automatisch, ob sich ein auszuführendes Objekt bereits im Datenspeicher befindet, so dass Sie nichts weiter tun müssen, sobald ein Objekt gespeichert ist. Gespeicherte Einträge sind standardmäßig maskiert und werden erst bei Verwendung demaskiert. Es ist auch möglich, generische Dateien in der Datenablage zu speichern, die dann für BOFs zur Verfügung stehen.
Die Standardgröße des Datenspeichers beträgt 16 Einträge. Dies kann jedoch durch Konfiguration der Option stage.data_store_size im Malleable C2-Profil geändert werden.
data-store load [bof|dotnet|file] [path] speichert einen Eintrag in den Speicher.
data-store unload [index] löscht einen gespeicherten Eintrag.
data-store list listet alle im Datenspeicher verfügbaren Elemente auf.
Eine Reihe von BOF-API-Funktionen wurde ebenfalls hinzugefügt, um den Zugriff auf und den Schutz von Elementen zu ermöglichen, die im Beacon-Datenspeicher gespeichert sind:
BeaconDataStoreGetItem(size_t index) gibt einen Zeiger auf den angegebenen Eintrag zurück.
Die Funktion gibt NULL zurück, wenn kein Eintrag am angegebenen Index existiert.
BeaconDataStoreProtectItem(size_t index) verschleiert einen bestimmten Eintrag im Beacon Data Store.
BeaconDataStoreUnprotectItem(size_t index) hebt die Verschleierung eines bestimmten Eintrags im Beacon-Datenspeicher auf.
BeaconDataStoreMaxEntries() gibt die maximale Größe des Beacon-Datenspeichers zurück.
Beacon Benutzerdaten
Beacon User Data ist eine C-Struktur, die es Reflective Loadern ermöglicht, zusätzliche Daten an Beacons zu übergeben. Sie wird als Zeiger an Beacon übergeben, indem die DllMain-Funktion von Beacon mit einer benutzerdefinierten Argumentation, bekannt als DLL_BEACON_USER_DATA (0x0d), aufgerufen wird. Diese muss an Beacon übergeben werden, bevor der Standardgrund DLL_PROCESS_ATTACH aufgerufen wird. Es ist nicht erforderlich, die Struktur nach dem DLL_BEACON_USER_DATA-Aufruf im Speicher zu halten, da Beacon während des Aufrufs notwendige Werte daraus kopiert.
Eine Versionsnummer ist in der Struktur enthalten, um die Abwärtskompatibilität zwischen verschiedenen Versionen von Beacons und Reflective Loaders zu gewährleisten. Neuere Beacons sind daher in der Lage, ältere Beacon User Data-Strukturen zu verarbeiten und zu nutzen, ohne abzustürzen.
Beacon User Data ermöglicht es einem Reflective Loader, Systemaufrufe aufzulösen und an Beacon weiterzugeben, wobei der Standard-Systemaufrufauflöser von Beacon außer Kraft gesetzt wird.Die Struktur SYSCALL_API_ENTRY wird für jeden unterstützten Systemaufruf verwendet.Die SYSCALL_API-Struktur enthält diese Einträge.Jeder Eintrag enthält Informationen über die Sprungadresse (abhängig von der Systemarchitektur), die Systemaufrufnummer und die Adresse der entsprechenden Nt*-Funktion. Die Sprungadresse und die Systemaufrufnummer werden für indirekte Systemaufrufe benötigt, während die Funktionsadresse für direkte Systemaufrufe erforderlich ist.Wenn keine Werte angegeben werden, greift Beacon auf den entsprechenden WinAPI-Aufruf zurück. Wenn das Feld für den Systemaufruf in der USER_DATA-Struktur auf NULL zeigt, werden die Systemaufrufinformationen übersprungen.
Beacon User Data erlaubt es einem Reflective Loader auch, einen kleinen Datenpuffer (32 Bytes) an Beacon zu übergeben, so dass der Benutzer seine eigenen Daten angeben und übergeben kann. BOFs können einen Zeiger auf diese Daten mit der Funktion BeaconGetCustomUserData abrufen.
Sie können beacon_user_data.h hier herunterladen und Sie können ein Anwendungsbeispiel in der UDRL-VS finden, die im Arsenal Kit zu finden ist.
WinHTTP-Unterstützung
Bis jetzt hat der HTTP(S)-Listener von Beacon standardmäßig die WinInet-Bibliothek verwendet. Aufgrund des Feedbacks einiger Benutzer wurde die Unterstützung für die WinHTTP-Bibliothek hinzugefügt.
Eine neue Malleable C2 Gruppe, .http-beacon, wurde erstellt. Außerdem wurde eine Option .http-beacon.library hinzugefügt, mit der Sie die Standardbibliothek festlegen können, die beim Erstellen eines neuen HTTP(S)-Listeners verwendet wird. Gültige Werte sind wininet und winhttp. Wenn die neue Option „Malleable C2 profile“ nicht angegeben wird, werden neue HTTP(S)-Listener weiterhin standardmäßig mit WinInet verwendet.
Die neue Profilgruppe http-beacon Malleable C2 unterstützt auch Varianten, die dann Hörern zugewiesen werden können. Zum Beispiel:
http-beacon {
set library "winhttp";
}
http-beacon "httplib-wininet" {
set library "wininet";
}
http-beacon "httplib-winhttp" {
set library "winhttp";
}
Der Standardwert im Malleable C2-Profil kann über die neue HTTP-Bibliotheksoption im stufenlosen Payload-Generator, in der Generierung aller Payloads und in den ausführbaren Windows-Dialogen außer Kraft gesetzt werden. Zum Beispiel:
Unterstützung wurde auch in einer Reihe von Aggressor-Skriptfunktionen hinzugefügt, die aktualisiert wurden, um Unterstützung für den neuen optionalen Bibliotheksparameter hinzuzufügen. Wenn der Parameter nicht angegeben wird, wird der Standard-Bibliothekswert aus der Listener-Definition aufgelöst. Wenn er angegeben ist, muss der Wert entweder ein leerer String, $null, wininet oder winhttp sein. Die folgenden Funktionen wurden aktualisiert, um diesen zusätzlichen Parameter zu unterstützen:
Nutzlast
Nutzlast_lokal
artifact_payload
all_payloads
Host-Profil-Unterstützung für HTTP(S)-Listener
Die HTTP(S)-Verarbeitung von Cobalt Strike hat Grenzen. Wir werden dies überprüfen und planen, in einer zukünftigen Version weitere, einschneidende Änderungen vorzunehmen, haben jedoch im Rahmen dieser Version einige Einschränkungen identifiziert und behoben. Bisher werden die Namen der Callback-Hosts bei der Generierung der Beacon-Payloads einem einzigen URI zugewiesen, und HTTP(S)-Parameter und Header werden auf Profil- oder Variantenebene definiert. Dies bedeutet, dass der gesamte HTTP(S)-Verkehr zu diesem Host sehr ähnlich aussieht.
Wir haben diese Einschränkungen durch Hinzufügen einer neuen Malleable C2-Profilgruppe – http-host-profiles – behoben. Damit können Sie HTTP-Merkmale (URI, Header und Parameter) definieren, die für HTTP(S)-Kommunikation für einen bestimmten Hostnamen verwendet werden. Es werden dynamische (zufällig ausgewählte) Werte unterstützt. Varianten werden verwendet, um Host-Profile für mehrere Host-Namen zu definieren.
Dynamische Daten sind von eckigen Klammern umgeben und unterstützen eine Liste von Werten (bis zu 32), die durch ein Pipe-Zeichen getrennt sind. Pro Anfrage wird ein einzelner Wert zufällig aus der Liste der dynamischen Datenwerte ausgewählt. Er kann auch in statische Daten eingebettet werden, wobei ein Teil der Zeichenkette zufällig ausgewählt wird.
Das Feld host-name ist eine feste Zeichenfolge, die das Host-Profil mit dem entsprechenden HTTP-Hosts-Feld im HTTP(S)-Listener-Dialog verknüpft.
Es werden bis zu 10 Werte für die Parameter- und Kopfzeilenwerte in einer einzelnen Hostprofil-Get/Post-Definition unterstützt.
Beide Optionen unterstützen eine dynamische Datensyntax.Die in einem Host-Profil definierten Parameter und Kopfzeilen werden zusätzlich zu den im jeweiligen Standard- oder Variantenprofil definierten Parametern und Kopfzeilen hinzugefügt.
Beacons unterstützen bis zu 8 Host-Profil-Definitionen pro Listener. Ein generiertes Beacon hat Platz für insgesamt 1024 Bytes an Host-Profil-Daten.Wenn mehrere Hosts definiert sind, müssen sie alle in die 1024 Bytes passen.
Ein Malleable C2 Profil mit einem Beispiel http-host-profiles Block finden Sie hier.
Inter-Client Communications
Mit dieser Version wird Aggressor Script Unterstützung für das Senden und Empfangen von Daten zwischen Cobalt Strike Clients hinzugefügt. Bis zu diesem Zeitpunkt war die einzige Möglichkeit, Daten zwischen Clients auszutauschen, das Event Log von Cobalt Strike – zum Beispiel verwendet @Octoberfest73’s MemFiles diesen Ansatz, um Daten zwischen Clients auszutauschen, und dies ist ein ausgezeichnetes Beispiel für diese neue Funktion.
Drei neue Aggressor-Skriptfunktionen wurden hinzugefügt, um das Abfeuern und den Verbrauch von benutzerdefinierten Ereignissen zu erleichtern:
custom_event wird verwendet, um ein benutzerdefiniertes Ereignis an alle Cobalt Strike Clients zu senden.
Die Argumente sind:
$1 – der Name des Themas
$2 – die Ereignisdaten
custom_event_private wird verwendet, um ein benutzerdefiniertes Ereignis an einen einzelnen, spezifischen Cobalt Strike-Client zu senden.
Die Argumente sind:
$1 – an wen das benutzerdefinierte Ereignis gesendet werden soll
$2 – der Name des Themas
$3 – die Ereignisdaten
custom_event_ wird abgefeuert, wenn ein Client ein benutzerdefiniertes Ereignis von einem anderen Client erhält.
Die Argumente sind:
$1 – wer das benutzerdefinierte Ereignis gesendet hat
$2 – die Daten des Ereignisses
$3 – der Zeitpunkt, zu dem das Ereignis gesendet wurde
BOF – Updates
Ein Feature, das wir schon seit einiger Zeit in unserem Backlog haben, ist das Hinzufügen eines Key/Value-Speichers zu Beacon, der als persistenter Speicher zwischen BOF-Ausführungen verwendet werden soll. Da wir in letzter Zeit Kundenanfragen in dieser Richtung hatten, dachten wir uns, dass jetzt ein guter Zeitpunkt wäre, um dies anzugehen.
Drei neue APIs wurden zu Beacon hinzugefügt, um diesen Schlüssel/Wertspeicher zu unterstützen:
BeaconAddValue(const char * key, void * ptr) ermöglicht das Hinzufügen einer Speicheradresse zu einem Schlüssel.
BeaconGetValue(const char * key) erlaubt es, die zu einem Schlüssel gehörende Speicheradresse abzurufen.
BeaconRemoveValue(const char * key) ermöglicht das Entfernen eines Schlüssels. Beachten Sie, dass dabei keine Speicherbereinigung durchgeführt wird; um Speicherlecks zu vermeiden, sollte diese Bereinigung vom BOF durchgeführt werden.
Wir haben auch eine neue API hinzugefügt, die von BOFs verwendet werden kann, um Informationen über Beacon zu erhalten, wie z.B. die Beacon-Adresse, zu maskierende Abschnitte, zu maskierende Heap-Records, die Maske, die Adresse der Schlafmaske und die Größe der Schlafmaske:
BeaconInformation(BEACON_INFO * pBeaconInfo)
Diese API ist besonders nützlich für das BOF der Schlafmaske, da sie zum Auffüllen der Datenstruktur BEACON_INFO verwendet wird. Diese Informationen können dann an die Implementierung von Evasive Sleep weitergegeben werden, um Größeninformationen bereitzustellen, die zum Ausblenden des BOF der Schlafmaske erforderlich sind. Das Schlafmasken-Kit im Arsenal-Kit wurde mit diesen Änderungen aktualisiert.
Beispiele für diese Änderungen wurden dem bof_template-Projekt auf dem öffentlichen Cobalt Strike GitHub hinzugefügt.
Obwohl nicht Teil der Hauptproduktversion, ist ein weiteres relevantes Update, das wir kürzlich veröffentlicht haben, die Möglichkeit, BOFs zu debuggen und zu testen, ohne ein Beacon spawnen zu müssen. Die BOF-VS-Vorlage wurde während des aktuellen Release-Zyklus erstellt und ein Blog-Post verfasst, auf den ich hier verweise, um diese Arbeit hervorzuheben. Aufgrund von Rückmeldungen und Fragen von Benutzern, wie die BOF-VS lizenziert wird und wie sie ihre eigene Arbeit veröffentlichen können, haben wir beschlossen, die BOF-VS aus dem Arsenal-Kit herauszunehmen und sie auf dem öffentlichen Cobalt-Strike GitHub zu veröffentlichen, um diese Probleme zu lösen.
Sleep Mask Update
Die Verarbeitung der Schlafmaske wurde aktualisiert, um den Code der Schlafmaske zu maskieren, der in Beacon eingefügt wurde.
System Call Updates
Die Unterstützung für Systemaufrufe, die in der Version 4.8 hinzugefügt wurde, wurde aktualisiert. Die Unterstützung für direkte und indirekte Systemaufrufe wurde für die folgenden Funktionen hinzugefügt:
DuplicateHandle
ReadProcessMemory
WriteProcessMemory
Produkt-Sicherheits-Updates
Es wurde eine Änderung an den Autorisierungsdateien vorgenommen, so dass sie nicht mehr rückwärtskompatibel mit älteren Versionen von Cobalt Strike sind. Das bedeutet, dass die Autorisierungsdatei, die beim Update auf die Version 4.9 oder bei der Installation dieser Version erzeugt wird, nicht mehr mit 4.8-Versionen funktioniert, die Sie möglicherweise ebenfalls verwenden müssen. Obwohl diese Änderung die Mehrheit unserer Benutzer nicht betreffen sollte, wissen wir, dass einige Benutzer neuere Versionen testen, bevor sie sie in Einsätzen verwenden, und von dieser Änderung betroffen sein könnten.
Lizenzierte Nutzer, die eine alte (vor 4.9) Autorisierungsdatei benötigen, können diese hier generieren: https://download.cobaltstrike.com/authgen.slp
Abwärtskompatibilität
Da wir gerade beim Thema Abwärtskompatibilität der Autorisierungsdateien sind, halte ich dies für eine gute Gelegenheit zu bekräftigen, dass Cobalt Strike selbst nicht abwärtskompatibel mit früheren Versionen ist. Dies ist ein Thema, das nach jeder neuen Version immer wieder auftaucht.
Wenn Sie Cobalt Strike in einem bestehenden Einsatz einsetzen möchten, müssen Sie einen neuen Teamserver einrichten und neue Beacons starten. Idealerweise warten die Benutzer, bis neue Einsätze anstehen, bevor sie auf die neueste Version umsteigen, anstatt dies mitten in einem bestehenden Einsatz zu versuchen. Dies bleibt natürlich Ihnen überlassen – aber bitte seien Sie sich der Probleme bewusst, die dabei auftreten können.
Andere Aktualisierungen
Wir haben in dieser Version einige andere, kleinere Änderungen vorgenommen.
Die Hörer, die in der Hörerauswahl aufgelistet sind, werden nun nach Namen aufgelistet und nicht mehr in einer zufälligen Reihenfolge präsentiert.
Die About-Box wurde aktualisiert, so dass sie nun besser reagiert, wenn sie erweitert wird.
Wir haben Unterstützung für das Erzeugen von Prozessen unter dem Sicherheitskontext „Impersonated User“ hinzugefügt.
Eine neue Malleable C2-Option, sleep, wurde hinzugefügt, um der in der Version 4.8 hinzugefügten sleep-Befehlssyntax zu entsprechen. Die neue Einstellung akzeptiert sowohl Sekunden/Jitter-Werte als auch die neue Syntax d/h/m/s/j. Zum Beispiel:
sleep 20 25
sleep 1d 3h 15m 30s 50j
Beachten Sie, dass bei der Einstellung des Sleep-Wertes die vorhandenen Werte für Sleeptime und Jitter nicht verwendet werden können. Die Einstellungen schließen sich gegenseitig aus.
Java-Unterstützung
Obwohl wir in dieser Version keine Änderungen vorgenommen haben, wollten wir unsere Benutzer nur vorab darüber informieren, dass wir planen, die minimal unterstützte Java-Version von Java 8 auf Java 11 in der nächsten Version zu aktualisieren. Wir hoffen, dass dies keine negativen Auswirkungen auf unsere Benutzer haben wird, aber es sollte Ihnen genug Zeit geben, dies zu berücksichtigen, falls Sie Änderungen an Ihrer Umgebung vornehmen müssen.
Eine vollständige Liste der Neuerungen in Cobalt Strike 4.9 finden Sie in den Versionshinweisen. Lizenzierte Benutzer können das Update-Programm ausführen, um die neueste Version zu erhalten, oder Version 4.9 von der Website herunterladen. Wenn Sie Cobalt Strike kaufen oder mehr erfahren möchten, kontaktieren Sie uns bitte.