一致セクションの構文
YARA-L 2.0 では、match セクションでマルチイベントの関連付けのメカニズムが提供されます。これは、特定の時間的境界内のユーザー、IP アドレス、ファイル ハッシュなどの共通属性をリンクして、イベントを単一の検出にグループ化するロジックを定義します。
match セクションは、次のユースケースで使用します。
- ルール内で 2 つ以上の異なるイベントをリンクします。
- 検索とダッシュボードでデータを集計します(特定の期間のログイン失敗回数をカウントするなど)。
相関条件を定義する
これを使用して、次の項目を指定して、この関連付けの条件を定義します。
グループ化フィールド(キー): 一致をトリガーするために、イベント(
eventsセクションで定義)間で同じ値を持つ必要がある変数($userや$ipなど)。時間制約: ルールまたは集計を満たすために、グループ化されたイベントが発生する必要がある期間ウィンドウ。ルールでは検出ウィンドウを定義し、検索とダッシュボードでは集計または相関ウィンドウを定義します。
機能要件を比較する
次の表に、ルールと検索、ダッシュボードの比較の詳細を示します。
| 機能 | ルール要件 | 検索とダッシュボードのサポート |
|---|---|---|
| 変数の型 | 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> |
固定サイズで重複しない連続した時間間隔。 | アクティビティを最大 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 つのウィンドウにのみ含まれます。タンブリング ウィンドウは重複しません。これは、時間間隔が重複する可能性があるスライディング ウィンドウやホップ ウィンドウとは対照的です。
タンブリング ウィンドウを実装するには、match セクションで by 演算子を使用します。
タンブリング ウィンドウは、時間を連続したブロックに分割します。次に例を示します。
by 1h: 各時間のウィンドウを作成します([00:00:00-00:59:59]、[01:00:00-01:59:59] など)。by 10m: 10 分間隔でウィンドウを作成します(例: [00:00:00-00:09:59]、[00:10:00-00:19:59] など)。
ユースケース
タンブリング ウィンドウは、次のような場合に使用します。
- 重複しない個別の時間ブロックでイベントを分析します。
- イベントの発生回数に関係なく、各固定時間間隔内で、特定エンティティ(一致変数で定義)に対して検出が 1 つだけ生成されるようにします。
- 一定期間にわたる一意のエンティティの数をカウントします。
重複除去の動作
タンブリング ウィンドウの主な特徴は、同じ一致変数のセットに対して各ウィンドウ内で検出がどのように処理されるかです。
- ウィンドウごとに 1 つの検出: 一致変数の特定の値のセット(特定の
$useridなど)に対して、タンブリング ウィンドウごとに最大 1 つの検出が生成されます。 - 最初の一致が優先: 特定の期間内に、その一連の一致変数のルール条件を満たす最初のイベントが取り込まれると、検出がトリガーされます。
- 重複除去: 同じウィンドウ インスタンス内で条件に一致する後続のイベントは、追加の検出を生成しません。
構文
match セクションの構文は次のとおりです。
match:
$variable by <duration>
ここで
$variableは、照合するプレースホルダ変数です。<duration>は、数値の後に時間単位が続きます。m: 分h: 時間d: 日
最小 1 分、最大 72 時間または 3 日を指定します。
例
次のルールグループは、1 時間の重複しないウィンドウ([00:00:00-00:59:59]、[01:00:00-01:59:59] など)内で $userid ごとにログインをグループ化します。
rule TumblingWindowExample {
meta:
description = "Example using a 1-hour tumbling window"
events:
$e.metadata.event_type = "USER_LOGIN"
$e.principal.user.userid = $userid
match:
$userid by 1h
condition:
$e
}
以下は、user = "alex" の検出動作の例です。
イベント 1: Alex が 00:30 にログインします。これは [00:00:00-00:59:59] ウィンドウに分類されます。このウィンドウで Alex の検出が生成されます。
イベント 2: 別のユーザー
"taylor"が 00:45 にログインします。これも [00:00:00-00:59:59] に該当しますが、$useridが異なるため、この時間枠で Taylor に対して別の検出が生成されます。イベント 3: Alex が 00:40 に再度ログインします。これは [00:00:00-00:59:59] の範囲内です。このウィンドウには Alex の検出がすでに存在するため、このイベントは重複除去されます。新しい検出は生成されません。
イベント 4: Alex が 01:20 にログインします。これは次のウィンドウ [01:00:00-01:59:59] に該当します。この新しいウィンドウで、Alex の新しい検出が生成されます。
Alice のイベント 1 とイベント 4 は 1 時間以内に発生しましたが、イベント 4 が固定ウィンドウの境界を越えているため、別々の検出に分類されます。
スライディング ウィンドウ
厳密な相対順序で発生するイベントを検索する必要がある場合は、スライディング ウィンドウを使用します(たとえば、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 のプロフェッショナルから回答を得ることができます。