ElasticとTinesの自動SIEM調査による誤検知削減

> この記事は Elastic 公式ブログ  
> 「[Reducing false positives with automated SIEM investigations from Elastic and Tines](https://www.elastic.co/blog/false-positives-automated-siem-investigations-elastic-tines)」  
> を日本語訳にしたものです。

---

セキュリティオペレーションセンター（SOC）が抱えるSIEM管理の大きな課題の1つに、膨大な誤検知によるアナリストの疲弊や、可視性の欠如が挙げられます。加えて、SaaSのアクセス トークンが侵害されたことを検知しようとすると、誤検知がさらに増えやすいという悩ましい問題もあります。

ElasticのInfoSecチームでは、[Tines](https://www.tines.com/)のようなツールを活用してSIEMアラートの初動調査を自動化し、こうした課題に対処しています。本記事では、ワークフローを効率化し、誤検知を削減し、本質的に重要な脅威に集中できるようにした取り組みを紹介します。

## SIEMアラートの初動調査を自動化する

先に[こちらのブログ記事](https://www.elastic.co/blog/detecting-account-compromise-ueba-detection-packages)で、Elastic InfoSecチームが[UEBA (User and Entity Behavior Analytics)](https://www.elastic.co/what-is/user-behavior-analytics)を活用したルールパッケージを作成した経緯を紹介しました。しかし、対応するデータソースを増やしていく中で、月に1回程度しか発生しないAPIトークンの動作や、スキャナーによるアクセスなど「異常だが実際には問題ない動き」による誤検知が多発し、SOCアナリストが処理しきれない状況になったのです。

「誤検知が多いルールをあえて作るか、それとも検知を入れない（可視性のギャップを許容する）か」というジレンマに直面した私たちは、新しいアプローチを考えました。それは、アラートが検知された際に最初の調査を自動化し、既知の誤検知を即座にクローズ、未知のものだけをエスカレーションする仕組みです。

実際、SaaSプロバイダやUEBAの多くのアラートは、アクティビティが「管理対象デバイス」由来の場合は問題ない（＝誤検知）と判断できます。たとえばアラートで `source.ip` が得られたら、Elasticsearch内の他のインデックスで `source.ip` を検索し、社内で管理されているワークステーション等のIPアドレスに該当すればクローズ、といった手順です。

例としてAWS Secret Keyに関するUEBAアラートがあった場合は、以下のようなElasticsearchクエリを自動的に実行します。

- プロキシログに、`source.ip` からElastic AgentがFleet Serverへ正常に接続している記録はあるか？  
- `source.ip` が自社管理ゾーン（AWS/GCP/Azureなどのネットワーク帯域）か？  
- `source.ip` がOktaやTerraformなど正規のサードパーティアプリケーションのものか？  
- 過去2時間以内に、その `source.ip` からFIDO2によるSSOログインが成功しているか？

1つでも該当する条件があれば、そのアクティビティは「正規の操作」とみなしてアラートをクローズします。すべて該当しなければ、SOCアナリストにエスカレーションします。これらのクエリはElasticsearchの[_search API](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-your-data.html)や[Signals API](https://www.elastic.co/guide/en/security/current/signals-api-overview.html#_set_alert_status)を利用して、自動で検索・クローズ・タグ付けなどを実行できます。

Elastic Securityの[Alert Actions](https://www.elastic.co/guide/en/security/current/rules-ui-create.html#rule-notifications)機能を使えば、SIEM検知をSOAR（[Security Orchestration, Automation, and Response](https://www.elastic.co/what-is/soar)）製品に転送し、上記の自動調査プロセスを実行させることが可能です。調査結果によって自動クローズかエスカレーションかを振り分けられます。

この自動トリアージによって、アラート量を劇的に増やしてもアナリストが疲弊することなく、より細かい検知を導入できます。実際にElastic社内では、一日あたり3,000件以上のアラートを無人でトリアージしクローズしています。人力なら1件15分程度かかるところですが、これに相当するには94名以上のフルタイムアナリストが必要になってしまいます。以下のグラフは、直近30日間のアラート数の一例です。

![30 days of alerts](https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc80752b0c3e4b095/66574c5386ba8b05c21d6fdd/1.png)

本記事では、Elasticが実際に使っている[Tines](https://www.tines.com/)を例に、自動化の構築手順を紹介します。カスタムスクリプトで同等のフローを構築することもできますが、Tinesを使うことで開発者を専属で用意しなくても、高度なSOARワークフローをGUIで簡単に組み立てられます。

---

## アラートを任意のSOARに送信する

最初のステップは、Elastic Securityが検知したアラート情報をSOARに送ることです。これにはElastic Securityの[Alert Actions](https://www.elastic.co/guide/en/security/current/rules-ui-create.html#rule-notifications)機能を利用します。

検知ルールを設定するとき、ルールアクション（Rule Action）として[コネクタ](https://www.elastic.co/guide/en/kibana/current/action-types.html)を追加できます。

![Rule action connector selection view](https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbd335a6577d14fc2/66574c76672d197ef5dc98e2/2.png)

Elasticでは、[Tinesコネクタ](https://www.elastic.co/guide/en/kibana/current/tines-action-type.html)を利用して簡単にアラートをTinesに送っていますが、汎用的には[Webhookコネクタ](https://www.elastic.co/guide/en/kibana/current/webhook-action-type.html)を使い、アラート内容をndjson形式でまとめて送信する方法もあります。Webhookコネクタを使う場合は、`POST` メソッドと `application/x-ndjson; charset=utf-8` を指定し、下記のようにMustache構文でアラート全体をndjsonにして渡します。

```plaintext
{{#context.alerts}}
{{{json}}}
{{/context.alerts}}
```

---

## タグを使った自動化ルーティング

自動化フローを構築する際、当初は個々のアラートに対して専用のパスを用意していたのですが、すぐにスケールしなくなりました。そこで採用したのが「ルールに付与するタグ」でルーティングを分ける方法です。

アラート全体がJSONでSOARへ送られる際、`signal.rule.tags` フィールドにタグ情報も含まれます。私たちは “`Triage:{オプション}`” という命名でタグを付け、アラートを該当するトリアージパスへ振り分けるようにしました。1つのルールに複数タグを付けることも可能です。

![Triage tags list](https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdc002f0fb1f8b370/66574e0c0d634752f87a08ea/5.png)

以下はElastic内部で主に使っているタグ例です。

- **Triage: All**  
  Asset（自社管理IPかどうか）、PMFA（フィッシング耐性MFAの利用）、Workstation（社内ワークステーション）など、複数の自動トリアージパスをすべて実行。いずれかに当てはまれば自動クローズ、なければエスカレーション。  
- **Triage: Asset**  
  自社管理しているAsset Database（[Elasticを使ったアセット管理例](https://www.elastic.co/blog/how-to-build-a-cybersecurity-asset-management-solution-on-the-elastic-stack)）、内部ネットワーク帯域、CI/CDシステム、OktaやTinesなどサードパーティの公開IPなどを参照し、`source.ip` が一致すればクローズ。  
- **Triage: PMFA**  
  [Oktaインテグレーション](https://docs.elastic.co/en/integrations/okta)で取得したログを参照し、FIDO2等の強力なMFAで認証済みかどうかを確認。  
- **Triage: Workstation**  
  Elastic Defendなどのエージェントがプロキシを通じてFleet Serverに定期的に接続するログを探し、`source.ip` が社内ワークステーションのものか確認。  
- **Triage: New Employee**  
  新入社員向けのSlack初期設定などで誤検知が多いケースを想定し、Asset Databaseに登録された社員リストをチェック。  
- **Triage: 1h / Triage: 24h**  
  一定時間（1時間または24時間）待ってから調査を開始するタグ。データベース更新が日次のものなどで有効。  
- **Triage: Custom**  
  サードパーティに提供している高権限APIキーの使用元IPをチェックするといったカスタム処理に利用。

---

## 自動化の構成要素（Tinesを例に）

JSON形式のアラートを受け取った後は、各トリアージパスを実行し、クローズあるいはSlackやPagerDutyなどへのエスカレーションを行います。Tinesでは以下7種類の[アクション](https://www.tines.com/docs/actions)を組み合わせて“ストーリー”を構築します。

1. **Webhook action**: Webhookからイベントを受信する。  
2. **Send Email action**: メール送信。  
3. **Receive Email action**: 新規メール受信をトリガにイベントを発火。  
4. **Event Transformation action**: 受信イベントを整形。非常に柔軟。  
5. **HTTP Request action**: 各種HTTPリクエストを送信。  
6. **Trigger action**: 受信データに対して条件分岐（If-Then）。  
7. **Send to Story action**: 別ストーリーを呼び出して戻り値を受け取る。

下図は簡略化した自動トリアージの一例です。

![Tines triage story](https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0a71ceeea0256272/66574ea96bf5e0163daf4dc7/6-2.png)

基本的な流れは、

1. Webhook actionでElasticからのndjsonデータを受け取る  
2. Event Transformation actionでndjsonをJSONオブジェクトに変換  
3. Trigger actionでタグなどを見て分岐  
4. HTTP Request actionでElasticsearchの[_search API](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-your-data.html)を叩き、ヒット数に応じてクローズか次のチェックへ  
5. すべてのチェックを通過しても怪しい場合はSlack通知やPagerDuty連携

### Elasticsearchクエリ例

たとえば「過去4時間の間に `source.ip` でヒットするドキュメントが1件でもあれば“既知のIP”とみなす」というクエリは以下のようになります。返ってきた `hits.total.value` が0より大きければ誤検知と判断できます。

```json
{
  "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": []
    }
  }
}
```

Trigger actionで、クエリ結果を見て「`hits.total.value > 0` ならクローズ」と条件分岐します。

### 管理対象ワークステーションの判定例

Elasticはリモートワーク文化が進んでおり、社員が世界中どこからでもログインするため、IPアドレスでの固定は困難です。そこで、Elastic DefendやAuditbeatの接続ログをNginx経由で収集し、常にエージェントがFleet Serverにアクセスしていれば「社内管理デバイス」と判断できるようにしています。

![Workstation story branch](https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9a7849d48544546d/66574e5fcb7d1802e465683a/8.png)

### クローズ処理用のSend to Story

チェックに合致したら、Signals APIを用いてアラートをクローズし、タグを付ける「クローズ処理」を行いますが、私たちはこれを個別のストーリー（サブフロー）に分けています。Send to StoryでサブフローにアラートIDなどを渡し、サブフロー内でクローズやタグ付けを一括で実行。二重クローズ対策やAPI呼び出しのスロットリングも併せて管理します。

![Close alert Send to Story](https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3334d819f041c24a/66574e753adef8fbbced18cb/9.png)

### アラートをSlackにエスカレーション

同時並行でいくつかのチェックを実行した後、少し待機（例: 5分）してまだアラートが「オープン」の状態なら、Slack通知でアナリストにエスカレーションを行うフローを設けています。

![Escalating open alerts to Slack](https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8c447ffae8327b82/66574e8d89ebe618400ac4b8/6.png)

さらに高度な要件があれば、このあとPagerDuty通知を追加したり、Elastic Securityの[Cases](https://www.elastic.co/guide/en/kibana/current/cases-api.html)機能と連携してケース管理を行うことも可能です。

![Escalating to PagerDuty](https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt23c0d72959744366/66574ec98e34d598f9e196de/10.png)

---

## 運用上の課題

もちろん、このような自動化にも課題はあります。例えば、インサイダー脅威やすでに社内ワークステーションが侵害されていた場合、アラートが「管理対象IP」として自動的にクローズされてしまい得る、という問題です。ただし、

1. 自動化をしないと処理しきれない大量検知を可能にするメリットは非常に大きい  
2. ワークステーションなどは高い監視・検知ルールを敷いているため、そこを踏み台とする攻撃はむしろ検知の可能性が高まる  

という理由から、一定の妥協をしても導入する価値は大いにあります。

もう1つは、いわゆる「シャドーIT」の問題です。ルールを作る際に「既知の良性IP」と定義していないアプリケーションやサードパーティのスキャンツールなどが勝手に導入されていると、正規操作でも毎回アラートを出してしまいます。そうしたIPを特定して例外に追加する作業は骨が折れますが、同時にシャドーITを発見・排除できるメリットもあります。

---

## 自動化と相性の良い検知例

もともとは特定の1つのルールで始まった自動化でしたが、運用するうちに多くのルールが自動化に適用可能だとわかりました。「このアラートが発火したとして、IPアドレスが社内管理や既知のものならアナリストはクローズするだろうか？」という観点で考えると、ほとんどのサードパーティSaaSやUEBA系のルールが該当します。

Elastic内部で自動トリアージを適用している例をいくつか挙げると、以下のような検知があります（一部は既存ルールにタグを追加し、自動化対応にしています）。

- Okta関連
  - リスクの高い認証や未知IPからの認証
  - サポートアカウントによる操作
  - パスワードリセットやアンロックの大量試行
  - MFAを使わないログイン
  - [Multiple Okta User Auth Events with Same Device Token Hash Behind a Proxy](https://www.elastic.co/guide/en/security/current/multiple-okta-user-auth-events-with-same-device-token-hash-behind-a-proxy.html) など  
- Slack UEBA: 新規ユーザーの複数アラート  
- GCP Portal/AWS Console/Azure Portalなど、クラウドログイン系の未知IPアクセス  
- GitHubやVaultなどのAPIキー・PATまわりのUEBA  
- [Potential Successful SSH Brute Force Attack](https://www.elastic.co/guide/en/security/current/potential-successful-ssh-brute-force-attack.html) や [VNC (Virtual Network Computing) from/to the Internet](https://www.elastic.co/guide/en/security/current/vnc-virtual-network-computing-from-the-internet.html) など  
- その他 多数

---

## まとめ：より高いレベルの保護と運用効率を実現

本記事では、Elastic InfoSecチームがTinesとElastic Securityを組み合わせて、アラートの初動調査を自動化し、膨大な誤検知を効率的にクローズしながら、より詳細な検知を行っている例を紹介しました。結果として、私たちは月間5万件以上のアラートを、アナリストの手を煩わすことなく数秒で精査しクローズできています。これはアナリストのみで対処するのは実質不可能な量であり、こうした自動化なしには実現できなかった高度な保護レベルを得ています。

もしご興味があれば、[Elastic Cloud](https://cloud.elastic.co/registration) の14日間無料トライアルと、無料の[Tines Community Edition](http://www.tines.com) を組み合わせることで、同様のワークフローをすぐにお試しいただけます。

> **注記**  
> 本記事で言及されている機能のリリースや時期は、Elasticの独自裁量により変更・延期・中止される場合があります。