Google Security Operations(Google SecOps)を利用したセキュリティ運用では、大量のアラートから重要な脅威を見つけ出すことが重要です。しかし、類似したアラートや正常な処理による誤検知が多いと、SOCアナリストの負担が増え、重大なインシデントを見落とすリスクも高まります。
本記事では、Professional Security Operations Engineer(PSOE)認定試験の対策として、YARA-L 2.0の重複排除機能であるdedupを解説します。さらに、matchによるイベントのグループ化、outcomeによる集計、参照リストなどを活用したノイズ削減の考え方も紹介します。それぞれの機能の違いを理解し、検出ルールの設計や試験問題での判断に役立てましょう。
是非、最後までご覧いただけると嬉しいです。
YARA-L 2.0による動的リスクスコアリングとOutcome Conditionals
Google Security Operationsで効率的なセキュリティ監視を実現するには、不審なイベントを検知するだけでなく、そのリスクを評価し、調査や対応の優先順位を適切に判断することが重要です。
Google SecOpsの検出言語であるYARA-L 2.0では、outcomeセクションを使用して、検出結果にリスクスコアや追加のコンテキスト情報を設定できます。さらに、if()による条件分岐や算術演算を組み合わせることで、ファイルサイズやユーザー属性などの条件に応じてリスクスコアを動的に算出できます。
本記事では、Professional Security Operations Engineer認定試験の対策として、outcomeセクションの基本構造、Outcome Conditionalsの使い方、集計関数によるリスク評価、検出結果の優先順位付けについて解説します。
1. YARA-L 2.0のoutcomeセクションの役割
YARA-L 2.0のルールは、主にmeta、events、match、outcome、conditionの各セクションで構成されます。
このうち、outcomeセクションは、検出結果に追加情報を付与したり、イベントの内容に基づいてリスクスコアなどの計算値を求めたりするために使用します。
outcomeセクションで設定する主な情報
- リスクスコア(
$risk_score):検出結果のリスクを数値で表現します。Google SecOpsでは、検出結果の優先順位付けなどに活用できます。 - コンテキスト情報:ユーザーID、ホスト名、IPアドレスなど、調査に役立つ情報を出力します。
- 集計値:複数イベントを対象とするルールでは、イベント数やデータ転送量などを集計できます。
- 条件に応じた計算結果:
if()を使用して、イベントの属性や条件に応じたスコアを算出できます。
$risk_scoreはGoogle SecOpsで特別な意味を持つOutcome変数です。検出ルールで設定した値は、検出結果のリスク値として表示され、UDMのsecurity_result.risk_scoreフィールドに格納されます。
なお、metaセクションのseverityはルールの重大度を示すメタデータであり、$risk_scoreとは別のものです。outcomeで独自の重大度ラベルを計算しても、それだけでルールの正式な重大度が動的に変更されるわけではありません。
2. Outcome Conditionalsによる動的なリスクスコアリング
Outcome Conditionalsとは、outcomeセクションで条件式を評価し、その結果に応じた値を返す仕組みです。
基本構文は次のとおりです。
$variable_name = if(条件式, 条件が真の場合の値, 条件が偽の場合の値)
たとえば、ファイルサイズが500MBを超えた場合にリスクスコアを加算するといった処理を記述できます。複数のif()と算術演算を組み合わせれば、異なる条件に応じてスコアを積み上げることも可能です。
実践例:ファイルサイズや端末情報に基づくリスク評価
以下は、ファイルコピーイベントを対象に、ファイルサイズ、曜日、端末名に応じてリスクスコアを計算するルール例です。
rule dynamic_file_copy_risk {
meta:
author = "SecOps Engineer"
description = "ファイルコピーイベントの条件に基づくリスク評価"
severity = "MEDIUM"
events:
$e.metadata.event_type = "FILE_COPY"
$e.principal.file.size = $file_size
$e.principal.hostname = $hostname
// 修正①: 検出ルールではevent_timestamp(イベント発生時刻)を使用する
// collected_timestamp(収集時刻)はログ遅延により実際の曜日とずれる可能性がある
// 1 = Sunday, 7 = Saturday
$day_of_week = timestamp.get_day_of_week(
$e.metadata.event_timestamp.seconds // collected_timestamp → event_timestamp
)
outcome:
// if()の2引数形式はinteger型の場合は有効(else省略時は0として評価される)
$risk_score =
if($file_size > 500 * 1024 * 1024, 2) +
if($file_size > 1024 * 1024 * 1024, 3) +
if($day_of_week = 1 or $day_of_week = 7, 4) +
if($hostname = /highly-privileged/, 5)
$observed_file_size = $file_size
$observed_hostname = $hostname
condition:
$e and $risk_score >= 10
}
この例では、次の条件に応じてリスクスコアを加算しています。
| 判定条件 | 加算スコア |
|---|---|
| ファイルサイズが500MBを超える | 2 |
| ファイルサイズが1GBを超える | 3 |
| 土曜日または日曜日に発生 | 4 |
端末名がhighly-privilegedに一致 | 5 |
最終的なリスクスコアが10以上の場合に、検出条件を満たします。
このように、outcomeで計算した変数はconditionでも参照できます。リスクスコアを算出するだけでなく、一定のスコアを超えた場合に検出するよう設計することで、優先度の低いイベントを抑制し、調査対象を絞り込めます。
注意: 上記は構文と設計の理解を目的とした例です。実環境で使用する前に、FILE_COPYイベントの有無、ファイルサイズのUDMフィールド、曜日関数、端末名の条件を、実際のログとGoogle SecOpsのルールエディタで検証してください。
3. 集計関数とoutcomeセクションの連携
単一イベントで判定できるルールだけでなく、複数イベントを時間軸で相関させるルールでも、outcomeセクションを活用できます。
複数イベントを対象とする場合は、matchセクションで相関の単位と時間範囲を指定し、outcomeセクションで必要な値を集計します。
主な集計関数
| 関数 | 役割 |
|---|---|
count() | 指定した値の件数を数える |
sum() | 数値を合計する |
max() | 最大値を取得する |
min() | 最小値を取得する |
array_distinct() | 重複を除いた値の配列を取得する |
実践例:複数イベントの集計
以下は、同じユーザーによるファイルコピーイベントを10分間で集約し、イベント数と合計ファイルサイズを出力する例です。
rule file_copy_activity_summary {
meta:
author = "SecOps Engineer"
description = "ユーザーごとのファイルコピー活動を集計"
severity = "MEDIUM"
events:
$e.metadata.event_type = "FILE_COPY"
$e.principal.user.userid = $user
$e.principal.file.size = $file_size
match:
$user over 10m
outcome:
$event_count = count($e.metadata.id)
$total_file_size = sum($file_size)
$risk_score = if(sum($file_size) > 1000000000, 80, 30)
condition:
#e >= 2
}
この例では、同じユーザーによるイベントを10分間で集約し、イベント数とファイルサイズの合計を算出します。合計ファイルサイズが1,000,000,000バイトを超える場合はリスクスコアを80、それ以外は30に設定します。
#e >= 2は、対象期間内に2件以上のイベントが存在することを検出条件としています。
なお、集計対象のイベント数と、count()で数えるフィールドの件数は、必ずしも同じとは限りません。欠損値などがある場合も考慮し、実際のログで期待どおりの値が算出されるか確認してください。
4. リスクスコアを使った検出ルール設計のポイント
4-1. リスクスコアと重大度を区別する
$risk_scoreは、検出結果のリスクを数値で表現するための変数です。一方、metaセクションのseverityはルールの重大度を示します。
Google SecOpsの公式ドキュメントでは、metaセクションのseverityの推奨値として「Low」「Medium」「High」が案内されています。ただし、「Critical」や「Information」も公式のサンプルルールやスキーマリファレンスで使用されており、有効な値として認められています。組織のポリシーや運用要件に合わせて、これらの値を適切に選択してください。なお、独自の重大度ラベルを出力変数として計算したい場合は、metaセクションのseverityとは区別し、outcomeセクションの追加コンテキスト情報として設計してください。
4-2. スコアの基準を組織内で統一する
リスクスコアの基準をルールごとにばらばらにすると、アラートの優先順位付けが難しくなります。
Google SecOpsの公式ドキュメントでは、カスタム検出のリスクスコアについて、次のような範囲が推奨されています。
| リスクの目安 | スコア |
|---|---|
| Critical相当のアラート | 90~100 |
| High相当のアラート | 80~89 |
| Medium相当のアラート | 50~79 |
| Low相当の非アラート | 20~49 |
| 情報収集を目的とした検出 | 1~19 |
これはリスク評価の一貫性を保つための目安です。組織のセキュリティポリシーや運用要件に合わせて調整してください。
4-3. リスク分析やSOAR連携は設定を確認する
Google SecOps Risk Analyticsは、検出やアラートを関連するエンティティと結び付けてリスク分析に利用します。エンティティにリスクスコアを割り当てる場合は、$risk_entity_to_scoreや、用途に応じた$risk_entity_to_score_で始まる変数を使う設計も検討します。
また、outcomeで定義した値が、すべてのSOARプレイブックに自動的に引き渡されるとは限りません。SOARでスコアやコンテキストを使う場合は、検出結果の参照方法、ケースへのマッピング、プレイブックの条件分岐を確認し、意図した対応が実行されるように設計してください。
5. PSOE認定試験に向けて押さえておきたいポイント
Professional Security Operations Engineer認定試験の対策では、次のポイントを整理しておきましょう。
outcomeの役割:検出結果に追加情報や計算値を付与する。- Outcome Conditionals:
if()と算術演算を使い、イベントの条件に応じた値を計算する。 - 集計関数:
count()、sum()、max()、min()などを使い、複数イベントの特徴を評価する。 conditionとの連携:outcomeで算出した値を条件に利用し、検出対象を絞り込む。- リスクスコアと重大度の違い:
$risk_scoreとmeta.severityの役割を混同しない。
これらを理解することで、YARA-L 2.0を使った検出ルールの設計だけでなく、アラートの優先順位付けや調査効率の改善にも役立てられます。
YARA-L 2.0による動的リスクスコアリングとOutcome Conditionalsのまとめ
YARA-L 2.0のoutcomeセクションでは、検知したイベントに関する情報を抽出し、集計値やリスクスコアなどを算出できます。
outcome conditionalsを活用すると、イベントの発生回数やデータ転送量、ユーザーやアセットの属性などの条件に応じて、スコアや判定結果を動的に変更するルールを設計できます。
また、countやsumなどの集計関数を組み合わせることで、一定期間内のイベント数や累積データ量を評価し、検知の精度向上に役立てられます。
実際の運用では、検知ルールの条件や出力する情報を適切に設計し、アラートの優先順位付けや調査の効率化につなげることが重要です。
PSOE認定試験対策として、outcomeセクションの役割、条件分岐の構文、集計関数の使い方を整理して理解しておきましょう。
YARA-L 2.0時間ウィンドウ処理
Google Security Operationsで複数のログを相関分析したり、時間ごとのイベント数を集計したりする際に重要なのが、時間ウィンドウ処理(Time Window Processing)です。
YARA-L 2.0 では、match セクションで時間ウィンドウを指定できます。ただし、すべてのウィンドウが同じ動作をするわけではありません。固定された時間枠で集計する Tumbling Window(タンブリングウィンドウ)、重なり合う時間枠でイベントを相関させる Hop Window(ホップウィンドウ)、特定のイベントを基準に前後のイベントを調べる Sliding Window(スライディングウィンドウ)を使い分ける必要があります。
本記事では、それぞれの仕組みとYARA-L 2.0での記述方法を、ブルートフォース攻撃の検知やダッシュボードの集計を例に解説します。Professional Security Operations Engineer認定試験の学習にも役立つよう、一般的なウィンドウ処理の概念とGoogle SecOps固有の仕様を区別して説明します。
1. 時間ウィンドウ処理とは
時間ウィンドウ処理とは、指定した時間範囲に含まれるイベントをグループ化し、集計や相関分析を行う仕組みです。
例えば、同じユーザーによるログイン失敗が短時間に何度も発生した場合、単一のログだけではブルートフォース攻撃かどうかを判断できません。一定の時間範囲でログをまとめ、失敗回数を評価することで、攻撃の可能性を検知できます。
Google SecOpsのYARA-L 2.0では、match セクションを使用して、イベントをグループ化するキーと時間ウィンドウを指定します。
match:
$user over 5m
この例では、$userをグループ化キーとし、5分間のホップウィンドウを使用してイベントを相関させます。
YARA-L 2.0では、主に次の3種類のウィンドウを区別します。
- Hop Window:重なり合う時間枠でイベントを相関させる。
- Tumbling Window:重なりのない固定時間枠でイベントを集計する。
- Sliding Window:特定のイベントを基準に、指定した時間だけ前後のイベントを調べる。
重要なのは、overを指定するだけで、イベントの到着ごとに窓が移動する一般的なストリーミング処理になるわけではないことです。Google SecOpsでは、over、by、イベントを基準にしたSliding Windowを区別して理解する必要があります。
2. Tumbling Window:重複のない固定時間枠で集計する
Tumbling Window(タンブリングウィンドウ)は、時間を重なりのない固定区間に分割する方式です。
例えば、1時間単位で集計する場合、時間枠は次のようになります。
<escape> 00:00 ───── 01:00 ───── 02:00 ───── 03:00 第1枠 第2枠 第3枠 </escape>
各イベントは、そのイベントの時刻に対応する時間枠に分類されます。隣接する時間枠は重ならないため、同じイベントが複数の枠に重複して集計されることを避けられます。
主な用途
- 時間ごとのログイン失敗数の集計
- ユーザー別のイベント件数の推移
- ダッシュボードでの時間別トレンド表示
- 一定期間内に発生したイベントの集計
- イベントが発生しなかった時間帯の確認など、固定区間を前提とする検出
YARA-L 2.0での記述例
次のクエリは、ユーザーごとに1時間単位の時間枠を作成し、ログインイベントを集計するための基本例です。
metadata.event_type = "USER_LOGIN"
principal.user.userid = $user
match:
$user by 1h
outcome:
$login_count = count(metadata.id)
by 1hがタンブリングウィンドウを指定する部分です。outcomeのcount(metadata.id)は、各グループに含まれるイベント数を集計します。
この例は、検索やダッシュボードでの集計を想定しています。検出ルールとして利用する場合は、ルールの構文要件に合わせてeventsやconditionなどを定義してください。
メリットと注意点
タンブリングウィンドウのメリットは、時間ごとの集計結果を比較しやすいことです。一方、固定時間枠をまたいで発生したイベントは、別々の枠に分類されます。
例えば、ログイン失敗が00:58に3回、01:02に3回発生した場合、1時間単位の集計では別々の時間枠に分かれます。攻撃を検知する条件が「同じ時間枠内で5回以上」であれば、この6回の失敗を1つのグループとして評価できません。
ただし、これは固定時間枠を使った場合の性質であり、すべてのタンブリングウィンドウの利用で攻撃を見落とすという意味ではありません。検出条件と時間枠の設計によって、適切な方式は変わります。
3. Hop Window:重なり合う時間枠でイベントを相関させる
Hop Window(ホップウィンドウ)は、時間枠同士が重なり合う方式です。Google SecOpsのYARA-L 2.0では、matchセクションでoverを指定することでホップウィンドウを使用できます。
match:
$user over 5m
この指定は、同じユーザーに関するイベントを5分間のホップウィンドウで相関させることを意味します。
ホップウィンドウは、あらかじめ定められた重なり合う時間区間にイベントを分類します。窓の重なり方や位置合わせはシステム側で決まり、利用者がイベント到着のたびに窓を移動させる処理を直接実装するわけではありません。
主な用途
- 複数イベントの相関分析
- 短時間に集中するログイン失敗の検知
- 同じユーザーやホストに関連するイベントのグループ化
- 固定時間枠の境界付近で発生するイベントを考慮した分析
YARA-L 2.0でのブルートフォース検知例
以下は、同一ユーザーによるログイン失敗が5分間に5回以上発生した場合に検知することを意図した、基本的なルール例です。
rule brute_force_hop_window {
meta:
author = "SecOps Engineer"
description = "5分間に同一ユーザーのログイン失敗が集中した場合に検知"
severity = "MEDIUM"
events:
$e.metadata.event_type = "USER_LOGIN"
$e.security_result.action = "FAIL"
$e.target.user.userid = $user
match:
$user over 5m
condition:
#e >= 5
}
この例では、次の処理を行います。
eventsでログインイベントを絞り込みます。$userをグループ化キーとして使用します。matchで5分間のホップウィンドウを指定します。conditionで対象イベントが5件以上あることを条件にします。
実環境に適用する前に確認すること: ログイン失敗を示す値がsecurity_result.action = "FAIL"であること、ユーザーIDがtarget.user.useridに格納されていることを、実際のUDMイベントで確認してください。ログソースによってはフィールドやアクション値が異なります。また、ルールの検知タイミングはイベントの取り込みやルール実行の仕様にも依存するため、「条件を満たした瞬間に必ず即時通知される」とは限りません。
メリットと注意点
ホップウィンドウは、重なり合う時間枠を使うため、固定時間枠の境界をまたぐイベントパターンを捉えやすくなります。ただし、ホップウィンドウは、イベントが到着するたびに任意の時刻を起点として過去5分を再計算する方式と同義ではありません。
また、時間枠が重なることにより、同じイベントが複数の集計枠に含まれる可能性があります。結果をダッシュボードで表示する場合は、集計単位と重複の有無を理解したうえで解釈する必要があります。
4. Sliding Window:特定イベントを基準に前後を調べる
Sliding Window(スライディングウィンドウ)は、一般的なデータ処理では「窓を滑らせる方式」という広い意味で使われることがあります。しかし、Google SecOpsのYARA-L 2.0では、Hop WindowとSliding Windowは区別されています。
YARA-L 2.0のSliding Windowは、特定のイベントを基準点(pivot)として、その前後の時間範囲に別のイベントが存在するかを調べる方式です。
例えば、ユーザーがログインした後、5分以内にファイルをダウンロードしたかを確認したい場合、ログインイベントを基準に、その後のイベントを相関させることができます。
主な用途
- ログイン後に発生したファイルダウンロードの確認
- 特定プロセスの実行前後に発生したイベントの調査
- イベントの発生順序が重要な相関分析
- 本来発生するはずのイベントが存在しないことを調べるケース
YARA-L 2.0での記述例
次の例は、ログインイベント$loginの後に発生したファイルダウンロードイベント$downloadを、同じユーザーについて相関させるための構文例です。
rule download_after_login {
meta:
author = "SecOps Engineer"
description = "ログイン後5分以内のファイルダウンロードを検知"
severity = "MEDIUM"
events:
$login.metadata.event_type = "USER_LOGIN"
$login.principal.user.userid = $user
$download.metadata.event_type = "FILE_DOWNLOAD"
$download.principal.user.userid = $user
match:
$user over 5m after $login
condition:
$login and $download
}
この例では、after $loginによってログインイベントを基準とする時間範囲を指定しています。ただし、実際のログインイベントとファイルダウンロードイベントの関連付けには、イベントのUDMフィールドや時間条件などの検証が必要です。上記は構文の考え方を示す例であり、すべての環境でそのまま実行できる完成済みルールを保証するものではありません。
Sliding WindowはHop Windowよりも処理負荷が高くなる場合があるため、イベントの順序や基準点が重要なケースで利用するのが適切です。単純なイベント件数の集計であれば、まずHop WindowやTumbling Windowを検討してください。
5. 3種類のウィンドウの比較
| 比較項目 | Tumbling Window | Hop Window | Sliding Window |
|---|---|---|---|
| YARA-Lの指定方法 | by 1h | over 5m | over 5m after $loginなど |
| 時間枠の特徴 | 固定・非重複 | 固定・重複あり | 基準イベントに対する相対的な時間範囲 |
| 主な目的 | 時間単位の集計 | 一般的なイベント相関 | イベントの順序や基準点を考慮した相関 |
| 代表的な用途 | 時間ごとの件数推移 | 短時間のログイン失敗の集計・検知 | ログイン後のダウンロード検知 |
| 境界の影響 | 固定枠の境界でイベントが分かれる | 重複枠により境界の影響を緩和 | 基準イベントからの時間関係を評価 |
| 注意点 | 枠をまたぐイベントは別集計になる | 重複枠を考慮して結果を解釈する | 基準イベントやイベント順序の定義が必要 |
選択の基本は、「固定区間で数えたいのか」「重なり合う区間で相関したいのか」「特定イベントとの時間関係を調べたいのか」という目的の違いです。
6. パフォーマンスと運用設計の注意点
6.1 ウィンドウの長さは検出目的に合わせる
時間枠を長くすると、より長い期間にわたるイベントを関連付けられます。一方で、対象となるイベントが増え、ルールの処理負荷や検知までの時間に影響する可能性があります。
例えば、5分間に集中するログイン失敗を検知するルールに24時間の時間枠を指定すると、検知したい行動の時間的な特徴と一致しない可能性があります。
時間枠は一律に短くするのではなく、攻撃シナリオに応じて設定してください。例えば、ブルートフォース攻撃、長時間にわたる不審な活動、イベントの欠落検知では、適切な時間枠が異なります。
6.2 固定時間枠と重複する時間枠を使い分ける
ダッシュボードで時間ごとの件数を比較する場合、非重複のTumbling Windowが適しています。一方、検出ルールでは、境界をまたぐイベントの相関が必要かどうかを考慮してHop Windowを検討します。
ただし、「ダッシュボードでは常にTumbling Windowしか使ってはいけない」というわけではありません。Google SecOpsの検索やダッシュボードでも、分析目的に応じて時間ウィンドウを選択できます。
6.3 ルールのテストで動作を確認する
ウィンドウの種類だけでなく、グループ化キー、イベントの条件、イベント時刻、しきい値も検知結果に影響します。
ルールを本番環境に適用する前に、Rules Editorのテスト機能などを使い、少なくとも次の観点を確認しましょう。
- 同じユーザーのイベントが意図したグループにまとめられるか
- 指定した時間枠内で条件を満たしたときに検知されるか
- 時間枠の境界付近にあるイベントが期待どおりに処理されるか
- イベントの順序を条件にする場合、基準イベントとの時間関係が正しいか
- 想定外のログや不完全なユーザーIDによって、誤検知や検知漏れが起きないか
なお、YARA-L 2.0の時間ウィンドウには利用上の制約があります。利用する機能や環境の最新ドキュメントで、対応する時間範囲や構文要件を確認してください。
YARA-L 2.0時間ウィンドウ処理のまとめ
Google SecOpsのYARA-L 2.0では、時間ウィンドウの種類によって、イベントのグループ化や相関分析の方法が変わります。
- Tumbling Window(
by):重なりのない固定時間枠で集計し、時間ごとの件数推移やトレンド分析に適しています。 - Hop Window(
over):重なり合う時間枠でイベントを相関させ、短時間に集中する不審な活動などの検出に適しています。 - Sliding Window(
over ... before/after):特定イベントを基準に前後のイベントを調べ、発生順序や時間関係が重要な相関分析に適しています。
PSOE認定試験の学習では、用語の定義だけでなく、byとoverの違い、Sliding Windowで基準イベントを指定する意味、そしてユースケースに応じた選択基準を理解しておくことが重要です。実際のルールを作成する際は、Google SecOpsの公式ドキュメントとRules Editorで構文や動作を検証し、検知要件に合った時間ウィンドウを選択しましょう。
YARA-L 2.0で重複排除とアラートノイズを削減する方法
セキュリティ運用センター(SOC)では、同じ不審なアクティビティに関連するアラートが大量に発生すると、重要なインシデントを見落とすリスクが高まります。こうした状態は「アラート疲れ(Alert Fatigue)」につながり、調査や対応の効率を低下させます。
Google Security Operationsでは、YARA-L 2.0のdedupセクションを利用して、検索結果やダッシュボードに表示される重複イベントを削減できます。また、検出ルールでは、matchによるイベントのグループ化、outcomeによる集計、条件式の調整などを組み合わせることで、過剰な検知を抑えられます。
ただし、検索結果の重複排除と、検出ルールでアラートの発生を抑制する仕組みは同じではありません。本記事では、それぞれの機能と使い分けを解説します。Professional Security Operations Engineer(PSOE)認定試験の学習に向けて、実際のYARA-L 2.0の構文も紹介します。
1. YARA-L 2.0における重複排除の基礎
1.1 なぜ重複排除が必要なのか
例えば、1回のログインに対して、認証システムとファイアウォールの両方がログを記録する環境を考えます。
同じ事象が複数のシステムに記録されると、検索結果に類似したイベントが複数表示されることがあります。そのまま調査すると、アナリストが同じ事象を何度も確認したり、集計結果を誤って解釈したりする可能性があります。
こうした場合に使用できるのが、YARA-L 2.0のdedupセクションです。
1.2 dedupでできること
dedupは、指定したキー変数やUDMフィールドの値に基づいて、検索結果の重複を取り除く機能です。
例えば、次のような目的に利用できます。
- 同じ送信元IPアドレスに関連する検索結果を整理する
- 重複するホスト名を除いて一覧表示する
- 複数のログソースに記録されたイベントを調査するとき、結果を絞り込む
- 集計結果を含む検索で、特定フィールドに基づいて結果を整理する
ただし、dedupは、同じユーザーに関するすべてのアラートを自動的に1件のアラートへ統合する機能ではありません。また、指定したフィールドの値が同じだからといって、イベントの内容や発生原因まで同一であることが保証されるわけでもありません。
重要なポイント: dedupはGoogle SecOpsの検索・ダッシュボードで利用する機能です。検出ルールでアラート数を制御する場合は、ルールのグループ化や検知条件などを別途設計する必要があります。
2. dedupセクションの構文と使い方
2.1 基本構文
dedupセクションでは、重複排除の基準にするフィールドや変数を指定します。
metadata.event_type = "USER_LOGIN"
security_result.action = "FAIL"
principal.user.userid != ""
dedup:
principal.user.userid
このクエリは、ログイン失敗イベントを検索し、ユーザーIDを基準として重複排除を行う例です。
例えば、検索結果に同じユーザーIDを持つイベントが複数存在する場合、指定したユーザーIDに基づいて結果を絞り込めます。
なお、この例は検索結果の重複排除を示すものであり、ユーザーごとのログイン失敗回数を集計するクエリとは異なります。回数を集計したい場合は、matchやoutcomeなどを使用します。
2.2 送信元IPアドレスで重複排除する
ネットワーク接続イベントを調査し、送信元IPアドレスを基準に結果を整理する例です。
events:
metadata.event_type = "NETWORK_CONNECTION"
target.ip != ""
principal.ip != ""
match:
target.ip, principal.ip
dedup:
principal.ip
この例では、通信先IPアドレスと送信元IPアドレスをmatchでグループ化し、dedupで送信元IPアドレスを基準に重複排除します。
matchとdedupは役割が異なります。
match:検索結果をグループ化するためのキーを指定するdedup:指定したキーに基づいて重複する検索結果を取り除く
この違いを理解することが重要です。
2.3 集計結果を含む検索で重複排除する
dedupは、matchやoutcomeを使用する集計検索でも利用できます。
例えば、送信元IPアドレスと通信先IPアドレスの組み合わせをグループ化し、送信バイト数を集計する場合、次のように記述できます。
events:
metadata.event_type = "NETWORK_CONNECTION"
target.ip != ""
principal.ip != ""
match:
target.ip, principal.ip
outcome:
$total_bytes = sum(network.sent_bytes)
dedup:
principal.ip
order:
$total_bytes desc
この例では、ネットワーク接続をIPアドレスの組み合わせでグループ化し、送信バイト数を集計します。その後、送信元IPアドレスを基準に重複排除し、集計結果を送信バイト数の降順で並べます。
集計検索では、dedupが適用される段階や指定可能なフィールドに制約があります。公式ドキュメントでは、matchやoutcomeを使用する集計検索の場合、重複排除の対象としてmatchのフィールドやoutcomeのフィールドを追加する必要があると説明されています。実際のクエリでは、利用する検索形式に応じて指定内容を確認してください。
3. 検出ルールのノイズ削減はdedupとは別に設計する
検索結果を整理するdedupと、検出ルールで発生するアラートを抑制する仕組みは区別する必要があります。
検出ルールでは、match、outcome、conditionなどを利用して、検知対象となるイベントのグループや条件を定義できます。
3.1 matchで同一ユーザーのイベントをグループ化する
例えば、同一ユーザーによるログイン失敗が10分間に何度も発生した場合に検知したいとします。
rule repeated_login_failures {
meta:
author = "SecOps Engineer"
description = "同一ユーザーのログイン失敗を検知"
severity = "MEDIUM"
events:
$e.metadata.event_type = "USER_LOGIN"
$e.security_result.action = "FAIL"
$e.target.user.userid = $user
match:
$user over 10m
condition:
#e >= 5
}
このルールは、次のように動作することを意図しています。
eventsでログイン失敗イベントを抽出する$userをグループ化キーとして指定するmatchで10分間の時間ウィンドウを指定するconditionで対象イベントが5件以上ある場合に検知する
ここで、$user over 10mは、同じユーザーのイベントを10分間のホップウィンドウで相関させる指定です。この指定自体が、dedupセクションと同じ重複排除を行うわけではありません。
また、検知結果の件数や通知のタイミングは、ルールの実行方式やイベントの取り込み状況などにも依存します。必ず「10分間に1件だけアラートを生成する」という動作を保証する構文ではありません。
実環境では、ログイン失敗を示すアクション値やユーザーIDの格納先を、実際のUDMイベントに合わせて確認してください。
3.2 outcomeでイベント数やリスクを評価する
outcomeでは、対象イベントの件数やリスクスコアなどを計算し、検知結果にコンテキストを追加できます。
例えば、同じユーザーのログイン失敗回数を集計する場合、次のように記述できます。
outcome:
$failed_count = count($e.metadata.id)
この値は、検出条件や結果の解釈に利用できます。
ただし、outcomeで件数を集計しただけで、アラートが自動的に1件に統合されたり、通知回数が抑制されたりするわけではありません。集計値を検知条件に使用するのか、結果のコンテキストとして表示するのかを明確に設計しましょう。
3.3 既知の正常な活動を除外する
バックアップ処理や定期バッチなど、正常な活動が繰り返し検知される場合は、検索結果の重複排除ではなく、検出条件そのものを見直す必要があります。
例えば、次のような対策を検討します。
- 参照リストなどを利用して、承認済みのユーザーやIPアドレスを条件に反映する
- 正常な処理に固有のイベント属性を利用して、検知対象を絞り込む
- 単一イベントの検知を、複数イベントの発生回数や時間的な関係を考慮したルールに見直す
- ルールの検知結果をテストし、誤検知の原因を特定する
ただし、除外条件を広く設定すると、実際の攻撃まで検知対象から外れる可能性があります。例外を追加するときは、対象の業務、期間、システム、アクセス元などを確認し、必要最小限の範囲に限定してください。
4. 検索結果の重複排除とアラートノイズ削減の使い分け
| 課題 | 主な対策 | 注意点 |
|---|---|---|
| 同じIPアドレスが検索結果に何度も表示される | 検索のdedup | 指定フィールドを基準に検索結果を整理する |
| 複数のログソースが同じ事象を記録する | 適切なフィールドを使ったdedupや検索条件の見直し | フィールド値が同じことと、事象そのものが同一であることは別 |
| 同一ユーザーのログイン失敗が短時間に集中する | 検出ルールのmatchとcondition | 時間枠としきい値を攻撃シナリオに合わせる |
| 正常なバッチ処理で誤検知が発生する | 検知条件の見直し、参照リストなどによる例外処理 | 例外の範囲を広げすぎない |
| アラートの調査に必要な情報が不足している | outcomeによる集計やコンテキスト追加 | 集計することと通知を抑制することを混同しない |
| 同じインシデントに関するケースが複数作成される | SOAR側のケース管理・グルーピング機能を検討 | YARA-Lの検索結果重複排除とは別の機能 |
SOARで既存ケースにアラートを統合する場合は、利用している製品や構成でサポートされるケース管理機能を確認してください。YARA-Lのdedupを指定するだけで、SOARのケース作成や統合まで自動的に制御できるわけではありません。
5. dedupのパフォーマンスと運用上の注意点
5.1 検索対象期間を必要最小限にする
dedupは、指定した時間範囲のデータを処理して重複排除を行います。Google Cloudの公式ドキュメントでは、1日以下の範囲でパフォーマンスが良好になりやすく、7~30日程度の範囲ではレイテンシが大幅に増加し、クエリがタイムアウトする可能性があると説明されています。
そのため、検索では調査目的に必要な期間を指定し、不要に広い期間を対象にしないことが重要です。
5.2 重複排除のキーを慎重に選ぶ
dedupで指定するフィールドによって、検索結果のまとまり方が変わります。
例えば、ユーザーIDだけで重複排除すると、同じユーザーによる異なるホストや異なる時間帯の活動も、同じキーとして扱われる可能性があります。
一方、ユーザーID、ホスト名、IPアドレスなどを組み合わせると、より細かな単位で結果を区別できます。
ただし、重複排除のキーを増やしすぎると、期待するほど結果が減らない場合もあります。何を「同じ結果」とみなすのかを明確にしてからフィールドを選びましょう。
5.3 検出ルールと検索クエリを別々にテストする
YARA-L 2.0は検索、ダッシュボード、検出ルールで利用されますが、検索結果と検出ルールのアラートは、実行エンジンや時間範囲、重複排除の扱いなどが異なる場合があります。
そのため、検索で重複排除が期待どおりに動作したとしても、同じ記述を検出ルールに適用すれば同様の結果になるとは限りません。
運用前には、次の点を確認しましょう。
dedupを使っている場合、意図したフィールドで検索結果が整理されているかmatchのグループ化キーと時間ウィンドウが、検知要件に合っているかconditionのしきい値が適切かoutcomeで算出した件数やスコアが想定どおりか- 例外条件によって、本来検知すべきイベントまで除外されていないか
6. PSOE認定試験に向けた設計判断のポイント
PSOEの学習では、単に構文を暗記するだけでなく、問題の原因に対応する機能を選択できることが重要です。
| 課題・症状 | 選択する機能・対策 |
|---|---|
| 検索結果に同じIPアドレスの結果が重複する | dedup |
| 複数イベントをユーザーやホストごとにグループ化したい | match |
| 一定期間内のイベント数を検知条件にしたい | matchとcondition |
| イベント数やリスクスコアを結果に付与したい | outcome |
| 既知の正常な活動による誤検知を減らしたい | 検知条件の見直し、参照リストなどによる例外処理 |
| 同じインシデントに関連するケースをまとめたい | SOAR側のケース管理機能を確認する |
特に、dedupは検索・ダッシュボードの重複排除、matchはイベントのグループ化と時間範囲の指定、outcomeは集計やコンテキストの付与という役割の違いを押さえておきましょう。
YARA-L 2.0で重複排除とアラートノイズを削減する方法のまとめ
Google SecOpsでアラートノイズを削減するには、重複イベントを整理することと、検知ルールそのものを適切に設計することの両方が重要です。
dedup:検索結果やダッシュボードで、指定したフィールドを基準に重複イベントを整理する。match:検出ルールで、ユーザーやホストなどをキーにイベントをグループ化し、時間範囲を指定する。outcome:イベント数やリスクスコアなどを計算し、検知結果に情報を追加する。conditionや例外条件:検知に必要な件数や条件を明確にし、誤検知を抑える。- SOARのケース管理機能:必要に応じて、同じインシデントに関連するアラートやケースを管理する。
これらの機能は、それぞれ目的が異なります。検索結果の重複排除だけでアラート疲れを解決しようとするのではなく、検知条件、時間ウィンドウ、集計方法、例外条件を組み合わせて設計することが大切です。PSOE認定試験の学習でも、各機能の構文だけでなく、どの課題にどの機能を使うべきかを理解しておきましょう。
まとめ
今回は、下記3点について説明しました。
- YARA-L 2.0による動的リスクスコアリングとOutcome Conditionals
- YARA-L 2.0時間ウィンドウ処理
- YARA-L 2.0で重複排除とアラートノイズを削減する方法
Google SecOpsでアラートノイズを削減するには、検索結果の重複排除と、検出ルールそのものの改善を区別して考えることが重要です。
YARA-L 2.0のdedupは、検索結果やダッシュボードで指定したフィールドを基準に重複を整理する機能です。一方、matchはイベントのグループ化や時間範囲の指定に、outcomeはイベント数やリスクスコアなどの集計に使用します。また、参照リストなどを活用して既知の正常な活動を適切に除外することも、誤検知の削減につながります。
Professional Security Operations Engineer認定試験では、各機能の構文を覚えるだけでなく、発生している問題に応じて適切な機能を選択できることが大切です。dedup、match、outcomeの役割の違いを理解し、効率的な検出ルールの設計につなげましょう。
これからも、Macのシステムエンジニアとして、日々、習得した知識や経験を発信していきますので、是非、ブックマーク登録してくれると嬉しいです!
それでは、次回のブログ!
