
CobaltStrike BOF para gerar Beacons usando DLL Application Directory Hijacking
DropSpawn é um BOF do CobaltStrike usado para gerar Beacons adicionais por meio de um método relativamente desconhecido de sequestro de DLL. Funciona em x86-x86, x64-x64 e x86-x64/vice-versa. Use como alternativa à injeção de processos.
Executáveis do Windows seguirão a ordem de pesquisa de DLL ao tentar carregar DLLs cujos caminhos absolutos não foram especificados:

O sequestro de DLL normalmente exige que:
A. Um usuário tenha permissões de escrita em uma pasta com precedência maior na ordem de pesquisa do que onde a DLL real reside
ou
B. Que a DLL em questão não exista em nenhum lugar do sistema; nesse caso, ela pode ser colocada em uma pasta gravável pelo usuário na variável %PATH% do usuário (como %USERPROFILE%\appdata\local\microsoft\windowsapps).
Esses requisitos descartam o sequestro de DLL para executáveis localizados em C:\Windows\System32, porque quase todas as DLLs que esses executáveis carregam também residem em System32. Copiar um executável do System32 para um local gravável pelo usuário e executá-lo lá é uma opção, mas não é muito seguro em termos de OPSEC, pois binários do System32 executados a partir de locais alternativos são fáceis de identificar.
DropSpawn permite o sequestro de DLL usando executáveis do System32 (e outros encontrados em pastas adicionais não graváveis pelo usuário) ao falsificar "O diretório a partir do qual o aplicativo é carregado" para um diretório arbitrário especificado pelo usuário.
O lançamento público do DropSpawn difere ligeiramente do não público. O lançamento não público utiliza um gerador de payload proprietário, tornando a experiência muito mais fluida para o operador. O lançamento público foi ligeiramente alterado para considerar o fato de que os usuários terão suas próprias formas de gerar payloads compatíveis com sequestro de DLL. Um script Python3, bem como o código-fonte de uma DLL de demonstração, foram incluídos para auxiliar os usuários na integração e weaponização do dropspawn.
Identifique alguns executáveis de destino que tentam carregar DLLs sem especificar seus caminhos absolutos. Você pode fazer isso copiando o exe para um diretório gravável pelo usuário e executando-o enquanto o monitora com o Procmon. Neste exemplo, usaremos o WerFault.exe, que normalmente reside em C:\Windows\System32\WerFault.exe

No exemplo acima, cryptsp.dll, wer.dll, dbghelp.dll e bcrypt.dll são todos candidatos viáveis porque seus caminhos absolutos não foram especificados dentro do WerFault; como resultado, o WerFault tentará carregá-los do seu diretório de aplicativo primeiro antes de recorrer ao restante da ordem de pesquisa de DLL. Observe que isso normalmente não é uma preocupação, pois o diretório do aplicativo do WerFault É o System32.
Baixe uma das DLLs sequestráveis do sistema de destino.
Isso é necessário para que possamos extrair suas exportações e incluí-las em nossa DLL de payload. É importante obter a DLL sequestrável da mesma máquina em que você deseja usar o DropSpawn, pois as DLLs mudam entre versões do Windows. Além disso, se você estiver executando um beacon x86 e quiser gerar um beacon x64 usando o DropSpawn, certifique-se de baixar a versão x64 da DLL real especificando 'C:\windows\sysnative...' em vez de 'C:\windows\system32...'.
Execute o generate_dll.py, passando a DLL baixada e a arquitetura de payload desejada. O generate_dll.py é uma versão modificada deste script. Ele analisará a DLL fornecida, criará um arquivo .def contendo as exportações da DLL e chamará o MingW para compilar nossa DLL de payload de demonstração. Quando o processo gerado tentar chamar uma função real dentro da DLL falsificada, nossa DLL de payload encaminhará a chamada para a DLL real localizada no System32 para que o processo host não falhe.

Chame o dropspawn usando a DLL de payload gerada.
dropspawn <payload DLL> <x86|x64> <programa a gerar> [pasta de destino gravável] [processo pai]
payload DLL - o caminho completo para a DLL de payload gerada.
arquitetura - a arquitetura do processo que você deseja gerar
programa a gerar - o nome/caminho do processo que você deseja gerar. Se este processo residir no System32 (ou syswow64), você pode simplesmente especificar o nome. Caso contrário, especifique o caminho completo. Você também pode fornecer argumentos de linha de comando para o processo. Se houver espaços no caminho/se você usar argumentos, coloque tudo entre aspas.
pasta de destino gravável - Opcional. Se deixado em branco, o dropspawn tentará usar o diretório atual do Beacon. Use aspas se houver espaços no caminho.
processo pai - Opcional. O nome do processo a ser usado para falsificação de PPID com o processo recém-gerado. Se um processo for especificado com múltiplas instâncias em execução de diferentes níveis de privilégio (ou seja, svchost.exe), o dropspawn tentará identificar uma que possa ser usada para falsificação de PPID.
Exemplo: dropspawn /root/dbgcore.dll x64 "WerFault.exe -u -p 4352 -s 160" C:\users\user\appdata\local\temp explorer.exe
Isso gravará a DLL de payload 'dbgcore.dll' em disco em 'c:\users\user\appdata\local\temp\dbgcore.dll' e gerará um processo WerFault.exe x64 com os argumentos de linha de comando '-u -p 4352 -s 160' e explorer.exe como processo pai.


A limpeza é fácil. Ao incluir a função de Auto-Exclusão na DLL de payload gravada em disco, ela será excluída assim que nosso novo processo for gerado e a carregar. Isso é um divisor de águas, pois normalmente a DLL ficaria bloqueada em disco enquanto nosso processo que a carregou continuasse em execução. Se a técnica de Auto-Exclusão falhar por algum motivo (ou o processo falhar ao ser gerado), o DropSpawn tentará excluir a DLL de payload do disco e informará o usuário sobre o resultado da operação de qualquer forma.
A injeção de processos normalmente segue a cadeia abrir processo remoto -> alocar memória remota -> escrever memória remota -> executar memória remota, com a opção de gerar um novo processo no início em vez de usar um existente. O DropSpawn apenas cria um novo processo; o processo recém-gerado é responsável por alocar, escrever e executar o shellcode, então podemos evitar muitos dos IOCs normalmente associados à injeção remota de processos.
Esta técnica está, é claro, à mercê da qualidade de suas DLLs de payload. Mas podemos observar o que o Windows vê (esta próxima seção usa a versão privada do DropSpawn e a geração de Beacons).
No que diz respeito ao Visualizador de Eventos, tudo parece normal:

No MDE há muito pouco para ver.
Executando o dropspawn:

Logs do MDE:
Com falsificação de PPID:

Sem falsificação de PPID:

Em ambos os casos, vemos nosso processo beacon original (também um werfault) gravar dbgcore.dll em disco, criar um novo processo WerFault.exe, o processo recém-gerado carregando dbgcore.dll e, em seguida, renomeando (excluindo) o arquivo. Criticamente, não há escrutínio extra sobre dbgcore.dll, que muitas vezes acompanha sequestros de DLL, porque não estamos gravando em nenhum local frequentemente sequestrado, e o WerFault.exe (ou qualquer processo que você escolher usar) não está realmente associado a sequestros de DLL da mesma forma que coisas como WmiPrvSE.exe estão.
Curiosamente, é quase mais visível fazer isso com falsificação de PPID do que sem. Isso pode variar dependendo do produto de segurança, no entanto.
Como mencionado, é essencial que os usuários baixem as DLLs reais da máquina de destino em que planejam usar o DropSpawn. Usar a versão errada de uma DLL pode resultar em falha do processo gerado se ele tentar chamar uma função que não existe.
O DropSpawn pode ser usado com executáveis fora do System32; no entanto, esteja avisado de que problemas podem surgir se o processo tentar carregar DLLs adicionais do diretório real do aplicativo do processo. Como falsificamos o diretório do aplicativo em outro lugar, se o diretório real do aplicativo também não for alcançável pela ordem de pesquisa de DLL de outra forma, o processo falhará/não iniciará porque não consegue localizar DLLs essenciais. Sempre teste possíveis sequestros em máquinas de desenvolvimento antes de usá-los em produção!
Esta pesquisa surgiu enquanto eu explorava como os processos montam sua ordem final de pesquisa de DLL (já que ela deve ser determinada em tempo de execução devido a executáveis residindo em diretórios diferentes, o diretório atual fazendo parte do caminho de pesquisa, etc.). Minha pesquisa me levou a este post de fórum, que serviu como origem das duas APIs não documentadas críticas que são centrais para esta técnica.
Elas já foram vinculadas anteriormente, mas este post sobre como evitar o bloqueio do loader, este script para gerar um arquivo .def para proxy de DLL e esta pesquisa sobre como habilitar a auto-exclusão de executáveis em execução são essenciais para produzir payloads de DLL eficazes e weaponizados adequados para o DropSpawn.
Quando publiquei esta técnica pela primeira vez no Twitter, várias outras pessoas se juntaram à conversa e produziram POCs. SecurityAndStuff produziu este, enquanto Snovvcrash tem o dele aqui