一致セクションの構文
YARA-L 2.0 では、match セクションでマルチイベントの関連付けのメカニズムが提供されます。これは、特定の時間的境界内のユーザー、IP アドレス、ファイル ハッシュなどの共通属性をリンクして、イベントを単一の検出にグループ化するロジックを定義します。
match セクションは、次のユースケースで使用します。
- ルール内で 2 つ以上の異なるイベントをリンクします。
- 検索とダッシュボードでデータを集計します(特定の期間のログイン失敗回数をカウントするなど)。
相関条件を定義する
これを使用して、次の項目を指定して、この関連付けの条件を定義します。
グループ化フィールド(キー): 一致をトリガーするために、イベント間で同じ値を持つ必要がある変数(
$userや$ipなど)。(eventsセクションで定義)。時間制約: グループ化されたイベントがルールまたは集計を満たすために発生する必要がある期間ウィンドウ。ルールでは、検出ウィンドウを定義します。検索とダッシュボードでは、集計または相関ウィンドウを定義します。
機能要件を比較する
次の表に、ルールと検索、ダッシュボードの比較の詳細を示します。
| 機能 | ルールに関する要件 | 検索とダッシュボードのサポート |
|---|---|---|
| 変数の型 | events セクションで定義されたプレースホルダを使用する必要があります。 |
プレースホルダと直接 UDM フィールドの両方をサポートします。 |
| 期間 | 検出境界を定義します。 | 集計または相関関係のバケットを定義します。 |
| 構文 | over <number><m/h/d>(例: 10m、2h、1d) |
over <number><m/h/d> |
| 上限 | 最小: 1m / 最大: 48h |
最小: 1m / 最大: 48h |
サポートされているウィンドウ タイプ
YARA-L 2.0 では、さまざまなウィンドウ処理の動作を使用して、時間のスライス方法とイベントのグループ化方法を決定します。match セクションのイベント フィールドとプレースホルダは、次のサポートされているウィンドウのいずれかを使用して、指定した時間粒度でグループ化できます。
| サポートされているウィンドウ タイプ | 構文 | 説明 | 一般的なユースケース |
|---|---|---|---|
| ホップ | $key over <duration> |
時間間隔の重複(デフォルトの動作)。 | 複数のイベントの一般的な相関関係。 |
| タンブリング | $key by <duration> tumbling |
固定サイズで重複しない連続した時間間隔。 | アクティビティを最大 1 時間のブロックで定量化します(例: $user by 30m)。 |
| スライド | $key over <duration> [before|after] $pivot |
特定の「ピボット」イベントに固定された時間間隔。 | 厳密な順序付け(例: File Download after Login)。 |
構文の例:
match:
$user, $source_ip over 5m // Groups events by user and IP within a 5-minute window
ホップ ウィンドウ
ホップ ウィンドウは、マルチイベント ルールのデフォルトの動作です。ウィンドウの境界付近で発生するイベントを見逃さないように、重複する時間間隔を作成します。
- 構文:
$key over <duration>(例:$user over 30m) - ユースケース: ウィンドウ間隔の開始または終了の正確なタイミングに関係なく、特定のシナリオが確実にキャッチされる必要がある検出に最適です。
- サポート: 検索とダッシュボードでの集計(
countなど)でサポートされています。
デフォルトでは、match セクションを含む YARA-L クエリは、ホップ ウィンドウを使用して、複数のイベントを時間経過とともに関連付けます。クエリの実行の時間範囲は、重複する固定ホップ ウィンドウのセットに分割されます。これらのウィンドウの期間は match セクションで指定されますが、重複間隔とウィンドウの配置はシステム定義であり、ユーザーが構成することはできません。その後、これらの各事前定義ウィンドウ内でイベントが関連付けられます。
例: 継続的な相関関係のためのホップ ウィンドウの重複
次の例は、時間範囲 [1:00, 2:00] で実行されるクエリを示しています。$user over 30m に match セクションがあり、重複するホップ ウィンドウのセットとして [1:00, 1:30]、[1:03, 1:33]、[1:06, 1:36] が生成される可能性があります。
rule hop_window_brute_force_example {
meta:
description = "Detects multiple failed logins within a shifting 30-minute window."
severity = "Medium"
events:
$login.metadata.event_type = "USER_LOGIN"
$login.extensions.auth.auth_status = "FAILURE"
$login.principal.user.userid = $user
match:
// This creates the overlapping windows (e.g., 1:00-1:30, 1:03-1:33)
$user over 30m
condition:
// This will trigger if 10 or more failures fall into any single 30m hop
#login >= 10
}
例: ホップ ウィンドウを使用したマルチイベントの相関関係
次の例は、ほとんどの複数イベント ルールのデフォルトを表しています。同じ一般的な期間内に発生したイベントをキャプチャします。
rule hop_window_example {
meta:
description = "Detect a user with a failed login followed by a success within 30m"
events:
$e1.metadata.event_type = "USER_LOGIN"
$e1.extensions.auth.auth_status = "FAILURE"
$e1.principal.user.userid = $user
$e2.metadata.event_type = "USER_LOGIN"
$e2.extensions.auth.auth_status = "SUCCESS"
$e2.principal.user.userid = $user
match:
$user over 30m // This is a hop window
condition:
$e1 and $e2
}
例: ホップ ウィンドウの比較
ブルート フォース アクセス試行を特定するために、10m ウィンドウはすべての USER_LOGIN 失敗をグループ化します。次に、condition は、その特定の 10 分間のバケット内のカウント(#e)がしきい値を超えているかどうかを評価します。
rule failed_logins
{
meta:
author = "Security Team"
description = "Detects multiple failed user logins within 10-minute windows."
severity = "HIGH"
events:
$e.metadata.event_type = "USER_LOGIN"
$e.security_result.action = "FAIL"
$user = $e.target.user.userid
match:
$user over 10m
condition:
#e >= 5
}
match セクションでは、10 分(10m)間隔で新しいロケーションでログインに失敗したユーザーを検索します。
match:
$user over 10m
タンブリング ウィンドウ
タンブリング ウィンドウは、データ ストリームを固定サイズで重複しない連続した時間間隔に分割します。各データイベントは 1 つのウィンドウにのみ割り当てられます。これは、時間間隔が重複する可能性があるスライディング ウィンドウやホップ ウィンドウとは対照的です。
- 構文:
by演算子($key by <duration>)を使用します(例:$user by 30m)。 - ユースケース: 異なるブロック(
"How many alerts per hour?"など)のイベント数をカウントする場合のレポート作成とダッシュボードの構築に最適です。 - 検索とダッシュボード: イベントを重複除去せずにクリーンな棒グラフを作成するために頻繁に使用されます。
例: タンブリング ウィンドウを使用した固定間隔のカウント
次の例は、30 分のタンブリング ウィンドウを示しています。このウィンドウでは、1:00:00 から 1:29:59 の間に発生したイベントがまとめて処理されます。次に、1 時 30 分 0 秒から 1 時 59 分 59 秒までの次のイベントセットが個別に処理されます。
rule tumbling_window_threshold_example {
meta:
description = "Detect more than 50 failed logins from a single IP within a fixed 1-hour block."
severity = "Medium"
events:
$login.metadata.event_type = "USER_LOGIN"
$login.extensions.auth.auth_status = "FAILURE"
$login.principal.ip = $ip
match:
// This creates distinct, 1-hour blocks (e.g., 1:00-1:59, 2:00-2:59)
$ip by 1h
condition:
#login > 50
}
スライディング ウィンドウ
厳密な相対順序で発生するイベントを検索する必要がある場合は、スライディング ウィンドウを使用します(たとえば、e1 は e2 から 2 分後までに発生します)。固定ウィンドウとは異なり、スライディング ウィンドウは、次の構文を使用して指定された $pivot_event の発生ごとにトリガーされます。
after: ウィンドウはピボット イベントのタイムスタンプから始まり、前方に拡張されます。before: ウィンドウはピボット イベントのタイムスタンプで終了し、後方に拡張されます。
クエリの match セクションで、スライディング ウィンドウを次のように指定します。
<match-var-1>, <match-var-2>, ... over <duration> [before|after] <pivot-event-var>
- 構文:
$key over <duration> before|after $<pivot_event> - グループ化キー: イベントをリンクするために使用される共通フィールド(
$user、$ipなど)。 - 期間: ピボット イベントからの時間オフセット(例:
5m、1h)。 - ユースケース:
- 厳密なシーケンス: 順序が必要な攻撃チェーン(ユーザーの作成に続いて権限昇格が行われるなど)を検出します。
- 相対タイミング: 「トリガー」の特定のオフセット内で発生するイベントを検索します(たとえば、
Process Startイベントの後に 30 秒以内にNetwork Connectionが発生する)。 - 不在検出: 開始イベントの後に必要な「クリーンアップ」イベントまたは「ハートビート」イベントが発生しなかった場合を特定します(たとえば、対応する
EndイベントのないDatabase Backup Startなど)。
有効なスライディング ウィンドウの例
次の例は、有効なスライディング ウィンドウを示しています。
$var1, $var2 over 5m after $e1
$user over 1h before $e2
$host, $ip over 1h before $e2
例: スライディング ウィンドウを使用した将来の相関関係(after)
次の例は、2 番目のイベントがプライマリの「トリガー」イベントまたはピボット イベントの特定の期間内に発生する必要があるイベントのシーケンスを検出する方法を示しています。これは、迅速な横方向の移動や自動化されたフォローアップ アクションを検出するのに役立ちます。
rule sliding_window_after_example {
meta:
description = "Detect a network connection occurring within 1 minute after a suspicious process launch."
severity = "High"
events:
$proc.metadata.event_type = "PROCESS_LAUNCH"
$proc.principal.hostname = $host
$net.metadata.event_type = "NETWORK_HTTP"
$net.principal.hostname = $host
match:
// $proc is the pivot; the 1-minute window starts at the $proc timestamp
$host over 1m after $proc
condition:
$proc and $net
}
例: スライディング ウィンドウを使用した後方相関(before)
"before" スライディング ウィンドウを使用して、特定のアラートにつながるアクティビティを調査します。これは、根本原因分析で、重大な検出の直前に何が起こったかを特定するためによく使用されます。
rule sliding_window_before_example {
meta:
description = "Identify file modifications occurring in the 5 minutes before a ransomware alert."
severity = "Critical"
events:
$file.metadata.event_type = "FILE_MODIFICATION"
$file.principal.hostname = $host
$alert.metadata.event_type = "ANTIVIRUS_DETECTION"
$alert.metadata.product_name = "Premium_AV"
$alert.principal.hostname = $host
match:
// $alert is the pivot; the 5-minute window ends at the $alert timestamp
$host over 5m before $alert
condition:
$file and $alert
}
パフォーマンスとベスト プラクティス
スライディング ウィンドウは、ピボット イベントが発生するたびに計算されるため、標準(ホップ)ウィンドウよりも処理能力が必要となり、パフォーマンスが低下する可能性があります。
ルール、検索、ダッシュボードで最適なパフォーマンスを得るには、次のガイドラインに沿って操作してください。
ホップ ウィンドウを優先する: 検出ロジックに特定のイベント シーケンス(注文 A の後に注文 B)が必要な場合を除き、デフォルトのホップ ウィンドウを使用します。スライディング ウィンドウは、イベントの順序が重要な場合や、欠落したイベントを検索する場合にのみ使用してください。
パフォーマンスにタイムスタンプ フィルタを使用する: あるイベントが別のイベントの後に発生したことを確認するだけでよい場合は、
eventsセクションまたはconditionセクションのタイムスタンプ比較の方が、スライディング ウィンドウよりも効率的なことがよくあります。たとえば、次のようにします。
$e1.metadata.event_timestamp.seconds <
$e2.metadata.event_timestamp.seconds
マルチイベント設計: 単一イベント クエリにスライディング ウィンドウを使用しないでください。スライド ウィンドウは、マルチイベントの関連付け用に設計されています。単一イベント ロジックには、次のガイドラインが適用されます。
- 複数のイベント変数を使用して、
conditionセクションを更新します。 - 相関関係が不要な場合は、
matchセクション全体を削除します。 - 必要に応じて、スライディング ウィンドウを使用する代わりに、タイムスタンプ フィルタを追加することを検討してください(例:
$permission_change.metadata.event_timestamp.seconds < $file_creation.metadata.event_timestamp.seconds)。
- 複数のイベント変数を使用して、
時間的境界を理解する
match セクションでは、グループ化キーに基づいてイベントをグループに分割します。指定された期間は、各グループの時間的境界を定義します。
- 包含: その特定の照合の
condition評価には、計測期間内のイベントのみが渡されます。 - 除外: ウィンドウ外のイベントは、その特定の照合グループでは無視されます。これにより、無関係のイベントが誤検出を引き起こすのを防ぎます。
match セクションの値が 0
Google SecOps は、match セクションで使用されているすべてのプレースホルダのゼロ値を暗黙的に除外します(文字列の場合は ""、数値の場合は 0、ブール値の場合は false、列挙型の場合は位置 0 の値です)。
例: ゼロ値を除外する
次の例では、ゼロ値を除外するクエリを示します。
rule ZeroValuePlaceholderExample {
events:
// Because $host is used in the match section, the query behaves
// as if the following predicate was added to the events section:
// $host != ""
$host = $e.principal.hostname
// Because $otherPlaceholder was not used in the match,
// there is no implicit filtering of zero values for $otherPlaceholder.
$otherPlaceholder = $e.principal.ip
match:
$host over 5m
condition:
$e
}ただし、プレースホルダが関数に割り当てられている場合、match セクションで使用されているプレースホルダのゼロ値がクエリによって暗黙的に除外されません。
ゼロ値の暗黙的なフィルタリングを無効にするには、オプション セクションで allow_zero_values オプションを使用します。allow_zero_values オプションはルールでのみ使用できます。
例: ゼロ値を許可する
次の例は、match セクションで使用されるプレースホルダのゼロ値を暗黙的に除外しないクエリを示しています。
rule AllowZeroValuesExample {
events:
// Because allow_zero_values is set to true, there is no implicit filtering
// of zero values for $host.
$host = $e.principal.hostname
// Because $otherPlaceholder was not used in the match,
// there is no implicit filtering of zero values for $otherPlaceholder.
$otherPlaceholder = $e.principal.ip
match:
$host over 5m
condition:
$e
options:
allow_zero_values = true
}次のステップ
次のリソースで、YARA-L ロジックを続行するか、高度なクエリ関数について詳しく学習してください。
構文とロジック
リファレンスと例
さらにサポートが必要な場合 コミュニティ メンバーや Google SecOps のプロフェッショナルから回答を得ることができます。