
ScareCrow - Framework de criação de payloads projetado para bypass de EDR.
Para visualizar a versão mais recente do ScareCrow ou enviar um problema, consulte https://github.com/Tylous/ScareCrow.
Se você quiser saber mais sobre as técnicas utilizadas neste framework, dê uma olhada na Parte 1 e na Parte 2
ScareCrow é um framework de criação de payloads para sideloading (não injeção) em um processo legítimo do Windows (contornando controles de Application Whitelisting). Uma vez que o carregador DLL é carregado na memória, ele utiliza uma técnica para remover os hooks de um EDR das DLLs do sistema em execução na memória do processo. Isso funciona porque sabemos que os hooks do EDR são colocados quando um processo é criado.
ScareCrow pode segmentar essas DLLs e manipulá-las na memória usando a função de API VirtualProtect, que altera as permissões de uma seção da memória de um processo para um valor diferente, especificamente de Executar–Ler para Ler-Gravar-Executar.
ScareCrow utiliza um de dois métodos para remover os hooks
Quando executado, o ScareCrow copiará os bytes das DLLs do sistema armazenadas em disco em C:\Windows\System32\. Essas DLLs são armazenadas em disco "limpas" de hooks de EDR porque são usadas pelo sistema para carregar uma cópia inalterada em um novo processo quando ele é criado. Como os EDRs apenas hookam esses processos na memória, eles permanecem inalterados. O ScareCrow não copia todo o arquivo DLL, em vez disso, ele foca apenas na seção .text das DLLs. Esta seção de uma DLL contém o assembly executável, e ao fazer isso, o ScareCrow ajuda a reduzir a probabilidade de detecção, pois a releitura de arquivos inteiros pode fazer com que um EDR detecte que há uma modificação em um recurso do sistema. Os dados são então copiados para a região correta da memória usando o offset de cada função. Cada função possui um offset que denota o número exato de bytes a partir do endereço base onde residem, fornecendo a localização da função na pilha.
Para fazer isso, o ScareCrow altera as permissões da região .text da memória usando VirtualProtect. Embora esta seja uma DLL do sistema, como foi carregada em nosso processo (que controlamos), podemos alterar as permissões de memória sem exigir privilégios elevados.
ScareCrow carrega o shellcode na memória primeiro descriptografando o shellcode, que é criptografado por um dos três métodos de criptografia (descritos abaixo). Uma vez descriptografado e carregado, o shellcode é então executado. Dependendo das opções do loader especificadas, o ScareCrow configurará diferentes funções de exportação para a DLL. A DLL carregada também não contém a função DLLMain padrão que todas as DLLs normalmente precisam para operar. A DLL ainda será executada sem problemas porque o processo no qual carregamos procurará por essas funções de exportação e não se preocupará com a presença do DLLMain.
After
KnownDLLs é uma lista de DLLs que são carregadas pelo Windows durante o processo de inicialização do sistema. Como essas DLLs são consideradas essenciais para o funcionamento do sistema operacional, elas são armazenadas em cache para ajudar a reduzir os tempos de carregamento e melhorar o desempenho quando os aplicativos são iniciados. KnownDLLs inclui DLLs como kernel32.dll, kernelbase.dll e ntdll.dll.
Utilizando esses KnownDlls, o ScareCrow mapeia uma cópia da DLL de \KnownDlls\<dllname> usando uma combinação de NtOpenSection e NtMapViewOfSection para carregá-la na memória do processo. O ScareCrow não carrega toda a DLL, apenas carrega a seção .text da DLL (pois esta contém todas as syscalls). A partir daí, o ScareCrow usa syscalls indiretas para chamar NtProtectVirtualMemory e alterar as permissões da seção .text da DLL para permitir que o ScareCrow sobrescreva os hooks do EDR antes de restaurar as permissões.
Para mais informações, você pode ler o artigo detalhado do modexp
Uma vez que esses hooks são removidos, o ScareCrow então utiliza System Calls personalizadas para carregar e executar shellcode na memória. O ScareCrow faz isso mesmo após os hooks do EDR serem removidos para ajudar a evitar a detecção por ferramentas de coleta de telemetria baseadas em hooks do modo de usuário, como Event Tracing for Windows (ETW) ou outros mecanismos de registro de eventos. Essas system calls personalizadas também são usadas para realizar a chamada VirtualProtect para remover os hooks colocados pelos EDRs, descrita acima, para evitar a detecção por quaisquer controles anti-adulteração do EDR. Isso é feito chamando uma versão personalizada da syscall VirtualProtect, NtProtectVirtualMemory. O ScareCrow utiliza Golang para gerar esses loaders e depois assembly para essas funções de syscall personalizadas.
Durante o processo de criação do loader, o ScareCrow utiliza uma biblioteca para se misturar ao fundo após um beacon contatar o servidor. Esta biblioteca faz duas coisas:
Arquivos que são assinados com certificados de assinatura de código são frequentemente colocados sob menos escrutínio, tornando mais fácil serem executados sem serem questionados, pois arquivos assinados por um nome confiável são geralmente menos suspeitos que outros. A maioria dos produtos antimalware não tem tempo para validar e verificar esses certificados (agora alguns o fazem, mas tipicamente os nomes de fornecedores comuns estão incluídos em uma whitelist). O ScareCrow cria esses certificados usando uma versão em pacote go da ferramenta limelighter para criar um arquivo pfx12. Este pacote pega um nome de domínio fornecido pelo usuário para criar um certificado de assinatura de código para esse domínio. Se necessário, você também pode usar seu próprio certificado de assinatura de código, se tiver um, usando a opção de linha de comando valid.
clone, junto com o caminho para o arquivo do qual você deseja copiar o certificado. Ao assinar o loader com microsoft.com, usá-lo contra produtos WINDOWS DEFENDER ATP pode não ser tão eficaz, pois eles podem validar o certificado já que ele pertence a eles. Se você estiver usando um loader contra um produto da Windows, possivelmente use um domínio diferente.
Com esses arquivos e o código go, o ScareCrow irá compilar cruzadamente em DLLs usando a opção de biblioteca c-shared. Uma vez que a DLL é compilada, ela é ofuscada em uma string base64 quebrada que será embutida em um arquivo. Isso permite que o arquivo seja puxado remotamente, acessado e executado programaticamente.
Enquanto o ScareCrow tem uma extensa lista de atributos de arquivo, existem algumas circunstâncias onde um conjunto personalizado (talvez específico do ambiente) de atributos é necessário. Para acomodar isso, o ScareCrow permite a entrada de um arquivo JSON contendo atributos. Usando a opção de linha de comando -configfile, o ScareCrow usará esses atributos e nome de arquivo em vez dos preexistentes no ScareCrow. O arquivo main.json contém um modelo de exemplo de como a estrutura JSON precisa ser para funcionar corretamente. Observe que o que você usar como "InternalName" será o nome do arquivo.
ScareCrow agora requer golang 1.19.1 ou posterior para compilar loaders. Se você estiver executando uma versão mais antiga, use a versão 1.19.1 ou posterior.
Veja para novas versões: https://golang.org/dl/.
O primeiro passo como sempre é clonar o repositório. Antes de compilar o ScareCrow, você precisará instalar as dependências.
Para instalá-las, execute os seguintes comandos:``` go get github.com/fatih/color go get github.com/yeka/zip go get github.com/josephspurrier/goversioninfo go get github.com/Binject/debug/pe go get github.com/awgh/rawreader
Certifique-se de que os seguintes estão instalados no seu SO:```
openssl
osslsigncode
mingw-w64
Em seguida, construa-o.``` go build ScareCrow.go
Além disso, o ScareCrow utiliza [Garble](https://github.com/burrowers/garble) para ofuscar todos os loaders.
Nota: Várias das dependências não funcionam bem no Windows ao compilar, por isso, é recomendado compilar seus loaders no OSX ou Linux.
## Help```
./ScareCrow -h
_________ _________
/ _____/ ____ _____ _______ ____ \_ ___ \_______ ______ _ __
\_____ \_/ ___\\__ \\_ __ \_/ __ \/ \ \/\_ __ \/ _ \ \/ \/ /
/ \ \___ / __ \| | \/\ ___/\ \____| | \( <_> ) /
/_______ /\___ >____ /__| \___ >\______ /|__| \____/ \/\_/
\/ \/ \/ \/ \/
(@Tyl0us)
“Fear, you must understand is more than a mere obstacle.
Fear is a TEACHER. the first one you ever had.”
Usage of ./ScareCrow:
-Evasion string
Sets the type of EDR unhooking technique:
[*] Disk - Retrives a clean version of the DLLs ".text" field from files stored on disk.
[*] KnownDLL - Retrives a clean version of the DLLs ".text" field from the KnownDLLs directory in the object namespace.
[*] None - The Loader that WILL NOT removing the EDR hooks in system DLLs and only use custom syscalls. (default "Disk")
-Exec string
Set the template to execute the shellcode:
[*] RtlCopy - Using RtlCopy to move the shellcode into the allocated address in the current running process by making a Syscall.
[*] ProcessInjection - Process Injection Mode.
[*] NtQueueApcThreadEx - Executes the shellcode by creating an asynchronous procedure call (APC) to a target thread.
[*] VirtualAlloc - Allocates shellcode into the process using custom syscalls in the current running process (default "RtlCopy")
-I string
Path to the raw 64-bit shellcode.
-Loader string
Sets the type of process that will sideload the malicious payload:
[*] binary - Generates a binary based payload. (This type does not benefit from any sideloading)
[*] control - Loads a hidden control applet - the process name would be rundll32 if -O is specified a JScript loader will be generated.
[*] dll - Generates just a DLL file. Can be executed with commands such as rundll32 or regsvr32 with DllRegisterServer, DllGetClassObject as export functions.
[*] excel - Loads into a hidden Excel process using a JScript loader.
[*] msiexec - Loads into MSIexec process using a JScript loader.
[*] wscript - Loads into WScript process using a JScript loader. (default "binary")
-O string
Name of output file (e.g. loader.js or loader.hta). If Loader is set to dll or binary this option is not required.
-clone string
Path to the file containing the certificate you want to clone
-configfile string
The path to a json based configuration file to generate custom file attributes. This will not use the default ones.
-console
Only for Binary Payloads - Generates verbose console information when the payload is executed. This will disable the hidden window feature.
-delivery string
Generates a one-liner command to download and execute the payload remotely:
[*] bits - Generates a Bitsadmin one liner command to download, execute and remove the loader (Compatible with Binary, Control, Excel, and Wscript Loaders).
[*] hta - Generates a blank hta file containing the loader along with an MSHTA command to execute the loader remotely in the background (Compatible with Control and Excel Loaders).
[*] macro - Generates an office macro that will download and execute the loader remotely (Compatible with Control, Excel, and Wscript Loaders).
-domain string
The domain name to use for creating a fake code signing cert. (e.g. www.acme.com)
-encryptionmode string
Sets the type of encryption to encrypt the shellcode:
[*] AES - Enables AES 256 encryption.
[*] ELZMA - Enables ELZMA encryption.
[*] RC4 - Enables RC4 encryption. (default "ELZMA")
-export string
For DLL Loaders Only - Specify an Export function for a loader to have.
-injection string
Enables Process Injection Mode and specify the path to the process to create/inject into (use \ for the path).
-noamsi
Disables the AMSI patching that prevents AMSI BufferScanner.
-noetw
Disables the ETW patching that prevents ETW events from being generated.
-nosign
Disables file signing, making -domain/-valid/-password parameters not required.
-nosleep
Disables the sleep delay before the loader unhooks and executes the shellcode.
-obfu
Enables Garbles Literal flag replaces golang libray strings with more complex variants, resolving to the same value at run-time. This creates a larger loader and times longer to compile
-outpath string
The path to put the final Payload/Loader once it's compiled.
-password string
The password for code signing cert. Required when -valid is used.
-sandbox
Enables sandbox evasion using IsDomainJoined calls.
-url string
URL associated with the Delivery option to retrieve the payload. (e.g. https://acme.com/)
-valid string
The path to a valid code signing cert. Used instead -domain if a valid code signing cert is desired.
O Carregador determina o tipo de técnica utilizada para carregar o shellcode no sistema alvo. Se nenhuma opção de carregador for escolhida, o ScareCrow irá apenas compilar um arquivo DLL padrão, que pode ser usado por rundll32, regsvr32 ou outras técnicas que utilizam uma DLL. O ScareCrow utiliza três tipos diferentes de carregadores para carregar shellcode na memória:
O ScareCrow também pode gerar payloads baseados em binários, se necessário, usando a opção de linha de comando -Loader. Esses binários não se beneficiam de técnicas de carregamento lado a lado, mas servem como uma técnica adicional para executar shellcode dependendo da situação.
O ScareCrow utiliza uma técnica para primeiro criar o processo e depois movê-lo para o segundo plano. Isso faz duas coisas: primeiro, ajuda a manter o processo oculto e, segundo, evita ser detectado por qualquer produto EDR. Criar um processo imediatamente em segundo plano pode ser muito suspeito e um indicador de malícia. O ScareCrow faz isso chamando as funções Windows 'GetConsoleWindow' e 'ShowWindow' após o processo ser criado e os hooks do EDR estarem carregados, e então altera os atributos da janela para oculto. O ScareCrow utiliza essas APIs em vez de usar o tradicional -ldflags -H=windowsgui, pois isso é altamente assinado e classificado na maioria dos produtos de segurança como um Indicador de Comprometimento.
Se a opção de linha de comando -console for selecionada, o ScareCrow não ocultará o processo em segundo plano. Em vez disso, o ScareCrow adicionará várias mensagens de depuração exibindo o que o carregador está fazendo.
O ScareCrow usa diferentes modelos para executar shellcode. Para escolher qual modelo, use a opção de linha de comando -Exec. Esses modelos incluem:
O ScareCrow possui a capacidade de realizar ataques de injeção de processo. Para evitar qualquer hook ou detecção tanto no processo do carregador quanto no próprio processo injetado, o ScareCrow primeiro retira os hooks do processo do carregador, como faria normalmente, para garantir que não haja hooks no processo. Uma vez concluído, o carregador criará o processo especificado no comando de criação. Após a criação, o carregador criará um handle para o processo para recuperar uma lista de DLLs carregadas. Quando encontrar as DLLs, ele enumerará o endereço base de cada DLL no processo remoto. Usando a função WriteProcessMemory, o carregador gravará os bytes das DLLs do sistema armazenadas em disco (já que estão "limpas" de hooks EDR) sem a necessidade de alterar as permissões de memória primeiro. O ScareCrow usa WriteProcessMemory porque esta função contém um recurso usado principalmente em depuração, onde mesmo se uma seção de memória for somente leitura, se tudo estiver correto na chamada para WriteProcessMemory, ela alterará temporariamente a permissão para leitura-gravação, atualizará a seção de memória e restaurará as permissões originais. Feito isso, o carregador pode injetar shellcode no processo criado sem problemas, pois não há hooks EDR em nenhum dos processos.
Esta opção pode ser usada com qualquer uma das opções de carregador. Para habilitar a injeção de processo, use a opção de linha de comando -injection junto com o caminho completo do processo que deseja usar para injetar. Ao colocar o caminho como argumento, é importante cercar o caminho completo com "" ou usar \\ duplo para cada diretório no caminho.
O ScareCrow possui a capacidade de corrigir (patch) as funções AMSI (Antimalware Scan Interface) e ETW, impedindo que qualquer evento seja gerado pelo processo.
AMSI é uma API nativa do Windows que permite ao Windows Defender (ou outros produtos antimalware) interagir profundamente no sistema operacional Windows e fornecer proteção aprimorada, especificamente contra ataques baseados em memória. AMSI permite que produtos de segurança detectem melhor indicadores maliciosos e ajudem a interromper ameaças. Como o AMSI é nativo do Windows, os produtos não precisam "hookar" o AMSI; em vez disso, carregam a DLL necessária para obter uma visão aprofundada do processo. Por isso, o ScareCrow carrega a DLL AMSI.dll e a corrige (patch), para garantir que quaisquer resultados da interface de varredura retornem como limpos. Corrigir o AMSI é padrão em todos os carregadores; se desejar não corrigir o AMSI, use a opção de linha de comando -noamsi para desabilitá-lo em seu carregador.
O ETW utiliza syscalls internos para gerar essa telemetria. Como o ETW também é um recurso nativo integrado ao Windows, os produtos de segurança não precisam "hookar" os syscalls do ETW para obter as informações. Como resultado, para prevenir o ETW, o ScareCrow corrige vários syscalls do ETW, eliminando os registradores e retornando o fluxo de execução para a próxima instrução. Corrigir o ETW agora é padrão em todos os carregadores; se desejar não corrigir o ETW, use a opção de linha de comando -noetw para desabilitá-lo em seu carregador.
Atualmente, essas opções funcionam apenas para o processo pai; se a opção de linha de comando -injection for usada, o processo principal corrigirá AMSI e ETW, mas o processo injetado
Criptografar o shellcode é uma técnica importante usada para protegê-lo de ser detectado e analisado por EDRs e outros produtos de segurança. O ScareCrow vem com múltiplos métodos para criptografar shellcode, incluindo AES, ELZMA e RC4.
AES (Advanced Encryption Standard) é um algoritmo de criptografia simétrica amplamente utilizado para criptografar dados. O ScareCrow usa tamanho de chave AES 256 bits para criptografar o shellcode. A vantagem de usar AES para criptografar shellcode é que ele fornece criptografia forte e é amplamente suportado por bibliotecas criptográficas. No entanto, o uso de um tamanho de bloco fixo pode torná-lo vulnerável a certos ataques, como o ataque de padding oracle.
ELZMA é um algoritmo de compressão e criptografia frequentemente usado em malware para ofuscar o código. Para criptografar shellcode usando ELZMA, o shellcode é primeiro comprimido usando o algoritmo ELZMA. Os dados comprimidos são então criptografados usando uma chave aleatória. Os dados criptografados e a chave são então incorporados no código de exploração. A vantagem de usar ELZMA para criptografar shellcode é que ele fornece compressão e criptografia em um único algoritmo. Isso pode ajudar a reduzir o tamanho do código de exploração e torná-lo mais difícil de detectar.
RC4 é um algoritmo de criptografia simétrica frequentemente usado em malware para criptografar shellcode. É uma cifra de fluxo que pode usar chaves de tamanho variável e é conhecida por sua simplicidade e velocidade.
Usar a opção de linha de comando -obfu habilita a flag Garbles Literal durante o processo de compilação. Isso substitui quaisquer referências de biblioteca e strings do Go por uma versão mais complexa, que resolve para o mesmo valor em tempo de execução. Esse processo leva mais tempo para ser concluído, resultando em um arquivo GO maior. Uma vez que o arquivo é compilado, o ScareCrow analisa o arquivo recém-criado, removendo quaisquer IOCs baseados em strings do Go.
O argumento de linha de comando de entrega permite gerar um comando ou string de código (no caso de macro) para puxar remotamente o arquivo de uma fonte remota para o host da vítima. Esses métodos de entrega incluem: