套用 YARA-L 2.0 視窗邏輯
本指南可協助安全工程師為查詢選擇正確的視窗類型,避免「變數未繫結」編譯器錯誤。從滑動視窗轉換為滾動式時間區間後,您就能建構依賴事件缺少的邏輯,例如缺少活動訊號或記錄來源失敗。
事前準備
確認您的帳戶具備下列任一角色,可建立及修改 YARA-L 查詢:
- 偵測引擎管理員 (
roles/chronicle.detectionEngineAdmin) - SecOps 編輯者 (
roles/chronicle.editor)
支援的視窗類型
YARA-L 2.0 會使用不同的視窗行為,判斷時間的切分方式和事件的分組方式。您可以在 match 區段中,使用下列支援的視窗,依指定的時間精細程度將事件欄位和預留位置分組:
| 支援的時段類型 | 語法 | 說明 | 常見用途 |
|---|---|---|---|
| Hop | $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 時間戳記,供查詢使用。這些關鍵字可讓您存取時間值區的邊界:
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 使用者介面中分析時間軸。 |
| 時間範圍篩選 | 滑動或翻滾 | condition: window_start > "2026-01-01 00:00:00Z" |
使用 GoogleSQL 時間戳記強制轉換,將規則評估限制在特定日期。 |
比較時間戳記類型和時區
YARA-L 支援直接比較 window_start 和 window_end 與 GoogleSQL 時間戳記格式的字串。這樣一來,您就能執行精確的篩選作業,不必手動進行型別轉換。
注意:請一律使用 Z 後置字串指定世界標準時間 (例如 "2026-03-17T17:35:00Z"),以便與 UDM 事件時間戳記保持一致。
使用時間戳記篩選器可提升效能。如果只需要確認一個事件發生在另一個事件之後,通常在 condition 區段中比較時間戳記會更有效率:$e1.metadata.event_timestamp.seconds < $e2.metadata.event_timestamp.seconds。
進一步瞭解 match 區段語法和 condition 區段語法。
例如:window_end 和 window_start
window_end < "2026-01-01T12:30:00Z"(日期、時間和世界標準時間後置字串)window_start != "2026-01-01 15:00:00+00"(含世界標準時間時差)
如果比較失敗,請確認字串是否符合 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
滾動式時間區間
注意:這項功能僅適用於部分地區的部分客戶。
「滾動式時間區間」會將資料分割成固定大小、不重疊且連續的時間間隔。每個事件的時間戳記只會落入一個回溯期。滾動式時間區間之間不會重疊。這與跳躍式時間區間或滑動視窗不同,後者可能會有重疊的時間間隔。
如要實作滾動式時間區間,請在 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])。
常見用途
需要執行下列操作時,請使用滾動式時間區間:
- 分析不重疊的不同時間區塊中的事件。
- 無論事件發生多少次,在每個固定時間間隔內,只針對特定實體 (由比對變數定義) 產生一項偵測結果。
- 計算固定時間範圍內的不重複實體。
簡化行為
滾動式時間區間的主要特徵,是引擎如何處理每個時間區間內,同一組比對變數的偵測結果:
- 每個時間範圍偵測一次:針對一組相符變數值 (例如特定
$userid),引擎在任何單一滾動式時間區間內最多只會產生一次偵測結果。 - 先到先贏:在特定時間範圍內,最先擷取且符合該組比對變數規則條件的事件會觸發偵測。
- 重複資料刪除:在同一個時間範圍內,如果後續事件符合條件,系統就不會產生額外的偵測結果。
語法
match 區段的語法如下:match: $variable by <duration>
$variable是要比對的預留位置變數。duration是數字,後接時間單位:m(分鐘)、h(小時)、d(天)。- 最短為一分鐘,最長為 72 小時或三天。
範例:固定間隔分組
下列規則會將登入作業依 $userid1 小時內不重疊的時段分組。
規則
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:小艾在 01:20 登入。這會落在下一個時間範圍,即
[01:00:00-01:59:59]。引擎會為 Alex 產生新的偵測結果。
雖然 Alex 的事件 1 和事件 4 發生時間相隔不到一小時,但由於事件 4 跨越固定時間範圍邊界,因此會歸入不同的偵測結果。
設定缺席偵測的滾動式時間區間
如要在計數為零時發出警告,並避免編譯器失敗,請完成下列步驟:
- 確立偵測目標。判斷您要搜尋高頻率還是缺乏活動。
- 選取
window關鍵字。使用over代表頻率,並使用by代表缺席。 - 參考視窗邊界。使用
window_start和window_end關鍵字,參照時間 bucket 的特定邊界。
背景資訊:使用 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之後最多兩分鐘內發生)。 - 相對時間:尋找在觸發事件特定時間差內發生的事件 (例如
Network Connection30 秒內的Process Start)。 - 偵測缺漏:在啟動事件後,找出未發生的必要「清除」或「心跳」事件。
語法
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
需求條件和限制
- 效能:滑動視窗比跳躍式時間區間需要更多處理能力。只有在事件順序有嚴格要求時 (例如某個事件必須在另一個事件發生後五分鐘內發生),才應使用這類條件。
- 單一事件查詢:請勿使用滑動視窗進行單一事件邏輯。請改用
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 小時時間範圍完全結束後,才會進行評估。快訊延遲:使用
by(翻滾) 的規則只會在固定時間區塊經過後觸發。by 24h規則不會在視窗期間中途發出快訊。使用者介面不符:在搜尋和資訊主頁中,
window_start關鍵字直接參照TIME_BUCKET欄位。依window_start篩選或分組時,使用者介面中的欄標題會顯示為TIME_BUCKET。這是已知的使用者介面顯示限制,您的邏輯仍有效。
錯誤修正
| 錯誤代碼 | 說明 | 修正 |
|---|---|---|
| 變數未設為有界 | 規則使用 over (滑動時間範圍) 和 $count = 0 條件。 |
將視窗關鍵字變更為 by (滾動式時間區間)。滑動視窗需要有事件做為視窗的錨點,但滾動式時間區間則不需要。 |
| UI 標頭不符 | 使用者在 UI 中看到 TIME_BUCKET,而非 window_start。 |
不需要修正。使用關鍵字時,篩選和排序邏輯仍可正常運作。 |
不明 ID:window_start |
已使用關鍵字,但 match 中未定義任何視窗。 |
在 match 區段中新增開窗期陳述式 (例如 $hostname by 1h)。 |
在活動中無效使用 window_start |
關鍵字參照位於 events 區段。 |
將邏輯移至 condition 或 outcome 區段。只有在比對階段將事件分組後,系統才會計算視窗界線。 |
後續步驟
還有其他問題嗎?向社群成員和 Google SecOps 專業人員尋求解答。