
Uno script per randomizzare i profili Malleable C2 di Cobalt Strike e ridurre le possibilità di attivare i controlli di rilevamento basati su firma.
Questo script randomizza i profili Malleable C2 di Cobalt Strike attraverso l'uso di un metalinguaggio, riducendo così le probabilità di attivare i controlli di rilevamento basati su firma. In breve, lo script analizza il template fornito, sostituisce le variabili con un valore casuale da una wordlist fornita o integrata, testa il nuovo template con c2lint e (se non ci sono errori c2lint) restituisce il nuovo profilo Malleable C2.
I profili Malleable C2 di esempio compatibili con questo script si trovano nella directory Sample Templates di questo repository.
Per maggiori informazioni su questo script, consulta il mio post sul blog 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]
| Parametro | Descrizione |
|---|---|
| -profile, -p | Percorso del template Malleable C2 da randomizzare (OBBLIGATORIO) |
| -count, -c | Il numero di profili randomizzati da creare {Predefinito = 1} |
| -cobalt, -d | La directory in cui si trova Cobalt Strike (per c2lint) {Predefinito = directory corrente} |
| -output, -o | Nome base di output {Predefinito = nome base del template e stringa casuale} |
| -notest, -n | Salta il test con c2lint (Flag) |
Se non viene fornita alcuna wordlist, verrà utilizzata una lista integrata per impostazione predefinita. Per maggiori informazioni su come creare queste liste, vedere sotto o la cartella Sample Wordlists in questo repository.
| Parametro | Descrizione |
|---|---|
| -charset | File con un set di caratteri personalizzato da usare con la variabile %%customchar%% |
| -wordlist | File con un elenco di parole personalizzate da usare con la variabile %%word%% |
| -useragent | File con un elenco di useragent |
| -spawnto | File con un elenco di processi spawnto personalizzati |
| -pipename | File con un elenco di valori pipename personalizzati |
| -pipename_stager | File con un elenco di valori pipename_stager personalizzati |
| -dns_stager_subhost | File con un elenco di valori dns_stager_subhost personalizzati |
| -dns_stager_prepend | File con un elenco di valori dns_stager_prepend personalizzati |
La maggior parte di queste variabili di wordlist è direttamente correlata alle opzioni di Malleable C2. Per maggiori informazioni su cosa fanno queste opzioni di profilo, consulta la documentazione ufficiale.
Il metalinguaggio di sostituzione comprende variabili specifiche, alcune delle quali consentono conteggi di ripetizione opzionali, racchiuse tra doppi segni di percentuale, come segue:
%%variable:count%%
Come altro esempio, la seguente variabile produrrà 20 caratteri alfanumerici:
%%alphanumeric:20%%
| Variabile | Descrizione | Supporta il conteggio? |
|---|---|---|
| alphanumeric | Restituisce una lettera ascii casuale con maiuscole/minuscole o una cifra | Sì |
| alphanumspecial | Restituisce una lettera ascii casuale con maiuscole/minuscole, una cifra o un segno di punteggiatura | Sì |
| alphanumspecialurl | Restituisce una lettera ascii casuale con maiuscole/minuscole, una cifra o uno dei seguenti caratteri: -._~ | Sì |
| alphaupper | Restituisce una lettera ascii casuale maiuscola | Sì |
| alphalower | Restituisce una lettera ascii casuale minuscola | Sì |
| alphauppernumber | Restituisce una lettera ascii casuale maiuscola o una cifra | Sì |
| alphalowernumber | Restituisce una lettera ascii casuale minuscola o una cifra | Sì |
| alpha | Restituisce una lettera ascii casuale | Sì |
| number | Restituisce una cifra casuale | Sì |
| hex | Restituisce una cifra esadecimale casuale | Sì |
| netbios | Restituisce una lettera ascii casuale con maiuscole/minuscole, una cifra o uno dei seguenti caratteri: !@#$%^&)(.-'_{}~ | Sì |
| custom | Corrisponde a un carattere casuale del file charset fornito | Sì |
| word | Restituisce una parola casuale dalla wordlist fornita o integrata | Sì |
| boolean | Restituisce 'True' o 'False' | Sì |
| useragent | Restituisce un useragent casuale dalla lista fornita o integrata | No |
| spawnto_x86 | Restituisce un percorso di processo x86 casuale dalla lista fornita o integrata | No |
| spawnto_x64 | Restituisce un percorso di processo x64 casuale dalla lista fornita o integrata | No |
| pipename | Restituisce un pipename casuale dalla lista fornita o integrata | No |
| pipename_stager | Restituisce un pipename_stager casuale dalla lista fornita o integrata | No |
| dns_stager_subhost | Restituisce un dns_stager_subhost casuale dalla lista fornita o integrata | No |
I file di wordlist sono semplicemente stringhe separate da righe, separate da tabulazioni o continue (a seconda del tipo di wordlist) collocate in un file di testo.
Le seguenti wordlist dovrebbero essere separate da nuove righe, con ogni voce su una nuova riga:
La wordlist spawnto è un po' più complicata. Malleable C2 richiede un'opzione x86 e x64 per modificare la creazione di tutti i processi. Pertanto, ogni riga della wordlist deve contenere sia i percorsi di processo x86 che x64 separati da una tabulazione, con il processo x86 elencato per primo. Per esempio:
%windir%\\syswow64\\eventvwr.exe %windir%\\sysnative\\eventvwr.exe
È importante notare che le stringhe syswow64 e sysnative nei percorsi di processo devono essere minuscole.
L'ultimo tipo di wordlist è il set di caratteri personalizzato. Questo file deve includere i caratteri che lo script può sostituire in modo casuale. Ad esempio, un file charset di AEIOUY e una variabile di %%custom:5%% produrranno cinque caratteri casuali dalla stringa del charset. Quando si crea questo set di caratteri, tenere presente che alcuni caratteri non possono comparire in un URI e potrebbero interferire con le comunicazioni di Beacon.
Per wordlist di esempio, vedere la directory Sample Wordlists in questo repository.
Ecco un frammento di un profilo Amazon modificato:
# 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";
}
}
}
Ed ecco due set di output dello stesso profilo:
# 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";
}
}
}
| dns_stager_prepend | Restituisce un dns_stager_prepend casuale dalla lista fornita o integrata | No |