Azure portalのMicrosoft Sentinelでのインシデント タスクの変更を監査および追跡する

インシデント タスク は、すべての SOC 担当者全体でインシデントを包括的かつ一様に処理します。 タスク リストは、通常、上級アナリストまたは SOC マネージャーによって行われた決定に従って定義され、オートメーション ルールまたはプレイブックを使用して実際に実施されます。

アナリストは、インシデントの詳細ページで特定のインシデントに対して実行する必要があるタスクの一覧を確認し、完了したタスクを完了としてマークすることができます。 アナリストは、インシデント内から直接、その場で手動で独自のタスクを作成することもできます。

この記事では、SOC マネージャーとして、タスクの割り当ての有効性と SOC の効率と適切な機能への貢献度を測定するために、Microsoft Sentinelインシデント タスクの履歴を監査し、ライフサイクル全体で行われた変更を追跡する方法について説明します。

SecurityIncident テーブル内の Tasks 配列の構造

SecurityIncident テーブルは監査テーブルであり、インシデント自体ではなく、インシデントの作成とそれに加えられた変更の有効期間の記録が格納されます。 インシデントが作成されたり、インシデントに変更が加えられたりするたびに、インシデントの現在の状態を示すレコードがこのテーブルに生成されます。

SecurityIncidentテーブルのスキーマにタスク詳細フィールドを追加することで、タスクをより深く監査することが可能になります。

[タスク] フィールドに追加される詳細情報は、次の構造を取るキーと値のペアで構成されます。

キー 値の説明
createdBy タスクを作成した ID:
- 電子メール: ID のメール アドレス
- name: ID の名前
- objectId: ID の GUID
- userPrincipalName: ID の UPN
createdTimeUtc タスクが作成された時刻 (UTC)。
lastCompletedTimeUtc タスクが完了とマークされた時刻 (UTC)。
lastModifiedBy タスクを最後に変更した ID:
- 電子メール: ID のメール アドレス
- name: ID の名前
- objectId: ID の GUID
- userPrincipalName: ID の UPN
lastModifiedTimeUtc タスクが最後に変更された時刻 (UTC)。
status タスクの現在の状態: 新規、完了、削除済み。
Taskid タスクのリソース ID。
title 作成者によってタスクに指定されたフレンドリ名。

SecurityIncident テーブルでインシデント タスクを表示する

[インシデント タスク] ブックとは別に、ログSecurityIncident テーブルに対してクエリを実行することで、タスク アクティビティを監査できます。 このセクションでは、テーブルをクエリし、結果を読み理解してタスク活動情報を得る方法を示します。

  1. [ ログ ] ページで、クエリ ウィンドウに次のクエリを入力して実行します。 このクエリは、タスクが割り当てられているすべてのインシデントを返します。

    SecurityIncident
    | where array_length( Tasks) > 0
    

    クエリに任意の数のステートメントを追加して、結果をフィルター処理して絞り込むことができます。 結果の見方と理解の仕方を示すために、特定の 1 件のインシデントのタスクだけが表示されるよう、結果をフィルター処理するステートメントを追加します。また、目的に役立つフィールドだけを、余計な情報を省いて表示できるように、project ステートメントも追加します。

    詳細については、「Kusto 照会言語の概要」を参照してください。

    SecurityIncident
    | where array_length( Tasks) > 0
    | where IncidentNumber == "405211"
    | sort by LastModifiedTime desc 
    | project IncidentName, Title, LastModifiedTime, Tasks
    
  2. このインシデントの最新のレコードを見て、それに関連付けられているタスクの一覧を見てみましょう。

    1. クエリ結果の先頭行の横にあるエキスパンダーを選択します (これは降順で並べ替えられています)。

      タスクを含むインシデントを示すクエリ結果のスクリーンショット。

    2. [タスク] フィールドは、このインシデントのすべてのタスクの現在の状態の配列です。 展開ツールを選択して、配列内の各項目を独自の行に表示します。

      タスクが展開されたインシデントを示すクエリ結果のスクリーンショット。

    3. これで、このインシデントに 2 つのタスクが存在することがわかります。 それぞれは、展開可能な配列によって順番に表されます。 1 つのタスクのエキスパンダーを選択して、その情報を表示します。

      1 つのタスクが展開されたインシデントを示すクエリ結果のスクリーンショット。

    4. ここでは、配列内の最初のタスクの詳細が表示されます ("0" は配列内のタスクのインデックス位置です)。 タイトル フィールドには、インシデントに表示されるタスクの名前が表示されます。

リストに追加されたタスクを表示する

以下の手順を実行してインシデントにタスクを追加し、 SecurityIncident レコードがどのように変化するかを観察してください。

  1. インシデントにタスクを追加し、ここに戻り、クエリをもう一度実行し、結果の変更を確認します。

    1. [インシデント] ページ 、[検索] バーにインシデント ID 番号を入力します。

    2. インシデントの詳細ページを開き、ツール バーから [タスク ] を選択します。

    3. 新しいタスクを追加し、「このタスクはテスト タスクです」という名前を付けて、[ 保存] を選択します。 次に示す最後のタスクは、最終的には次のようになります。

      [インシデント タスク] パネルを示すスクリーンショット。

  2. では、 ログ ページに戻り、再度 SecurityIncident クエリを実行しましょう。

    結果では、この同じインシデントの 新しいレコードがテーブルに 表示されます (タイムスタンプに注意してください)。 レコードを展開すると、前に見たレコードに Tasks 配列に 2 つのタスクが含まれているのに対し、新しい タスク には 3 つのタスクが含まれていることがわかります。 最新のタスクは、タイトルからわかるように、追加したタスクです。

    新しく作成されたタスクを含むインシデントを示すクエリ結果のスクリーンショット。

タスクの状態の変更を表示する

次に、インシデントの詳細ページで "This task is a test task!" というタイトルのタスクに戻り、完了としてマークした後、 ログ に戻ってクエリをもう一度再実行すると、同じインシデントの新しいレコードが表示され、今回はタスクの新しい状態が [完了] と表示されます。

新しい状態のインシデント タスクを示すクエリ結果のスクリーンショット。

タスクの削除を表示する

インシデントの詳細ページのタスク リストに戻り、「このタスクはテスト タスクです」というタイトルのタスクを削除しましょう。

Logsに戻ってインシデントタスククエリを再実行すると、別の新しいレコードが表示されます。今回はタスクの状態で、「このタスクはテストタスクです!」というタイトルのものです。—は削除される。

ただし、タスクが配列に 1 回出現すると (削除済み状態)、SecurityIncident テーブル内のそのインシデントの新しいレコードの Tasks 配列に表示されなくなります。 この事件の既存の記録は、この任務がかつて存在した証拠を引き続き保存し続けるでしょう。

閉じたインシデントに属するアクティブなタスクを表示する

次のクエリを使用すると、インシデントが閉じられたが、割り当てられたタスクがすべて完了していないかどうかを確認できます。 この情報は、調査に残っている未解決事項がきちんと解決されたこと、つまり、すべての関係者に通知が行われ、すべてのコメントが記録され、すべての回答が確認されるなどしたことを確認するのに役立ちます。 クエリは arg_max 集約関数を用いて、各インシデントとタスクごとに最新のレコードのみを返すため、結果は最新の状態を反映します。

以下のクエリを実行して、各インシデントの最新レコードを取得し、クローズ済みのインシデントをフィルタリングし、まだ完了または削除されていないタスクを返します。

SecurityIncident
| summarize arg_max(TimeGenerated, *) by IncidentNumber
| where Status == 'Closed'
| mv-expand Tasks
| evaluate bag_unpack(Tasks)
| summarize arg_max(lastModifiedTimeUtc, *) by taskId
| where status !in ('Completed', 'Deleted')
| project TaskTitle = ['title'], TaskStatus = ['status'], createdTimeUtc, lastModifiedTimeUtc = column_ifexists("lastModifiedTimeUtc", datetime(null)), TaskCreator = ['createdBy'].name, lastModifiedBy, IncidentNumber, IncidentOwner = Owner.userPrincipalName
| sort by lastModifiedTimeUtc desc

この記事の例クエリで使われているKusto演算子や関数の詳細については、以下をご覧ください:

KQL の詳細については、「Kusto 照会言語 (KQL) の概要」を参照してください。

その他のリソース:

次の手順