0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Microsoft Sentinelの分析ルール追加/更新を検出する

Last updated at Posted at 2023-01-02

Microsoft Sentinelの分析ルールはデプロイすればすぐに利用可能なものが多数存在している。具体的には「規則のテンプレート」にリストアップされている。このルールについて、新しく追加もしくは更新されたとしてもユーザーに通知する仕組みが実装されておらず、自らが気づく仕組みづくりを作る必要がある。

一番簡単なのは定期的に手動でリスト画面を眺める方法があるが、GUIの構成仕様上バージョン情報等は1つずつルールを選択して確認していく必要がある。

目指すゴール

REST API経由ですべてのアラート ルール テンプレートを取得し、その結果をLog Analyticsの指定したテーブルに格納する。
その後、Sentinelの自作ルールで定期的に更新もしくは追加を確認し該当すればインシデントとして起票する。

実装

以下の流れで実装をすすめる。

  1. [Azure AD] REST APIのbearer token取得用にサービスプリンシパルを作成、設定する
  2. [Logic Apps] tokenの取得、REST API経由でルール一覧を取得、Log Analyticsにデータを送信する
  3. [Sentinel] 追加/更新を検出する

1. サービスプリンシパルの設定

ユーザーが画面経由で様々な操作をする際、操作している人を識別・認可しているがアプリケーションでも同様の仕組みで利用することができる。
人の場合はユーザープリンシパルだが、アプリケーションの場合はサービスプリンシパルとなる。アプリケーションを活用する例は今回のように自動化された仕組みのなかで自動的にリソースへアクセスする場合などである。詳細は以下の記事を参照すること。

今回はサービスプリンシパルを利用するためその設定を行う。

アプリケーションの作成・設定

以下の記事の「Azure AD にアプリケーションを登録し、サービス プリンシパルを作成する」を参考にしてアプリの作成を行う。

パラメーターは以下のように設定する。

項目
名前 (任意)
サポートされているアカウントの種類 この組織ディレクトリのみに含まれるアカウント (既定のディレクトリ のみ - シングル テナント)
リダイレクト URI(省略可能) 設定しない

次に作成されたアプリケーションに対してシークレット(パスワードのようなもの)を設定する。
以下の記事の「オプション 2:新しいアプリケーション シークレットを作成する」を参考にシークレットを作成する。
なお、シークレットの値をメモしておく。

最後に以下の記事の「サインインするためのテナントとアプリ ID の値を取得する」を参考にアプリケーションのテナントIDおよびアプリIDをメモする。

アプリケーションの設定

作成されたアプリケーションに対して権限を付与する。
最小権限の場合、Log Analytics ワークスペースが最小範囲となる。よって、Log Analytics ワークスペースへのRead権限を付与すれば良い。
対象のワークスペースを開き、左側のメニューペインから「アクセス制御(IAM)」を選択し画面上部の「+ 追加」 -> 「ロールの割り当ての追加」をクリックする。
ロールリストから「閲覧者」を選択しメンバーを付与する。なお、キーワード検索ではなく前方一致で選択肢が出てくるようなので、アプリ名を手打ちして選択すること。

スクリーンショット 2023-01-04 12.57.16.png

2. ルールの一覧取得ならびにLog Analyticsへのデータ送信

ロジックアプリを用いて実装する。完成イメージは以下の通り。
スクリーンショット 2023-01-04 13.03.35.png

Recurrenceは自分の好きな時間帯/周期を設定すれば良い。また、変数を準備して各種パラメーターを設定する方法やハードコーディングする方法どちらでも良い。なお、Client Secretは定期的に更新する必要があるため変数化しておくことを推奨する。
それ以外の部分については詳しく記載していく。

HTTP: Bearer Tokeの取得

パラメーターを以下の通り設定する。

項目
方法 POST
URI https://login.microsoftonline.com/{TenantID}/oauth2/token
ヘッダー Content-Type/application/x-www-form-urlencoded
本文 grant_type=client_credentials&client_id={APP ID}&client_secret={Client Secret}&resource=https%3A%2F%2Fmanagement%2Eazure%2Ecom

スクリーンショット 2023-01-04 13.08.53.png

JSON の解析: Bearer Token

パラメーターを以下の通り設定する。

項目
コンテンツ (HTTP: Bearer Tokenの取得)本文
スキーマ 下記コードセクション参照
スキーマ
{
    "properties": {
        "access_token": {
            "type": "string"
        },
        "expires_in": {
            "type": "string"
        },
        "expires_on": {
            "type": "string"
        },
        "ext_expires_in": {
            "type": "string"
        },
        "not_before": {
            "type": "string"
        },
        "resource": {
            "type": "string"
        },
        "token_type": {
            "type": "string"
        }
    },
    "type": "object"
}

HTTP: ルールリストの取得

パラメーターを以下の通り設定する。

項目
方法 GET
URI https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}/providers/Microsoft.SecurityInsights/alertRuleTemplates?api-version=2022-11-01
ヘッダー Authorization/Bearer {(JSONの解析: Bearer TOken)access token}

スクリーンショット 2023-01-04 13.15.05.png

JSON の解析

パラメーターを以下の通り設定する。

項目
コンテンツ 本文/body('HTTP')
スキーマ 以下のコードブロックに示す値
スキーマ
{
    "properties": {
        "value": {
            "items": {
                "properties": {
                    "id": {
                        "type": "string"
                    },
                    "kind": {
                        "type": "string"
                    },
                    "name": {
                        "type": "string"
                    },
                    "properties": {
                        "properties": {
                            "alertRulesCreatedByTemplateCount": {
                                "type": "integer"
                            },
                            "createdDateUTC": {
                                "type": "string"
                            },
                            "description": {
                                "type": "string"
                            },
                            "displayName": {
                                "type": "string"
                            },
                            "entityMappings": {
                                "items": {
                                    "properties": {
                                        "entityType": {
                                            "type": "string"
                                        },
                                        "fieldMappings": {
                                            "items": {
                                                "properties": {
                                                    "columnName": {
                                                        "type": "string"
                                                    },
                                                    "identifier": {
                                                        "type": "string"
                                                    }
                                                },
                                                "required": [
                                                    "identifier",
                                                    "columnName"
                                                ],
                                                "type": "object"
                                            },
                                            "type": "array"
                                        }
                                    },
                                    "required": [
                                        "entityType",
                                        "fieldMappings"
                                    ],
                                    "type": "object"
                                },
                                "type": "array"
                            },
                            "lastUpdatedDateUTC": {
                                "type": "string"
                            },
                            "query": {
                                "type": "string"
                            },
                            "queryFrequency": {
                                "type": "string"
                            },
                            "queryPeriod": {
                                "type": "string"
                            },
                            "requiredDataConnectors": {
                                "items": {
                                    "properties": {
                                        "connectorId": {
                                            "type": "string"
                                        },
                                        "dataTypes": {
                                            "items": {
                                                "type": "string"
                                            },
                                            "type": "array"
                                        }
                                    },
                                    "required": [
                                        "connectorId",
                                        "dataTypes"
                                    ],
                                    "type": "object"
                                },
                                "type": "array"
                            },
                            "severity": {
                                "type": "string"
                            },
                            "status": {
                                "type": "string"
                            },
                            "tactics": {
                                "items": {
                                    "type": "string"
                                },
                                "type": "array"
                            },
                            "triggerOperator": {
                                "type": "string"
                            },
                            "triggerThreshold": {
                                "type": "integer"
                            },
                            "version": {
                                "type": "string"
                            }
                        },
                        "type": "object"
                    },
                    "type": {
                        "type": "string"
                    }
                },
                "required": [
                    "id",
                    "name",
                    "type",
                    "kind",
                    "properties"
                ],
                "type": "object"
            },
            "type": "array"
        }
    },
    "type": "object"
}

データの送信

コネクタ「Azure Log Analytics Data Collector」、アクション「データの送信」を利用する。
なお、パラメーターを以下の通り設定する。

項目
JSON 要求本文 (JSONの解析)value
カスタム ログの名前 (任意)SentinelAlertRules_CL

3. Sentinelで追加/更新を検出する

Log Analyticsでのデータ確認

以下のクエリを実行してデータ格納状況を確認する。なお、timeframe変数の値を調整する必要がある。

確認用クエリ
let timeframe = ago(30d);
SentinelAlertRules_CL
| where properties_severity_s != "" and properties_status_s == "Available" and properties_lastUpdatedDateUTC_t > timeframe
| summarize arg_max(TimeGenerated, *) by properties_displayName_s
| extend type=case(properties_lastUpdatedDateUTC_t == properties_createdDateUTC_t,"Add","Update")
| project ruleName=properties_displayName_s, ruleId=name_g, version=properties_version_s, lastUpdateDateUTC=properties_lastUpdatedDateUTC_t, createdDateUTC=properties_createdDateUTC_t, severity=properties_severity_s, kind_s, type, TimeGenerated

実行結果
スクリーンショット 2023-01-04 13.18.33.png

Sentinelの独自ルール追加

1日に1回実行するという前提のクエリを以下に示す。

追加
let timeframe = ago(1d);
SentinelAlertRules_CL
| where properties_severity_s != "" and properties_status_s == "Available" and properties_lastUpdatedDateUTC_t > timeframe
| summarize arg_max(TimeGenerated, *) by properties_displayName_s
| extend type=case(properties_lastUpdatedDateUTC_t == properties_createdDateUTC_t,"Add","Update")
| where type == "Add"
| project ruleName=properties_displayName_s, ruleId=name_g, version=properties_version_s, lastUpdateDateUTC=properties_lastUpdatedDateUTC_t, createdDateUTC=properties_createdDateUTC_t, severity=properties_severity_s, kind_s, type, TimeGenerated
更新
let timeframe = ago(1d);
SentinelAlertRules_CL
| where properties_severity_s != "" and properties_status_s == "Available" and properties_lastUpdatedDateUTC_t > timeframe
| summarize arg_max(TimeGenerated, *) by properties_displayName_s
| extend type=case(properties_lastUpdatedDateUTC_t == properties_createdDateUTC_t,"Add","Update")
| where type == "Update"
| project ruleName=properties_displayName_s, ruleId=name_g, version=properties_version_s, lastUpdateDateUTC=properties_lastUpdatedDateUTC_t, createdDateUTC=properties_createdDateUTC_t, severity=properties_severity_s, kind_s, type, TimeGenerated

おまけ

表示されたruleIDはsigmaファイルのIDとなるため、リポジトリでsigmaファイルを検索し確認すれば更に詳細情報を取得することが可能である。

以下のツールを使えばSigmaファイルの特定が楽にできる。

参考記事

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?