Aaron Jewitt

Kibanaケースによる検出チューニングリクエストの自動化

Elastic Security で検出ルールの調整リクエストを自動化する方法を学びます。このガイドでは、ケースにカスタム フィールドを追加する方法、チューニングのニーズを検出するためのルールを作成する方法、Webhook を使用してアナリストと検出エンジニアの間で摩擦のないフィードバック ループを作成する方法を説明します。

20分で読めます有効化
Kibanaケースによる検出チューニングリクエストの自動化

Elastic Securityによる検出チューニングリクエストの自動化

Elastic では、Infosec チームが「顧客ゼロ」です。当社では、組織のセキュリティ確保のために最新バージョンの Elastic 製品を広範に使用しており、これにより、現実世界のセキュリティ課題を解決する方法について独自の洞察が得られます。セキュリティ オペレーション センター (SOC) の効率を向上した方法の 1 つは、アナリストがKibana Casesから 1 回のクリックで直接検出チューニング リクエストを開くことができる、シームレスで自動化されたワークフローを作成することです。

どの SOC でも、セキュリティ アナリストと検出エンジニア間のフィードバック ループは、健全で効果的なセキュリティ体制を維持するために重要です。最前線のアナリストは、検出ルールが現実世界でどのように機能するかを最初に確認します。どのアラートが価値があり、どのアラートがノイズが多く、どのアラートを少し調整すれば改善できるかがわかります。ノイズの多いアラートによるアラート疲労により、真に陽性のアラートを見逃すリスクが高まります。陽性に対応するには、誤検出を迅速に調整することが重要です。このアラート フィードバックを効率的に取得することは困難な場合があります。メールの送信、チケットのオープン、ダイレクト メッセージなどの手動プロセスは一貫性がなく、時間がかかり、追跡が困難になる可能性があります。

Elastic Security を使用すると、アナリストは Kibana の新規または既存のケースにアラートを添付して調査を実施し、カスタマイズと自動化により、 Kibana Casesから 1 回のクリックで直接チューニング リクエストを開始できます。この記事では、この自動化をどのように構築したか、そして同様のシステムを実装してフィードバック ループを閉じ、検出および対応プログラムを最適化する方法について説明します。

Kibana Casesのカスタムフィールド

カスタム フィールドは、 Kibana Cases内のこの自動化の重要なコンポーネントです。これらのカスタム フィールドを使用すると、アナリストがすでに使用しているツールから必要な情報を直接取得できます。これらのカスタム フィールドはすべての新規および既存のケースに表示され、アナリストが検出をレビュー用にフラグ付けするための明確で一貫した方法を提供します。

注: ケースにカスタム フィールドを追加する機能は、バージョン 8.15 で導入されました。詳細については、 Cases の公式ドキュメントを参照してください。

すべての Kibana ケースは、専用の Elasticsearch インデックス.kibana_alerting_casesに保存されるドキュメントです。つまり、Elastic の他のデータ ソースと同様に、すべてのケース データをクエリ、集計、自動化に利用できるようになります。各ケース ドキュメントには豊富な情報が含まれていますが、メトリックと自動化に特に役立つフィールドがいくつかあります。cases.statusフィールドは、ケースがオープン、進行中、または終了しているかどうかを追跡し、 cases.created_atcases.updated_atは、平均解決時間 (MTTR) などのメトリックを計算するために重要なタイムスタンプを提供します。cases.severitycases.ownerなどのフィールドを使用すると、メトリックを細かく分析して、チームのパフォーマンスを確認できます。このブログにとって最も重要なのは、 cases.custom_fieldsオブジェクトに、設定したカスタム フィールドの配列が含まれていることです。ランタイム フィールドを使用すると、カスタム フィールドの配列を解析して、ワークフローをトリガーするクエリ、ダッシュボード、視覚化、検出ルールを構築できます。

リクエストの調整以外にも、カスタム フィールドはメトリックの追跡やケースの充実化に非常に役立ちます。たとえば、解決に 1 時間以上かかるケースにフラグを設定するための「複雑なケース」カスタム フィールドがあり、調査時間を短縮するために、より優れた調査ガイドや自動化が必要なルールを特定するのに役立ちます。また、 「検出ルール有効」「True Positive Alert」などのカスタム フィールドを使用して、ルールのパフォーマンスと忠実度に関する詳細なフィードバックを収集し、Kibana で強力なダッシュボードを構築して SOC の運用効果を視覚化できるようにしています。

ケース情報のデータ ビューをまだ作成していない場合は、ケースでランタイム フィールドとデータ視覚化を使用する場合は、データ ビューを作成する必要があります。

インデックス パターンに移動します。Kibanaで、[スタック管理] > [データ ビュー] に移動し、[新しいデータ ビューの作成] をクリックします。

.kibana_alerting_casesシステム インデックスをマップするようにデータ ビューを構成します。これを許可するには、 「隠しインデックスとシステムインデックスを許可する」ボタンをクリックする必要があります。タイムスタンプ フィールドでは、ケースが最新のアクティビティによって表示されるようにcases.updated_atフィールドを使用することをお勧めします。

カスタムフィールドの作成

カスタム フィールドには、自由形式の入力用のTextフィールドと、単純なはい/いいえのフィードバック用のToggleフィールドの 2 種類があります。チューニング リクエストの自動化では、それぞれ 1 つを使用します。テキスト フィールドは、アナリストからの追加フィードバックを取得するために使用されるオプション フィールドであり、トグル フィールドは自動化をトリガーするために使用されます。

Kibana で、「セキュリティ」>「ケース」に移動し、右上の「設定」をクリックします。設定ページには、必要な新しいフィールドを追加できるカスタム フィールドセクションが表示されます。フィールドはケース UI にアルファベット順に表示されるため、フィールドの先頭に数字を付けて、希望どおりの順序を維持します。

新しいカスタム フィールドを作成できます。UI に追加されたラベルはアナリスト専用であり、ケース インデックスには保存されません。これらには任意の値を設定できます。

カスタム フィールドの追加:このワークフローには 2 つのフィールドが必要です。

  • フィールド1:チューニング必須の切り替え
    • これは、アナリストがチューニング要求を開始するためにクリックするボタンになります。

      • ラベル: Open tuning request?
      • タイプ:トグル
      • デフォルト値:オフ
    • フィールド2:チューニングリクエストの詳細

      • このフィールドを使用すると、アナリストは、例外の追加、重大度の引き下げ、クエリ ロジックの調整など、変更が必要な内容に関する具体的な詳細を提供できます。
      • Name: Tuning request detail
      • タイプ:テキスト
    • デフォルト値:オフ

ランタイムフィールドを使用してカスタムフィールドをマッピングする

Kibana Cases でカスタム フィールドを操作する際の課題は、 cases.custom_fieldsフィールドがオブジェクトの配列としてマップされ、各オブジェクトが名前と値を持つカスタム フィールドを表すことです。この構造により、KQL で特定のカスタム フィールドを直接クエリすることが難しくなります。たとえば、単純にcases.custom_fields.open_tuning_request : "true"のようなクエリを使用することはできません。これを克服するには、ランタイム フィールドを使用してカスタム フィールドを解析およびクエリすることができます。

ランタイム フィールドは、クエリ時に評価されるフィールドです。データのインデックスを再作成することなく、新しいフィールドを即座に作成できます。.kibana_alerting_casesインデックスにランタイム フィールドを定義すると、簡単なスクリプトを使用してcases.custom_fields配列を解析し、必要な値を新しい簡単にクエリ可能なフィールドに抽出することができます。

このワークフローでは、上記で作成したカスタム フィールドにマップされる 2 つのランタイム フィールドを作成します:
* TuningRequired : 「チューニング要求を開く」トグルがオンの場合にtrueになるブールフィールド。
* TuningDetail : 「チューニング要求の詳細」フィールドからのアナリストのコメントが含まれるテキスト フィールド。

ランタイム フィールドを作成する前に、まず Kibana が各カスタム フィールドに割り当てる一意の ID ( key ) を識別する必要があります。現在、UI でこの ID を表示する簡単な方法はありません。これを見つけるために、次の回避策を使用しました。

  1. フィールドを作成します。他のカスタム フィールドを使用している場合は、新しいフィールド キーを識別しやすくするために、カスタム フィールドを一度に 1 つずつ作成する必要があります。上記の 2 つのフィールドしかない場合は、テキストまたはトグルのいずれかであるtype値を使用してそれらを区別できます。
  2. 新しいケースを作成します。フィールドを追加した後、Kibana でテスト ケースを作成し、説明フィールドにデータを追加し、チューニング必須フィールドを true に切り替えて、他のすべてのカスタム フィールドを false または空白に設定しました。
  3. ケース文書を検査します。次に、Discover に移動し、 .kibana_alerting_casesインデックスをクエリして、新しいケースのドキュメントを検索しました。ドキュメントのソース内のcases.customFields配列を調べると、新しいカスタム フィールドに関連付けられたkeyを見つけることができます。ランタイム スクリプトで使用されるkeyフィールドの値を保存します。

cases.customFieldsデータは次のようにフォーマットされます:

  [
    {
      "key": "4537b921-3ca4-4ff0-aa39-02dd6a3177bd",
      "type": "text",
      "value": "This alert is too noisy"
    },
    {
      "key": "cdf28896-c793-43d2-9384-99562e23a646",
      "type": "toggle",
      "value": true
    }
  ]

ランタイムフィールドの作成

ランタイム フィールドは、Kibana UI または Dev Tools コンソールの Elasticsearch API を使用して追加できます。ケース情報のデータ ビューをまだ作成していない場合は、最初にそれを作成する必要があります。

新しい Kibana Cases データ ビューを表示しているときに、「フィールドの追加」ボタンをクリックしてフライアウト メニューを開き、新しいランタイム フィールドを作成します。

フィールドの名前を入力します。この例では、 TuningRequired新しいブール型フィールド タイプとして構成しています。「値の設定」トグルをクリックして、これを、簡単なスクリプトで構成された新しいランタイム フィールドとして構成します。この簡単なスクリプトを更新して、 TUNING_REQUIRED_FIELD_KEY_UUID 「チューニングが必要」カスタム フィールドのkey値に置き換え、それを値フィールドに貼り付けて、新しいランタイム フィールドを保存します。

...
    if (params._source.containsKey('cases') &&
    params._source.cases != null &&
    params._source.cases.containsKey('customFields') &&
    params._source.cases.customFields != null) 
{
  for (def cf : params._source.cases.customFields) {
    if (cf != null &&
        cf.containsKey('key') &&
        cf.key != null &&
        cf.key.contains('TUNING_REQUIRED_FIELD_KEY_UUID') &&
        cf.containsKey('value') &&
        cf.value != null) {
      emit(cf.value);
      break;
    }
  }
}

このプロセスをTuningDetailフィールドに対して繰り返します。このフィールドの painless スクリプトでは、テキスト フィールドのkey値を使用することを忘れないでください。ダッシュボードやメトリックに使用したい追加のカスタム フィールドがケース内に存在する場合、それらも同じプロセスでマップできます。

クラスター設定とデータ ビューを「コードとして」制御する場合は、Kibana Dev Tools コンソールから更新マッピング API を使用して、ランタイム フィールドをインデックス マッピングに追加することもできます。

チューニングリクエストの作成を自動化する

この自動化は、カスタム検出ルール (チューニング リクエストでケースが更新されたときに新しいアラートを作成してコネクタに送信する) を使用する方法と、API をクエリするスケジュールされた外部自動化を使用する方法の 2 つの方法でトリガーできます。

この自動化は、Tines、Github Actions、カスタム スクリプトなどの任意の自動化プラットフォームを使用して作成できます。これは自動化に使用するロジックです。

ステップ1: 最近タグ付けされたケースを検索する TuningRequired

この elasticsearch クエリを使用すると、過去 1 時間以内に更新され、 TuningRequiredフィールドがtrueに設定されているケースを見つけることができます。このクエリは、 cases.updated_atフィールドを時間範囲として使用します。カスタム フィールドをクエリするには、API リクエストにランタイム フィールド マッピングを含める必要があります。

このクエリは、過去 1 時間以内に更新され、 TuningRequiredフィールドがtrueに設定されている.kibana_alerting_casesインデックスのすべてのケース ドキュメントを返します。

POST /.kibana_alerting_cases/_search  
{  
  "query": {  
    "bool": {  
      "must": [],  
      "filter": [  
        {  
          "bool": {  
            "should": [  
              {  
                "match": {  
                  "TuningRequired": true  
                }  
              }  
            ],  
            "minimum_should_match": 1  
          }  
        },  
        {  
          "range": {  
            "cases.updated_at": {  
              "format": "strict_date_optional_time",  
              "gte": "now-1h",  
              "lte": "now"  
            }  
          }  
        }  
      ],  
      "should": [],  
      "must_not": []  
    }  
  },  
 "runtime_mappings": {  
   "TuningDetail": {  
     "type": "keyword",  
     "script": {  
       "source": "if (\nparams._source.containsKey('cases') &&\nparams._source.cases != null &&\nparams._source.cases.containsKey('customFields') &&\nparams._source.cases.customFields != null\n) {\nfor (def cf : params._source.cases.customFields) {\nif (\ncf != null &&\ncf.containsKey('key') &&\ncf.key != null &&\ncf.key.contains('6cadc70a-7d68-4531-9861-7d5bc24c4c1c') &&\ncf.containsKey('value') &&\ncf.value != null\n) {\nemit(cf.value);\nbreak;\n}\n}\n}"  
     }  
   },  
   "TuningRequired": {  
     "type": "boolean",  
     "script": {  
       "source": "if (\nparams._source.containsKey('cases') &&\nparams._source.cases != null &&\nparams._source.cases.containsKey('customFields') &&\nparams._source.cases.customFields != null\n) {\nfor (def cf : params._source.cases.customFields) {\nif (\ncf != null &&\ncf.containsKey('key') &&\ncf.key != null &&\ncf.key.contains('496e71f2-2bce-47a2-93a8-00db0de2d1b4') &&\ncf.containsKey('value') &&\ncf.value != null\n) {\nemit(cf.value);\nbreak;\n}\n}\n}"  
     }  
   }  
 },  
  "fields": [  
    "TuningDetail",  
    "TuningRequired"  
  ]  
}

フィールドが変更されたり、ケースにコメントが追加されたりすると、 updated_atフィールドが現在の時刻に更新されます。ケースに更新やコメントが追加されるとこのタイムスタンプが更新されるため、ケースの更新中にこの自動化を定期的に実行すると、1 つのケースが複数回返される可能性があります。このシナリオで同じケースが複数回処理されるのを防ぐため、これに使用される自動化プロセスには重複排除プロセスが必要です。

ステップ2: 各ケースの解析

前のクエリによって返された各ケースをループして、一度に 1 つずつ処理します。返される各ドキュメントには、カスタム フィールドの値とその他の便利なフィールドを含むfields配列が含まれます。次の各フィールドを解析し、将来使用するために保存します。

  • _idフィールドはcases:{{case_ID}}のような形式になります。ケース ID は、自動化における今後の API リクエストで、ケースにコメントを追加したり、ケースに添付されたすべてのアラートを取得したりするために使用されます。
  • cases.title 事件のタイトルは
  • cases.assignees ケースが誰に割り当てられているか
  • cases.updated_by ケースを最後に更新する人物であり、チューニング リクエストを送信する人物であることが多く、詳細情報を取得するために誰に連絡すればよいかを知るのに役立ちます。
  • cases.tags タグを使用してケースを並べ替えたり識別したりする場合に役立ちます。

ステップ3: ケースに添付されたアラートを取得する

それぞれのケースについて、どのアラートがケースに添付されているかを把握し、どのアラートを調整する必要があるかを把握する必要があります。これは、ケースの_idフィールドを指定したケース APIを使用して実行できます。

/api/cases/{caseId}/alerts

このクエリは、ケースに関連付けられているすべてのアラートid値の配列を返します。この ID 値を使用して、 .siem-signals* elasticsearch インデックスをクエリし、調整が必要なケースに添付された各アラートの完全な情報を見つけることができます。

POST /.siem-signals-*/_search  
{  
 "size": 1,  
 "query": {  
   "bool": {  
     "must": [],  
     "filter": [  
       {  
         "bool": {  
           "should": [  
             {  
               "match": {  
                 "_id": "{{alert_id}}"  
               }  
             }  
           ],  
           "minimum_should_match": 1  
         }  
       },  
       {  
         "range": {  
           "@timestamp": {  
             "format": "strict_date_optional_time",  
             "gte": "now-30d",  
             "lte": "now"  
           }  
         }  
       }  
     ],  
     "should": [],  
     "must_not": []  
   }  
 }  
}

このクエリの結果から、名前や作成日などのアラートに関する情報や、 user.nameフィールドやprocess.nameフィールドなどのチューニングに役立つその他の情報を抽出できます。ケースには多くのアラートが関連付けられる可能性があるため、 signal.rule.name値でアラートの重複を排除する必要があります。

ステップ 4: チューニング リクエストを開きます。

この手順は、環境内で使用しているチケット システムによって異なります。私たちのチームでは、チューニングリクエストを追跡するために github の問題を使用し、通知には slack を使用していますが、自動化をサポートするチケット管理システムやプロジェクト管理システムでも同様のことができます。

これは、チューニング リクエストを追跡するために Github と Slack の両方を使用する自動化に使用するロジック フローです。

  • アラートの名前を使用して、既存のオープンチューニング要求を検索します。
    • 既存のチューニングリクエストが存在する場合は、そのリクエストをケースの詳細と新しいリクエストで更新します。
    • 既存のリクエストが存在しない場合は、新しいチューニングリクエストの問題を開き、情報を添付します。
  • 次に、チューニング リクエストへのリンク、ケースへのリンク、リクエストとアラートの詳細を含む Slack 通知を検出エンジニアリング チームの Slack チャネルに送信します。
  • 次に、 Cases APIを使用して、チューニングリクエストの問題へのリンクを含むコメントを元のケースに追加します。
  • オプションの AI エージェント: AI エージェントを使用してアラートとケース情報を分析し、チューニング要求にさらに適切なコンテキストを提供して、検出ルールの変更を推奨するなどの実験を開始しています。

この自動化の最終結果として、SOC アナリストはケースから 1 回のクリックで詳細な検出調整リクエスト チケットを作成できるようになります。この自動化により、誤検知の削減と検出ルールの全体的な効率が劇的に向上しました。

まとめ

カスタム フィールドを備えた Kibana Cases を使用し、自動化プラットフォームと統合することで、多くの手動プロセスを最適化できます。この自動化されたワークフローにより、アナリストのフィードバックの収集に関連する手動のオーバーヘッドが削減され、アナリストの貴重な洞察が検出ルールの実用的な改善に迅速に変換されます。その結果、新たな脅威に迅速に適応し、アラート疲労を軽減できる、より効率的で正確かつ回復力のある SOC が実現します。

SOC の効率を最適化し、検出体制を改善する準備はできていますか?Elastic Security を詳しく調べて、今すぐ独自の自動チューニング リクエスト ワークフローの構築を始めましょう。

この記事を共有する