Emulazione automatizzata dell'avversario (Caldera) contro un laboratorio AD per validare la copertura di rilevamento Sigma e mappare i risultati su MITRE ATT&CK.
Validazione automatizzata purple-team delle regole di rilevamento Sigma create in detection-as-code-repo, utilizzando MITRE Caldera per eseguire un percorso di attacco concatenato di accesso alle credenziali Active Directory contro un laboratorio di dominio esistente, e una heatmap di ATT&CK Navigator per visualizzare la copertura.
Caldera è stato scelto al posto di Atomic Red Team per questo progetto perché fornisce un framework C2 completo, con agenti, profili avversari e operazioni multi-step concatenate, piuttosto che l'esecuzione di singole tecniche isolate. Questo si allinea più strettamente all'obiettivo di questo progetto: non solo "questa singola tecnica è stata rilevata", ma "una catena di attacco realistica e ordinata sopravvive al nostro attuale stack di rilevamento, dall'inizio alla fine."
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
Ho distribuito un server Caldera dedicato tramite Docker Compose su una VM
Ubuntu separata (caldera-server, 192.168.18.205) sulla stessa rete di laboratorio
del laboratorio di dominio AD esistente, mantenendolo isolato dallo stack ELK/SIEM.
Caldera v5.0.0 è partito con 2000 abilità stock e 29 avversari stock
out of the box.
Problemi di build di cui ho individuato la causa lungo il percorso:
plugins/magma/dist/assets/). Ho rintracciato la causa in un mount di volume Docker
dell'intera directory in docker-compose.yml che sovrascriveva il frontend compilato dell'immagine
con il sorgente host non compilato. Risolto rimuovendo il
mount dell'intera directory.npm/nodejs dopo la
build dell'immagine per mantenere l'immagine finale snella.localhost:8888 hardcoded come base API, incorporato
al momento della build di Vue tramite plugins/magma/.env (VITE_CALDERA_URL), che
non è controllato dall'impostazione runtime app.frontend.api_base_url di conf/local.yml. L'ho risolto modificando .env con l'IP reale della VM e ricompilando.lvextend -l +100%FREE + resize2fs, oltre a recuperare i layer della build-cache
tramite docker system prune -a --volumes.Stockpile fornisce nativamente solo un'abilità per il credential
dumping basato su LSASS/Mimikatz (T1003.001). Le quattro tecniche che mi servivano per questo progetto,
Kerberoasting, AS-REP Roasting, Password Spraying e DCSync, richiedevano tutte
abilità personalizzate che ho costruito attorno a Impacket (GetUserSPNs.py,
GetNPUsers.py, secretsdump.py) e Kerbrute, poiché le abilità Kerberoasting esistenti di Stockpile (Rubeus, WinPwn) sono solo per Windows/.NET e
incompatibili con l'agente Sandcat basato su Linux di questo laboratorio.
Ho incontrato due problemi di build mentre le scrivevo:
plugins.stockpile.app.parsers.katz) con
campi source/edge/target, non un parser regex generico pattern come
avevo inizialmente assunto. Questo causava un silenzioso
TypeError('ParserConfig.__init__()') al caricamento. Poiché non esiste alcun parser integrato
per l'output grezzo di Impacket, ho rimosso completamente il blocco parsers:
da tutte e quattro le abilità. I risultati vengono catturati come file di output/hash grezzi
e validati manualmente contro Kibana (vedi /validation).nano è fallito silenziosamente. L'ho scoperto
controllando ogni file con cat/wc -l prima di riavviare il
container.Ho distribuito un agente Sandcat (Linux, gruppo red) sulla VM Kali
(192.168.18.70), usando il nome di processo splunkd per il mascheramento OPSEC,
e ho confermato che è partito attivo e trusted, in esecuzione come root con
l'executor proc/sh.
Ho creato il profilo avversario AD Credential Access Chain per concatenare le
quattro abilità personalizzate nell'ordine in cui un attaccante interno opportunistico
tenterebbe tipicamente di eseguirle:
→ Password Spray (Kerbrute)
→ Kerberoasting (GetUserSPNs.py)
→ AS-REP Roasting (GetNPUsers.py)
→ DCSync (secretsdump.py)
Il poisoning LLMNR/NBT-NS (T1557.001) è stato deliberatamente escluso dal
profilo Caldera. Vedi validation/llmnr-known-gap.md
per il motivo, e come sia comunque incluso come controllo negativo di gap noto.
Tutte e quattro le tecniche eseguite sono state confermate rilevate contro le regole Sigma di detection-as-code-repo, verificate direttamente in Kibana. Il poisoning LLMNR/NBT-NS rimane un gap aperto e documentato.
| Tecnica | Stato |
|---|---|
| T1110.003 – Password Spraying | 🟢 Rilevata |
| T1558.003 – Kerberoasting | 🟢 Rilevata |
| T1558.004 – AS-REP Roasting | 🟢 Rilevata |
| T1003.006 – DCSync | 🟢 Rilevata |
| T1557.001 – LLMNR/NBT-NS Poisoning | 🔴 Gap |
Dettagli completi: validation/detection-results.md
Write-up completo: purple-team-automation-report.md
Heatmap interattiva: attack-navigator-heatmap.json