DSCourier BOF
Esta é uma implementação BOF do projeto DSCourier de Dylan Davis e Matthew Schramm. Utiliza a interface COM do WinGet para executar código powershell arbitrário em um processo assinado e confiável da Microsoft. O blog completo da pesquisa pode ser encontrado aqui.
Ao contrário da maioria dos projetos que lanço, esta NÃO é uma ferramenta operacionalmente pronta, mas sim mais uma prova de conceito (POC). Optei por não continuar com isso após descobrir uma série de problemas que impedem que seja um BOF facilmente implantável. O código foi quase inteiramente clanked. Vários problemas permanecem sem solução e são discutidos abaixo
Uso
Coloque seu código powershell arbitrário no arquivo dist/rev.yml. Por padrão, ele contém um simples reverse shell em powershell do repositório original. Se optar por usá-lo, certifique-se de substituir o IP no exemplo existente pelo IP desejado.
Exemplo usando o reverse shell em powershell:


Como Funciona / Limitações
Em nenhuma ordem específica, aqui estão alguns problemas/limitações em torno desta ferramenta.
- Para que as chamadas COM tenham sucesso, o arquivo Microsoft.Management.Configuration.winmd deve estar presente no mesmo diretório que o executável que faz as chamadas COM. Isso representa um problema imediato ao executar um Beacon a partir de um processo system32 esvaziado (hollowed-out), por exemplo, onde usuários normais não têm permissões de escrita. Para contornar isso, o arquivo é enviado para %APPDATA%\temp e a função WinTypes!RoGetMetaDataFile que recupera o caminho do arquivo winmd é interceptada com um hook inline para que possamos fornecer a localização do caminho temporário. Isso permite que o arquivo winmd seja lido / as chamadas COM sejam bem-sucedidas, mas significa que há chamadas VirtualProtect e substituição de memória da DLL, o que cria IOCs.
- Seguindo o item #1, o arquivo winmd fica bloqueado no disco após a execução do BOF até que o processo Beacon seja encerrado. Brinquei um pouco com isso para tentar resolver, inclusive adicionando a funcionalidade de auto-exclusão (Self-delection) que é bem conhecida neste ponto, mas o arquivo permaneceu bloqueado no disco. Talvez seja possível contornar/resolver isso, mas fica para outra pessoa perseguir.
- Conforme mencionado na pesquisa original, como isso usa o recurso pwsh dentro do WinGet, um processo conhost.exe é gerado sob ConfigurationRemotingServer.exe. Claude sugeriu que seria possível carregar um módulo binário personalizado como recurso em vez de invocar pwsh, o que resolveria o problema do conhost, mas isso requer o envio de arquivos adicionais para o disco e não consegui fazer funcionar. Pode não ser possível. Se fosse, abriria a porta para enviar uma DLL .NET genérica ao disco que poderia ser carregada por ConfigurationRemotingServer.exe e executar shellcode/params/etc passados.
- Este BOF implementa as versões Async das interfaces COM necessárias. Usar as versões Sync resulta em Beacon travando / não retornando até que o processo ConfigurationRemotingServer.exe termine; com o exemplo de reverse shell simples, isso significaria que o Beacon não faria check-in novamente até que o shell fosse encerrado. Mudar para as interfaces Async evita esse problema, mas introduz alguns problemas de temporização. Há um sleep fixo de 3 segundos que funcionou na prática para atrasar entre chamadas específicas, mas isso obviamente não é a maneira correta de implementar.
- As definições da interface COM foram obtidas baixando o .msixbundle do winget-cli do Github, extraindo, extraindo o .msix e encontrando o arquivo .winmd. O winmdidl.exe foi então usado para extrair os arquivos IDL. O midlrt.exe foi então usado para converter o IDL em arquivos de cabeçalho/.c, que foram então reduzidos por Claude para conter apenas as definições necessárias. Ainda é uma bagunça de código. Este link da Microsoft provavelmente será útil para entender melhor esse processo.
- O código é geralmente uma bagunça porque isso não saiu do estágio de POC.
Compilação
Esta ferramenta foi escrita sem o uso de declarações normais da API BOF (por exemplo, um arquivo bofdefs.h). Conforme descrito neste post do blog por Matt Ehrnschwender, é possível usar objcopy para corrigir os símbolos apropriados no formato DLL$API no BOF pós-compilação.
Eu escrevi uma ferramenta chamada BOFPatcher que automatiza esse processo. Isso permite que os usuários escrevam BOFs como C normal sem se preocupar com declarações de API complicadas:

Esta ferramenta está disponível para aqueles que adquirirem meu curso BOF Development and Tradecraft.
Embora a ferramenta BOFPatcher não esteja incluída neste repositório, o Makefile desta ferramenta chama objcopy, passando um arquivo imports_dscourier64.txt contendo as substituições de símbolos adequadas, o que torna o BOF utilizável.
Créditos
- Ótimo trabalho de Dylan e Matt. Espero ver mais deles!
- Claude por ter gerado (clanked) a maior parte disso.