比對區段語法

支援的國家/地區:

在 YARA-L 2.0 中,match 區段提供多事件關聯的機制。系統會根據特定時間範圍內的使用者、IP 位址或檔案雜湊等常見屬性,將事件分組為單一偵測結果,藉此定義分組邏輯。

您可以在下列情況使用 match 區段:

  • 在規則中連結兩個以上不同的事件。
  • 在「搜尋」和「資訊主頁」中匯總資料,例如計算特定時間範圍內的登入失敗次數。

定義關聯條件

您可以指定下列項目,定義這項關聯性的條件:

  • 分組欄位 (鍵):事件 (定義於 events 區段) 必須具有相同值的變數 (例如 $user$ip),才能觸發比對。

  • 時間限制:事件必須在時間範圍內發生,才能滿足規則或匯總條件。在「規則」中,這會定義偵測時間範圍;在「搜尋」和「資訊主頁」中,這會定義彙整或關聯時間範圍。

比較功能需求

下表詳細比較了搜尋規則和資訊主頁。

功能 規則規定 支援搜尋和資訊主頁
變數類型 必須使用 events 區段中定義的預留位置。 支援預留位置和直接 UDM 欄位。
時間範圍 定義偵測邊界。 定義匯總或關聯性 bucket。
語法 over <number><m/h/d> (例如 10m2h1d) 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] 時間範圍內執行的查詢,其中包含 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
}

範例:使用躍點視窗進行多事件關聯

以下範例代表大多數多事件規則的預設值。並擷取同一段時間內發生的事件。

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

滾動式時間區間

滾動式時間區間會將資料串流劃分為固定大小、不重疊的連續時間間隔。每個事件的時間戳記只會落入一個時間範圍。滾動視窗之間不會重疊。這與滑動或跳躍式時間區間不同,後者可能會有重疊的時間間隔。

如要實作滾動視窗,請在 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 小時或三天。

範例

下列規則會依 $userid 將登入作業分組,時間範圍為 1 小時,且不會重疊 (例如 [00:00:00-00:59:59]、[01:00:00-01:59:59] 等):

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 發生時間相差不到一小時,但由於事件 4 跨越固定時間範圍的界線,因此會分別偵測。

滑動時間範圍

如要搜尋以嚴格相對順序發生的事件 (例如 e1e2 發生後兩分鐘內發生),請使用滑動時間區間。與固定時間區間不同,滑動時間區間會由指定 $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)。
  • 時間長度:與樞紐事件的時間差 (例如 5m1h)。
  • 用途
    • 嚴格排序:偵測需要依序執行的攻擊鏈 (例如,先建立使用者,再提升權限)。
    • 相對時間:找出在「觸發」事件特定偏移時間內發生的事件 (例如 Process Start 事件後 30 秒內發生的 Network Connection)。
    • 缺席偵測:找出在開始事件後,必要「清除」或「心跳」事件未發生時 (例如 Database Backup Start 沒有對應的 End 事件)。

有效的滑動視窗範例

以下範例顯示有效的滑動視窗:

$var1, $var2 over 5m after $e1 $user over 1h before $e2 $host, $ip over 1h before $e2

範例:使用滑動視窗進行前瞻性關聯 (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
}

範例:使用滑動視窗進行回溯相關性分析 (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),否則請使用預設跳躍視窗。只有在事件順序至關重要或您要搜尋遺失的事件時,才使用滑動視窗。

  • 使用時間戳記篩選條件來評估成效:如果您只需要確認某個事件是否發生在另一個事件之後,通常在 eventscondition 區段中比較時間戳記,會比使用滑動時間區間更有效率,例如:

$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」部分中的零值

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 專業人員尋求答案。