
Um script para randomizar perfis Malleable C2 do Cobalt Strike e reduzir as chances de acionar controles de detecção baseados em assinatura
Este script aleatoriza perfis Malleable C2 do Cobalt Strike através do uso de uma metalíngua, esperando reduzir as chances de ativar controles de detecção baseados em assinaturas. Resumidamente, o script analisa o modelo fornecido, substitui as variáveis por um valor aleatório de uma wordlist fornecida ou integrada, testa o novo modelo com c2lint e (se não houver erros do c2lint) gera o novo perfil Malleable C2.
Exemplos de perfis Malleable C2 compatíveis com este script podem ser encontrados no diretório Sample Templates deste repositório.
Para mais informações sobre este script, veja meu post no 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]
| Parâmetro | Descrição |
|---|---|
| -profile, -p |
Se nenhuma wordlist for fornecida, uma lista embutida será usada por padrão. Para mais informações sobre como criar essas listas, veja abaixo ou a pasta Sample Wordlists neste repositório.
A maioria dessas variáveis de wordlist está diretamente relacionada às opções do Malleable C2. Para mais informações sobre o que essas opções de perfil fazem, consulte a documentação oficial.
A metalíngua de substituição compreende variáveis específicas, algumas das quais permitem contagens de repetição opcionais, envolvidas por sinais de porcentagem duplos, assim:
%%variavel:contagem%%
Como outro exemplo, a variável a seguir resultará em 20 caracteres alfanuméricos:
%%alphanumeric:20%%
Arquivos de wordlist são simplesmente strings separadas por linha, por tabulação ou contínuas (dependendo do tipo de wordlist) colocadas em um arquivo de texto.
As seguintes wordlists devem ser separadas por linha, com cada entrada em uma nova linha:
A wordlist spawnto é um pouco mais complicada. O Malleable C2 exige uma opção x86 e x64 para modificar todas as criações de processo. Portanto, cada linha da wordlist deve conter ambos os caminhos de processo x86 e x64 separados por uma tabulação, com o processo x86 listado primeiro. Por exemplo:
%windir%\\syswow64\\eventvwr.exe %windir%\\sysnative\\eventvwr.exe
É importante observar que as strings syswow64 e sysnative nos caminhos de processo devem estar em minúsculas.
O tipo final de wordlist é o conjunto de caracteres personalizado. Este arquivo deve incluir quaisquer caracteres para o script substituir aleatoriamente. Por exemplo, um arquivo charset de AEIOUY e uma variável de %%custom:5%% gerará cinco caracteres aleatórios da string do charset. Ao construir este charset, lembre-se de que alguns caracteres são proibidos de aparecer em uma URI e podem interferir nas comunicações do Beacon.
Para exemplos de wordlists, veja o diretório Sample Wordlists neste repositório.
Aqui está um trecho de um perfil Amazon modificado:
# 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";
}
}
}
E aqui estão dois conjuntos de saída do mesmo perfil:
# 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";
}
}
}
| Caminho para o modelo Malleable C2 a ser aleatorizado (OBRIGATÓRIO) |
| -count, -c | Número de perfis aleatorizados a serem criados {Padrão = 1} |
| -cobalt, -d | Diretório onde o Cobalt Strike está localizado (para o c2lint) {Padrão = diretório atual} |
| -output, -o | Nome base da saída {Padrão = nome base do modelo e string aleatória} |
| -notest, -n | Ignorar teste com c2lint (Flag) |
| Parâmetro | Descrição |
|---|
| -charset | Arquivo com um conjunto de caracteres personalizado para usar com a variável %%customchar%% |
| -wordlist | Arquivo com uma lista de palavras personalizadas para usar com a variável %%word%% |
| -useragent | Arquivo com uma lista de useragents |
| -spawnto | Arquivo com uma lista de processos spawnto personalizados |
| -pipename | Arquivo com uma lista de valores pipename personalizados |
| -pipename_stager | Arquivo com uma lista de valores pipename_stager personalizados |
| -dns_stager_subhost | Arquivo com uma lista de valores dns_stager_subhost personalizados |
| -dns_stager_prepend | Arquivo com uma lista de valores dns_stager_prepend personalizados |
| Variável | Descrição | Suporta Contagem? |
|---|
| alphanumeric | Gera uma letra ou dígito ASCII aleatório (maiúscula/minúscula mista) | Sim |
| alphanumspecial | Gera uma letra ASCII aleatória (maiúscula/minúscula mista), dígito ou pontuação | Sim |
| alphanumspecialurl | Gera uma letra ASCII aleatória (maiúscula/minúscula mista), dígito ou um dos seguintes caracteres: -._~ | Sim |
| alphaupper | Gera uma letra ASCII maiúscula aleatória | Sim |
| alphalower | Gera uma letra ASCII minúscula aleatória | Sim |
| alphauppernumber | Gera uma letra ASCII maiúscula aleatória ou dígito | Sim |
| alphalowernumber | Gera uma letra ASCII minúscula aleatória ou dígito | Sim |
| alpha | Gera uma letra ASCII aleatória | Sim |
| number | Gera um dígito aleatório | Sim |
| hex | Gera um dígito hexadecimal aleatório | Sim |
| netbios | Gera uma letra ASCII aleatória (maiúscula/minúscula mista), dígito ou um dos seguintes caracteres: !@#$%^&)(.-'_{}~ | Sim |
| custom | Mapeia para um caractere aleatório no arquivo charset fornecido | Sim |
| word | Gera uma palavra aleatória da wordlist fornecida ou embutida | Sim |
| boolean | Gera 'True' ou 'False' | Sim |
| useragent | Gera um useragent aleatório da lista fornecida ou embutida | Não |
| spawnto_x86 | Gera um caminho de processo x86 aleatório da lista fornecida ou embutida | Não |
| spawnto_x64 | Gera um caminho de processo x64 aleatório da lista fornecida ou embutida | Não |
| pipename | Gera um pipename aleatório da lista fornecida ou embutida | Não |
| pipename_stager | Gera um pipename_stager aleatório da lista fornecida ou embutida | Não |
| dns_stager_subhost | Gera um dns_stager_subhost aleatório da lista fornecida ou embutida | Não |
| dns_stager_prepend | Gera um dns_stager_prepend aleatório da lista fornecida ou embutida | Não |