YARA-L 2.0 ウィンドウ処理ロジックを適用する
このガイドは、セキュリティ エンジニアが「変数に境界がない」というコンパイラ エラーを回避するために、クエリの正しいウィンドウ タイプを選択するのに役立ちます。スライディング ウィンドウからタンブリング ウィンドウに移行すると、ハートビートの欠落やログソースの失敗など、イベントの欠落に依存するロジックを構築できます。
始める前に
YARA-L クエリを作成および変更するには、アカウントに次のいずれかのロールがあることを確認します。
- 検出エンジン管理者(
roles/chronicle.detectionEngineAdmin) - SecOps 編集者(
roles/chronicle.editor)
サポートされているウィンドウ タイプ
YARA-L 2.0 は、さまざまなウィンドウ処理動作を使用して、時間のスライス方法とイベントのグループ化方法を決定します。match セクションのイベント フィールドとプレースホルダは、次のサポートされているウィンドウを使用して、指定した時間の粒度でグループ化できます。
| サポートされているウィンドウ タイプ | 構文 | 説明 | 一般的なユースケース |
|---|---|---|---|
| ホップ | $key over <duration> |
固定された重複する時間間隔を作成します。システムは、境界付近のイベントをキャッチするために、オーバーラップと配置を定義します。 | 正確な開始時間に関係なく、複数のイベントの一般的な相関関係。 |
| タンブリング | $key by <duration> |
データを固定サイズの連続した重複しないブロックにセグメント化します。イベントの到着とは無関係に評価します。 | 固定スロットでのアクティビティの定量化($user by 30m など)またはイベントの欠落の検出。 |
| スライド | $key over <duration> [before|after] $pivot |
ウィンドウを特定の "pivot" イベントに固定します。ピボットが存在し、ルックバックまたはルックフォワードをトリガーする必要があります。 |
イベントの順序が重要な厳密なシーケンス(File Download after Login など)。 |
window_start と window_end のロジックを理解する
Google Security Operations は、クエリ内で使用するために GoogleSQL タイムスタンプに直接解決される 2 つの汎用的な予約済みキーワードを提供します。これらのキーワードを使用すると、時間バケットの境界にアクセスできます。
window_start: 時間バケットの開始境界。window_end: 時間バケットの終了境界。
使用制約
- 一致の要件: これらのキーワードを使用するには、
matchセクションでウィンドウ(byまたはover)を定義する必要があります。 - セクションの制限: これらのキーワードは、
condition、order、outcomeで使用します。eventsセクションでは無効です。 - 名前空間: これらをカスタム変数名として使用しないでください(例:
$window_start)。
ウィンドウのタイプと構文を決定する
この表は、検出ルールに使用するウィンドウ タイプと構文を決定する際のクイック リファレンスとして使用してください。
| シナリオ | 推奨時間枠 | 推奨キーワード | 主なメリット |
|---|---|---|---|
| 高頻度の検出(総当たり攻撃など) | スライディング ウィンドウ(over) |
window_start、window_end |
周期的な期間内にしきい値が満たされると、すぐにトリガーされます。 |
| 欠落/不存在(心拍数の欠落など) | タンブリング ウィンドウ(by) |
window_start、window_end |
イベントがゼロの場合でも固定時間ブロックを評価し、変数がバインドされていないエラーを防ぎます。 |
| 時系列レポート | スライドまたはタンブル | order: window_start asc |
アラート出力を標準化して、Chronicle UI でのタイムライン分析を容易にします。 |
| 時間制限付きフィルタリング | 滑り落ちる、転がる | condition: window_start > "2026-01-01 00:00:00Z" |
GoogleSQL タイムスタンプ強制を使用して、ルール評価を特定の日付に制限します。 |
タイムスタンプの型とタイムゾーンを比較する
YARA-L では、window_start と window_end を GoogleSQL タイムスタンプ形式の文字列と直接比較できます。これにより、手動で型キャストを行わずに正確なフィルタリングを実行できます。
注: UDM イベントのタイムスタンプと一致させるには、常に Z 接尾辞("2026-03-17T17:35:00Z" など)を使用して UTC を指定します。
パフォーマンスを向上させるには、タイムスタンプ フィルタを使用します。あるイベントが別のイベントの後に発生したことを確認するだけでよい場合は、condition セクションのタイムスタンプ比較($e1.metadata.event_timestamp.seconds < $e2.metadata.event_timestamp.seconds)の方が効率的なことがよくあります。
詳しくは、match セクションの構文と condition セクションの構文をご覧ください。
例: window_end、window_start
window_end < "2026-01-01T12:30:00Z"(日付、時刻、UTC サフィックス)window_start != "2026-01-01 15:00:00+00"(UTC オフセット付き)
比較が失敗した場合は、文字列が GoogleSQL の正規タイムスタンプ形式に従っていることを確認します。
ホッピング ウィンドウ
ホップ ウィンドウは、重複する時間間隔を作成するため、ウィンドウの境界付近で発生するイベントが見逃されることはありません。
- ユースケース: ウィンドウ間隔の開始または終了の正確なタイミングに関係なく、特定のシナリオをキャッチする必要がある検出に最適です。
- サポート: 検索とダッシュボードでの集計でサポートされています。
match セクションを含む YARA-L クエリは、ホップ ウィンドウを使用して複数のイベントを時間経過に沿って関連付けます。システムは、クエリの実行期間を、重複する固定ホップ ウィンドウのセットに分割します。これらのウィンドウの期間は match セクションで指定しますが、オーバーラップ間隔とウィンドウの配置はシステムによって定義されます。次に、これらの事前定義された各ウィンドウ内でイベントが関連付けられます。
詳しくは、match セクションの構文をご覧ください。
ホップ ウィンドウは、複合ルールの検出に特定の影響を及ぼします。詳細については、複合ルール: 時間間隔とホップ ウィンドウをご覧ください。
例: 連続相関の重複するホップ ウィンドウ
次の例は、期間 [1:00, 2:00] で実行されるクエリを示しています。match セクションは $user over 30m です。システムが生成する重複するホップ ウィンドウのセットは、[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
}
検索
metadata.event_type = "USER_LOGIN"
security_result.action = "FAIL"
principal.user.userid = $user
match:
// This creates the overlapping windows (e.g., 1:00-1:30, 1:03-1:33)
$user over 30m
```
ダッシュボード
metadata.event_type = "USER_LOGIN"
security_result.action = "FAIL"
principal.user.userid = $user
match:
// This creates the overlapping windows (e.g., 1:00-1:30, 1:03-1:33)
$user over 30m
例: ホップ ウィンドウを使用したマルチイベントの相関関係
次の例では、同じ一般的な期間内に発生したイベントをキャプチャします。
ルール
rule hop_window_example {
meta:
description = "Detect a user with a failed login followed by a success within 30m"
events:
// Event 1: Capture failed login attempts
$fail.metadata.event_type = "USER_LOGIN"
$fail.security_result.action = "FAIL"
$fail.principal.user.userid = $user
// Event 2: Capture successful login attempts
$success.metadata.event_type = "USER_LOGIN"
$success.security_result.action = "ALLOW"
$success.principal.user.userid = $user
match:
// Correlate events for the SAME $user within a rolling 30-minute window.
$user over 30m
condition:
// Ensure both a failed ($fail) and a successful ($success) login event occurred for the same user within the 30m window.
$fail and $success
}
検索
// Event 1: Capture failed login attempts
metadata.event_type = "USER_LOGIN"
security_result.action = "FAIL"
principal.user.userid = $user // Assign user ID to a placeholder
// Event 2: Capture successful login attempts
metadata.event_type = "USER_LOGIN"
security_result.action = "ALLOW"
principal.user.userid = $user // Link to the same user placeholder
match:
// Correlate events for the SAME $user within a rolling 30-minute window.
$user over 30m
ダッシュボード
// Event 1: Capture failed login attempts
metadata.event_type = "USER_LOGIN"
security_result.action = "FAIL"
principal.user.userid = $user // Assign user ID to a placeholder
// Event 2: Capture successful login attempts
metadata.event_type = "USER_LOGIN"
security_result.action = "ALLOW"
principal.user.userid = $user // Link to the same user placeholder
match:
// Correlate events for the SAME $user within a rolling 30-minute window.
$user over 30m
例: ホップ ウィンドウの比較
ブルート フォース アクセス試行を特定するために、10m ウィンドウはすべての USER_LOGIN エラーをグループ化します。次に、条件は、その特定の 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
}
検索
metadata.event_type = "USER_LOGIN"
security_result.action = "FAIL"
$user = target.user.userid
match:
$user over 10m
ダッシュボード
metadata.event_type = "USER_LOGIN"
security_result.action = "FAIL"
$user = target.user.userid
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 つのタンブリング ウィンドウに対して最大 1 つの検出を生成します。 - 最初に着信したイベントが優先される: 特定の期間内に、その一連のマッチ変数のルール条件を満たす最初のイベントが取り込まれると、検出がトリガーされます。
- 重複除去: 同じウィンドウ インスタンス内で条件に一致する後続のイベントは、追加の検出を生成しません。
構文
match セクションの構文は match: $variable by <duration> です。
$variableは、照合するプレースホルダ変数です。durationは、数値の後に時間単位(m(分)、h(時間)、d(日))を付けたものです。- 最小 1 分、最大 72 時間または 3 日を指定します。
例: 固定間隔のグループ化
次のルールは、1 時間の重複しないウィンドウ内で $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
}
検索
metadata.event_type = "USER_LOGIN"
principal.user.userid = $userid
match:
$userid by 1h
ダッシュボード
metadata.event_type = "USER_LOGIN"
principal.user.userid = $userid
match:
$userid by 1h
例: 検出動作(ユーザー = 「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 の新しい検出結果を生成します。
Alex のイベント 1 とイベント 4 は 1 時間未満の間隔で発生しましたが、イベント 4 が固定ウィンドウの境界を越えているため、別々の検出に分類されます。
不在検出のタンブリング ウィンドウを構成する
カウントがゼロの場合にアラートを生成し、コンパイラの障害を回避するには、次の操作を行います。
- 検出の目標を特定する。高頻度のアクティビティを検索するか、アクティビティの欠如を検索するかを判断します。
windowキーワードを選択します。頻度にはover、不在にはbyを使用します。- 参照ウィンドウの境界。
window_startキーワードとwindow_endキーワードを使用して、時間バケットの特定の境界を参照します。
コンテキスト: outcome: $ext_window_end = window_end を使用して、アラート メタデータに欠落したハートビートの正確な終了時刻を含めます。
例: メタデータを使用してハートビートの欠落を検出する
タンブリング ウィンドウを使用すると、カウントがゼロの場合にアラートを送信できるため、アクティビティの欠如を検索する際にコンパイラ エラーを回避できます。
ルール
rule missing_heartbeat_detection {
meta:
description = "Alert when a system fails to check in within a 24h block"
events:
$e.metadata.event_type = "STATUS_UPDATE"
$host = $e.principal.hostname
match:
$host by 24h // Tumbling window lets you detect zero counts
outcome:
$event_count = count($e.metadata.id)
$missing_window_start = window_start
$missing_window_end = window_end
condition:
$event_count = 0 and window_start > "2026-01-01T12:30:00Z"
}
検索
metadata.event_type = "STATUS_UPDATE"
$host = principal.hostname
match:
$host by 24h // Tumbling window lets you detect zero counts
outcome:
$event_count = count(metadata.id)
$missing_window_start = window_start
$missing_window_end = window_end
ダッシュボード
metadata.event_type = "STATUS_UPDATE"
$host = principal.hostname
match:
$host by 24h // Tumbling window lets you detect zero counts
outcome:
$event_count = count(metadata.id)
$missing_window_start = window_start
$missing_window_end = window_end
スライディング ウィンドウ
スライディング ウィンドウは特定のピボット イベントに固定され、前方(after)または後方(before)を検索します。
一般的なユースケース
イベントの順序付けが重要な場合は、スライディング ウィンドウを使用します。
- 厳密なシーケンス: 攻撃チェーンを検出します(例:
e1はe2の 2 分後に発生します)。 - 相対タイミング: トリガーの特定のオフセット内で発生するイベントを検索します(たとえば、
Process Startの 30 秒以内のNetwork Connection)。 - 不在検出: 開始イベントの後に必要な「クリーンアップ」イベントまたは「ハートビート」イベントが発生しなかった場合を特定します。
構文
match: <grouping_keys> over <duration> [before|after] <$pivot_event>
| コンポーネント | 説明 | 例 |
|---|---|---|
| グループ化キー | イベントをリンクするために使用される共通フィールド。 | $host、$user |
| 期間 | ピボット イベントからの時間オフセット。 | 5m、1h、30s |
| 方向 | ウィンドウが前後に拡張されるかどうか。 | after、before |
| ピボット イベント | ウィンドウを固定するイベント変数。 | $proc、$alert |
有効なスライディング ウィンドウの例を次に示します。
$var1, $var2 over 5m after $e1$user over 1h before $e2$host, $ip over 1h before $e2
要件と制限事項
- パフォーマンス: スライディング ウィンドウは、ホップ ウィンドウよりも多くの処理能力を必要とします。イベントの順序が厳密に必要とされる場合(たとえば、あるイベントの 5 分後に別のイベントが発生する必要がある場合)にのみ使用してください。
- 単一イベント クエリ: 単一イベント ロジックにスライディング ウィンドウを使用しないでください。代わりに、
conditionセクションで複数のイベント変数を使用します。
例: 将来予測の相関(after)
ルール
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
}
検索
after は検索ではサポートされていません。
ダッシュボード
after はダッシュボードでサポートされていません。
例: 後方相関(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
}
検索
before は検索ではサポートされていません。
ダッシュボード
before はダッシュボードでサポートされていません。
トラブルシューティング
このセクションでは、YARA-L の一般的なウィンドウ処理の問題のレイテンシ、上限、修正について説明します。
レイテンシと上限
タンブリング ウィンドウ(
by)を使用するルールは、固定時間ブロックの終了時にのみトリガーされます。たとえば、match: $user by 24hを含むルールは、24 時間のウィンドウが完全に経過した後に 1 回だけ評価されます。アラートのレイテンシ:
by(タンブリング)を使用するルールは、固定時間ブロックが経過した後にのみトリガーされます。by 24hルールは、ウィンドウの途中でアラートを生成しません。UI の不一致: 検索とダッシュボードでは、
window_startキーワードはTIME_BUCKETフィールドを直接参照します。window_startでフィルタリングまたはグループ化すると、UI で列ヘッダーがTIME_BUCKETとして表示されます。これは UI の表示に関する既知の制限事項です。ロジックは引き続き有効です。
エラーの修正
| エラーコード | 説明 | 修正 |
|---|---|---|
| Variable Not Bounded | このルールでは、$count = 0 条件とともに over(スライディング ウィンドウ)を使用します。 |
ウィンドウ処理キーワードを by(タンブリング ウィンドウ)に変更します。スライディング ウィンドウではウィンドウを固定するためのイベントが必要ですが、タンブリング ウィンドウでは必要ありません。 |
| UI ヘッダーの不一致 | UI に window_start ではなく TIME_BUCKET が表示されます。 |
修正は必要ありません。フィルタリングと並べ替えのロジックは、キーワードを使用して引き続き正しく機能します。 |
不明な識別子: window_start |
キーワードは使用されていますが、match でウィンドウが定義されていません。 |
match セクションにウィンドウ ステートメントを追加します(例: $hostname by 1h)。 |
イベントでの window_start の使用が無効です |
キーワードは events セクションで参照されます。 |
ロジックを condition セクションまたは outcome セクションに移動します。ウィンドウ境界は、イベントが一致フェーズでグループ化された後にのみ計算されます。 |
次のステップ
さらにサポートが必要な場合 コミュニティ メンバーや Google SecOps のプロフェッショナルから回答を得ることができます。