Автоматизированная эмуляция действий противника (Caldera) против лаборатории AD для проверки покрытия Sigma-детектирования и сопоставления результатов с MITRE ATT&CK.
Автоматизированная проверка правил обнаружения Sigma в рамках purple-team, построенных в detection-as-code-repo, с использованием MITRE Caldera для выполнения цепочки атаки на доступ к учётным данным Active Directory против существующей лаборатории домена, и тепловой карты ATT&CK Navigator для визуализации покрытия.
Caldera была выбрана вместо Atomic Red Team для этого проекта, потому что она предоставляет полноценный C2-фреймворк с агентами, профилями противника и цепочками многошаговых операций, а не единичное, изолированное выполнение техник. Это гораздо точнее соответствует цели проекта: не просто «была ли обнаружена эта одна техника», а «выживает ли реалистичная, упорядоченная цепочка атаки против нашего текущего стека обнаружения, от начала до конца».
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
Я развернул выделенный сервер Caldera через Docker Compose на отдельной
виртуальной машине Ubuntu (caldera-server, 192.168.18.205) в той же лабораторной сети, что и
существующая лаборатория домена AD, изолировав его от стека ELK/SIEM.
Caldera v5.0.0 запустилась с 2000 стандартными способностями и 29 стандартными противниками
из коробки.
Проблемы сборки, которые я выявил по ходу дела:
plugins/magma/dist/assets/). Я отследил это до монтирования тома Docker с полным каталогом в docker-compose.yml, которое перезаписывало скомпилированный
фронтенд образа некомпилированным исходным кодом хоста. Исправлено удалением
монтирования полного каталога.npm/nodejs после
сборки образа, чтобы финальный образ оставался компактным.localhost:8888 в качестве базового адреса API, зашитый
во время сборки Vue через plugins/magma/.env (VITE_CALDERA_URL), который
не контролируется настройкой app.frontend.api_base_url во время выполнения в conf/local.yml. Я исправил это, отредактировав .env на реальный IP виртуальной машины и пересобрав.lvextend -l +100%FREE + resize2fs, а также освобождения слоёв кэша сборки
через docker system prune -a --volumes.Stockpile поставляется только с нативной способностью для дампа учётных данных на основе LSASS/Mimikatz (T1003.001). Четыре техники, которые мне были нужны для этого проекта,
Kerberoasting, AS-REP Roasting, Password Spraying и DCSync, все
требовали пользовательских способностей, которые я построил вокруг Impacket (GetUserSPNs.py,
GetNPUsers.py, secretsdump.py) и Kerbrute, поскольку существующие способности Kerberoasting в Stockpile (Rubeus, WinPwn) предназначены только для Windows/.NET и
несовместимы с Linux-агентом Sandcat в этой лаборатории.
При написании этих способностей я столкнулся с двумя проблемами сборки:
plugins.stockpile.app.parsers.katz) с
полями source/edge/target, а не универсальный парсер регулярных выражений pattern, как
я изначально предполагал. Это вызвало молчаливую
TypeError('ParserConfig.__init__()') при загрузке. Поскольку встроенного парсера
для необработанного вывода Impacket не существует, я полностью убрал блок parsers:
из всех четырёх способностей. Результаты сохраняются как необработанный вывод/файлы хешей
и проверяются вручную через Kibana (см. /validation).nano молча не удалась. Я обнаружил это, проверив
каждый файл с помощью cat/wc -l перед перезапуском контейнера.Я развернул агент Sandcat (Linux, группа red) на виртуальной машине Kali
(192.168.18.70), используя имя процесса splunkd для маскировки OPSEC,
и подтвердил, что он запустился живым и доверенным, работая от имени root с
исполнителем proc/sh.
Я создал профиль противника AD Credential Access Chain, чтобы объединить в цепочку
четыре пользовательские способности в том порядке, в котором оппортунистический внутренний атакующий
обычно попытался бы их выполнить:
→ Password Spray (Kerbrute)
→ Kerberoasting (GetUserSPNs.py)
→ AS-REP Roasting (GetNPUsers.py)
→ DCSync (secretsdump.py)
Отравление LLMNR/NBT-NS (T1557.001) было намеренно исключено из
профиля Caldera. См. validation/llmnr-known-gap.md
о том, почему, и как оно всё ещё включено в качестве негативного контроля известного пробела.
Все четыре выполненные техники были подтверждены как обнаруженные в соответствии с правилами Sigma из detection-as-code-repo, перекрёстно проверенными непосредственно в Kibana. Отравление LLMNR/NBT-NS остаётся открытым, задокументированным пробелом.
| Техника | Статус |
|---|---|
| T1110.003 – Password Spraying | 🟢 Обнаружено |
| T1558.003 – Kerberoasting | 🟢 Обнаружено |
| T1558.004 – AS-REP Roasting | 🟢 Обнаружено |
| T1003.006 – DCSync | 🟢 Обнаружено |
| T1557.001 – LLMNR/NBT-NS Poisoning | 🔴 Пробел |
Полные детали: validation/detection-results.md
Полный отчёт: purple-team-automation-report.md
Интерактивная тепловая карта: attack-navigator-heatmap.json