
ADラボに対する自動敵対者エミュレーション(Caldera)を実施し、Sigma検知カバレッジを検証して結果をMITRE ATT&CKにマッピングします。
detection-as-code-repo で構築した Sigma 検出ルールを、既存のドメインラボに対して連鎖的な Active Directory 資格情報アクセス攻撃パスを実行する MITRE Caldera と、カバレッジを可視化する ATT&CK Navigator ヒートマップを用いて自動的にパープルチーム検証する。
本プロジェクトで Atomic Red Team ではなく Caldera を選んだのは、単発の独立したテクニック実行ではなく、エージェント、敵対者プロファイル、連鎖的な多段階オペレーションを備えた完全な C2 フレームワークを提供するからである。これは本プロジェクトの目標により合致している。すなわち「この単一のテクニックが検出されたか」ではなく、「現実的で順序立てられた攻撃チェーンが、我々の現在の検出スタックを最初から最後まで生き残るか」である。
Purple-Team-Automation/
├── abilities/ カスタム Caldera アビリティ YAML
├── adversary-profiles/ オペレーションで使用した連鎖的敵対者プロファイル
├── validation/ テクニックごとの Kibana エビデンス + LLMNR 既知ギャップの記述
├── attack-navigator-heatmap.json ATT&CK Navigator レイヤー、mitre-attack.github.io/attack-navigator で読み込み
├── purple-team-automation-report.md 完全な記述: スコープ、手法、結果、ギャップ分析
└── README.md 本ファイル
Docker Compose を介して専用の Caldera サーバーを、既存の AD ドメインラボと同じラボネットワーク上の別の Ubuntu VM (caldera-server、192.168.18.205) にデプロイし、ELK/SIEM スタックから分離した。Caldera v5.0.0 は、2000 個の標準アビリティと 29 個の標準敵対者をすぐに利用できる状態で起動した。
途中で根本原因を特定したビルドの問題:
plugins/magma/dist/assets/) が存在しないためにクラッシュループに陥った。これは docker-compose.yml のディレクトリ全体の Docker ボリュームマウントが、イメージのコンパイル済みフロントエンドを未コンパイルのホストソースで上書きしていたことに起因すると突き止めた。ディレクトリ全体のマウントを削除して修正した。npm/nodejs を意図的にアンインストールしているため失敗した。localhost:8888 を API ベースとしてハードコードしており、これは Vue ビルド時に plugins/magma/.env (VITE_CALDERA_URL) を介して焼き込まれ、conf/local.yml の実行時 app.frontend.api_base_url 設定では制御されない。.env を VM の実際の IP に編集して再ビルドすることで修正した。lvextend -l +100%FREE + resize2fs で修正し、さらに docker system prune -a --volumes でビルドキャッシュレイヤーを回収した。Stockpile には LSASS/Mimikatz ベースの資格情報ダンプ (T1003.001) 用のネイティブアビリティしか同梱されていない。本プロジェクトで必要とした 4 つのテクニック、Kerberoasting、AS-REP Roasting、Password Spraying、DCSync はすべて、Impacket (GetUserSPNs.py、GetNPUsers.py、secretsdump.py) と Kerbrute を中心に構築したカスタムアビリティを必要とした。Stockpile の既存の Kerberoasting アビリティ (Rubeus、WinPwn) は Windows/.NET 専用であり、本ラボの Linux ベースの Sandcat エージェントとは互換性がないためである。
これらを作成する際に 2 つのビルド問題に遭遇した:
source/edge/target フィールドを持つツールごとの専用パーサーモジュール (例: plugins.stockpile.app.parsers.katz) を使用しており、当初想定していたような汎用の正規表現 pattern パーサーではない。これによりロード時に TypeError('ParserConfig.__init__()') が黙って発生した。生の Impacket 出力用の組み込みパーサーが存在しないため、4 つのアビリティすべてから parsers: ブロックを完全に削除した。結果は生の出力/ハッシュファイルとしてキャプチャし、Kibana に対して手動で検証する (/validation を参照)。nano の貼り付けが黙って失敗した後、当初 0 バイトのファイルとして保存されていた。コンテナを再起動する前に、すべてのファイルを cat/wc -l で健全性チェックすることでこれを発見した。Sandcat エージェント (Linux、グループ red) を Kali VM (192.168.18.70) にデプロイし、OPSEC マスカレードのためにプロセス名 splunkd を使用し、proc/sh エグゼキューターで root として実行され、稼働中かつ信頼済みであることを確認した。
AD Credential Access Chain 敵対者プロファイルを構築し、日和見的な内部攻撃者が通常試みる順序で 4 つのカスタムアビリティを連鎖させた:
→ 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 を参照。
実行された 4 つのテクニックはすべて、detection-as-code-repo の Sigma ルールに対して検出が確認され、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