Émulation automatisée d'adversaire (Caldera) contre un lab AD afin de valider la couverture de détection Sigma et de mapper les résultats à MITRE ATT&CK.
Validation automatisée purple-team des règles de détection Sigma construites dans detection-as-code-repo, en utilisant MITRE Caldera pour exécuter un chemin d'attaque en chaîne d'accès aux identifiants Active Directory contre un lab de domaine existant, et une heatmap ATT&CK Navigator pour visualiser la couverture.
Caldera a été choisi plutôt qu'Atomic Red Team pour ce projet car il fournit un framework C2 complet, avec des agents, des profils d'adversaire et des opérations chaînées multi-étapes, plutôt qu'une exécution de technique unique et isolée. Cela correspond davantage à l'objectif de ce projet : pas seulement « est-ce que cette technique a été détectée », mais « est-ce qu'une chaîne d'attaque réaliste et ordonnée survit à notre stack de détection actuelle, du début à la fin. »
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
J'ai déployé un serveur Caldera dédié via Docker Compose sur une VM
Ubuntu séparée (caldera-server, 192.168.18.205) sur le même réseau de lab que
le lab de domaine AD existant, en le gardant isolé de la stack ELK/SIEM.
Caldera v5.0.0 a démarré avec 2000 abilities stock et 29 adversaries stock
prêts à l'emploi.
Problèmes de build dont j'ai identifié la cause racine en cours de route :
plugins/magma/dist/assets/). J'ai tracé cela jusqu'à un montage de volume Docker
de répertoire complet dans docker-compose.yml qui écrasait le frontend compilé de l'image
avec les sources non compilées de l'hôte. Corrigé en supprimant le
montage de répertoire complet.npm/nodejs après le
build de l'image pour garder l'image finale légère.localhost:8888 codé en dur comme base d'API, intégré
au moment du build Vue via plugins/magma/.env (VITE_CALDERA_URL), ce qui
n'est pas contrôlé par le paramètre runtime app.frontend.api_base_url de conf/local.yml. Je l'ai corrigé en modifiant .env avec la vraie IP de la VM et en rebuildant.lvextend -l +100%FREE + resize2fs, plus la récupération des couches de cache de build
via docker system prune -a --volumes.Stockpile ne fournit nativement qu'une ability pour le credential
dumping basé sur LSASS/Mimikatz (T1003.001). Les quatre techniques dont j'avais besoin pour ce projet,
Kerberoasting, AS-REP Roasting, Password Spraying et DCSync, ont toutes
nécessité des abilities personnalisées que j'ai construites autour d'Impacket (GetUserSPNs.py,
GetNPUsers.py, secretsdump.py) et Kerbrute, car les abilities Kerberoasting existantes de Stockpile
(Rubeus, WinPwn) sont Windows/.NET uniquement et
incompatibles avec l'agent Sandcat basé sur Linux de ce lab.
J'ai rencontré deux problèmes de build lors de l'écriture de celles-ci :
plugins.stockpile.app.parsers.katz) avec
les champs source/edge/target, et non un parser générique à regex pattern comme
je l'avais supposé à l'origine. Cela a causé un
TypeError('ParserConfig.__init__()') silencieux au chargement. Comme aucun parser intégré
n'existe pour la sortie brute d'Impacket, j'ai supprimé entièrement le bloc parsers:
des quatre abilities. Les résultats sont capturés sous forme de fichiers de sortie brute/de hash
et validés manuellement contre Kibana (voir /validation).nano a échoué silencieusement. Je l'ai repéré en
vérifiant chaque fichier avec cat/wc -l avant de redémarrer le
conteneur.J'ai déployé un agent Sandcat (Linux, groupe red) sur la VM Kali
(192.168.18.70), en utilisant le nom de processus splunkd pour le masquage OPSEC,
et j'ai confirmé qu'il était actif et de confiance, s'exécutant en root avec
l'exécuteur proc/sh.
J'ai construit le profil d'adversaire AD Credential Access Chain pour chaîner les
quatre abilities personnalisées dans l'ordre qu'un attaquant interne opportuniste
tenterait typiquement :
→ Password Spray (Kerbrute)
→ Kerberoasting (GetUserSPNs.py)
→ AS-REP Roasting (GetNPUsers.py)
→ DCSync (secretsdump.py)
L'empoisonnement LLMNR/NBT-NS (T1557.001) a été délibérément exclu du
profil Caldera. Voir validation/llmnr-known-gap.md
pour savoir pourquoi, et comment il reste inclus comme contrôle négatif de lacune connue.
Les quatre techniques exécutées ont toutes été confirmées détectées par les règles Sigma de detection-as-code-repo, recoupées directement dans Kibana. L'empoisonnement LLMNR/NBT-NS reste une lacune ouverte et documentée.
| Technique | Statut |
|---|---|
| T1110.003 – Password Spraying | 🟢 Détecté |
| T1558.003 – Kerberoasting | 🟢 Détecté |
| T1558.004 – AS-REP Roasting | 🟢 Détecté |
| T1003.006 – DCSync | 🟢 Détecté |
| T1557.001 – LLMNR/NBT-NS Poisoning | 🔴 Lacune |
Détails complets : validation/detection-results.md
Rapport complet : purple-team-automation-report.md
Heatmap interactive : attack-navigator-heatmap.json