Automatisierte Gegneremulation (Caldera) gegen ein AD-Lab, um die Sigma-Erkennungsabdeckung zu validieren und Ergebnisse MITRE ATT&CK zuzuordnen.
Automatisierte Purple-Team-Validierung der Sigma-Erkennungsregeln, die in detection-as-code-repo erstellt wurden, unter Verwendung von MITRE Caldera zur Ausführung eines verketteten Active-Directory-Credential-Access-Angriffspfads gegen ein bestehendes Domain-Lab sowie einer ATT&CK Navigator-Heatmap zur Visualisierung der Abdeckung.
Caldera wurde für dieses Projekt gegenüber Atomic Red Team gewählt, weil es ein vollständiges C2-Framework mit Agents, Adversary-Profilen und verketteten mehrstufigen Operationen bietet, statt einer einzelnen, isolierten Technikausführung. Das entspricht dem Ziel dieses Projekts genauer: nicht nur „wurde diese eine Technik erkannt“, sondern „übersteht eine realistische, geordnete Angriffs-Kette unseren aktuellen Erkennungs-Stack von Anfang bis Ende“.
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
Ich habe einen dedizierten Caldera-Server über Docker Compose auf einer
separaten Ubuntu-VM (caldera-server, 192.168.18.205) im selben Lab-Netzwerk
wie das bestehende AD-Domain-Lab bereitgestellt und ihn vom ELK/SIEM-Stack
isoliert gehalten. Caldera v5.0.0 startete out of the box mit 2000
Stock-Abilities und 29 Stock-Adversaries.
Build-Probleme, deren Ursache ich unterwegs ermittelt habe:
plugins/magma/dist/assets/). Ich führte dies auf einen
Docker-Volume-Mount des gesamten Verzeichnisses in docker-compose.yml
zurück, der das kompilierte Frontend des Images mit unkompiliertem
Host-Quellcode überschrieb. Behoben durch Entfernen des
Verzeichnis-Mounts.npm/nodejs nach dem
Image-Build deinstalliert, um das finale Image schlank zu halten.localhost:8888 als API-Basis fest einprogrammiert, eingebacken zur
Vue-Build-Zeit über plugins/magma/.env (VITE_CALDERA_URL), was nicht
durch die Laufzeit-Einstellung app.frontend.api_base_url in
conf/local.yml gesteuert wird. Ich behob es, indem ich .env auf die
echte IP der VM änderte und neu baute.lvextend -l +100%FREE + resize2fs, plus Rückgewinnung von
Build-Cache-Layern über docker system prune -a --volumes.Stockpile liefert nur eine native Ability für LSASS/Mimikatz-basiertes
Credential Dumping (T1003.001). Die vier Techniken, die ich für dieses Projekt
benötigte – Kerberoasting, AS-REP Roasting, Password Spraying und DCSync –
erforderten alle Custom Abilities, die ich um Impacket (GetUserSPNs.py,
GetNPUsers.py, secretsdump.py) und Kerbrute herum baute, da die
bestehenden Kerberoasting-Abilities von Stockpile (Rubeus, WinPwn) nur für
Windows/.NET sind und mit dem Linux-basierten Sandcat-Agent dieses Labs
inkompatibel sind.
Beim Erstellen dieser stieß ich auf zwei Build-Probleme:
plugins.stockpile.app.parsers.katz) mit
source/edge/target-Feldern, nicht einen generischen Regex-pattern-Parser,
wie ich ursprünglich angenommen hatte. Dies verursachte beim Laden einen
stillen TypeError('ParserConfig.__init__()'). Da kein eingebauter Parser
für rohe Impacket-Ausgabe existiert, habe ich den parsers:-Block aus allen
vier Abilities vollständig entfernt. Ergebnisse werden als rohe
Output-/Hash-Dateien erfasst und manuell gegen Kibana validiert (siehe
/validation).nano-Einfügen stillschweigend
fehlschlug. Ich erkannte dies, indem ich jede Datei mit cat/wc -l auf
Plausibilität prüfte, bevor ich den Container neu startete.Ich habe einen Sandcat-Agent (Linux, Gruppe red) auf der Kali-VM
(192.168.18.70) bereitgestellt, unter Verwendung des Prozessnamens
splunkd zur OPSEC-Verschleierung, und bestätigt, dass er als alive und
trusted hochkam, laufend als root mit dem proc/sh-Executor.
Ich habe das Adversary-Profil AD Credential Access Chain erstellt, um die
vier Custom Abilities in der Reihenfolge zu verketten, in der ein
opportunistischer interner Angreifer sie typischerweise versuchen würde:
→ Password Spray (Kerbrute)
→ Kerberoasting (GetUserSPNs.py)
→ AS-REP Roasting (GetNPUsers.py)
→ DCSync (secretsdump.py)
LLMNR/NBT-NS-Poisoning (T1557.001) wurde bewusst aus dem Caldera-Profil
ausgeschlossen. Siehe validation/llmnr-known-gap.md
für den Grund und dafür, wie es weiterhin als Known-Gap-Negativkontrolle
enthalten ist.
Alle vier ausgeführten Techniken wurden als erkannt gegen die Sigma-Regeln von detection-as-code-repo bestätigt, direkt in Kibana gegengeprüft. LLMNR/NBT-NS-Poisoning bleibt eine offene, dokumentierte Lücke.
| Technik | Status |
|---|---|
| T1110.003 – Password Spraying | 🟢 Erkannt |
| T1558.003 – Kerberoasting | 🟢 Erkannt |
| T1558.004 – AS-REP Roasting | 🟢 Erkannt |
| T1003.006 – DCSync | 🟢 Erkannt |
| T1557.001 – LLMNR/NBT-NS Poisoning | 🔴 Lücke |
Vollständige Details: validation/detection-results.md
Vollständiger Write-up: purple-team-automation-report.md
Interaktive Heatmap: attack-navigator-heatmap.json