Emulação automatizada de adversário (Caldera) contra um laboratório de AD para validar a cobertura de detecção do Sigma e mapear os resultados para o MITRE ATT&CK.
Validação automatizada de purple team das regras de detecção Sigma criadas em detection-as-code-repo, usando MITRE Caldera para executar um caminho de ataque encadeado de acesso a credenciais do Active Directory contra um laboratório de domínio existente, e um heatmap do ATT&CK Navigator para visualizar a cobertura.
O Caldera foi escolhido em vez do Atomic Red Team para este projeto porque fornece um framework C2 completo, com agentes, perfis de adversário e operações encadeadas de múltiplas etapas, em vez de execução de técnicas únicas e isoladas. Isso corresponde mais de perto ao objetivo deste projeto: não apenas "esta única técnica foi detectada", mas "uma cadeia de ataque realista e ordenada sobrevive à nossa stack de detecção atual, do início ao fim."
Purple-Team-Automation/
├── abilities/ Custom Caldera ability YAMLs
├── adversary-profiles/ The chained adversary profile used in the operation
├── validation/ Kibana evidence per technique + the LLMNR known-gap writeup
├── attack-navigator-heatmap.json ATT&CK Navigator layer, load at mitre-attack.github.io/attack-navigator
├── purple-team-automation-report.md Full write-up: scope, methodology, results, gap analysis
└── README.md This file
Implantei um servidor Caldera dedicado via Docker Compose em uma VM Ubuntu
separada (caldera-server, 192.168.18.205) na mesma rede do laboratório
que o laboratório de domínio AD existente, mantendo-o isolado da stack ELK/SIEM.
O Caldera v5.0.0 subiu com 2000 abilities padrão e 29 adversários padrão
prontos para uso.
Problemas de build que diagnostiquei pelo caminho:
plugins/magma/dist/assets/). Rastreei isso até uma montagem de volume Docker de diretório completo no docker-compose.yml que sobrescrevia o
frontend compilado da imagem com o código-fonte não compilado do host. Corrigido removendo a
montagem de diretório completo.npm/nodejs após o
build da imagem para manter a imagem final enxuta.localhost:8888 fixado como sua base de API, embutido
em tempo de build do Vue via plugins/magma/.env (VITE_CALDERA_URL), que
não é controlado pela configuração de runtime app.frontend.api_base_url do conf/local.yml. Corrigi editando o .env para o IP real da VM e reconstruindo.lvextend -l +100%FREE + resize2fs, além de recuperar camadas de cache de build
via docker system prune -a --volumes.O Stockpile só fornece uma ability nativa para dump de credenciais baseado em LSASS/Mimikatz (T1003.001). As quatro técnicas que eu precisava para este projeto,
Kerberoasting, AS-REP Roasting, Password Spraying e DCSync, todas
exigiram abilities personalizadas que construí em torno do Impacket (GetUserSPNs.py,
GetNPUsers.py, secretsdump.py) e do Kerbrute, já que as abilities de Kerberoasting existentes do Stockpile (Rubeus, WinPwn) são exclusivas para Windows/.NET e
incompatíveis com o agente Sandcat baseado em Linux deste laboratório.
Encontrei dois problemas de build ao criar essas abilities:
plugins.stockpile.app.parsers.katz) com
campos source/edge/target, não um parser genérico de regex pattern como
eu havia assumido originalmente. Isso causou um
TypeError('ParserConfig.__init__()') silencioso ao carregar. Como não existe parser embutido
para a saída bruta do Impacket, removi completamente o bloco parsers:
de todas as quatro abilities. Os resultados são capturados como arquivos brutos de saída/hash
e validados manualmente no Kibana (veja /validation).nano falhou silenciosamente. Percebi isso ao
verificar cada arquivo com cat/wc -l antes de reiniciar o
contêiner.Implantei um agente Sandcat (Linux, grupo red) na VM Kali
(192.168.18.70), usando o nome de processo splunkd para mascaramento de OPSEC,
e confirmei que ele subiu ativo e confiável, executando como root com o
executor proc/sh.
Construí o perfil de adversário AD Credential Access Chain para encadear as
quatro abilities personalizadas na ordem em que um atacante interno oportunista
normalmente tentaria executá-las:
→ Password Spray (Kerbrute)
→ Kerberoasting (GetUserSPNs.py)
→ AS-REP Roasting (GetNPUsers.py)
→ DCSync (secretsdump.py)
O envenenamento LLMNR/NBT-NS (T1557.001) foi deliberadamente excluído do
perfil do Caldera. Veja validation/llmnr-known-gap.md
para entender o motivo, e como ele ainda é incluído como um controle negativo de lacuna conhecida.
Todas as quatro técnicas executadas foram confirmadas como detectadas pelas regras Sigma do detection-as-code-repo, verificadas diretamente no Kibana. O envenenamento LLMNR/NBT-NS permanece como uma lacuna aberta e documentada.
| Técnica | Status |
|---|---|
| T1110.003 – Password Spraying | 🟢 Detectado |
| T1558.003 – Kerberoasting | 🟢 Detectado |
| T1558.004 – AS-REP Roasting | 🟢 Detectado |
| T1003.006 – DCSync | 🟢 Detectado |
| T1557.001 – LLMNR/NBT-NS Poisoning | 🔴 Lacuna |
Detalhes completos: validation/detection-results.md
Relatório completo: purple-team-automation-report.md
Heatmap interativo: attack-navigator-heatmap.json