ElasticとTinesによる自動化されたSIEM調査で誤検知を削減

SOCチームが直面する最大のSIEM管理上の問題の1つは、誤検知に圧倒されることが多く、それがアナリストの疲労や可視性のギャップにつながっていることです。それに加えて、セキュリティにおける最大の課題の1つは、誤検知の問題を増やすことなく、SaaSのアクセストークンが侵害されたことを検出することです。
Elasticでは、InfoSecチームがTinesのようなツールを使用してSIEMアラートの調査を自動化することで、これら両方の課題に取り組んでいます。このブログ記事では、私たちがどのようにワークフローを効率化し、誤検知を削減し、アナリストが真の脅威に集中できるようにしたかを紹介します。
SIEMアラートの初期調査の自動化
以前のブログ記事で、ElasticのInfoSecチームがユーザーおよびエンティティ行動分析(UEBA)を検出するルールパッケージを作成したことについて書きました。これらのアラートパッケージをより多くのデータソースに対応させるよう拡張する過程で、異常ではあるものの無害なアクティビティ(月に1回しか発生しないAPIトークンのアクティビティや、既知のスキャナーからのアクティビティなど)によって発生する大量の誤検知が、SOCアナリストの負担になっていることがわかりました。その結果、誤検知が多くノイズの多い検出ルールを作成するか、あるいはその検出を行わないことによる可視性のギャップを受け入れるかという問題に直面しました。誤検知の多いノイズの多い検出は、アナリストの疲労を招き、それ自体が可視性のギャップを生み出します。しかし、この問題から新しいアイデアが生まれました。アラートの初期調査を自動化し、既知の誤検知をクローズし、クローズできないものをエスカレーションできればどうだろうか、という考えです。
当社のSaaSプロバイダーおよびUEBA検出ルールの多くにおいて、管理対象ワークステーションなどの信頼できるデバイスからのアクティビティであれば、ルールをクローズできることがわかりました。初期調査プレイブックのアクションとして、多くの場合、元のアラートからsource.ipなどの情報を取得し、そのsource.ipについてElasticsearch内の他のインデックスパターンをクエリします。クエリの結果が返された場合、そのアラートは誤検知としてクローズできます。例えば、AWSシークレットキーのアクティビティに関するUEBAアラートが表示された場合、以下の一連のクエリを実行してアラートをトリアージし、そのアクティビティが信頼できるデバイスからのものかどうかを確認します:
ワークステーションまたはサーバーから、そのsource.ipを使用してElastic AgentがFleet Serverへの接続に成功したことを示すプロキシログはありますか?
そのsource.ipは、当社が管理・制御するAWS、GCP、またはAzureネットワークゾーンのいずれかのパブリックIP範囲に属していますか?
source.ip は、Okta、Terraform、Tines、Qualys、Snykなどの認定されたサードパーティ製アプリケーションに属していますか?
過去2時間以内に、その source.ip からのFIDO2シングルサインオン(SSO)ログインは成功しましたか?
これらの後続のElasticsearchクエリのいずれかが結果を返した場合、このAWS APIキーのアクティビティは承認されている可能性が高いと判断し、アラートをクローズできます。これらのクエリがすべてゼロ件の結果を返した場合、そのアクティビティは疑わしいと判断し、SOCチームのメンバーにエスカレーションして詳細な調査を依頼します。上記のすべてのElasticsearchクエリは_search APIを使用して実行でき、Signals APIを使用してアラートのクローズとタグ付けを行うことで、プロセス全体を自動化できます。
ElasticのSIEM**検出**をセキュリティオーケストレーション、自動化、対応(SOAR)システムに送信し、アラートアクション**特徴**を使用することで、SOARを活用して該当するすべてのアラートに対してこれらの調査クエリを自動的に実行できます。クエリの結果に基づいて、アラートを自動的にクローズするか、アナリストにエスカレーションすることができます。
この自動トリアージ機能により、SOC担当者を大幅に増員しなければ調査するにはノイズが多すぎるような、あらゆる種類の検出を作成できます。当社の自動ワークフローは現在、人間の介入なしに1日あたり3,000件以上のアラートをトリアージおよびクローズしています。経験豊富なアナリストが同じ方法でトリアージを行うには、アラート1件あたり15分以上かかります。この自動化なしで同じ検出を行うには、さらに94名のフルタイム従業員が必要になります。このチャートは、当社のSIEMにおける過去30日間のアラート数を示しています:

この自動トリアージワークフローはカスタムスクリプトを使用して作成することもできますが、本ブログでは Tines を使用してこの自動化を構築する方法を紹介します。Elasticの情報セキュリティチームがこの方法を採用しており、スクリプトよりも単純で簡単であるため、このアプローチを検討することにしました。Tinesを使用すれば、専任の開発チームがいなくても、自動化の構築や変更が容易に行えることがわかっています。
任意のSOARへのアラート送信
前述の通り、最初のステップは、アラートコンテンツをElastic Securityから任意のSOARソリューションに転送することです。これにはElastic SecurityのAlert Actions機能を使用します。この機能により、アラートがトリガーされるたびにカスタムアクションが実行されます。
検出ルールを設定する際、ルールアクションを追加するオプションがあります。ここから、目的のコネクタタイプを選択できます。

アラートをTinesに送信する最も簡単な方法は、Elasticに搭載のTinesコネクタを設定して使用することです。これにより、アラートが処理のためにTinesストーリーへ送信されます。
もう1つの選択肢は、Webhookコネクターを使用することです。これは非常に柔軟性が高く、アラートの一部または全体をndjson形式でWebhookリスナーに送信できます。ElasticではTinesコネクターが存在する以前から社内でTinesを使用しており、現在も自動化の大部分でWebhookコネクターを使用しています。アラートは1つずつWebhookに送信することも、まとめて1つのndjsonとして送信することも可能です。カスタムスクリプトを使用している場合は、このコネクターを使用してアラートを受信・処理できます。また、Tines Webhookアクションとも連携します。アラートの全内容をWebhookに送信するには、Webhookコネクターを設定し、POSTアクションを使用してコンテンツタイプをapplication/x-ndjson; charset=utf-8に設定する必要があります。

ルールにアクションを追加する際は、構成済みのWebフックコネクターを選択し、構成内で以下のmustache構文を使用して、アラート全体をndjsonとしてWebフックに送信します。

タグを使用した自動化のルーティング
これらの自動化を構築する際、最初は各アラートに対して個別にカスタム自動化パスを作成していましたが、すぐにスケールしないことが判明しました。これに対する解決策として、検出ルールにカスタムタグを使用して、ルールを適切なトリアージパスにルーティングすることにしました。Tinesにはアラート全体を送信しており、これにはsignal.rule.tagsフィールドの配列としてタグが含まれています。ルールに対してどの自動チェックを実行するかを記述するために、Triage:{option}という命名規則を使用することにしました。検出ルールには、複数の異なるタグを設定できます。

私たちが使用している自動トリアージタグの説明は以下の通りです。
トリアージ:すべて は、アセット、PMFA、ワークステーションの自動トリアージパスを通じてアラートをルーティングし、いずれかのクエリがtrueを返すとアラートがクローズされます。どのクエリもtrueを返さない場合、アラートはエスカレーションされます。
トリアージ:アセットは、さまざまなインデックスパターンをチェックし、ソースIPがElasticが所有または何らかの形で管理しているアセットからのものかどうかを判断します。これには、Elasticに格納している社内のアセットデータベース、社内ネットワークゾーン、当社のElastic CloudパブリックIP、CI/CDシステム、およびOktaやTinesなどの認定されたサードパーティシステムのパブリックIPスペースが含まれます。
トリアージ:PMFA は、Okta VerifyやWindows Helloを使用したパスキーなど、フィッシング耐性のあるMFAを使用した認証の成功について、Okta監査ログを確認します。Okta監査ログの収集には、Okta統合を使用します。
トリアージ:ワークステーションは、IPアドレスからElastic Defendへの接続が成功したかどうかを、Nginxプロキシログで確認します。Elasticは分散型の企業であり、従業員は世界中のどこからでも働けますが、Elastic Defendエージェントは定期的に接続しているため、通常はElasticの従業員が管理するワークステーションが、アラートを生成したのと同じIPから接続されていたことを確認できます。
Triage: New Employeeは、人事システムからエクスポートされた全従業員のレポートを毎日格納している資産データベースを確認し、ユーザーが新規従業員かどうかを判定します。これは、新規従業員がアカウントを設定する際にはトリガーされるものの、既存の従業員に対してはほとんどアラートを出さないSlack UEBAのような特定のカテゴリの検出ルールにおいて重要です。
トリアージ:1時間 は、残りのトリアージアクションを実行する前に、Tinesに対してアラートのトリアージを1時間一時停止するように指示します。これは、ユーザーが真新しいワークステーションを構成している場合など、Elastic Defendをインストールするエンドポイント管理システムにワークステーションが適切に登録されていればアラートを閉じることができるイベントに役立ちます。
トリアージ:24時間は、Tinesに対してアラートのトリアージを丸24時間一時停止してから処理するよう指示します。これは、すべてのコンピューター、ユーザー、クラウドアカウントのインベントリを毎日収集するアセットデータベースの一部など、データが1日1回しか更新されない一部のトリアージパスで必要になる場合があります。
トリアージ:カスタムは、アラートに対して必要となる可能性のあるカスタムトリアージパス用です。その好例として、Azureでのアカウント作成や無効化に使用される権限の高いAPIキーをOktaなどのサードパーティに提供し、そのAPIトークンがOktaに属さないIPアドレスから使用された場合にアラートを受け取りたいというシナリオが挙げられます。このアラートと自動トリアージにより、OktaによるAPIキーの保管が侵害され、OktaのIPスペース外で使用された場合に「信頼するが検証する(Trust but Verify)」ことが可能になります。
自動化のための構成要素
これで、完全なアラートをJSONとしてSOARに送信できるようになったため、トリアージパスを通じてSlackやPagerDutyなどの他のソースに送信できます。Tinesには、ストーリーの構築に使用できる7種類のアクションがあります。
Webhook アクションは、Webhook(HTTPコールバック)を通じて受信したイベントを発行します。これは、Tinesのストーリーにイベントを送信するための主要な方法です。
メール送信 アクションは、アクションオプションで指定された受信者にメールを送信します。
メール受信アクション (以前はIMAPアクションと呼ばれていました)は、IMAPサーバー上で新しいメールを検出したとき、または一意に生成されたメールアドレスにメールが送信されたときにイベントを発行します。
Event Transformation actionには、受信したイベントの内容を修正するいくつかのモードがあります。これらのアクションは非常に柔軟で強力です。
HTTP Requestアクションは、さまざまなメソッドを使用して指定されたURLにHTTPリクエストを送信します。
トリガー アクションは、受信したイベントのフィールドの内容を定義済みのルールと比較し、ルールが一致するとイベントの発行がトリガーされます。これは「If Then(もし〜なら)」ロジックアクションと考えることができます。
Send to Storyアクションは、イベントを別のTinesストーリー(サブストーリー)に送信します。サブストーリーがアクションを完了すると、Send to Storyアクションがイベントを発行します。Send to Storyアクションは、コード内の関数やライブラリと同様に、複数の場所でアクションを再利用したい場合に役立ちます。
これらのアクションを使用することで、毎月数千時間の作業を削減する自動化を構築できます。
自動化されたトリアージワークフローの簡略例:

この自動化ストーリーでは、Webhookに届く新しいアラートを処理し、イベント変換アクションを使用してndjsonをより簡単に参照できるオブジェクトに解析します。その後、トリガーアクションを使用して、そのアラートがどのトリアージパスに進むべきかを決定します。
HTTPリクエストアクションのほとんどは、Elasticsearch _search APIへのクエリです。これらの後続クエリでは、元の通知に含まれる source.ip や user.email といったフィールドを使用して、アラートのトリアージを行います。
Tinesには、Elasticsearchと連携するためのものを含め、数百もの事前構築済みアクションテンプレートが用意されています。 「Query an Elasticsearch index for all records」(Elasticsearchインデックスの全レコードをクエリ) テンプレートを使用し、アラートの送信元IPを使用してクエリを追加するようにペイロードを変更できます。ほとんどのクエリは特定の source.ip からの あらゆる イベントを検索するため、クエリの速度とパフォーマンスを向上させるために”size”: 1 オプションを追加することをお勧めします。これにより、Elasticsearchが過去4時間以内にsource.ipと一致する結果を見つけた場合に返されます。
{
"size": 1,
"query": {
"bool": {
"must": [],
"filter": [
{
"bool": {
"should": [
{
"match_phrase": {
"source.ip": "<<extract_source_ip.source_ip>>"
}
}
]
}
},
{
"range": {
"@timestamp": {
"format": "strict_date_optional_time",
"gte": "now-4h",
"lte": "now"
}
}
}
],
"should": [],
"must_not": []
}
}
}各クエリアクションの後には、結果が見つかったかどうかを確認するトリガーアクションがあります。ヒット数が0より大きい場合は、Signals APIを使用してアラートをクローズします。結果が0件の場合は、処理を継続して次のアクションに進みます。すべてのアクションで結果が0件だった場合は、Slackにアラートを送信し、アナリストに調査を通知します。
これは、クエリの結果を確認するトリガーアクションの設定例です:

Elasticsearchクエリを実行し、結果がある場合にアラートをクローズするというロジックを使用することで、これらのアクションをいくつか連鎖させ、既知の安全なIPアドレスからのアラートをクローズする包括的なストーリーを構築できます。
管理対象ワークステーションのトリアージ例
以下のストーリー分岐の例では、当社が管理するワークステーションまたはサーバーから発生したアラートをすべてクローズしています。Elasticは世界中に分散した企業であり、従業員の大多数が在宅勤務をしているため、従業員がどのIPアドレスからインターネットに接続するかを予測する方法がなく、多くの場合、パブリックIPアドレスは1日に何度も変更される可能性があります。世界中を移動するこれらのワークステーションのパブリックIPを確実に特定するための当社のソリューションは、情報セキュリティインフラの前面に配置されたNginxプロキシにElastic Agentをデプロイすることです。
このデータを使用することで、Elastic Agent、Auditbeat、またはEndgameのトラフィックをクラスターに送信するプロキシ経由の接続が成功したことを特定できるようになりました。当社のすべてのクラウドサーバーシステムにはAuditbeatまたはElastic Agentがインストールされているため、これらのクエリは、CI/CDおよびDevOpsパイプラインを実行するためにシークレットキーを定期的に使用するサーバーシステムのパブリックIPアドレスも検出します。
以下は、ソースIPから管理対象のワークステーションまたはサーバーを確認するために使用する、Tinesストーリー内のパスです。トリガーアクションから伸びる破線は、トリガーアクションがtrueを返さない場合にストーリーが流れるパスです。

クローズアラートの「ストーリーに送信」
お気づきかもしれませんが、アラートをクローズするたびに、Tinesの「Send to Story」アクションを使用しています。このアクションにより、選択したフィールドがWebhook経由でTinesの新しいストーリーに送信され、そこでアラートのクローズとタグ付けが行われます。「Send to Story」を使用することで、メインストーリーの保守が容易になります。また、シグナルIDによる重複排除などの機能を追加して、トリアージの異なる2つのブランチから同じアラートを二重にクローズしないようにしたり、スロットルアクションを使用して、大量のアラートが一度に発生した場合でもAPIに過度な負荷がかからないようにしたりすることが可能です。
また、Signals APIを使用してルールタグを更新しており、これはメトリクスやアラートのステータス追跡に役立ちます。自動トリアージワークフローでクローズしたすべてのアラートにはAutomated Triageというタグも付けられるため、月ごとのトリアージ済みアラート数を追跡し、SIEM UIでそのアラートが自動化によってクローズされたのか、アナリストによってクローズされたのかを簡単に確認できます。

オープンなアラートをSlackにエスカレーションする
アラートをさまざまな自動トリアージパスに並行して送信する一方で、処理を5分間一時停止するパスにもストーリーを送信します。この5分間の休止により、他のブランチが完了するまでの時間を確保し、信頼できる送信元IPからのものと判明したアラートをクローズできます。5分間の休止後、signals検索APIにリクエストを送信し、アラートがまだオープンかどうかを確認します。アラートがまだオープンな場合は、アラートが自動的にトリアージされなかったことをSOCアナリストに通知するため、アラート用のSlackチャンネルにメッセージを送信します。

このストーリーに機能を追加したい場合、Tinesならストーリーに別のブランチを作成して機能を追加するのも簡単です。例えば、重大または高緊急度のアラートを一定時間内に確認することを義務付けるSLAがある場合、1時間待機してからElastic SIEMでアラートが確認されたかどうかをチェックするロジックを追加できます。アラートがオープンなままで誰にも割り当てられていない場合は、PagerDutyにアラートを送信するか、別のチームに2通目のSlackメッセージを送信してエスカレーションできます。

Tinesには、Elastic Securityでケースを扱うためのテンプレートも含まれています。このブランチでいくつかのアクションを追加すれば、新しいケースを開き、オンコールのアナリストにアサインし、アラートの詳細をケースに追加することができます。
直面した課題
セキュリティに完璧なものは存在せず、どのようなセキュリティ制御であっても、脅威主体がそれを回避する方法は存在します。しかし、完璧ではないからといって、努力する価値がないわけではありません。明らかな弱点の1つは、これらのアラートが内部脅威に対して限定的な効果しか持たないことです。脅威主体が侵害されたワークステーション、サーバー、または企業のVPN接続を経由してピボットしている場合、既知の安全なIPアドレスからアクセスされる可能性があり、自動トリアージワークフローを持つルールではアラートが自動的にクローズされてしまいます。
それについては2つの主張があります。1つ目は、この自動化がなければ、これらの検出のほとんどは数百人の追加従業員なしではデプロイ不可能であるということです。弱点はあるものの、これらの自動化された検出は、ない場合よりも優れた可視性を提供します。トリアージされたアラートは脅威ハンティングに使用でき、ホストまたはユーザーに対する複数の異なる検出ルールでアラートを出す検出に含めることで、依然として価値を提供できます。
次に、脅威アクターの戦術変更を強制できれば(例えば、当社のワークステーションやサーバーを侵害して経由させるなど)、検出の可能性が劇的に高まります。当社のワークステーションとサーバーにはElastic Defendが高度に実装されており、1,000を超える検出ルールが設定されています。脅威アクターがSaaSの認証情報やAPIシークレットトークンを侵害する場合、そのほとんどは侵害されたホストを経由せず、自身のインフラから直接サービスに接続することが確認されています。
これらの検出を構築する際のもう一つの大きな課題は、シャドウITと、現代のITシステムにおける第三者との相互接続や信頼です。シャドウITとは、会社のチームが独自のITシステムをセットアップし、適切なルートを経ずに資産インベントリに追加し、Elastic AgentやAuditbeatをインストールしない場合を指します。
こうしたトリアージワークフローを構築し、「既知の安全なIP」を定義する際、自社に属さないIPアドレスからAPIトークンが承認された方法で使用されているケースが必然的に見つかることになります。これらのトークンは通常、GitHub Actionsなどのさまざまなサードパーティ製自動化ツールや、QualysやSnykといったスキャンアプリケーションによって使用されます。これらを追跡して例外を構築するには時間がかかる場合がありますが、シャドーITを特定して排除する上で非常に有益な作業となります。
Okta 、 GitHub 、または Elastic Cloud などのサードパーティプロバイダーは、パブリックIPスペースを公開している場合があり、それらのIPからのアクティビティを除外するための追加チェックを構築できます。Tinesクラウドテナントを使用している場合は、 https://<tenant-domain> /info からテナントの現在のパブリックIPを取得できます。
検出の例
これらの自動化は当初、単一の検出ルールのためのソリューションとして始まりましたが、多くの異なるシナリオにおいて非常に価値があることがわかりました。多くの検出ルールについて、「もしこのアラートが自社のものであると確認済みのIPアドレスによってトリガーされた場合、SOCはアラートをクローズするか?」と自問してみてください。サードパーティサービス向けの行動ベースの検出ルールのほとんどにおいてこれが当てはまることがわかっており、自動トリアージに適した候補となっています。
このワークフローで構築できる検出のアイデアとして、初期トリアージを自動化している検出のリストを以下に示します。これらの検出の一部は、この自動トリアージワークフローで動作するように構築されたカスタム検出ですが、その多くは、誤検知を排除するためにトリアージタグを追加した既存の検出です。
Oktaの高リスク認証
Okta以外のIPからのOktaサポートアクティビティ
新しいIPからのOkta APIアクティビティ
Okta UEBA:同一のメールアドレスとIPに対する複数の異なるアラート
Okta:単一のdtハッシュで複数のメールアドレスが確認されました
フィッシング耐性のあるMFAを使用しないOktaでのユーザーログイン成功
新規IPからのMFA除外アカウントによるOkta認証
Slack UEBA:Slackユーザーに対する複数の異なるアラート
新しいIPからのGCPポータルへのログイン
新しいIPからのGCP IAMアクティビティ
新しいIPからのBuildkite Webアクティビティ
新しいIPからのBuildkite APIアクティビティ
GitHub:GitHub PATに対する複数のUEBAアラート
GitHub:ユーザーによるプライベートリポジトリのクローンが急増
Hashicorp Vault:Vaultユーザーに対する複数のUEBAアラート
Azure Active Directoryの高リスク認証
新しいIPからのAzure Portalログイン
新しいIPからのAzure Active Directory PowerShellサインイン
Azure Active Directoryデバイスコード認証
MFAを使用しないAzure Active Directoryのログイン成功
新しいIPからのAWS IAMアクティビティ
AWSキーUEBA:AWSキーに対する複数の異なるアラート
AWSユーザーUEBA:AWSアカウントに対する複数の異なるアラート
新しいIPからのAWSコンソール認証
Microsoft 365 ユーザーアカウントへのブルートフォース攻撃の試み
新たなレベルの保護を実現
本ブログ記事では、Elastic情報セキュリティチームがTinesを使用して、多くのアラートの初期トリアージを自動化する方法を紹介しました。この自動化により、効率性を高めながら可視性を大幅に向上させることができ、真の脅威の調査に時間を割けるようになります。Tinesを使用することで、過去30日間で50,000件以上のアラートを完全に調査し、クローズすることができました。これらのアラートはすべて、トリガーされてから数秒以内に徹底的に調査され、クローズされました。これなしでは、ネットワークで同水準の保護を実現することは不可能です。
実際に試してみたい場合は、Elastic Cloudの14日間無料トライアルと、常に無料で利用できるTinesのコミュニティエディションを組み合わせて、これらのワークフローがどれほど強力かをご確認いただけます。
本記事に記述されているあらゆる機能ないし性能のリリースおよびタイミングは、Elasticの単独裁量に委ねられます。現時点で提供されていないあらゆる機能ないし性能は、すみやかに提供されない可能性、または一切の提供が行われない可能性があります。