
Ein Skript zum Randomisieren von Cobalt Strike Malleable C2-Profilen, um die Wahrscheinlichkeit zu verringern, von signaturbasierten Erkennungskontrollen erkannt zu werden.
Dieses Skript randomisiert Malleable-C2-Profile für Cobalt Strike mithilfe einer Metasprache, wodurch hoffentlich die Wahrscheinlichkeit verringert wird, signaturbasierte Erkennungsmaßnahmen auszulösen. Kurz gesagt, das Skript parst die bereitgestellte Vorlage, ersetzt die Variablen durch einen zufälligen Wert aus einer bereitgestellten oder integrierten Wortliste, testet die neue Vorlage mit c2lint und gibt (wenn keine c2lint-Fehler auftreten) das neue Malleable-C2-Profil aus.
Beispielhafte Malleable-C2-Profile, die mit diesem Skript kompatibel sind, finden Sie im Verzeichnis Sample Templates dieses Repos.
Weitere Informationen zu diesem Skript finden Sie in meinem Blogbeitrag Randomized Malleable C2 Profiles Made Easy.
python malleable-c2-randomizer.py [-h] -profile PROFILE
[-count COUNT]
[-cobalt COBALT]
[-output OUTPUT]
[-notest]
[-charset CHARSET]
[-wordlist WORDLIST]
[-useragent USERAGENT]
[-spawnto SPAWNTO]
[-pipename PIPENAME]
[-pipename_stager PIPENAME_STAGER]
[-dns_stager_subhost DNS_STAGER_SUBHOST]
| Parameter | Beschreibung |
|---|
Wenn keine Wortliste bereitgestellt wird, wird standardmäßig eine integrierte Liste verwendet. Weitere Informationen zum Erstellen dieser Listen finden Sie unten oder im Ordner Sample Wordlists dieses Repos.
Die meisten dieser Wortlistenvariablen stehen in direktem Zusammenhang mit Malleable-C2-Optionen. Weitere Informationen darüber, was diese Profiloptionen bewirken, finden Sie in der offiziellen Dokumentation.
Die Substitutions-Metasprache besteht aus spezifischen Variablen, von denen einige optionale Wiederholungsanzahlen unterstützen, die in doppelte Prozentzeichen eingeschlossen sind, etwa so:
%%variable:count%%
Als weiteres Beispiel ergibt die folgende Variable 20 alphanumerische Zeichen:
%%alphanumeric:20%%
Wortlistendateien sind einfach zeilengetrennte, tabgetrennte oder fortlaufende Zeichenketten (abhängig vom Wortlistentyp), die in einer Textdatei abgelegt werden.
Die folgenden Wortlisten sollten zeilengetrennt sein, wobei jeder Eintrag in einer neuen Zeile steht:
Die spawnto-Wortliste ist etwas komplizierter. Malleable C2 erfordert eine x86- und eine x64-Option, um das gesamte Prozess-Spawning zu ändern. Daher sollte jede Zeile der Wortliste sowohl den x86- als auch den x64-Prozesspfad enthalten, getrennt durch einen Tab, wobei der x86-Prozess zuerst aufgeführt wird. Zum Beispiel:
%windir%\\syswow64\\eventvwr.exe %windir%\\sysnative\\eventvwr.exe
Es ist wichtig zu beachten, dass die Zeichenfolgen syswow64 und sysnative in den Prozesspfaden kleingeschrieben sein sollten.
Der letzte Wortlistentyp ist der benutzerdefinierte Zeichensatz. Diese Datei sollte alle Zeichen enthalten, die das Skript zufällig ersetzen soll. Zum Beispiel gibt eine Zeichensatzdatei AEIOUY zusammen mit einer Variablen %%custom:5%% fünf zufällige Zeichen aus der Zeichensatzzeichenfolge aus. Beachten Sie beim Erstellen dieses Zeichensatzes, dass einige Zeichen nicht in einer URI vorkommen dürfen und die Kommunikation von Beacon stören können.
Beispiel-Wortlisten finden Sie im Verzeichnis Sample Wordlists dieses Repos.
Hier ist ein Ausschnitt aus einem modifizierten Amazon-Profil:
# This profile has been modified to use with the Malleable C2 Profile Randomizer
#
# Amazon browsing traffic profile
#
# Author: @harmj0y
#
set sleeptime "%%number:2%%00";
set jitter "1%%number%%";
set maxdns "24%%number%%";
set useragent "%%useragent%%";
http-get {
set uri "/s/ref=nb_sb_noss_1/%%number:3%%-%%number:8%%-%%number:7%%/field-keywords=%%word%%";
client {
header "Accept" "*/*";
header "Host" "www.amazon.com";
metadata {
base64;
prepend "session-token=";
prepend "skin=noskin;";
append "csm-hit=s-%%alphanumeric:20%%|%%number:13%%";
header "Cookie";
}
}
}
Und hier sind zwei Ausgabesätze aus demselben Profil:
# This profile has been modified to use with the Malleable C2 Profile Randomizer
#
# Amazon browsing traffic profile
#
# Author: @harmj0y
#
set sleeptime "5600";
set jitter "19";
set maxdns "244";
set useragent "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1";
http-get {
set uri "/s/ref=nb_sb_noss_1/818-61846941-6716865/field-keywords=number";
client {
header "Accept" "*/*";
header "Host" "www.amazon.com";
metadata {
base64;
prepend "session-token=";
prepend "skin=noskin;";
append "csm-hit=s-UXnlEVYWc36qEuDMFPzW|2872195700726";
header "Cookie";
}
}
}
# This profile has been modified to use with the Malleable C2 Profile Randomizer
#
# Amazon browsing traffic profile
#
# Author: @harmj0y
#
set sleeptime "7400";
set jitter "19";
set maxdns "246";
set useragent "Mozilla/5.0 (Windows NT 10.0; WOW64)";
http-get {
set uri "/s/ref=nb_sb_noss_1/684-10075672-1686806/field-keywords=year";
client {
header "Accept" "*/*";
header "Host" "www.amazon.com";
metadata {
base64;
prepend "session-token=";
prepend "skin=noskin;";
append "csm-hit=s-ub5oBmGd0pnDoImCjDyK|2539750656854";
header "Cookie";
}
}
}
| -profile, -p | Pfad zur Malleable-C2-Vorlage, die randomisiert werden soll (ERFORDERLICH) |
| -count, -c | Die Anzahl der zu erstellenden randomisierten Profile {Standard = 1} |
| -cobalt, -d | Das Verzeichnis, in dem sich Cobalt Strike befindet (für c2lint) {Standard = aktuelles Verzeichnis} |
| -output, -o | Basisname der Ausgabe {Standard = Basisname der Vorlage und zufällige Zeichenfolge} |
| -notest, -n | Testen mit c2lint überspringen (Flag) |
| Parameter | Beschreibung |
|---|
| -charset | Datei mit einem benutzerdefinierten Zeichensatz für die Variable %%customchar%% |
| -wordlist | Datei mit einer Liste benutzerdefinierter Wörter für die Variable %%word%% |
| -useragent | Datei mit einer Liste von User-Agents |
| -spawnto | Datei mit einer Liste benutzerdefinierter spawnto-Prozesse |
| -pipename | Datei mit einer Liste benutzerdefinierter Pipename-Werte |
| -pipename_stager | Datei mit einer Liste benutzerdefinierter pipename_stager-Werte |
| -dns_stager_subhost | Datei mit einer Liste benutzerdefinierter dns_stager_subhost-Werte |
| -dns_stager_prepend | Datei mit einer Liste benutzerdefinierter dns_stager_prepend-Werte |
| Variable | Beschreibung | Unterstützt Anzahl? |
|---|
| alphanumeric | Gibt einen zufälligen ASCII-Buchstaben (groß/klein gemischt) oder eine Ziffer aus | Ja |
| alphanumspecial | Gibt einen zufälligen ASCII-Buchstaben (groß/klein gemischt), eine Ziffer oder ein Satzzeichen aus | Ja |
| alphanumspecialurl | Gibt einen zufälligen ASCII-Buchstaben (groß/klein gemischt), eine Ziffer oder eines der folgenden Zeichen aus: -._~ | Ja |
| alphaupper | Gibt einen zufälligen großgeschriebenen ASCII-Buchstaben aus | Ja |
| alphalower | Gibt einen zufälligen kleingeschriebenen ASCII-Buchstaben aus | Ja |
| alphauppernumber | Gibt einen zufälligen großgeschriebenen ASCII-Buchstaben oder eine Ziffer aus | Ja |
| alphalowernumber | Gibt einen zufälligen kleingeschriebenen ASCII-Buchstaben oder eine Ziffer aus | Ja |
| alpha | Gibt einen zufälligen ASCII-Buchstaben aus | Ja |
| number | Gibt eine zufällige Ziffer aus | Ja |
| hex | Gibt eine zufällige hexadezimale Ziffer aus | Ja |
| netbios | Gibt einen zufälligen ASCII-Buchstaben (groß/klein gemischt), eine Ziffer oder eines der folgenden Zeichen aus: !@#$%^&)(.-'_{}~ | Ja |
| custom | Gibt ein zufälliges Zeichen aus der bereitgestellten Datei charset aus | Ja |
| word | Gibt ein zufälliges Wort aus der bereitgestellten oder integrierten Wortliste aus | Ja |
| boolean | Gibt 'True' oder 'False' aus | Ja |
| useragent | Gibt einen zufälligen User-Agent aus der bereitgestellten oder integrierten Liste aus | Nein |
| spawnto_x86 | Gibt einen zufälligen x86-Prozesspfad aus der bereitgestellten oder integrierten Liste aus | Nein |
| spawnto_x64 | Gibt einen zufälligen x64-Prozesspfad aus der bereitgestellten oder integrierten Liste aus | Nein |
| pipename | Gibt einen zufälligen Pipename aus der bereitgestellten oder integrierten Liste aus | Nein |
| pipename_stager | Gibt einen zufälligen pipename_stager aus der bereitgestellten oder integrierten Liste aus | Nein |
| dns_stager_subhost | Gibt einen zufälligen dns_stager_subhost aus der bereitgestellten oder integrierten Liste aus | Nein |
| dns_stager_prepend | Gibt einen zufälligen dns_stager_prepend aus der bereitgestellten oder integrierten Liste aus | Nein |