
Cobalt Strike BOF para execução de assembly .NET em processo com bypass de AMSI/ETW, AppDomain personalizado e redirecionamento de saída por named pipe/mailslot.
InlineExecute-Assembly é uma prova de conceito de Beacon Object File (BOF) que permite que profissionais de segurança realizem execução de assemblies .NET in-process como alternativa ao módulo tradicional fork and run execute-assembly do Cobalt Strike. O InlineExecute-Assembly executará qualquer assembly com o ponto de entrada Main(string[] args) ou Main(). Isso deve permitir executar a maioria das ferramentas publicadas sem necessidade de modificação prévia.
O BOF determinará automaticamente qual Common Language Runtime (CLR) precisa ser carregado no processo para seu assembly (v2.0.50727 ou v4.0.30319) antes da execução e, na maioria dos casos, deve terminar graciosamente se houver algum problema. O BOF também suporta várias flags que permitem ao operador ditar comportamentos antes da execução .NET, incluindo: desabilitar o AMSI via patching in-memory, desabilitar e restaurar o ETW via patching in-memory, personalizar o nome do App Domain CLR a ser criado, determinar se deve criar e direcionar a saída do console do seu assembly para um named pipe ou mailslot, e permite ao operador alterar o ponto de entrada padrão de Main(string[] args) para Main(). Mais detalhes sobre uso, casos de uso e possíveis detecções podem ser encontrados abaixo e em https://securityintelligence.com/posts/net-execution-inlineexecute-assembly/.
Por fim, a vantagem de executar nossos assemblies .NET no mesmo processo que nosso beacon implant é que evitamos o comportamento padrão do módulo execute-assembly do Cobalt Strike, que cria um novo processo para então carregar/injetar o CLR/assembly .NET. No entanto, outras considerações de OPSEC ainda existem, por exemplo: o processo em que estamos executando normalmente carrega o CLR? O assembly .NET que estamos executando tem assinaturas conhecidas? Portanto, a desvantagem é que, se algo for detectado e eliminado, por exemplo pelo AMSI, seu beacon também será eliminado.
Esta ferramenta não existiria sem o apoio de pesquisas, ferramentas e códigos excelentes já publicados por membros da comunidade de segurança. Muito obrigado. Por fim, se você achar que alguém foi deixado de fora abaixo, por favor me avise e garantirei que seja adicionado.
inlineExecute-Assembly --dotnetassembly /caminho/para/assembly.exe para execução mais básica (veja os casos de uso abaixo para exemplos específicos de flags)Execute o comando abaixo dentro do diretório src via Prompt de Comando de Ferramentas Nativas x64 para VS 2019
cl.exe /c inlineExecute-Assembly.c /GS- /FoinlineExecute-Assemblyx64.o
Execute o comando abaixo dentro do diretório src via Prompt de Comando de Ferramentas Nativas x86 para VS 2019
cl.exe /c inlineExecute-Assembly.c /GS- /FoinlineExecute-Assemblyx86.o
--dotnetassembly Caminho do diretório para seu assembly **obrigatório**
--assemblyargs Argumentos do assembly a serem passados
--appdomain Altera o nome padrão do AppDomain enviado (valor padrão é totesLegit e é definido via script aggressor incluído) *Domínio sempre descarregado*
--amsi Tenta desabilitar o AMSI via patching in-memory (Se bem-sucedido, AMSI será desabilitado por toda a vida do processo)
--etw Tenta desabilitar o ETW via patching in-memory (Se bem-sucedido, ETW será desabilitado por toda a vida do processo, a menos que revertido)
--revertetw Tenta desabilitar o ETW via patching in-memory e depois o repatcha de volta ao estado original
--pipe Altera o nome padrão do named pipe (valor padrão é totesLegit e é definido via script aggressor incluído)
--mailslot Alterna para uso de mailslots para redirecionar a saída do console. Altera o nome padrão do mailslot (Se deixado em branco, valor padrão é totesLegit e é definido via script aggressor incluído)
--main Altera o ponto de entrada para Main() (valor padrão é Main(string[] args))
Executar assembly .NET
beacon> inlineExecute-Assembly --dotnetassembly /root/Desktop/Seatbelt.exe
Executar assembly .NET com argumentos
beacon> inlineExecute-Assembly --dotnetassembly /root/Desktop/Seatbelt.exe --assemblyargs AntiVirus AppLocker
Executar assembly .NET com argumentos e desabilitar AMSI
beacon> inlineExecute-Assembly --dotnetassembly /root/Desktop/Seatbelt.exe --assemblyargs AntiVirus AppLocker --amsi
Executar assembly .NET com argumentos e desabilitar ETW
beacon> inlineExecute-Assembly --dotnetassembly /root/Desktop/Seatbelt.exe --assemblyargs AntiVirus AppLocker --etw
Executar assembly .NET com argumentos e redirecionar saída via mailslots em vez do named pipe padrão
beacon> inlineExecute-Assembly --dotnetassembly /root/Desktop/Seatbelt.exe --mailslot
Executar assembly .NET com argumentos e alterar o nome do named pipe padrão definido no script aggressor
beacon> inlineExecute-Assembly --dotnetassembly /root/Desktop/Seatbelt.exe --pipe forRealLegit
Executar assembly .NET e alterar o app domain padrão definido no script aggressor
beacon> inlineExecute-Assembly --dotnetassembly /root/Desktop/Seatbelt.exe --appdomain forRealLegit
Executar assembly .NET com ponto de entrada Main() em vez do padrão Main(string[] args)
beacon> inlineExecute-Assembly --dotnetassembly /root/Desktop/simpleMain.exe --main
Ir com tudo (Go HAM)
beacon> inlineExecute-Assembly --dotnetassembly /root/Desktop/Seatbelt.exe --assemblyargs AntiVirus AppLocker --amsi --etw --appdomain forRealLegit --mailslot forRealLegit
Algumas estratégias de detecção e mitigação que poderiam ser usadas: