Microsoft Defender for Cloud / Defender CSPM で攻撃パス分析を検知した際にアラートを通報させよう

# 1. はじめに
Microsoft Defender for Cloud (以下 Defender for Cloud) で Defender CSPM を利用すると、検知した様々な推奨事項やリソース同士の接続情報を元にリスク分析を行い、攻撃が成立する可能性があるリスクを検出する「[攻撃パス分析 (Attack Path Analysis)](https://learn.microsoft.com/ja-jp/azure/defender-for-cloud/how-to-manage-attack-path) 」機能がリリースされました。
本機能はマルチクラウドにも対応しており、Azure / AWS / GCP のリソース情報の推奨事項に対しても利用が出来るようになっています。本記事では、Defender CSPM を用いて攻撃パス分析を検知した際に外部アラート通知するテンプレートを試してみました。

# [参考] 検知可能な攻撃パス分析のリスト
攻撃パス分析のリストはドキュメントに掲載されていますので、以下をご確認下さい。

https://learn.microsoft.com/ja-jp/azure/defender-for-cloud/attack-path-reference

# 2. 構成概要
Defender CSPM 攻撃パス分析の概念と、外部通知するイメージです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/f74a3f6c-926c-ddee-213b-8e6334c59360.png)

- Defender CSPM を有効にして、攻撃パス検知機能を有効にします。
- 攻撃パス分析は、個々の推奨事項を統合し、CSPM で得たリソース情報（アセット）のコネクション情報を解析し、リスク分析を行います。
- 攻撃パス分析が判定されると、Defender for Cloud 画面の「攻撃パスの分析」機能にアラートとして表示されます。
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/46d35397-f6d4-3ef1-9d03-8a60596bca4b.png)

    - 2023.10 現在、攻撃パスのアラートは **1日1回** のタイミングで検知される仕様となっています。
    - 「**環境**」にクラウド種別 (Azure/AWS/GCP)、「**パス数**」に攻撃パスが成立するパス数が表示されます
- 攻撃パスのアラートを選択すると、一連の脅威の情報を確認することが出来ます
    - 攻撃パスの概要
    - 含まれる推奨事項数 / 推奨事項の詳細
    - 攻撃パスのイメージ
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/e4035e7f-855f-0ff3-f7b2-4d18d37444dc.png)
- ロジックアプリを用いて、定期的に Azure Resource Graph をチェックし、新規に攻撃パスが発生した際に外部にメール通報を行います
    - メール概要例
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/2be9b3bf-67f8-947c-9512-bc85e8218f9a.png)

なお、今回の通知テンプレートは Azure Github のテンプレートを用いていますが、Azure OpenAI を用いることで和訳などの応用も可能ではないかと思います。

# 3. テンプレートのデプロイ
今回用いた ARM テンプレートは以下になります。
デプロイ時に幾つか注意が必要でしたので、以下ご注意ください。

https://github.com/Azure/Microsoft-Defender-for-Cloud/tree/main/Workflow%20automation/Notify-NewAttackPath

## 3.1 Azure Storage を事前に用意する
本テンプレートでは、定期的なロジックアプリ起動の際に過去通知したリソースを繰り返し通報しないために、Azure Storage テーブルにデータを記録して、次回時にテーブルを参照して新規分のみを通知する方式を採用しています。事前に Azure Storage と、専用のテーブル名「``attackPaths``」を作成して下さい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/4a79fcf0-ccff-7855-3465-ee9ac8b26d8e.png)

Azure Storage テーブルの参照のため、アクセスキーも入手しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/86e57757-5d1c-fd73-7a8f-dd5465229d71.png)

## 3.2 ARM テンプレートのデプロイ
[テンプレート](https://github.com/Azure/Microsoft-Defender-for-Cloud/tree/main/Workflow%20automation/Notify-NewAttackPath)のデプロイを行います。
``Email Address`` の枠はメール通知先を記入しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/a300f282-a78a-a0f3-13f0-5518c2a86e34.png)

## 3.3 ロジックアプリ / API 接続の編集
テンプレートのデプロイが成功すると、ロジックアプリ ``attachPathNotification`` が作成されます。
ロジックアプリを起動し、各々の API 接続を編集します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/ffd7a454-98c4-18e4-f925-234659d08793.png)

### 3.3.1 Azuretables-attachPathNotification
API 接続の編集より、パラメータにストレージ名、もしくはストレージエンドポイント ``https://xxxxx.table.core.windows.net/`` を設定します。
共有ストレージキーにストレージのアクセスキーを設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/89d8f4af-ad35-469e-5ce7-b79504df9da8.png)

### 3.3.2 Office365-attachPathNotification
API 接続の編集より、「承認する」をクリックして、送信元の Office 365 ユーザーで認証承認を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/36d2f658-529c-23f7-366d-3ec97bd98baa.png)

## 3.4 マネージド ID に対するサブスクリプション「閲覧者」権限の付与
ロジックアプリを用いて、RESTAPI で Microsoft Resource Graph にクエリーを行う際に認証が必要となります。マネージドIDを用いていますので、Defender CSPM が検知する対象のサブスクリプションすべてに対する「閲覧者 (Reader)」権限を付与して下さい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/1ab06a3c-dc28-fd39-369c-edb627d37cf2.png)

## 3.5 ロジックアプリ / デザイナーで確認する
コネクタの接続、マネージド ID に対する権限の付与が終わったら、デザイナーで一連のフローを確認します。

- **Reccurence**
    - ロジックアプリを起動する定期時間を設定します
    - Defender CSPM の検知が 1回/日 になっていますが、何時検知するのか分からない場合などを考慮して、本検証では 1回/時間に設定しました。
- **HTTP-AttackPaths**
    - HTTP RESTAPI (マネージド ID 認証)を用いて、攻撃パスの情報をクエリーします
- **Set variable - Notification Body**
    - Office 365 コネクタ経由で通知する際に用いる HTML メールのテンプレートになっています。
    - 日本語化や CSS などのカスタマイズを行いたい場合はこちらを修正してみてください。
- **Send an email (V2)**
    - コネクタ経由でメール宛先にメールを送ります
    - 事前パラメータで定義した宛先がセットされていますので、事後カスタマイズする際はこちらを編集します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/a104be2e-573c-ad73-eb70-385185240df6.png)

## 3.6 テストしてみる
設定が完了しましたら、ロジックアプリの「概要」からテスト実行してみます。
無事成功すると、実行の履歴に結果が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/733e568e-69b5-5328-eb40-e44287bc88dc.png)

初の検知の際は RESTAPI で取得したデータを Condition 条件でメール通知する動きが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/1994dd81-82ff-79ac-accf-0300715a4f3a.png)

次回の検知の際にも ARG には情報が残っているため、RESTAPI のクエリーでは引っ掛かりますが、Condition 条件で Azure Storage テーブルに記録されている既存データと判定されるため、メール通知は行わず終了しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/808b6752-6fbf-9b49-2e76-411ec85c04a9.png)

メール通知が行われると、対象のメールアドレスに HTML メールで通知されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/2be9b3bf-67f8-947c-9512-bc85e8218f9a.png)

# [補足] Azure Storage テーブルに格納されている情報
ロジックアプリを用いて Azure Storage テーブルに格納されている情報は、``Get-AzTableRow`` などを通じて確認が可能です。

```powershell
$table = Get-AzTableTable -resourceGroup "rg-CSPMTest-JE" -TableName "attackPaths" -storageAccountName "sthnakadacspmdata"
Get-AzTableRow -Table $table
```

AttackPath の情報が以下のフィールド情報で格納されていることが確認出来ます。
```powershell
DisplayName    : Internet exposed VM has high severity vulnerabilities
LastUpdate     : 2023-10-26T08:21:54Z
Notified       : True
TimeGenerated  : 2023-10-25T02:44:53Z
PartitionKey   : AttackPath
RowKey         : 6aa891cd748ed0f92c940d31f7c6925562d67032fff131c6f105d6322429041c
TableTimestamp : 2023/10/26 17:21:54 +09:00
Etag           : W/"datetime'2023-10-26T08%3A21%3A54.6328478Z'"
```
ロジックアプリでは、上記に格納された ``RowKey`` を見て既存の AttackPath かどうかを判定しています。Azure Storage テーブルの ``RowKey`` プロパティは、各パーティション内のエンティティを一意に識別する文字列値を格納しています。
``PartitionKey`` と ``RowKey`` は、Table Storage がデフォルトで用意する文字列型プロパティで、これらを組み合わせたものがテーブル内でデータを一意に特定する情報になります（RDB のプライマリキーのような位置づけです）

| Key | 意味 |
| ---- | ---- |
|  PartitionKey  | テーブル内のエンティティが所属するパーティションを指定します。PC のストレージのパーティションと同じような概念で、データ取得時（検索時）には、内部的にこの PartitionKey の範囲で検索することになります。同一のパーティションに含まれるデータは、1回のクエリで取得することができます。|
|  RowKey  | RDB のプライマリキーに相当するものです。任意の文字列を指定できますが、同一の PartitionKey の中で一意になるようにしなければいけません。Table Storage 用の検索クエリを用いると、この値の大小比較によるデータ検索を行うことができます。 |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/4ba9ece4-24f6-2d9a-de7b-4f77d6573d63.png)

なお、テスト用途で格納したテーブルを削除したい場合は、``Remove-AzTableRow`` コマンドを用いて取得したテーブルを削除することが出来ます。
```powershell
Get-AzTableRow -table $Table | Remove-AzTableRow -table $Table
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/47990274-5e64-77a6-a660-d7fcbe1d3332.png)

# 4. まとめ
以上、Defender CSPM の攻撃パス検知を外部アラートとして通報する例をご紹介しました。これまでの推奨事項検知ではなく、Defender CSPM の有償プランを活用いただくことで、より精度の高いリスク判定をマルチクラウドで監視することが出来るようになります。本記事がどなたかの参考になれば幸いです。

＊本稿は、個人の見解に基づいた内容であり、所属する会社の公式見解ではありません。また、いかなる保証を与えるものでもありません。正式な情報は、各製品の販売元にご確認ください。

# 5. 参考情報

https://techcommunity.microsoft.com/t5/microsoft-defender-for-cloud/microsoft-defender-for-cloud-automate-notifications-when-new/ba-p/3832385