Elasticでは、複数のデータセット、環境、および深刻度レベルにわたって、大規模かつ多様な動作検出ルールを運用しています。これらのルールのほとんどはアトミックであり、それぞれが特定の動作、信号、または攻撃パターンを検出するように設計されています。さらに、ファイアウォール、EDR、WAFなどのセキュリティ統合システムやその他のセキュリティ制御システムからの外部アラートを取り込み、配信します。
その結果、視認性は大幅に向上するものの、アラート量も相当なものとなる。テレメトリデータによると、ビルディングブロックルール以外のルールのみを考慮した場合でも、 65個の固有の検出ルールによって、本番クラスターごとに1日あたり約8000件のアラートが生成されます。アラートを個別に分析することは、拡張性にもコスト効率にも欠ける。
ここで高次規則が重要になってくる。
高次のルールは、単一の行動を検出するものではありません。その代わりに、関連するアラートを時間経過、データソース間、または共通のコンテキスト(ホスト、ユーザー、IP、プロセスなど)内で相関付けます。信号を意味のあるパターンにグループ化することで、本当に重要なことを優先し、手動、自動、またはAIによる拡張のいずれの場合でも、個々のアラートごとに詳細で費用のかかる分析を行う必要性を減らすことができます。
このブログでは、Elasticで高階ルールを構築するためのアプローチを解説し、実践的な例を紹介するとともに、その過程で得られた重要な教訓を重点的に取り上げます。
高次ルールとは何ですか?
高次ルール(HOR)は、アラートを入力として使用する検出方法であり、アラートを他のアラートと関連付ける(アラート・オン・アラート)か、アラートを生イベント、メトリック、コンテキストテレメトリなどの追加データと組み合わせます。
単一の動作を検出するアトミックルールとは異なり、高次ルールは信号全体にわたるパターンを識別します。それらの目的は、基本的な検出に取って代わることではなく、実際の攻撃活動を反映している可能性が高い検出結果の組み合わせを強化することにある。実際には、より信頼性の高い所見を明らかにし、トリアージの優先順位付けを改善する。高次ルールは、基本ルールと連携して機能するように設計されています。構成要素ルールは、デフォルトのアラートビューには表示されないアラートを生成し、相関のある検出結果を提供しながらもノイズを低減します。この記事で言及されている基本ルールの多くは、構成要素ルールとしても設定できるため、アナリストのレビュー対象として高次の相関関係のみが表示されるようになります。
核心となる洞察は、同一の対象に収束する独立した検出結果が信頼性を高め、追加される信号ごとに、その活動が無害ではなく現実のものである可能性が高まるという点です。以下の3つの設計原則は、この洞察を具体化したものです。
1. エンティティベースの相関関係
ルールは、ホスト、ユーザー、送信元IP、宛先IP、プロセスなどの共通エンティティによるアクティビティを関連付けることで、アナリストが複数の検出結果が同じ資産またはIDに集約されるかどうかを迅速に把握できるようにします。
2. データソース間の可視性
一部のルールは単一の統合内で動作します(たとえば、Elastic DefendまたはサードパーティのEDRからのエンドポイントのみの検出など)。その他にも、エンドポイントとネットワーク(PANW、FortiGate、Suricata)、エンドポイントと電子メール、またはエンドポイントとシステムメトリクスなど、ドメインをまたいだシグナルを意図的に組み合わせることで、多段階またはクロスサーフェスのアクティビティを捕捉するものもあります。
3. 時間と普及率の認識
時間論理が重要な役割を果たす。
新たに適用されたルールでは、定義された遡及期間(例えば5日間)内で特定の警告が最初に発生した場合を強調表示することで、まれな警告であっても必ず確認できるようにします。
発生頻度に基づくロジック(INLINE STATSの使用など)は、世界中でごく少数のホストでのみ発生するアラートをフィルタリングし、ノイズを低減して異常な動作を強調するのに役立ちます。
高次ルールの完全なセットには、エンドポイントのみの相関関係、クロスドメイン検出(エンドポイント + ネットワーク、エンドポイント + メール)、横方向の移動パターン(例: alert_1 host.ip = alert_2 source.ip )、ATT&CK に準拠したグループ分け(単一または複数の戦術による活動)、新たに観測されたアラート、およびアラートとイベントの相関関係(異常な CPU メトリックと組み合わせたアラートなど)が含まれます。以下のセクションでは、これらのカテゴリーから代表的な例を順に紹介します。
相関関係と新たに観測された高次規則
実際には、高リスクな活動は必ずしも同じ形をとるわけではない。
妥協は、複数の兆候が重なり合うことで明らかになる場合がある。また、これまで一度も見たことのない単一のアラートとして表示される場合もあります。
両方の現実に対応するため、高次ルールを3つの相補的なパターンに整理します。
- 相関ルールは、共通のエンティティ(ホスト、ユーザー、IPアドレス、またはプロセス)に関連付けられた複数のアラートまたはイベントを関連付けます。
- 新たに観測されたルールとは、稀な、または定義された時間枠内で初めて確認された単一のアラートを指します。
- 相関関係と初見の論理を組み合わせたハイブリッドパターンは、疑念をさらに高め、特に興味深い活動を明らかにする可能性がある。
相関ルールは、信号の密度と多様性を通じて信頼性を高めます。複数の独立した検出結果が同じ対象を指し示す場合、実際の悪意のある活動である可能性が高まります。
新たに観察されたルールは、その逆のケース、つまり取引量は少ないが新規性が高いケースに対応するものである。彼らは、時間の経過に伴う発生頻度に基づいてアラートの優先順位を付け、初めて発生した事象や非常に珍しい事象が、単に一度しか発生しないという理由だけで見落とされないようにしている。
これらのアプローチを組み合わせることで、効率的かつ拡張性のあるトリアージ戦略の基盤が形成される。
それでは、具体的な例を通して、それぞれのパターンの違い、長所、そしてトレードオフを探っていきましょう。
エンドポイントアラートの相関関係
実際の攻撃発見の大部分は、エンドポイントのテレメトリデータから得られる。これは、プロセス活動、コマンドライン、ファイル動作、ユーザー操作など、豊富なコンテキスト情報を提供するため、最も強力な検出ソースの1つとなっています。
同時に、エンドポイント環境は動的である。正規のソフトウェア、管理ツール、サードパーティ製アプリケーション(最近ではGenAIエンドポイントユーティリティ🥲も)は、大量のアラートや誤検知を発生させる可能性があり、継続的な調整が必要です。
高次相関は、個々の警告から同一ホストまたはプロセス上の複数の明確なシグナルへと焦点を移すことで、この問題に対処するのに役立ちます。これにより、信頼性が向上し、不要な調査作業が削減されます。
以下の ES|QL クエリは、一意の Elastic Defend 動作ルールが 3 ある場合、または異なる機能からのアラート (例えば、動作を持つ shellcode_thread が 1 つ、動作を持つ malicious_file が 1 つ) がある場合、または同じホストからの 24 時間以内に 2 超えるマルウェア アラートがある場合にトリガーされます。
from logs-endpoint.alerts-* metadata _id
| eval day = DATE_TRUNC(24 hours, @timestamp)
| where event.code in ("malicious_file", "memory_signature", "shellcode_thread", "behavior") and
agent.id is not null and not rule.name in ("Multi.EICAR.Not-a-virus")
| stats Esql.alerts_count = COUNT(*),
Esql.event_code_distinct_count = count_distinct(event.code),
Esql.rule_name_distinct_count = COUNT_DISTINCT(rule.name),
Esql.file_hash_distinct_count = COUNT_DISTINCT(file.hash.sha256),
Esql.process_entity_id_distinct_count = COUNT_DISTINCT(process.entity_id) by host.id, day
| where (Esql.event_code_distinct_count >= 2 or Esql.rule_name_distinct_count >= 3 or Esql.file_hash_distinct_count >= 2)
さらに疑念を深めるために、同じプロセスツリーに属するElastic Defendアラートを関連付けることもできます。
from logs-endpoint.alerts-*
| where event.code in ("malicious_file", "memory_signature", "shellcode_thread", "behavior") and
agent.id is not null and not rule.name in ("Multi.EICAR.Not-a-virus") and process.Ext.ancestry is not null
// aggregate alerts by process.Ext.ancestry and agent.id
| stats Esql.alerts_count = COUNT(*),
Esql.rule_name_distinct_count = COUNT_DISTINCT(rule.name),
Esql.event_code_distinct_count = COUNT_DISTINCT(event.code),
Esql.process_id_distinct_count = COUNT_DISTINCT(process.entity_id),
Esql.message_values = VALUES(message),
... by process.Ext.ancestry, agent.id
// filter for at least 3 unique process IDs and 2 or more alert types or rule names.
| where Esql.process_id_distinct_count >= 3 and (Esql.rule_name_distinct_count >= 2 or Esql.event_code_distinct_count >= 2)
// keep unique values
| stats Esql.alert_names = values(Esql.message_values),
Esql.alerts_process_cmdline_values = VALUES(Esql.process_command_line_values),
... by agent.id
| keep Esql.*, agent.id
試合例:
報道内容を補完するためには、希少な原子核も探す必要があるだろう。以下のES|QLは、 5 または 7 日のルックバックウィンドウで10分間隔で実行されるように設計されています。ルックバック機能は、全期間にわたってルール名ごとにすべてのアラートを集計し、最初に検出された時刻を計算します。最後のフィルター( Esql.recent <= 10 )は、最初に検出された時刻が現在の10分間の実行ウィンドウ内にあるルールのみが表示されるようにし、ルックバック期間中にルールが最初に発火した瞬間を効果的に検出します。これにより、通常であれば大量のデータに埋もれてしまう可能性のある、まれな誤検出や巧妙な挙動が明らかになる。
from logs-endpoint.alerts-*
| WHERE event.code == "behavior" and rule.name is not null
| STATS Esql.alerts_count = count(*),
Esql.first_time_seen = MIN(@timestamp),
Esql.last_time_seen = MAX(@timestamp),
Esql.agents_distinct_count = COUNT_DISTINCT(agent.id),
Esql.process_executable = VALUES(process.executable),
Esql.process_parent_executable = VALUES(process.parent.executable),
Esql.process_command_line = VALUES(process.command_line),
Esql.process_hash_sha256 = VALUES(process.hash.sha256),
Esql.host_id_values = VALUES(host.id),
Esql.user_name = VALUES(user.name) by rule.name
// first time seen in the last 5 days - defined in the rule schedule Additional look-back time
| eval Esql.recent = DATE_DIFF("minute", Esql.first_time_seen, now())
// first time seen is within 10m of the rule execution time
| where Esql.recent <= 10 and Esql.agents_distinct_count == 1 and Esql.alerts_count <= 10 and (Esql.last_time_seen == Esql.first_time_seen)
// Move single values to their corresponding ECS fields for alerts exclusion
| eval host.id = mv_min(Esql.host_id_values)
| keep host.id, rule.name, Esql.*
同様のロジックは、他のサードパーティ製EDRからの外部アラートにも適用できます。
ネットワークアラート相関を持つエンドポイント
エンドポイントのアラートとネットワークのアラートを関連付けることは、強力な検出手法の一つです。これは重要な疑問に答えるのに役立ちます。
どのプロセスがこのネットワークアラートを引き起こしましたか?
ネットワークアラートだけでは、どのユーザーや実行ファイルがアクティビティを開始したかといったプロセスコンテキストが不足していることが多い。ネットワークアラートとエンドポイントテレメトリ(EDRデータ)を組み合わせることで、アラートを以下の情報で強化できます。
- プロセス名とハッシュ
- コマンドラインと親プロセス
- ユーザーおよびデバイス情報
以下のクエリは、Elastic Defendのアラートと、Palo Alto Networks(PANW)やFortinet FortiGateなどのネットワークセキュリティデバイスからの疑わしいイベントとの相関関係を調べます。参加キーはIPアドレスです。ネットワークアラートの場合はsource.ip 、エンドポイントアラートの場合はhost.ipです。このクエリは、 COALESCEを使用してこれらを単一のフィールドに正規化し、同じエンティティに対して異なるフィールド名を使用するデータソース間で相関関係を可能にします。これは、このホストが侵害され、複数のデータソースからのアラートがトリガーされていることを示している可能性があります。
FROM logs-* metadata _id
| WHERE
(event.module == "endpoint" and event.dataset == "endpoint.alerts") or
(event.dataset == "panw.panos" and event.action in ("virus_detected", "wildfire_virus_detected", "c2_communication", ...)) or
(event.dataset == "fortinet_fortigate.log" and (...)) or
(event.dataset == "suricata.eve" and message in ("Command and Control Traffic", "Potentially Bad Traffic", ...))
| eval
fw_alert_source_ip = CASE(event.dataset in ("panw.panos", "fortinet_fortigate.log"), source.ip, null),
elastic_defend_alert_host_ip = CASE(event.module == "endpoint" and event.dataset == "endpoint.alerts", host.ip, null)
| eval Esql.source_ip = COALESCE(fw_alert_source_ip, elastic_defend_alert_host_ip)
| where Esql.source_ip is not null
| stats Esql.alerts_count = COUNT(*),
Esql.event_module_distinct_count = COUNT_DISTINCT(event.module),
Esql.message_values_distinct_count = COUNT_DISTINCT(message),
... by Esql.source_ip
| where Esql.event_module_distinct_count >= 2 AND Esql.message_values_distinct_count >= 2
| eval concat_module_values = MV_CONCAT(Esql.event_module_values, ",")
| where concat_module_values like "*endpoint*"
Elastic DefendとFortiGateのアラートを関連付けるマッチング例。FortiGateアラートのsource.ipがElastic Defendエンドポイントアラートのhost.ipと等しい場合:
以下の EQL クエリは、Suricata のアラートと Elastic Defend のネットワーク イベントを関連付け、ソース プロセスとホストに関するコンテキストを提供します。
sequence by source.port, source.ip, destination.ip with maxspan=5s
// Suricata severithy 3 corresponds to information alerts, which are excluded to reduce noise
[network where event.dataset == "suricata.eve" and event.kind == "alert" and event.severity != 3 and source.ip != null and destination.ip != null]
[network where event.module == "endpoint" and event.action in ("disconnect_received", "connection_attempted")]
Suricataアラートを確認し、Web攻撃の試みを裏付けるElastic Defendイベントから、ターゲットWebサーバープロセスnginxにリンクする一致例:
可観測性を備えたエンドポイントセキュリティ
可観測性テレメトリとセキュリティアラートを関連付けることは、強力な検出戦略となる。
XZ Utilsのバックドア事件は、セキュリティ関連の異常が、従来のセキュリティ警告ではなく、パフォーマンスの低下という形で最初に現れる可能性があることを示した。その場合、SSHデーモンの異常な動作がきっかけとなり、より詳細な調査が行われ、最終的に悪意のあるコードが発見された。
これは重要な原則を浮き彫りにしている。すなわち、運用上の異常は、侵害の早期兆候となり得るということだ。
Elastic Agentを使用すると、CPUやメモリ使用率などのシステムメトリクスをセキュリティテレメトリと併せて収集できます。プロセス別またはホスト別に、異常なリソース急増とSIEMアラートを関連付けることで、検出の信頼性を高め、高リスクな活動をより早期に発見することができます。
例えば、ES|QL相関ルールを使用すると、CPU使用率が70%以上で推移しているプロセスを特定できます。このプロセスは、Elastic Defendによる仮想通貨マイナーのメモリシグネチャアラートの発生源でもあります。個々の信号は、それぞれ軽度または中程度の深刻度を示す可能性がある。これらを総合的に見ると、悪意のある活動である可能性が非常に高い。
私たちは、さまざまな種類の関係性を網羅する 30 以上の高次検出機能を開発しました。ここではすべてを網羅することはできませんが、以下のリンクには、これらのルールをあなたの環境に合わせて適用するための十分な情報が記載されています。
エンドポイントアラート:
エージェントによる複数の Elastic Defend アラート
単一のプロセスツリーからの 複数の Elastic Defend アラート
ホストによる複数の稀な Elastic Defend 動作ルール
新たに観測された Elastic Defend 動作アラート
ホストによる複数の外部 EDR アラート
エンドポイントとネットワーク:
新たに検出された Palo Alto Networks アラート
新たに検出された高深刻度の Suricata アラート
異常なプロセスからの FortiGate SOCKS トラフィック
PANW と Elastic Defend - コマンド アンド コントロールの相関関係
Elastic Defend とネットワーク セキュリティ アラートの相関関係
Suricata と Elastic Defend ネットワークの相関関係
MITRE ATT&CK による汎用:
ホストごとの異なる ATT&CK 戦術におけるアラート
ホストごとの同じ ATT&CK 戦術における複数のアラート
汎用マルチインテグレーション相関:
ソースアドレスによる複数のインテグレーションからのアラート
宛先アドレスによる複数のインテグレーションからのアラート
ユーザー名による複数のインテグレーションからのアラート
新たに観測された高重大度検出アラート
横方向移動の相関関係:
侵害されたホストからの横方向移動の疑い
新たに観測された送信元アドレスからの横方向移動アラート
新たに観測されたユーザーからの横方向移動アラート
可観測性とセキュリティの相関関係:
CPUスパイクを示すプロセスに対する検出アラート
CPUスパイクを示すホストに対する複数のアラート
新たに観測された高CPU使用率を示すプロセス
機械学習相関:
インフルエンサー分野別の複数の機械学習アラート
その他の相関関係のアイデア:
Wiz によるアセットごとの複数の脆弱性
Elastic Defend とメールアラートの相関関係
不審な Kerberos 認証チケット要求
ソース アドレスによってアクセスされた複数のクラウド シークレット
これらの例は、エンドポイント、ネットワーク、および可観測性全体にわたるアラートを関連付けることで、コンテキストを充実させ、調査を迅速化し、検出の信頼性を向上させることができることを示しています。当社は、より多くの相関シナリオをサポートするため、この分野におけるサービス提供範囲を積極的に拡大しています。
ルール管理ページで、タグ値「ルールタイプ: 高次ルール」でフィルタリングすることで、これらのルールを有効にできます。
15日間の期間中、アラートの件数は許容範囲内(1日あたり約30件)にとどまりました。初期の異常値を的確に調整することで、1日あたりのアラート数を約20件にまで減らし、信号品質全体を大幅に向上させることが期待されます。
考慮事項とトレードオフ
高次ルールは、スケジューリングの遅延を引き起こす可能性がある。アラートインデックスを照会するため、基本アラートが発生してから相関関係が明らかになるまでには、必然的に遅延が生じます。ルールのスケジュール間隔とループバックウィンドウは、適時性とパフォーマンスコストのバランスを取るように調整する必要があります。さらに、HORの品質は、塩基検出の品質に直接依存する。ノイズの多いアトミックルールは、それを参照するすべての相関関係に偽陽性を連鎖的に引き起こします。依存する高次ルールを有効にする前に、基本ルールを積極的に調整することをお勧めします。最後に、広範なインデックスパターンに対するESQLクエリ(例:ログは大規模になるとコストが高くなる可能性がある。大量のデータを扱う環境では、インデックスパターンを特定のデータセットに限定したり、データビューを使用したりすることで、クエリコストを大幅に削減できます。
まとめ
高次ルールは、アラートの優先順位付けや、自動化およびAI駆動型分析のためのアラート量の管理に不可欠です。エンティティリスクスコアリングと組み合わせることで、高次ルールはホストおよびユーザーのリスクプロファイルに直接反映され、定量的な優先順位付けレイヤーを作成することで、手動によるトリアージの負担をさらに軽減できます。弊社の製品テストでは、これらの検出の大部分において中程度から低レベルのアラート音量しか発生せず、実用的であることが確認されました。最初は少数のノイズの多いルールや誤検出が現れるかもしれないが、それらを最小単位のルールレベルで除外することで、価値の高い相関関係の確固たるセットがすぐに残る。
その効果を最大限に高めるためには、2つの運用方法が重要である。まず、入力アラートがノイズと現実世界への影響の両方を正確に反映する深刻度レベルを使用していることを確認してください。深刻度のクリーニングと正規化は、有意義な相関関係の基礎となります。第二に、小規模から始めて段階的に拡大していくこと。考えられるすべての警告信号を関連付けようとするのは避けること。本質的にノイズの多い戦術(発見など)を除外し、重要度の低いシグナルの優先順位を下げ、相関結果に不均衡な影響を与えるルールを非推奨とする。
適切に適用すれば、高次ルールは捜査を効率化し、検出精度を向上させ、現代のセキュリティ運用の効率性と信頼性を大幅に高める。