YARA-L 2.0 語言語法

支援的國家/地區:

本節說明 YARA-L 語法的主要元素。另請參閱 YARA-L 2.0 語言總覽

規則結構

如果是 YARA-L 2.0,您必須依下列順序指定變數宣告、定義和用法:

  1. meta
  2. 直播
  3. 相符項目 (選填)
  4. 結果 (選填)
  5. 條件
  6. 選項 (選用)

以下範例說明規則的一般結構:

rule <rule Name>
{
    meta:
    // Stores arbitrary key-value pairs of rule details, such as who wrote
    // it, what it detects on, version control, etc.

  events:
    // Conditions to filter events and the relationship between events.

  match:
    // Values to return when matches are found.

  outcome:
    // Additional information extracted from each detection.

  condition:
    // Condition to check events and the variables used to find matches.

  options:
    // Options to turn on or off while executing this rule.
}

中繼部分語法

中繼資料部分由多行組成,每行定義一個鍵/值組合。鍵部分必須是不含引號的字串,值部分則必須是含引號的字串:

<key> = "<value>"

以下是有效的 meta 區段行範例:

meta:
    author = "Google"
    severity = "HIGH"

「Events」區段語法

events 區段中,列出述詞來指定下列項目:

  • 變數宣告
  • 事件變數篩選器
  • 事件變數聯結

變數宣告

如要宣告變數,請使用下列語法:

  • <EVENT_FIELD> = <VAR>
  • <VAR> = <EVENT_FIELD>

兩者效果相同,如下列範例所示:

  • $e.source.hostname = $hostname
  • $userid = $e.principal.user.userid

這項宣告表示這個變數代表事件變數的指定欄位。如果事件欄位是重複欄位,比對變數可以代表陣列中的任何值。您也可以將多個事件欄位指派給單一比對或預留位置變數。這是遞移聯結條件。

例如:

  • $e1.source.ip = $ip
  • $e2.target.ip = $ip

等同於:

  • $e1.source.ip = $ip
  • $e1.source.ip = $e2.target.ip

使用變數時,必須透過變數宣告來宣告變數。如果使用變數時未進行任何宣告,系統會將其視為編譯錯誤。

事件變數篩選器

對單一事件變數執行的布林運算式會視為篩選器。

事件變數聯結

規則中使用的所有事件變數都必須與其他事件變數合併,方法如下:

  • 直接透過兩個已聯結事件變數的事件欄位進行相等比較,例如:$e1.field = $e2.field。運算式不得包含算術。

  • 間接透過只涉及事件欄位的遞移聯結 (如需「遞移聯結」的定義,請參閱變數宣告)。運算式不得包含算術。

舉例來說,假設規則中使用了 $e1、$e2 和 $e3,則下列 events 區段有效。

events:
  $e1.principal.hostname = $e2.src.hostname // $e1 joins with $e2
  $e2.principal.ip = $e3.src.ip // $e2 joins with $e3
events:
  // $e1 joins with $e2 via function to event comparison
  re.capture($e1.src.hostname, ".*") = $e2.target.hostname
events:
  // $e1 joins with $e2 via an `or` expression
  $e1.principal.hostname = $e2.src.hostname
  or $e1.principal.hostname = $e2.target.hostname
  or $e1.principal.hostname = $e2.principal.hostname
events:
  // all of $e1, $e2 and $e3 are transitively joined via the placeholder variable $ip
  $e1.src.ip = $ip
  $e2.target.ip = $ip
  $e3.about.ip = $ip
events:
  // $e1 and $e2 are transitively joined via function to event comparison
  re.capture($e2.principal.application, ".*") = $app
  $e1.principal.hostname = $app

不過,以下是無效的 events 區段範例。

events:
  // Event to arithmetic comparison is an invalid join condition for $e1 and $e2.
  $e1.principal.port = $e2.src.port + 1
events:
  $e1.src.ip = $ip
  $e2.target.ip = $ip
  $e3.about.ip = "192.1.2.0" //$e3 is not joined with $e1 or $e2.
events:
  $e1.src.port = $port

  // Arithmetic to placeholder comparison is an invalid transitive join condition.
  $e2.principal.port + 800 = $port

比對區段語法

match 部分,列出群組事件的相符變數,然後檢查相符條件。系統會在每次比對時傳回這些欄位。

  • events 區段中,指定每個比對變數代表的內容。
  • over 關鍵字後方指定時間長度,用於關聯事件。系統會忽略時間範圍外的事件。
  • 請使用下列語法指定時間長度:<number><m/h/d>

    其中 m/h/d 分別代表分鐘、小時和天數。

  • 最短時間為 1 分鐘。

  • 最長可指定 48 小時。

以下是有效的 match 範例:

$var1, $var2 over 5m

當規則找到相符項目時,這項陳述式會傳回 $var1$var2 (定義於 events 區段)。指定的時間為 5 分鐘。如果事件間隔超過 5 分鐘,系統就不會將其關聯,因此規則會忽略這些事件。

以下是有效 match 區段的另一個範例:

$user over 1h

規則找到相符項目時,這項陳述式會傳回 $user。指定的時間範圍為 1 小時。如果事件間隔超過一小時,系統就不會將其相互關聯。規則不會將其視為偵測結果。

以下是有效 match 區段的另一個範例:

$source_ip, $target_ip, $hostname over 2m

如果規則找到相符項目,這個陳述式會傳回 $source_ip$target_ip$hostname。指定的時間範圍為 2 分鐘。如果事件間隔超過 2 分鐘,系統就不會將這些事件相互關聯。規則不會將其視為偵測結果。

以下範例說明無效match 區段:

  • var1, var2 over 5m // invalid variable name
  • $user 1h // missing keyword

比對區段中的零值處理方式

規則引擎會隱含地篩除比對區段中所有預留位置的零值 (字串為 ""、數字為 0、布林值為 false列舉型別則為位置 0 中的值)。以下範例說明如何使用規則篩除零值。

rule ZeroValuePlaceholderExample {
  meta:
  events:
    // Because $host is used in the match section, the rule 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 section,
    // there is no implicit filtering of zero values for $otherPlaceholder.
    $otherPlaceholder = $e.principal.ip

  match:
    $host over 5m

  condition:
    $e
}

不過,如果將預留位置指派給函式,規則就不會隱含地篩除比對區段中使用的預留位置零值。以下範例說明如何使用規則篩除零值:

rule ZeroValueFunctionPlaceholder {
  meta:
  events:
    // Even though $ph is used in the match section, there is no
    // implicit filtering of zero values for $ph, because $ph is assigned to a function.
    $ph = re.capture($e.principal.hostname, "some-regex")

  match:
    $ph over 5m

  condition:
    $e
}

如要停用零值的隱含篩選,請使用選項部分中的 allow_zero_values 選項。

跳躍式時間區間

根據預設,系統會使用跳躍視窗評估含有相符區段的 YARA-L 2.0 規則。 規則的執行時間範圍會劃分為一組重疊的跳躍視窗,每個視窗的持續時間都由 match 區段指定。然後,系統會在每個躍點視窗中關聯事件。

舉例來說,如果規則在 [1:00, 2:00] 的時間範圍內執行,且 match 區段大於 30m,則可能產生的一組重疊跳躍視窗為 [1:00, 1:30]、[1:03, 1:33] 和 [1:06, 1:36]。這些時間範圍可用於關聯多個事件。

滑動視窗

使用跳躍視窗無法有效搜尋以特定順序發生的事件 (例如 e1 發生在 e2 之後最多 2 分鐘)。只有在產生的相同跳躍視窗中發生事件 e1 和事件 e2 時,這兩個事件才會相互關聯。

如要更有效率地搜尋這類事件序列,請使用滑動視窗。 如果以指定的樞紐事件變數做為開始或結束時間,系統就會產生 match 區段中指定時間長度的滑動視窗。然後在每個滑動視窗中相互關聯。這樣一來,您就能搜尋以特定順序發生的事件 (例如 e1e2 發生後的 2 分鐘內發生)。如果事件 e1 在事件 e2 發生後的滑動視窗時間長度內發生,則事件 e1 和事件 e2 的發生次數會相互關聯。

在規則的 match 區段中指定滑動視窗,如下所示:

<match-var-1>, <match-var-2>, ... over <duration> before|after <pivot-event-var>

樞紐事件變數是滑動視窗的依據事件變數。如果您使用 before 關鍵字,系統會產生滑動視窗,並以每個樞紐事件的發生時間做為結尾。如果使用 after 關鍵字,系統會從每個樞紐事件開始產生滑動視窗。

以下是有效使用滑動視窗的範例:

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

請參閱滑動視窗規則範例

建議不要對單一事件規則使用滑動視窗,因為滑動視窗的設計目的是偵測多個事件。如果您的規則屬於這類,建議採取下列其中一種解決方法:

  • 將規則轉換為使用多個事件變數,並在規則需要多次發生事件時,更新條件部分。
    • 視需要考慮新增時間戳記篩選器,而非使用滑動時間範圍。 例如 $permission_change.metadata.event_timestamp.seconds < $file_creation.metadata.event_timestamp.seconds
  • 取下滑動式視窗。

結果區段語法

outcome 區段中,您最多可以定義 20 個結果變數,並任意命名。這些結果會儲存在規則產生的偵測結果中。每次偵測的結果值可能不同。

結果名稱「$risk_score」是特殊名稱,您可以選擇定義具有這個名稱的結果,如果定義,結果必須是整數或浮點數類型。如果已填寫,risk_score 會顯示在企業洞察檢視畫面中,用於來自規則偵測的快訊。

如果規則的結果部分未包含 $risk_score 變數,系統會設定下列其中一個預設值:

  • 如果規則設定為產生快訊,則 $risk_score 會設為 40。
  • 如果規則未設定為產生快訊,則 $risk_score 會設為 15。

$risk_score 的值會儲存在 security_result.risk_score UDM 欄位中。

結果變數資料類型

每個結果變數可以有不同的資料類型,這取決於用於計算結果變數的運算式。我們支援下列結果資料類型:

  • 整數
  • 浮動
  • 字串
  • 整數清單
  • 浮點數清單
  • 字串清單

條件式邏輯

您可以使用條件式邏輯計算結果的值。條件式 是使用下列語法模式指定:

if(BOOL_CLAUSE, THEN_CLAUSE)
if(BOOL_CLAUSE, THEN_CLAUSE, ELSE_CLAUSE)

您可以將條件運算式解讀為「如果 BOOL_CLAUSE 為 true,則傳回 THEN_CLAUSE,否則傳回 ELSE_CLAUSE」。

BOOL_CLAUSE 必須評估為布林值。BOOL_CLAUSE 運算式的形式與 events 區段中的運算式類似。例如:

  • 含有比較運算子的 UDM 欄位名稱,例如:

    if($context.graph.entity.user.title = "Vendor", 100, 0)

  • events 區段中定義的預留位置變數,例如:

    if($severity = "HIGH", 100, 0)

  • outcome 區段中定義的另一個結果變數,例如:

    if($risk_score > 20, "HIGH", "LOW")

  • 傳回布林值的函式,例如:

    if(re.regex($e.network.email.from, `.*altostrat.com`), 100, 0)

  • 參考清單中查詢,例如:

    if($u.principal.hostname in %my_reference_list_name, 100, 0)

  • 匯總比較,例如:

    if(count($login.metadata.event_timestamp.seconds) > 5, 100, 0)

THEN_CLAUSE 和 ELSE_CLAUSE 必須是相同的資料類型。我們支援整數、浮點數和字串。

如果資料類型是整數或浮點數,可以省略 ELSE_CLAUSE。如果省略,ELSE_CLAUSE 會評估為 0。例如:

`if($e.field = "a", 5)` is equivalent to `if($e.field = "a", 5, 0)`

如果資料類型是字串,或 THEN_CLAUSE 是預留位置變數或結果變數,則必須提供 ELSE_CLAUSE。

數學運算

您可以在規則的 outcomeevents 區段中,使用數學運算計算整數或浮點資料型別。Google Security Operations 支援加法、減法、乘法、除法和模數,做為運算中的頂層運算子。

以下程式碼片段是 outcome 區段的計算範例:

outcome:
  $risk_score = max(100 + if($severity = "HIGH", 10, 5) - if($severity = "LOW", 20, 0))

只要每個運算元和整個算術運算式都經過適當彙整 (請參閱「彙整」),即可對下列類型的運算元執行數學運算:

  • 數值事件欄位
  • events 部分定義的數字預留位置變數
  • outcome 部分中定義的數值結果變數
  • 傳回整數或浮點數的函式
  • 傳回整數或浮點數的彙整

浮點數不允許使用模數。

結果中的預留位置變數

計算結果變數時,您可以使用規則事件部分中定義的預留位置變數。在本範例中,假設 $email_sent_bytes 是在規則的事件部分中定義:

單一事件範例:

// No match section, so this is a single-event rule.

outcome:
  // Use placeholder directly as an outcome value.
  $my_outcome = $email_sent_bytes

  // Use placeholder in a conditional.
  $other_outcome = if($file_size > 1024, "SEVERE", "MODERATE")

condition:
  $e

多事件範例:

match:
  // This is a multi event rule with a match section.
  $hostname over 5m

outcome:
  // Use placeholder directly in an aggregation function.
  $max_email_size = max($email_sent_bytes)

  // Use placeholder in a mathematical computation.
  $total_bytes_exfiltrated = sum(
    1024
    + $email_sent_bytes
    + $file_event.principal.file.size
  )

condition:
  $email_event and $file_event

結果指派運算式中的結果變數

結果變數可用於衍生其他結果變數,類似於 events 區段中定義的預留位置變數。您可以在指派其他結果變數時,使用 $ 符記,後面加上變數名稱,參照結果變數。必須先定義結果變數,才能在規則文字中參照這些變數。在指派運算式中使用時,結果變數不得匯總 (請參閱「匯總」)。

在下列範例中,結果變數 $risk_score 的值衍生自結果變數 $event_count

多事件範例:

match:
  // This is a multi event rule with a match section.
  $hostname over 5m

outcome:
  // Aggregates all timestamp on login events in the 5 minute match window.
  $event_count = count($login.metadata.event_timestamp.seconds)

  // $event_count cannot be aggregated again.
  $risk_score = if($event_count > 5, "SEVERE", "MODERATE")

  // This is the equivalent of the 2 outcomes above combined.
  $risk_score2 = if(count($login.metadata.event_timestamp.seconds) > 5, "SEVERE", "MODERATE")

condition:
  $e

結果變數可用於結果指派右側的任何類型運算式,但下列運算式除外:

  • 匯總資料
  • Arrays.length() 個函式呼叫
  • 使用 anyall 修飾符

匯總資料

重複事件欄位為非純量值。也就是說,單一變數會指向多個值。舉例來說,事件欄位變數 $e.target.ip 是重複欄位,可以有零個、一個或多個 IP 值。這是非純量值,而事件欄位變數 $e.principal.hostname 不是重複欄位,只有 1 個值 (即純量值)。

同樣地,在具有比對時間範圍的規則結果部分中,使用的非重複事件欄位和重複事件欄位都是非純量值。舉例來說,下列規則會使用比對區段將事件分組,並在結果區段中參照非重複事件欄位:

rule OutcomeAndMatchWindow{
  ...
  match:
    $userid over 5m
  outcome:
    $hostnames = array($e.principal.hostname)
  ...
}

規則執行的任何 5 分鐘時間範圍,可能包含零個、一個或多個事件。結果部分會處理相符視窗中的所有事件。在結果部分中參照的任何事件欄位變數,都可以在比對視窗中,指向每個事件的零個、一個或多個欄位值。舉例來說,如果 5 分鐘的時間範圍內有 5 個 $e 事件,結果部分會顯示 5 個不同的主機名稱。$e.principal.hostname系統會將事件欄位變數 $e.principal.hostname 視為這項規則 outcome 區段中的非純量值。

由於結果變數一律必須產生單一純量值,因此結果指派作業所依據的任何非純量值,都必須經過彙整,才能產生單一純量值。在結果部分中,下列為非純量值,必須經過彙整:

  • 規則使用相符區段時的事件欄位 (重複或非重複)
  • 規則使用比對區段時的活動預留位置 (重複或非重複)
  • 規則未使用比對區段時,重複的事件欄位
  • 規則未使用相符區段時,重複的活動預留位置

在不含比對部分的規則中,純量事件欄位、純量事件預留位置和常數可以包裝在彙整函式中。不過在大多數情況下,這些匯總會傳回包裝值,因此沒有必要。例外狀況是 array() 匯總,您可以使用這項匯總將純量值明確轉換為陣列。

結果變數會視為匯總資料,因此在其他結果指派中參照時,不得重新匯總。

您可以使用下列匯總函式:

  • max():輸出所有可能值的最大值。僅適用於整數和浮點數。
  • min():輸出所有可能值的最小值。僅適用於整數和浮點數。
  • sum():輸出所有可能值的總和。僅適用於整數和浮點數。
  • count_distinct():收集所有可能的值,然後輸出可能值的不同計數。
  • count():行為與 count_distinct() 類似,但會傳回可能值的非相異計數。
  • array_distinct():收集所有可能的不重複值,然後輸出這些值的清單。系統會將不重複值清單截斷為 25 個隨機元素。系統會先套用去重複程序,取得不重複的清單,然後再套用截斷程序。
  • array():行為與 array_distinct() 類似,但會傳回不重複的值清單。此外,也會將值清單截斷為 25 個隨機元素。
  • period_start_for_max():列出值達到最大值時的時間範圍開頭。
  • period_start_for_min():列出值達到最低點的時間範圍開頭。

如果規則包含 condition 區段,且該區段指定必須存在多個事件,則匯總函式就非常重要,因為匯總函式會對產生偵測結果的所有事件執行運算。

舉例來說,如果 outcomecondition 區段包含:

outcome:
  $asset_id_count = count($event.principal.asset_id)
  $asset_id_distinct_count = count_distinct($event.principal.asset_id)

  $asset_id_list = array($event.principal.asset_id)
  $asset_id_distinct_list = array_distinct($event.principal.asset_id)

condition:
  #event > 1

由於條件部分需要每個偵測項目有多個 event,因此匯總函式會對多個事件執行運算。假設下列事件產生一項偵測結果:

event:
  // UDM event 1
  asset_id="asset-a"

event:
  // UDM event 2
  asset_id="asset-b"

event:
  // UDM event 3
  asset_id="asset-b"

那麼結果的值會是:

  • $asset_id_count = 3
  • $asset_id_distinct_count = 2
  • $asset_id_list = ["asset-a", "asset-b", "asset-b"]
  • $asset_id_distinct_list = ["asset-a", "asset-b"]

使用結果專區時,請注意以下事項:

其他注意事項和限制:

  • outcome 區段無法參照 events 區段或 outcome 區段中未定義的新預留位置變數。
  • outcome 區段無法使用 events 區段中未定義的事件變數。
  • 如果事件欄位所屬的事件變數已在 events 區段中定義,則 outcome 區段可以使用 events 區段中未使用的事件欄位。
  • outcome」部分只能關聯已在「events」部分關聯的事件變數。當不同事件變數的兩個事件欄位相等時,就會發生關聯。

如需使用結果部分的範例,請參閱「YARA-L 2.0 總覽」。如要瞭解如何使用結果部分偵測及重複資料刪除,請參閱「建立情境感知分析」。

條件區段語法

  • 指定在 events 區段中定義的事件和預留位置比對條件。詳情請參閱下一節「事件和預留位置條件」。
  • (選用) 使用 and 關鍵字,透過 outcome 區段中定義的結果變數指定比對條件。詳情請參閱下節「結果條件」。

計算字元

# 字元是 condition 區段中的特殊字元。如果是在任何事件或預留位置變數名稱之前使用,則代表滿足所有 events 區段條件的不同事件或值數量。

舉例來說,#c > 1 表示變數 c 必須出現超過 1 次。

值字元

$ 字元是 condition 區段中的特殊字元。如果這個符號出現在任何結果變數名稱之前,則代表該結果的值。

如果這個字元出現在任何事件或預留位置變數名稱之前 (例如 $event),則代表 #event > 0

活動和預留位置條件

使用 andor 關鍵字,列出事件和預留位置變數的條件述詞。您可以使用 and 連結任意條件組合; 不過,只有在所有條件都參照相同事件變數時,才能使用 or

以下是使用 or 的有效範例,在同一事件的兩個預留位置之間:

rule ValidConditionOr {
  meta:
  events:
      $e.metadata.event_type = "NETWORK_CONNECTION"

      // Note that all placeholders use the same event variable.
      $ph = $e.principal.user.userid  // Define a placeholder variable to put in match section.
      $ph2 = $e.principal.ip  // Define a second placeholder variable to put in condition section.
      $ph3 = $e.principal.hostname  // Define a third placeholder variable to put in condition section.

  match:
    $ph over 5m

  condition:
    $ph2 or $ph3
}

以下是無效範例,說明如何在不同事件的兩個條件之間使用 or

rule InvalidConditionOr {
  meta:
  events:
      $e.metadata.event_type = "NETWORK_CONNECTION"
      $e2.graph.metadata.entity_type = "FILE"
      $e2.graph.entity.hostname  = $e.principal.hostname

      $ph = $e.principal.user.userid  // Define a placeholder variable to put in match section.

  match:
    $ph over 5m

  condition:
    $e or $e2 // This line will cause an error because there is an or between events.
}

受限和不受限的條件

下列條件為有界條件。這類規則會強制存在相關聯的事件變數,也就是說,任何偵測結果都必須至少出現一次事件。

  • $var // equivalent to #var > 0
  • #var > n // where n >= 0
  • #var >= m // where m > 0

下列條件是不受限的條件。這類變數可讓相關聯的事件變數不存在,也就是說,偵測結果可能不會顯示任何事件發生次數,且對事件變數中欄位的任何參照都會產生零值。無界限條件可用於偵測一段時間內是否沒有發生事件。舉例來說,如果威脅事件在 10 分鐘內沒有緩解事件,使用無界條件的規則稱為不存在規則。

  • !$var // equivalent to #var = 0
  • #var >= 0
  • #var < n // where n > 0
  • #var <= m // where m >= 0

不存在的規定

如要編譯不存在的規則,必須符合下列規定:

  1. 至少一個 UDM 事件必須有界限條件 (也就是至少要有一個 UDM 事件)。
  2. 如果預留位置有不設限的條件,則必須與至少一個設限的 UDM 事件建立關聯。
  3. 如果實體具有無界限條件,則必須與至少一個有界限的 UDM 事件建立關聯。

請參考下列規則,其中省略了條件部分:

rule NonexistenceExample {
  meta:
  events:
      $u1.metadata.event_type = "NETWORK_CONNECTION" // $u1 is a UDM event.
      $u2.metadata.event_type = "NETWORK_CONNECTION" // $u2 is a UDM event.
      $e1.graph.metadata.entity_type = "FILE"        // $e1 is an Entity.
      $e2.graph.metadata.entity_type = "FILE"        // $e2 is an Entity.

      $user = $u1.principal.user.userid // Match variable is required for Multi-Event Rule.

      // Placeholder Associations:
      //   u1        u2
      //   |  \    /
      // port   ip
      //   |       \
      //   e1        e2
      $u1.target.port = $port
      $e1.graph.entity.port = $port
      $u1.principal.ip = $ip
      $u2.target.ip = $ip
      $e2.graph.entity.ip = $ip

      // UDM-Entity Associations:
      // u1 - u2
      // |  \  |
      // e1   e2
      $u1.metadata.event_type = $u2.metadata.event_type
      $e1.graph.entity.hostname = $u1.principal.hostname
      $e2.graph.entity.hostname = $u1.target.hostname
      $e2.graph.entity.hostname = $u2.principal.hostname

  match:
    $user over 5m

  condition:
      <condition_section>
}

以下是 <condition_section>有效範例:

  • $u1 and !$u2 and $e1 and $e2
    • 條件部分會顯示所有 UDM 事件和實體。
    • 至少有一個 UDM 事件受到限制。
  • $u1 and !$u2 and $e1 and !$e2
    • $e2不受限制,但由於與受限的 $u1 相關聯,因此允許使用。如果 $e2 未與 $u1 建立關聯,則無效。
  • #port > 50 and #ip = 0
    • 條件部分沒有 UDM 事件和實體,但現有的預留位置涵蓋所有 UDM 事件和實體。
    • $ip 同時指派給 $u1$u2,且 #ip = 0 是無界限條件。不過,有界條件比無界條件更嚴格。由於 $port 已指派給 $u1,且 #port > 50 是有界條件,因此 $u1 仍是有界條件。

以下是 <condition_section>無效範例:

  • $u1 and $e1
    • 「事件」部分中顯示的每個 UDM 事件和實體,都必須出現在「條件」部分中 (或已指派給出現在「條件」部分的預留位置)。
  • $u1, $u2, $e1, $u2, #port > 50
    • 條件分隔符號不得使用半形逗號。
  • !$u1 and !$u2 and $e1 and $e2
    • 違反第一項規定,即至少要繫結一個 UDM 事件。
  • ($u1 or #port < 50) and $u2 and $e1 and $e2
    • 無界條件不支援 or 關鍵字。
  • ($u1 or $u2) and $e1 and $e2
    • 不同事件變數之間不支援 or 關鍵字。
  • not $u1 and $u2 and $e1 and $e2
    • not 關鍵字不適用於事件和預留位置條件。
  • #port < 50 and #ip = 0
    • 現有的預留位置涵蓋所有 UDM 事件和實體,但所有條件都不受限制。也就是說,沒有任何 UDM 事件受到限制,導致規則無法編譯。

結果條件

在此列出結果變數的條件述詞,並以 andor 關鍵字加入,或以 not 關鍵字開頭。

視結果變數類型而定,指定結果條件的方式也不同:

  • 整數:使用 =, >, >=, <, <=, != 運算子與整數常值比較,例如:

    $risk_score > 10

  • float:使用 =, >, >=, <, <=, != 運算子與浮點常值比較,例如:

    $risk_score <= 5.5

  • string:使用 =!= 與字串常值比較,例如:

    $severity = "HIGH"

  • 整數或陣列清單:使用 arrays.contains 函式指定條件,例如:

    arrays.contains($event_ids, "id_1234")

規則分類

在含有相符區段的規則中指定結果條件,表示該規則會歸類為規則配額的多重事件規則。 如要進一步瞭解單一和多重事件分類,請參閱單一事件規則多重事件規則

「選項」專區語法

在「規則」options部分,您可以指定規則的選項。以下範例說明如何指定選項部分:

rule RuleOptionsExample {
  // Other rule sections

  options:
    allow_zero_values = true
}

您可以使用 key = value 語法指定選項,其中 key 必須是預先定義的選項名稱,而 value 必須是選項的有效值,如下列選項所示:

allow_zero_values

這個選項的有效值為 truefalse,可決定是否啟用這個選項。預設值為 false。如果規則中未指定這個選項,系統會停用此選項。

如要啟用這項設定,請在規則的選項部分新增以下內容:allow_zero_values = true。這麼做可避免規則隱含地篩除比對區段中使用的預留位置零值,詳情請參閱比對區段中的零值處理方式

suppression_window

suppression_window 選項可讓你控制規則觸發偵測的頻率。即使規則條件多次符合,系統也不會在指定時間範圍內,針對同一規則產生多個偵測項目。抑制時間區間設定會採用滾動式時間區間方法,在固定大小的非重疊時間區間內抑制重複項目。

您可以選擇提供 suppression_key,進一步縮小範圍,在抑制時間範圍內抑制哪些規則例項。如未指定,系統會抑制所有規則例項。這個鍵定義為結果變數。

在下列範例中,suppression_window 會設為 5m,而 suppression_key 會設為 $hostname 變數。規則觸發 $hostname 的偵測項目後,接下來五分鐘內,系統會抑制 $hostname 的任何後續偵測項目。不過,如果規則因主機名稱不同的事件而觸發,系統就會建立偵測結果。

suppression_window 的預設值為 0,也就是預設停用抑制視窗。這個選項只適用於沒有 match 區段的單一事件規則

範例:

rule SuppressionWindowExample {
  // Other rule sections

  outcome:
    $suppression_key = $hostname

  options:
    suppression_window = 5m
}

複合偵測規則

Google SecOps 中的複合式偵測功能會連結多個 YARA-L 規則。本節說明如何建構複合規則。如要瞭解複合偵測項目的總覽,請參閱複合偵測項目總覽

規則結構

複合偵測規則一律為多重事件規則,並遵循相同的結構和語法。 複合式偵測規則須符合下列規定:

  • 複合規則必須使用 match 區段定義偵測觸發條件。
  • 如果規則同時使用偵測欄位和 UDM 事件,就必須明確彙整這些資料來源。

如要瞭解規則限制,請參閱「限制」一節。

將偵測結果做為規則的輸入內容

複合規則可以參照任何自訂或精選規則產生的規則偵測結果。Google SecOps 提供兩種方法。

使用結果變數、比對變數或中繼標籤,參照偵測到的內容

如要存取偵測結果中的資料,但不想參照原始 UDM 事件,請使用 outcome 變數、match 變數或 meta 標籤。建議採用這種做法,因為這樣做彈性較大,且與不同規則類型相容性較佳。

舉例來說,如果您要在不同情境中尋找字串,多項規則可以將字串 (例如網址、檔案名稱或登錄機碼) 儲存在通用 outcome 變數中。如要從複合規則存取這個字串,請從 detection 開始,然後使用集合資源中的元素找出相關資訊。

示例: 舉例來說,假設偵測規則產生下列資訊:

  • 結果變數:dest_domain = "cymbal.com"
  • UDM 欄位:target.hostname = "cymbal.com"

在複合規則中,您可以使用下列路徑存取這項資料:

  • detection.detection.outcomes["dest_domain"] 存取 dest_domain 結果變數。
  • detection.collection_elements.references.event.target.hostname 存取 target.hostname UDM 欄位。
  • detection.time_window.start_time.seconds 即可存取偵測時間戳記。

Collection API 和 SecurityResult API 可存取下列兩項資源:

  • 偵測中繼資料和結果值 (detection.detection)
  • 參照規則的基礎 UDM 事件 (collection_elements)

使用規則 ID 或規則名稱參照偵測內容

您可以依規則名稱或 ID 參照規則。如果偵測邏輯取決於特定規則,建議採用這種做法。依名稱或 ID 參照相關規則,可減少分析的資料量,進而提升效能並避免逾時。舉例來說,您可以直接從已知的先前偵測結果查詢 target.urlprincipal.ip 等欄位。

  • 依規則 ID 參照規則 (建議):使用 detection.detection.rule_id 欄位依 ID 參照規則。您可以在 Google SecOps 中規則的網址中找到規則 ID。使用者產生的規則 ID 格式為 ru_UUID,而精選偵測項目的 ID 格式為 ur_UUID。例如:

    detection.detection.rule_id = "ru_e0d3f371-6832-4d20-b0ad-1f4e234acb2b"

  • 依規則名稱參照規則:使用 detection.detection.rule_name 欄位依名稱參照規則。您可以指定確切的規則名稱,或使用規則運算式比對。例如:

    • detection.detection.rule_name = "My Rule Name"
    • detection.detection.rule_name = "/PartOfName/"

注意:建議使用規則 ID 進行參照,因為 ID 是不重複的,而且不會變更。規則名稱可以修改,但可能會導致複合式偵測中斷。

合併事件和偵測結果

複合規則可以結合不同的資料來源,包括 UDM 事件、實體圖表資料和偵測欄位。須符合下列規範:

  • 為每個來源使用不同的變數:為每個資料來源指派專屬事件變數 (例如事件的 $e、偵測的 $d),其中資料來源包括事件、實體和偵測。
  • 根據共用環境加入來源:使用規則條件中的使用者 ID、IP 位址或網域名稱等通用值,連結資料來源。
  • 定義比對時間範圍:請務必加入 match 子句,且時間範圍不得超過 48 小時。

例如:

rule CheckCuratedDetection_with_EDR_and_EG {
  meta:
    author = "noone@cymbal.com"
  events:
    $d.detection.detection.rule_name = /SCC: Custom Modules: Configurable Bad Domain/
    $d.detection.collection_elements.references.event.network.dns.questions.name = $domain
    $d.detection.collection_elements.references.event.principal.asset.hostname = $hostname

    $e.metadata.log_type = "LIMACHARLIE_EDR"
    $e.metadata.product_event_type = "NETWORK_CONNECTIONS"
    $domain = re.capture($e.principal.process.command_line, "\\s([a-zA-Z0-9.-]+\\.[a-zA-Z0-9.-]+)$")
    $hostname = re.capture($e.principal.hostname, "([^.]*)")

    $prevalence.graph.metadata.entity_type = "DOMAIN_NAME"
    $prevalence.graph.metadata.source_type = "DERIVED_CONTEXT"
    $prevalence.graph.entity.hostname = $domain
    $prevalence.graph.entity.domain.prevalence.day_count = 10
    $prevalence.graph.entity.domain.prevalence.rolling_max <= 5
    $prevalence.graph.entity.domain.prevalence.rolling_max > 0

  match:
    $hostname over 1h

  outcome:
    $risk_score = 80
    $CL_target = array($domain)

  condition:
    $e and $d and $prevalence
}

建立連續複合偵測項目

連續複合式偵測會找出相關事件的模式,偵測順序非常重要,例如偵測到暴力登入嘗試,接著登入成功。這些模式可結合多個基本偵測結果、原始 UDM 事件,或兩者兼具。

如要建立循序複合式偵測,您必須在規則中強制執行該順序。如要強制執行預期順序,請使用下列其中一種方法:

  • 滑動視窗:match 條件中使用滑動視窗定義偵測順序。
  • 時間戳記比較:比較規則邏輯中偵測結果的時間戳記,確認這些結果是否按照所選順序發生。

例如:

events:
    $d1.detection.detection.rule_name = "fileEvent_rule"
    $userid = $d1.detection.detection.outcomes["user"]
    $hostname = $d1.detection.detection.outcomes["hostname"]

    $d2.detection.detection.rule_name = "processExecution_rule"
    $userid = $d2.detection.detection.outcomes["user"]
    $hostname = $d2.detection.detection.outcomes["hostname"]

    $d3.detection.detection.rule_name = "networkEvent_rule"
    $userid = $d3.detection.detection.outcomes["user"]
    $hostname = $d3.detection.detection.outcomes["hostname"]

$d3.detection.collection_elements.references.event.metadata.event_timestamp.seconds > $d2.detection.collection_elements.references.event.metadata.event_timestamp.seconds

  match:
    $userid over 24h after $d1

布林運算式

布林運算式是布林型別的運算式。

比較

如要將二元運算式做為條件,請使用下列語法:

  • <EXPR> <OP> <EXPR>

運算式可以是事件欄位、變數、常值或函式運算式。

例如:

  • $e.source.hostname = "host1234"
  • $e.source.port < 1024
  • 1024 < $e.source.port
  • $e1.source.hostname != $e2.target.hostname
  • $e1.metadata.collected_timestamp.seconds > $e2.metadata.collected_timestamp.seconds
  • $port >= 25
  • $host = $e2.target.hostname
  • "google-test" = strings.concat($e.principal.hostname, "-test")
  • "email@google.org" = re.replace($e.network.email.from, "com", "org")

如果兩側都是常值,則視為編譯錯誤。

函式

部分函式運算式會傳回布林值,可用做 events 區段中的個別述詞。這類函式包括:

  • re.regex()
  • net.ip_in_range_cidr()

例如:

  • re.regex($e.principal.hostname, `.*\.google\.com`)
  • net.ip_in_range_cidr($e.principal.ip, "192.0.2.0/24")

參照清單運算式

您可以在「事件」部分使用參照清單。詳情請參閱參考清單一節。

邏輯運算式

您可以在 events 區段中使用邏輯 and 和邏輯 or 運算子,如下列範例所示:

  • $e.metadata.event_type = "NETWORK_DNS" or $e.metadata.event_type = "NETWORK_DHCP"
  • ($e.metadata.event_type = "NETWORK_DNS" and $e.principal.ip = "192.0.2.12") or ($e.metadata.event_type = "NETWORK_DHCP" and $e.principal.mac = "AB:CD:01:10:EF:22")
  • not $e.metadata.event_type = "NETWORK_DNS"

根據預設,優先順序從高到低依序為 notandor

舉例來說,如果運算式中明確定義了 orand 運算子,「a or b and c」會評估為「a or (b and c)」。

events 區段中,如果未明確定義運算子,系統會使用 and 運算子聯結述詞。

如果運算式中隱含 and 運算子,評估順序可能會有所不同。

舉例來說,請看下列比較運算式,其中 or 是明確定義。系統會默示使用 and 運算子。

$e1.field = "bat"
or $e1.field = "baz"
$e2.field = "bar"

這個範例的解讀方式如下:

($e1.field = "bat" or $e1.field = "baz")
and ($e2.field = "bar")

由於 or 是明確定義的,因此系統會先將 or 周圍的述詞分組並評估。最後一個述詞 $e2.field = "bar" 會使用 and 隱含聯結。因此評估順序會有所變更。

列舉型別

您可以在列舉型別中使用運算子。這項功能可套用至規則,簡化及最佳化成效 (使用運算符而非參照清單)。

在下列範例中,「USER_UNCATEGORIZED」和「USER_RESOURCE_DELETION」分別對應 15000 和 15014,因此規則會尋找所有列出的事件:

$e.metadata.event_type >= "USER_CATEGORIZED" and $e.metadata.event_type <= "USER_RESOURCE_DELETION"

活動清單:

  • USER_RESOURCE_DELETION
  • USER_RESOURCE_UPDATE_CONTENT
  • USER_RESOURCE_UPDATE_PERMISSIONS
  • USER_STATS
  • USER_UNCATEGORIZED

Nocase 修飾符

如果您有字串值或規則運算式之間的比較運算式,可以在運算式結尾附加 nocase,忽略大小寫。

  • $e.principal.hostname != "http-server" nocase
  • $e1.principal.hostname = $e2.target.hostname nocase
  • $e.principal.hostname = /dns-server-[0-9]+/ nocase
  • re.regex($e.target.hostname, `client-[0-9]+`) nocase

如果欄位類型是列舉值,則無法使用這項功能。下列範例無效,會產生編譯錯誤:

  • $e.metadata.event_type = "NETWORK_DNS" nocase
  • $e.network.ip_protocol = "TCP" nocase

重複欄位

在整合式資料模型 (UDM) 中,部分欄位標示為重複,表示這些欄位是值清單或其他類型的訊息。

重複欄位和布林運算式

有 2 種布林運算式可對重複欄位執行動作:

  1. 已修改
  2. 未修改

請參考下列事件:

event_original {
  principal {
    // ip is a repeated field
    ip: [ "192.0.2.1", "192.0.2.2", "192.0.2.3" ]

    hostname: "host"
  }
}

已修改的運算式

以下章節說明運算式中 anyall 修飾符的用途和使用方式。

不限

如果重複欄位的任何元素符合條件,則整個事件都符合條件。

  • event_original 滿足 any $e.principal.ip = "192.0.2.1"
  • event_original失敗any $e.repeated_field.field_a = "9.9.9.9
全部

如果重複欄位的所有元素都符合條件,則事件整體符合條件。

  • event_original 滿足 net.ip_in_range_cidr(all $e.principal.ip, "192.0.2.0/8")
  • event_original失敗all $e.principal.ip = "192.0.2.2"

使用 anyall 編寫條件時,請注意以 not 否定條件,可能與使用否定運算子意義不同。

例如:

  • not all $e.principal.ip = "192.168.12.16" 會檢查是否所有 IP 位址都符合 192.168.12.16,也就是檢查至少有一個 IP 位址不符合 192.168.12.16
  • all $e.principal.ip != "192.168.12.16" 會檢查所有 IP 位址是否不符合 192.168.12.16,也就是檢查是否有任何 IP 位址符合 192.168.12.16

限制:

  • anyall 運算子僅適用於重複欄位 (不適用於純量欄位)。
  • anyall 無法用於合併兩個重複欄位。舉例來說,any $e1.principal.ip = $e2.principal.ip 是無效。
  • 參考清單運算式不支援 anyall 運算子。

未修改的運算式

如果運算式未經修改,系統會個別處理重複欄位中的每個元素。如果事件的重複欄位包含 n 個元素,系統會將規則套用至 n 個事件副本,每個副本都有重複欄位中的其中一個元素。這些副本是暫時性的,不會儲存。

這項規則會套用至下列副本:

活動副本 principal.ip principal.hostname
event_copy_1 「192.0.2.1」 「主機」
event_copy_2 「192.0.2.2」 「主機」
event_copy_3 「192.0.2.3」 「主機」

如果任何事件副本符合重複欄位中的所有未修改條件,則該事件整體符合所有條件。也就是說,如果重複欄位有多個條件,事件副本必須符合「所有」條件。下列規則範例會使用上述範例資料集,示範這項行為。

針對 event_original 範例資料集執行下列規則時,系統會傳回一個相符項目,因為 event_copy_1 符合所有事件述詞:

rule repeated_field_1 {
  meta:
  events:
    net.ip_in_range_cidr($e.principal.ip, "192.0.2.0/8") // Checks if IP address matches 192.x.x.x
    $e.principal.ip = "192.0.2.1"
  condition:
    $e
}

針對 event_original 範例資料集執行下列規則時,不會傳回相符項目,因為 $e.principal.ip 中沒有符合「所有」事件述詞的事件副本。

rule repeated_field_2 {
  meta:
  events:
    $e.principal.ip = "192.0.2.1"
    $e.principal.ip = "192.0.2.2"
  condition:
    $e
}

重複欄位中的修改運算式與未修改的運算式相容,因為每個事件副本的元素清單都相同。請參考以下規則:

rule repeated_field_3 {
  meta:
  events:
    any $e.principal.ip = "192.0.2.1"
    $e.principal.ip = "192.0.2.3"
  condition:
    $e
}

這項規則會套用至下列副本:

活動副本 principal.ip any $e.principal.ip
event_copy_1 「192.0.2.1」 ["192.0.2.1", "192.0.2.2", "192.0.2.3"]
event_copy_2 「192.0.2.2」 ["192.0.2.1", "192.0.2.2", "192.0.2.3"]
event_copy_3 「192.0.2.3」 ["192.0.2.1", "192.0.2.2", "192.0.2.3"]

在本例中,所有副本都符合 any $e.principal.ip = "192.0.2.1",但只有 event_copy_3 符合 $e.principal.ip = "192.0.2.3"。因此,整個活動會相符。

這些運算式類型也可以這樣理解:

  • 使用 anyall 的重複欄位運算式會在 event_original 的清單上運作。
  • 重複欄位中未使用 anyall 的運算式,會對個別 event_copy_n 事件執行運算。

重複欄位和預留位置

重複欄位可搭配預留位置指派作業使用。與重複欄位中未修改的運算式類似,系統會為每個元素建立事件副本。以 event_copy 為例,預留位置會取得 event_copy_n 的重複欄位值,其中 n 是事件副本編號。如果預留位置用於比對區段,可能會導致多個比對結果。

以下範例會產生一個相符項目。$ip 預留位置等於 event_copy_1event_copy_1,符合規則中的述詞。192.0.2.1相符項目的事件樣本包含單一元素 event_original

// Generates 1 match.
rule repeated_field_placeholder1 {
  meta:
  events:
    $ip = $e.principal.ip
    $ip = "192.0.2.1"
    $host = $e.principal.hostname

  match:
    $host over 5m

  condition:
    $e
}

下列範例會產生三筆相符項目。$ip 預留位置等於不同值,適用於每個不同的 event_copy_n 副本。分組程序是按照 $ip 執行,因為該項目位於比對區段。因此,您會得到三筆相符項目,每筆相符項目的$ip相符變數值都不同。每個相符項目都有相同的事件樣本:單一元素 event_original

// Generates 3 matches.
rule repeated_field_placeholder2 {
  meta:
  events:
    $ip = $e.principal.ip
    net.ip_in_range_cidr($ip, "192.0.2.0/8") // Checks if IP matches 192.x.x.x

  match:
    $ip over 5m

  condition:
    $e
}

指派給重複欄位的預留位置結果

系統會為每個重複欄位的每個元素指派預留位置,而非整個清單。因此,當這些元素用於結果部分時,系統只會使用滿足先前部分的元素來計算結果。

請參考以下規則:

rule outcome_repeated_field_placeholder {
  meta:
  events:
    $ip = $e.principal.ip
    $ip = "192.0.2.1" or $ip = "192.0.2.2"
    $host = $e.principal.hostname

  match:
    $host over 5m

  outcome:
    $o = array_distinct($ip)

  condition:
    $e
}

這項規則的執行作業分為 4 個階段。第一階段是複製事件:

活動副本 $ip $host $e
event_copy_1 「192.0.2.1」 「主機」 event_id
event_copy_2 「192.0.2.2」 「主機」 event_id
event_copy_3 「192.0.2.3」 「主機」 event_id

事件部分隨即會濾除不符合篩選條件的資料列:

活動副本 $ip $host $e
event_copy_1 「192.0.2.1」 「主機」 event_id
event_copy_2 「192.0.2.2」 「主機」 event_id

event_copy_3 已遭篩除,因為 "192.0.2.3" 不符合 $ip = "192.0.2.1" or $ip = "192.0.2.2"

然後,比對部分會依比對變數分組,結果部分則會對每個群組執行匯總:

$host $o $e
「主機」 ["192.0.2.1", "192.0.2.2"] event_id

$o = array_distinct($ip) 是使用前一階段的 $ip 計算得出,而非事件複製階段。

最後,條件區段會篩選每個群組。由於這項規則只會檢查 $e 是否存在,因此先前資料列會產生單一偵測結果。

$o 未包含 $e.principal.ip 中的所有元素,因為並非所有元素都符合事件部分的所有條件。不過,由於事件範例使用 event_original,因此 e.principal.ip 的所有元素都會顯示在事件範例中。

陣列索引

您可以對重複欄位執行陣列索引編製作業。如要存取第 n 個重複欄位元素,請使用標準清單語法 (元素以 0 為索引)。超出界限的元素會傳回預設值。

  • $e.principal.ip[0] = "192.168.12.16"
  • $e.principal.ip[999] = "" 如果元素少於 1000 個,則評估結果為 true

限制:

  • 索引必須是非負整數常值。舉例來說,$e.principal.ip[-1] 是無效。
  • 如果值為 int 類型 (例如設為 int 的預留位置),則不計入。
  • 陣列索引無法與 anyall 合併使用。舉例來說,any $e.intermediary.ip[0] 是無效。
  • 陣列索引無法與對應語法合併使用。舉例來說,$e.additional.fields[0]["key"] 是無效。
  • 如果欄位路徑包含多個重複欄位,所有重複欄位都必須使用陣列索引。舉例來說,$e.intermediary.ip[0] 無效,因為 intermediaryip 都是重複欄位,但只有 ip 有索引。

重複訊息

重複 message 欄位會產生非預期的效果,降低比對成功的可能性。如以下範例所示。

請參考下列事件:

event_repeated_message {
  // about is a repeated message field.
  about {
    // ip is a repeated string field.
    ip: [ "192.0.2.1", "192.0.2.2", "192.0.2.3" ]

    hostname: "alice"
  }
  about {
    hostname: "bob"
  }
}

如重複欄位中未修改的運算式所述,系統會為重複欄位的每個元素建立事件的暫時副本。請參考以下規則:

rule repeated_message_1 {
  meta:
  events:
    $e.about.ip = "192.0.2.1"
    $e.about.hostname = "bob"
  condition:
    $e
}

這項規則會套用至下列副本:

活動副本 about.ip about.hostname
event_copy_1 「192.0.2.1」 "alice"
event_copy_2 「192.0.2.2」 "alice"
event_copy_3 「192.0.2.3」 "alice"
event_copy_4 "" "bob"

由於沒有任何事件副本符合所有運算式,因此事件不符合規則。

重複訊息和陣列索引

如果對重複訊息欄位使用陣列索引,且未修改運算式,也可能發生非預期行為。請參考下列使用陣列索引的規則範例:

rule repeated_message_2 {
  meta:
  events:
    $e.about.ip = "192.0.2.1"
    $e.about[1].hostname = "bob"
  condition:
    $e
}

這項規則會套用至下列副本:

活動副本 about.ip about[1].hostname
event_copy_1 「192.0.2.1」 "bob"
event_copy_2 「192.0.2.2」 "bob"
event_copy_3 「192.0.2.3」 "bob"
event_copy_4 "" "bob"

由於 event_copy_1 滿足 repeated_message_2 中的所有運算式,因此事件符合規則。

這可能會導致非預期的行為,因為規則 repeated_message_1 缺少陣列索引,因此沒有產生任何相符項目,而規則 repeated_message_2 使用陣列索引,因此產生相符項目。

註解

使用兩個斜線字元 (// comment) 指定註解,或使用斜線星號字元 (/* comment */) 設定多行註解,就像在 C 中一樣。

文字

支援非負整數和浮點數、字串、布林值和規則運算式常值。

字串和規則運算式常值

您可以使用下列任一引號字元,在 YARA-L 2.0 中括住字串。不過,引號文字的解讀方式會因使用的引號而異。

  1. 雙引號 (「"」):用於一般字串。必須包含逸出字元。
    例如:「hello\tworld」—\t 會解讀為 Tab 鍵

  2. 左引號 (`):用於以常值解讀所有字元。
    例如:`hello\tworld` - \t 不會解讀為 Tab 鍵

規則運算式有兩種做法。

如要直接使用規則運算式,而不使用 re.regex() 函式,請使用 /regex/ 做為規則運算式常值。

使用 re.regex() 函式時,您也可以將字串常值做為規則運算式常值。請注意,如果是雙引號字串常值,您必須使用反斜線字元逸出反斜線字元,這可能看起來很奇怪。

舉例來說,下列規則運算式的作用相同:

  • re.regex($e.network.email.from, `.*altostrat\.com`)
  • re.regex($e.network.email.from, ".*altostrat\\.com")
  • $e.network.email.from = /.*altostrat\.com/

Google 建議在規則運算式中使用反引號字元表示字串,方便閱讀。

運算子

您可以在 YARA-L 中使用下列運算子:

運算子 說明
= equal/declaration
!= 不等於
< 小於
<= 小於或等於
> 大於
>= 大於或等於

變數

在 YARA-L 2.0 中,所有變數都會以 $<variable name> 表示。

您可以定義下列類型的變數:

  • 事件變數:以標準化形式 (UDM) 或實體事件表示事件群組。在「條件」部分指定事件變數的條件。events您可以使用名稱、事件來源和事件欄位來識別事件變數。允許的來源為 udm (適用於標準化事件) 和 graph (適用於實體事件)。如果省略來源,系統會將 udm 設為預設來源。事件欄位會以 .<欄位名稱> 鏈結表示 (例如 $e.field1.field2)。事件欄位鏈結一律從頂層來源 (UDM 或實體) 開始。

  • 比對變數 - 在 match 區段中宣告。比對變數會成為查詢的分組欄位,因為系統會針對每個不重複的比對變數組合 (以及每個時間範圍) 傳回一列。如果規則找到相符項目,就會傳回相符變數值。在 events 區段中,指定每個比對變數代表的內容。

  • 預留位置變數:在 events 區段中宣告及定義。預留位置變數與比對變數類似,不過,您可以在 condition 區段中使用預留位置變數,指定相符條件。

使用比對變數和預留位置變數,透過遞移聯結條件宣告事件欄位之間的關係 (詳情請參閱「事件區段語法」)。

關鍵字

YARA-L 2.0 中的關鍵字不區分大小寫。例如 andAND 是等效的。變數名稱不得與關鍵字衝突。例如,$AND$outcome 無效。

偵測引擎規則的關鍵字如下:rulemetamatchovereventsconditionoutcomeoptionsandornotnocaseinregexcidrbeforeafterallanyifmaxminsumarrayarray_distinctcountcount_distinctisnull

地圖

YARA-L 支援結構和標籤的地圖存取權。

結構和標籤

部分 UDM 欄位會使用「Struct」或「Label」資料類型。

如要在 Struct 和 Label 中搜尋特定鍵/值組合,請使用標準對應語法:

// A Struct field.
$e.udm.additional.fields["pod_name"] = "kube-scheduler"
// A Label field.
$e.metadata.ingestion_labels["MetadataKeyDeletion"] = "startup-script"

地圖存取權一律會傳回字串。

支援的案件

以下是支援的關鍵字用途。

活動和結果部分
// Using a Struct field in the events section
events:
  $e.udm.additional.fields["pod_name"] = "kube-scheduler"

// Using a Label field in the outcome section
outcome:
  $value = array_distinct($e.metadata.ingestion_labels["MetadataKeyDeletion"])
將對應值指派給預留位置
$placeholder = $u1.metadata.ingestion_labels["MetadataKeyDeletion"]
在聯結條件中使用對應欄位
// using a Struct field in a join condition between two udm events $u1 and $u2
$u1.metadata.event_type = $u2.udm.additional.fields["pod_name"]

不支援的案例

地圖不支援下列情況。

anyall 關鍵字與地圖合併

舉例來說,系統不支援下列項目:

all $e.udm.additional.fields["pod_name"] = "kube-scheduler"
其他類型的值

對應語法只能傳回字串值。如果是 Struct 資料類型,地圖語法只能存取值為字串的鍵。您無法存取值為整數等其他原始型別的鍵。

重複值處理方式

地圖存取權一律會傳回單一值。在罕見的極端情況下,地圖存取權可能參照多個值,地圖存取權會確定傳回第一個值。

這可能發生於下列情況:

  • 標籤含有重複的鍵。

    標籤結構代表對應,但不會強制執行鍵的唯一性。 按照慣例,地圖應具有不重複的鍵,因此 Google SecOps 不建議使用重複的鍵填入標籤。

    如果對下列資料範例執行規則文字 $e.metadata.ingestion_labels["dupe-key"],會傳回第一個可能的值 val1

    // Disrecommended usage of label with a duplicate key:
    event {
      metadata{
        ingestion_labels{
          key: "dupe-key"
          value: "val1" // This is the first possible value for "dupe-key"
        }
        ingestion_labels{
          key: "dupe-key"
          value: "val2"
        }
      }
    }
    
  • 標籤有重複的祖先欄位。

    重複欄位可能包含標籤做為子項欄位。頂層重複欄位中的兩個不同項目可能含有索引鍵相同的標籤。如果對下列資料範例執行規則文字 $e.security_result.rule_labels["key"],則會傳回第一個可能的值 val3

    event {
      // security_result is a repeated field.
      security_result {
        threat_name: "threat1"
        rule_labels {
          key: "key"
          value: "val3" // This is the first possible value for "key"
        }
      }
      security_result {
        threat_name: "threat2"
        rule_labels {
          key: "key"
          value: "val4"
        }
      }
    }
    

函式

本節說明可在偵測引擎規則和搜尋中使用的 YARA-L 2.0 函式。

這些函式可用於 YARA-L 規則的下列部分:

  • events部分。
  • BOOL_CLAUSE,即可在結果部分中查看條件。

arrays.concat

支援的國家/地區:
arrays.concat(string_array, string_array)

說明

複製原始字串陣列中的元素,然後傳回新的字串陣列。

參數資料類型

ARRAY_STRINGSARRAY_STRINGS

傳回類型

ARRAY_STRINGS

程式碼範例

範例 1

以下範例會串連兩個不同的字串陣列。

arrays.concat(["test1", "test2"], ["test3"]) = ["test1", "test2", "test3"]
範例 2

以下範例會使用空字串串連陣列。

arrays.concat([""], [""]) = ["", ""]
範例 3

以下範例會串連空陣列。

arrays.concat([], []) = []

arrays.join_string

支援的國家/地區:
arrays.join_string(array_of_strings, optional_delimiter)

說明

將字串陣列轉換為單一字串,並以選用參數分隔。如未提供分隔符號,系統會使用空字串。

參數資料類型

ARRAY_STRINGSSTRING

傳回類型

STRING

程式碼範例

以下列舉幾個函式使用範例:

範例 1

這個範例會使用分隔符號,將陣列與非空值元素聯結。

arrays.join_string(["foo", "bar"], ",") = "foo,bar"
範例 2

這個範例會將陣列與空值元素和分隔符號合併。

arrays.join_string(["foo", NULL, "bar"], ",") = "foo,bar"
範例 3

這個範例會將陣列與非空值元素聯結,且不含分隔符號。

arrays.join_string(["foo", "bar"]) = "foobar"

arrays.length

支援的國家/地區:
arrays.length(repeatedField)

說明

傳回重複欄位元素的數量。

參數資料類型

LIST

傳回類型

NUMBER

程式碼範例

範例 1

傳回重複欄位元素的數量。

arrays.length($e.principal.ip) = 2
範例 2

如果路徑上有多個重複欄位,則會傳回重複欄位元素的總數。

arrays.length($e.intermediary.ip) = 3

arrays.max

支援的國家/地區:
arrays.max(array_of_ints_or_floats)

說明

傳回陣列中的最大元素,如果陣列為空白,則傳回零。

參數資料類型

ARRAY_INTS|ARRAY_FLOATS

傳回類型

FLOAT

程式碼範例

以下列舉幾個函式使用範例:

範例 1

這個範例會傳回整數陣列中較大的元素。

arrays.max([10, 20]) = 20.000000
範例 2

這個範例會傳回浮點數陣列中較大的元素。

arrays.max([10.000000, 20.000000]) = 20.000000

arrays.min

支援的國家/地區:
arrays.min(array_of_ints_or_floats[, ignore_zeros=false])

說明

傳回陣列中的最小元素,如果陣列為空,則傳回零。如果將第二個選用引數設為 true,系統會忽略等於零的元素。

參數資料類型

ARRAY_INTS|ARRAY_FLOATSBOOL

傳回類型

FLOAT

程式碼範例

以下列舉幾個函式使用範例:

範例 1

這個範例會傳回整數陣列中的最小元素。

arrays.min([10, 20]) = 10.000000
範例 2

這個範例會傳回浮點數陣列中的最小元素。

arrays.min([10.000000, 20.000000]) = 10.000000
範例 3

這個範例會傳回浮點數陣列中的最小元素,同時忽略零。

arrays.min([10.000000, 20.000000, 0.0], true) = 10.000000

arrays.size

支援的國家/地區:
arrays.size( array )

說明

傳回陣列的大小。若是空陣列,就會傳回 0。

參數資料類型

ARRAY_STRINGS|ARRAY_INTS|ARRAY_FLOATS

傳回類型

INT

程式碼範例

範例 1

這個範例使用包含兩個元素的字串陣列。

arrays.size(["test1", "test2"]) = 2
範例 2

這個範例使用包含 3 個元素的 int 陣列。

arrays.size([1, 2, 3]) = 3
範例 3

這個範例使用包含 1 個元素的浮點數陣列

arrays.size([1.200000]) = 1
範例 4

本範例使用空陣列。

arrays.size([]) = 0

arrays.index_to_float

支援的國家/地區:
arrays.index_to_float(array, index)

說明

傳回陣列中指定索引位置的元素。該索引處的元素會以浮點數形式傳回。

索引是整數值,代表陣列中元素的位置。 根據預設,陣列的第一個元素索引為 0,最後一個元素的索引為 n-1,其中 n 是陣列的大小。 負數索引可存取陣列元素,相對於陣列結尾。舉例來說,索引 -1 是指陣列中的最後一個元素,索引 -2 則是指陣列中的倒數第二個元素。

參數資料類型

ARRAY_STRINGS|ARRAY_INTS|ARRAY_FLOATSINT

傳回類型

FLOAT

程式碼範例

範例 1

以下範例會從浮點數陣列中擷取索引 1 的元素。

arrays.index_to_float([1.2, 2.1, 3.5, 4.6], 1) // 2.1
範例 2

以下範例會從浮點數陣列中擷取索引為 -1 的元素。

arrays.index_to_float([1.2, 2.1, 3.5, 4.6], 0-1) // 4.6
範例 3

以下範例會擷取索引大於陣列大小的元素。

arrays.index_to_float([1.2, 2.1, 3.5, 4.6], 6) // 0.0
範例 4

以下範例會從空陣列擷取元素。

arrays.index_to_float([], 0) // 0.0
範例 5

以下範例會從字串陣列中擷取索引 1 的元素。

arrays.index_to_float(["1.2", "3.3", "2.4"], 1) // 3.3
範例 6

以下範例會從整數陣列中擷取索引 2 的元素。

arrays.index_to_float([1, 3, 2], 2) // 2.0

arrays.index_to_int

支援的國家/地區:
arrays.index_to_int(array_of_inputs, index)

說明

傳回陣列中指定索引的值 (整數)。

索引是整數值,代表陣列中元素的位置。 根據預設,陣列的第一個元素索引為 0,最後一個元素的索引為 n-1,其中 n 是陣列的大小。 負數索引可存取陣列元素,相對於陣列結尾。舉例來說,索引 -1 是指陣列中的最後一個元素,索引 -2 則是指陣列中的倒數第二個元素。

參數資料類型

ARRAY_STRINGS|ARRAY_INTS|ARRAY_FLOATSINT

傳回類型

INT

程式碼範例

範例 1

如果索引處的值為非數字字串,這個函式呼叫會傳回 0。

arrays.index_to_int(["str0", "str1", "str2"], 1) = 0
範例 2

這個函式會傳回索引 -1 的元素。

arrays.index_to_int(["44", "11", "22", "33"], 0-1) = 33
範例 3

若是超出範圍的元素,則傳回 0。

arrays.index_to_int(["44", "11", "22", "33"], 5) = 0
範例 4

這個函式會從索引 1 的浮點數陣列擷取元素。

arrays.index_to_int([1.100000, 1.200000, 1.300000], 1) = 1
範例 5

這個函式會從索引 0 的整數陣列擷取元素。

arrays.index_to_int([1, 2, 3], 0) = 1

arrays.index_to_str

支援的國家/地區:
arrays.index_to_str(array, index)

說明

從陣列中傳回指定索引處的元素 (以字串形式)。索引是整數值,代表陣列中元素的位置。 根據預設,陣列的第一個元素索引為 0,最後一個元素的索引為 n-1,其中 n 是陣列的大小。 負數索引可從陣列結尾存取陣列元素。舉例來說,索引 -1 是指陣列中的最後一個元素,索引 -2 則是指陣列中的倒數第二個元素。

參數資料類型

ARRAY_STRINGS|ARRAY_INTS|ARRAY_FLOATSINT

傳回類型

STRING

程式碼範例

範例 1

以下範例會從字串陣列中擷取索引 1 的元素。

arrays.index_to_str(["test1", "test2", "test3", "test4"], 1) // "test2"
範例 2

以下範例會從字串陣列中,擷取索引為 -1 的元素 (陣列的最後一個元素)。

arrays.index_to_str(["test1", "test2", "test3", "test4"], 0-1) // "test4"
範例 3

以下範例會擷取索引大於陣列大小的元素,並傳回空字串。

arrays.index_to_str(["test1", "test2", "test3", "test4"], 6) // ""
範例 4

以下範例會從空陣列擷取元素。

arrays.index_to_str([], 0) // ""
範例 5

以下範例會從浮點數陣列中擷取索引 0 的元素。輸出內容會以字串形式傳回。

arrays.index_to_str([1.200000, 3.300000, 2.400000], 0) // "1.2"
範例 6

以下範例會從整數陣列中擷取索引 2 的元素。輸出內容為字串。

arrays.index_to_str([1, 3, 2], 2) // "2"

cast.as_bool

支援的國家/地區:
cast.as_bool(string_or_int)

說明

函式會將 int 或字串值轉換為布林值。如果函式呼叫的值無法轉換,就會傳回 FALSE。只會針對整數 1 和不區分大小寫的字串「true」傳回 TRUE。

參數資料類型

INT|STRING

傳回類型

BOOL

程式碼範例

範例 1

這個範例說明如何轉換非布林值字串

cast.as_bool("123") = false
範例 2

Truthy 整數 (1)

cast.as_bool(1) = true
範例 3

Truthy 字串

cast.as_bool("true") = true
範例 4

大寫的真值字串

cast.as_bool("TRUE") = true
範例 5

負整數

cast.as_bool(0-1) = false
範例 6

False 整數 (0)

cast.as_bool(0) = false
範例 7

空字串

cast.as_bool("") = false

cast.as_float

支援的國家/地區:
cast.as_float(string_to_cast)

說明

將數值字串轉換為浮點數。如果函式呼叫的值無法轉換,就會傳回 0。浮點數可維持最多 7 個小數位數的精確度。

參數資料類型

STRING

傳回類型

FLOAT

程式碼範例

範例 1

如果轉換的字串不是數字,則會傳回 0。

cast.as_float("str") = 0.0000000
範例 2

轉換空白字串會傳回 0。

cast.as_float("") = 0.0000000
範例 3

轉換有效的數字字串會傳回浮點值。

cast.as_float("1.012345678") = 1.0123456

cast.as_string

支援的國家/地區:
cast.as_string(int_or_bytes_or_bool, optional_default_string)

說明

cast.as_string 函式會將 INTBYTESBOOL 值轉換為字串表示法。您可以提供選用的 default_string 引數,處理轉換失敗的情況。如果省略 default_string 引數,或輸入無效的 UTF-8BASE64 位元組序列,函式會傳回空字串。

參數資料類型

INT|BYTES|BOOLSTRING

傳回類型

STRING

程式碼範例

整數轉換為字串

這個函式會將整數 123 轉換為字串 "123"

cast.as_string(123) = "123"
將浮點數轉換為字串

這個函式會將浮點數 2.25 轉換為字串 "2.25"

cast.as_string(2.25) = "2.25"
位元組轉字串

這個函式會將原始二進位 b'01 轉換為字串 "\x01"

cast.as_string(b'01, "") = "\x01"
布林值轉換為字串

此函式會將布林值 true 轉換為字串 "true"

cast.as_string(true, "") = "true"
轉換失敗 (預設為選填字串)

如果提供的值無效,函式預設會使用字串「"casting error"」。

cast.as_string(9223372036854775808, "casting error") = "casting error"

指紋

支援的國家/地區:
hash.fingerprint2011(byteOrString)

說明

這個函式會計算輸入位元組序列或字串的 fingerprint2011 雜湊值。這個函式會傳回 INT 範圍內的無符號 [2, 0xFFFFFFFFFFFFFFFF] 值。

參數資料類型

BTYESTRING

傳回類型

INT

程式碼範例

id_fingerprint = hash.fingerprint2011("user123")

群組

支援的國家/地區:
group(field1, field2, field3, ...)

說明

將類似類型的欄位歸入預留位置變數。

在 UDM 搜尋中,同組欄位可用於搜尋多個類似類型的欄位。群組功能與分組欄位類似,但可讓您選取要分組的欄位,以觸發偵測。您可以使用群組函式,收集不同名詞類型中特定實體 (例如主機名稱、IP 位址或使用者 ID) 的相關資訊。

程式碼範例

範例 1

將所有 IP 位址歸類在一起,並依掃描時間範圍內最常見的 IP 位址,提供遞減計數。

$ip = group(principal.ip, about.ip, target.ip)
$ip != ""
match:
  $ip
outcome:
  $count = count_distinct(metadata.id)
order:
  $count desc

hash.sha256

支援的國家/地區:
hash.sha256(string)

說明

傳回輸入字串的 SHA-256 雜湊值。

參數資料類型

STRING

傳回類型

STRING

程式碼範例

範例 1

這個範例顯示輸入內容為有效字串時的 SHA-256 雜湊。

hash.sha256("str") = "8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a"
範例 2

這個範例顯示輸入空白字串時的 SHA-256 雜湊。

hash.sha256("") = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"

math.abs

支援的國家/地區:
math.abs(numericExpression)

說明

傳回整數或浮點運算式的絕對值。

參數資料類型

NUMBER

傳回類型

NUMBER

程式碼範例

範例 1

如果事件時間與指定時間 (以 Unix Epoch 的秒數表示) 相差超過 5 分鐘,這個範例就會傳回 True,無論事件發生在指定時間之前或之後。對 math.abs 的呼叫不得依附於多個變數或預留位置。舉例來說,您無法將下列範例中硬式編碼的時間值 1643687343 替換為 $e2.metadata.event_timestamp.seconds

300 < math.abs($e1.metadata.event_timestamp.seconds - 1643687343)

math.ceil

支援的國家/地區:
math.ceil(number)

說明

傳回大於或等於指定數字的最小整數 (無條件進位)。如果輸入為空值或太大而無法放入 int64,則會傳回 0。

參數資料類型

FLOAT

傳回類型

INT

程式碼範例

本節提供 math.ceil 的使用範例。

範例 1

這個範例會傳回整數的上限。

math.ceil(2.000000) = 2
範例 2

這個範例會傳回負數的上限。

math.ceil(0-1.200000) = -1
範例 3

這個範例會傳回 0,因為數字太大,無法以 64 位元整數表示。

math.ceil(184467440737095516160.0) = 0

math.floor

支援的國家/地區:
math.floor(float_val)

說明

傳回不大於所提供值的最大整數值 (向下捨入)。如果輸入為空值或過大而無法納入 int64,則傳回 0。

參數資料類型

FLOAT

傳回類型

INT

程式碼範例

範例 1

這個範例顯示正數的情況。

math.floor(1.234568) = 1
範例 2

這個範例顯示負數的情況。

math.floor(0-1.234568) = -2
範例 3

這個範例顯示零的情況。

math.floor(0.000000) = 0

math.geo_distance

支援的國家/地區:
math.geo_distance(longitude1, latitude1, longitude2, latitude2))

說明

傳回兩個地理位置 (座標) 之間的距離,單位為公尺。如果座標無效,則傳回 -1。

參數資料類型

FLOATFLOATFLOATFLOAT

傳回類型

FLOAT

程式碼範例

範例 1

以下範例會傳回距離,前提是所有參數都是有效的座標:

math.geo_distance(-122.020287, 37.407574, -122.021810, 37.407574) = 134.564318
範例 2

以下範例會在其中一個參數是截斷的座標時傳回距離:

math.geo_distance(-122.000000, 37.407574, -122.021810, 37.407574) = 1926.421905
範例 3

如果其中一個參數是無效的座標,以下範例會傳回 -1

math.geo_distance(0-122.897680, 37.407574, 0-122.021810, 97.407574) = -1.000000
範例 4

以下範例會在座標相同時傳回 0

math.geo_distance(-122.897680, 37.407574, -122.897680, 37.407574) = 0.000000

math.is_increasing

支援的國家/地區:
math.is_increasing(num1, num2, num3)

說明

取用數值清單 (整數或雙精度浮點數),如果值為遞增順序,則傳回 True,否則傳回 False

參數資料類型

INT|FLOATINT|FLOATINT|FLOAT

傳回類型

BOOL

程式碼範例

範例 1

這個範例包含以秒為單位的時間戳記值。

math.is_increasing(1716769112, 1716769113, 1716769114) = true
範例 2

這個範例包含一個負數 double、一個零 INT64 和一個正數 INT64 值。

math.is_increasing(-1.200000, 0, 3) = true
範例 3

這個範例包含一個負數 double、一個零 INT64 和一個負數 INT64 值。

math.is_increasing(0-1.200000, 0, 0-3) = false
範例 4

這個範例包含兩個負數倍精確度值和一個零 INT64 值。

math.is_increasing(0-1.200000, 0-1.50000, 0) = false
範例 5

這個範例包含一個負數雙精度浮點數和兩個相同的值。

math.is_increasing(0-1.200000, 0, 0) = false

math.log

支援的國家/地區:
math.log(numericExpression)

說明

傳回整數或浮點運算式的自然對數值。

參數資料類型

NUMBER

傳回類型

NUMBER

程式碼範例

範例 1
math.log($e1.network.sent_bytes) > 20

math.pow

支援的國家/地區:
math.pow(base, exponent)

說明

傳回第一個引數的第二個引數次方。如果發生溢位,就會傳回 0。

參數資料類型

底數:INT|FLOAT 指數:INT|FLOAT

傳回類型

FLOAT

程式碼範例

範例 1

這個範例顯示整數案例。

math.pow(2, 2) // 4.00
範例 2

這個範例顯示分數基本情況。

math.pow(2.200000, 3) // 10.648
範例 3

這個範例顯示分數底數和指數的情況。

math.pow(2.200000, 1.200000) // 2.575771
範例 4

這個範例顯示負數次方的情況。

math.pow(3, 0-3) // 0.037037
範例 5

這個範例顯示分數次方的情況。

math.pow(3, 0-1.200000) // 0.267581
範例 6

這個範例顯示負數基本情況。

math.pow(0-3, 0-3) // -0.037037
範例 7

這個範例顯示零基底案例。

math.pow(0, 3) // 0
範例 8

這個範例顯示零次方的案例。

math.pow(9223372036854775807, 0) // 1
範例 9

這個範例顯示大型基本案例。

math.pow(9223372036854775807, 1.200000) // 57262152889751593549824

math.random

支援的國家/地區:
math.random()

說明

產生 [0, 1) 範圍內的 DOUBLE 型虛擬隨機值,包含 0 但不含 1。

傳回類型

FLOAT

程式碼範例

以下範例會檢查隨機值是否在 [0, 1) 範圍內。none if(math.random() >= 0 and math.random() < 1) = true

math.round

支援的國家/地區:
math.round(numericExpression, decimalPlaces)

說明

傳回四捨五入至最接近整數或指定小數位數的值。

參數資料類型

NUMBER

傳回類型

NUMBER

程式碼範例

math.round(10.7) // returns 11
math.round(1.2567, 2) // returns 1.25
math.round(0-10.7) // returns -11
math.round(0-1.2) // returns -1
math.round(4) // returns 4, math.round(integer) returns the integer

math.sqrt

支援的國家/地區:
math.sqrt(number)

說明

傳回指定數字的平方根。如果數字為負數,則傳回 0。

參數資料類型

INT|FLOAT

傳回類型

FLOAT

程式碼範例

範例 1

這個範例會傳回 int 引數的平方根。

math.sqrt(3) = 1.732051
範例 2

這個範例會傳回負數 int 引數的平方根。

math.sqrt(-3) = 0.000000
範例 3

這個範例會傳回零引數的平方根。

math.sqrt(0) = 0.000000
範例 4

這個範例會傳回浮點引數的平方根。

math.sqrt(9.223372) = 3.037000
範例 5

這個範例會傳回負浮點引數的平方根。

math.sqrt(0-1.200000) = 0.000000

個指標

支援的國家/地區:

指標函式可以匯總大量歷來資料。您可以在規則中使用這項功能,方法是在結果部分使用 metrics.functionName()

詳情請參閱「YARA-L 指標」。

net.ip_in_range_cidr

支援的國家/地區:
net.ip_in_range_cidr(ipAddress, subnetworkRange)

說明

如果指定 IP 位址位於指定子網路內,則傳回 true

您可以使用 YARA-L,透過 net.ip_in_range_cidr() 陳述式,在子網路內的所有 IP 位址中搜尋 UDM 事件。支援 IPv4 和 IPv6。

如要搜尋某個 IP 位址範圍,請指定 IP UDM 欄位和 CIDR 範圍。YARA-L 可處理單一和重複的 IP 位址欄位。

如要搜尋特定範圍的 IP 位址,請指定 ip UDM 欄位和無類別跨網域路由 (CIDR) 範圍。YARA-L 可處理單一和重複的 IP 位址欄位。

參數資料類型

STRINGSTRING

傳回類型

BOOL

程式碼範例

範例 1

IPv4 範例:

net.ip_in_range_cidr($e.principal.ip, "192.0.2.0/24")
範例 2

IPv6 範例:

net.ip_in_range_cidr($e.network.dhcp.yiaddr, "2001:db8::/32")

如需使用 net.ip_in_range_cidr() 陳述式的規則範例,請參閱「IP 位址範圍內的單一事件」中的規則範例。

re.regex

支援的國家/地區:

您可以使用下列任一語法,在 YARA-L 2.0 中定義規則運算式比對:

  • 使用 YARA-L 語法 - 與事件相關。 以下是這類語法的泛型表示法:

    $e.field = /regex/
    
  • 使用 YARA-L 語法 - 做為函式,並採用下列參數:

    • 套用規則運算式的欄位。
    • 以字串形式指定的規則運算式。

    以下是這類語法的泛型表示法:

    re.regex($e.field, `regex`)
    

說明

如果字串包含與所提供規則運算式相符的子字串,這個函式會傳回 true。不必在規則運算式的開頭或結尾加上 .*

附註
  • 如要比對確切字串,或只比對前置字元或後置字元,請在規則運算式中加入 ^ (開頭) 和 $ (結尾) 的錨點字元。 舉例來說,/^full$/ 完全符合 "full",而 /full/ 可能符合 "fullest""lawfull""joyfully"
  • 如果 UDM 欄位包含換行字元,regexp 只會比對 UDM 欄位的第一行。如要強制執行完整 UDM 欄位比對,請在規則運算式中加入 (?s)。例如,將 /.*allUDM.*/ 替換為 /(?s).*allUDM.*/
  • 您可以在字串後使用 nocase 修飾符,表示搜尋時應忽略大小寫。

參數資料類型

STRINGSTRING

參數運算式類型

ANYANY

傳回類型

BOOL

程式碼範例

範例 1
// Equivalent to $e.principal.hostname = /google/
re.regex($e.principal.hostname, "google")

re.capture

支援的國家/地區:
re.capture(stringText, regex)

說明

使用引數中提供的規則運算式模式,從字串擷取資料。

這個函式會採用兩個引數:

  • stringText:要搜尋的原始字串。
  • regex:表示要搜尋模式的規則運算式。

規則運算式可包含 0 或 1 個括號中的擷取群組。如果規則運算式包含 0 個擷取群組,函式會傳回第一個相符的完整子字串。如果規則運算式包含 1 個擷取群組,函式會傳回擷取群組的第一個相符子字串。定義兩個以上的擷取群組會傳回編譯器錯誤。

參數資料類型

STRINGSTRING

傳回類型

STRING

程式碼範例

範例 1

在本範例中,如果 $e.principal.hostname 包含「aaa1bbaa2」,則下列項目為 true,因為函式會傳回第一個例項。這個範例沒有擷取群組。

"aaa1" = re.capture($e.principal.hostname, "a+[1-9]")
範例 2

這個範例會擷取電子郵件中 @ 符號後的所有內容。如果 $e.network.email.from 欄位為 test@google.com,範例會傳回 google.com。下列範例包含一個擷取群組。

"google.com" = re.capture($e.network.email.from , "@(.*)")
範例 3

如果規則運算式與文字中的任何子字串都不相符,函式會傳回空字串。您可以排除空字串,省略未發生相符項目的事件,這在使用 re.capture() 搭配不等式時特別重要:

// Exclude the empty string to omit events where no match occurs.
"" != re.capture($e.network.email.from , "@(.*)")

// Exclude a specific string with an inequality.
"google.com" != re.capture($e.network.email.from , "@(.*)")

re.replace

支援的國家/地區:
re.replace(stringText, replaceRegex, replacementText)

說明

執行規則運算式取代作業。

這個函式需要三個引數:

  • stringText:原始字串。
  • replaceRegex:表示要搜尋模式的規則運算式。
  • replacementText:要插入每個相符項目的文字。

傳回衍生自原始 stringText 的新字串,其中所有符合 replaceRegex 模式的子字串都會替換為 replacementText 中的值。您可以在 replacementText 內使用反斜線逸出數字 (\1\9),好在 replaceRegex 模式中插入與對應放入括號內群組相符的文字。請使用 \0 來參照完整的相符文字。

函式會取代非重疊相符項目,並優先取代找到的第一個相符項目。舉例來說,re.replace("banana", "ana", "111") 會傳回字串「b111na」。

參數資料類型

STRINGSTRINGSTRING

傳回類型

STRING

程式碼範例

範例 1

這個範例會擷取電子郵件中 @ 符號後的所有內容,將 com 取代為 org,然後傳回結果。請注意巢狀函式的使用方式。

"email@google.org" = re.replace($e.network.email.from, "com", "org")
範例 2

本範例在 replacementText 引數中使用反斜線逸出數字,參照 replaceRegex 模式的相符項目。

"test1.com.google" = re.replace(
                       $e.principal.hostname, // holds "test1.test2.google.com"
                       "test2\.([a-z]*)\.([a-z]*)",
                       "\\2.\\1"  // \\1 holds "google", \\2 holds "com"
                     )
範例 3

處理空字串和 re.replace() 時,請注意下列情況:

使用空字串做為 replaceRegex

// In the function call below, if $e.principal.hostname contains "name",
// the result is: 1n1a1m1e1, because an empty string is found next to
// every character in `stringText`.
re.replace($e.principal.hostname, "", "1")

如要取代空字串,可以使用 "^$" 做為 replaceRegex

// In the function call below, if $e.principal.hostname contains the empty
// string, "", the result is: "none".
re.replace($e.principal.hostname, "^$", "none")

sample_rate

支援的國家/地區:
optimization.sample_rate(byteOrString, rateNumerator, rateDenominator)

說明

這個函式會根據確定性取樣策略,判斷是否要納入事件。這個函式會傳回:

  • 輸入值的分數,相當於 (rateNumerator / rateDenominator),表示事件應納入樣本。true
  • false,表示不應將事件納入樣本。

這項函式適用於只想處理部分事件的優化情境。等同於:

hash.fingerprint2011(byteOrString) % rateDenominator < rateNumerator

參數資料類型

  • byteOrString:評估結果為 BYTESTRING 的運算式。
  • rateNumerator: 'INT'
  • rateDenominator: 'INT'

傳回類型

BOOL

程式碼範例

events:
    $e.metadata.event_type = "NETWORK_CONNECTION"
    $asset_id = $e.principal.asset.asset_id
    optimization.sample_rate($e.metadata.id, 1, 5) // Only 1 out of every 5 events

  match:
    $asset_id over 1h

  outcome:
    $event_count = count_distinct($e.metadata.id)
  // estimate the usage by multiplying by the inverse of the sample rate
    $usage_past_hour = sum(5.0 * $e.network.sent_bytes)

 condition:
  // Requiring a certain number of events after sampling avoids bias (e.g. a
  // device with just 1 connection will still show up 20% of the time and
  // if we multiply that traffic by 5, we'll get an incorrect estimate)
  $e and ($usage_past_hour > 1000000000) and $event_count >= 100

strings.base64_decode

支援的國家/地區:
strings.base64_decode(encodedString)

說明

傳回字串,其中包含編碼字串的 Base64 解碼版本。

這個函式會將一個 Base64 編碼的字串做為引數。如果 encodedString 不是有效的 Base64 編碼字串,函式會傳回未變更的 encodedString

參數資料類型

STRING

傳回類型

STRING

程式碼範例

範例 1
"test" = strings.base64_decode($e.principal.domain.name)

strings.coalesce

支援的國家/地區:
strings.coalesce(a, b, c, ...)

說明

這個函式可接受無限數量的引數,並傳回第一個未評估為空字串的運算式值 (例如「非零值」)。如果所有引數評估結果都是空字串,函式呼叫會傳回空字串。

引數可以是常值、事件欄位或函式呼叫。所有引數都必須是 STRING 型別。如有任何引數是事件欄位,屬性必須來自同一個事件。

參數資料類型

STRING

傳回類型

STRING

程式碼範例

範例 1

以下範例包含做為引數的字串變數。當 (1) $e.network.email.fromsuspicious@gmail.com 或 (2) $e.network.email.from 為空且 $e.network.email.tosuspicious@gmail.com 時,條件會評估為 true。

"suspicious@gmail.com" = strings.coalesce($e.network.email.from, $e.network.email.to)
範例 2

下列範例會使用兩個以上的引數呼叫 coalesce 函式。這項條件會比較事件 $e 中的第一個非空值 IP 位址與參照清單 ip_watchlist 中的值。這個呼叫中引數的合併順序,與規則條件中列舉的順序相同:

  1. $e.principal.ip 會最先受到評估。
  2. $e.src.ip
  3. $e.target.ip
  4. 如果先前的 ip 欄位未設定,則最後會傳回「No IP」字串做為預設值。
strings.coalesce($e.principal.ip, $e.src.ip, $e.target.ip, "No IP") in %ip_watchlist
範例 3

以下範例嘗試從事件 principal.hostname 和事件 $e2 合併 principal.hostname$e1由於引數是不同的事件變數,因此會傳回編譯器錯誤。

// returns a compiler error
"test" = strings.coalesce($e1.principal.hostname, $e2.principal.hostname)

strings.concat

支援的國家/地區:
strings.concat(a, b, c, ...)

說明

傳回無限多個項目的串連結果,每個項目可以是字串、整數或浮點數。

如有任何引數是事件欄位,屬性必須來自同一個事件。

參數資料類型

STRINGFLOATINT

傳回類型

STRING

程式碼範例

範例 1

下列範例包含字串變數和整數變數做為引數。principal.hostnameprincipal.port 都來自同一個事件 $e,並會串連在一起,傳回字串。

"google:80" = strings.concat($e.principal.hostname, ":", $e.principal.port)
範例 2

下列範例包含字串變數和字串常值做為引數。

"google-test" = strings.concat($e.principal.hostname, "-test") // Matches the event when $e.principal.hostname = "google"
範例 3

以下範例包含字串變數和浮點文字做為引數。以字串表示時,整數的浮點數會以不含小數點的格式表示 (例如 1.0 會表示為「1」)。此外,如果浮點數的小數位數超過 16 位,系統會將其截斷至第 16 位。

"google2.5" = strings.concat($e.principal.hostname, 2.5)
範例 4

以下範例包含字串變數、字串常值、整數變數和浮點常值做為引數。所有變數都來自同一個事件 $e,並與常值串連,以傳回字串。

"google-test802.5" = strings.concat($e.principal.hostname, "-test", $e.principal.port, 2.5)
範例 5

以下範例會嘗試將事件 $e1 中的 principal.port 與事件 $e2 中的 principal.hostname 串連。因為引數是不同的事件變數,所以會傳回編譯器錯誤。

// Will not compile
"test" = strings.concat($e1.principal.port, $e2.principal.hostname)

strings.contains

支援的國家/地區:
strings.contains( str, substr )

說明

如果指定字串包含指定子字串,則傳回 true。否則會傳回 false。

參數資料類型

STRINGSTRING

傳回類型

BOOL

程式碼範例

範例 1

這個範例會傳回 true,因為字串含有子字串「is」。

strings.contains("thisisastring", "is") = true
範例 2

這個範例會傳回 false,因為字串沒有子字串「that」。

strings.contains("thisisastring", "that") = false

strings.count_substrings

支援的國家/地區:
strings.count_substrings(string_to_search_in, substring_to_count)

說明

如果提供字串和子字串,則會傳回 int64,表示字串中不重疊的子字串出現次數。

參數資料類型

STRINGSTRING

傳回類型

INT

程式碼範例

本節包含的範例會計算子字串在指定字串中出現的次數。

範例 1

這個範例使用非空字串和非空單一子字串字元。

strings.count_substrings("this`string`has`four`backticks", "`") = 4
範例 2

本範例使用非空值字串和非空值子字串 (長度超過一個字元)。

strings.count_substrings("str", "str") = 1
範例 3

這個範例使用非空值字串和空白子字串。

strings.count_substrings("str", "") = 0
範例 4

這個範例使用空白字串和長度超過一個字元的非空值子字串。

strings.count_substrings("", "str") = 0
範例 5

這個範例使用空字串和空子字串。

strings.count_substrings("", "") = 0
範例 6

這個範例使用非空值字串和非空值子字串,且子字串長度超過一個字元,出現次數也超過一次。

strings.count_substrings("fooABAbarABAbazABA", "AB") = 3
範例 7

本範例使用非空字串和非空子字串,且子字串長度超過一個字元,出現次數也超過一次。這項功能會醒目顯示重疊子字串出現次數的限制

strings.count_substrings("ABABABA", "ABA") = 2

strings.extract_domain

支援的國家/地區:
strings.extract_domain(url_string)

說明

從字串中擷取網域。

參數資料類型

STRING

傳回類型

STRING

程式碼範例

範例 1

這個範例顯示空白字串

strings.extract_domain("") = ""
範例 2

隨機字串,而非網址

strings.extract_domain("1234") = ""
範例 3

多個反斜線

strings.extract_domain("\\\\") = ""
範例 4

妥善處理非字母字元

strings.extract_domain("http://例子.卷筒纸.中国") = "卷筒纸.中国"
範例 5

處理 URI

strings.extract_domain("mailto:?to=&subject=&body=") = ""
範例 6

實際網址前有多個字元

strings.extract_domain("     \t   !$5*^)&dahgsdfs;http://www.google.com") = "google.com"
範例 7

URI 中的特殊字元 #

strings.extract_domain("test#@google.com") = ""
範例 8

網址中的特殊字元 #

strings.extract_domain("https://test#@google.com") = ""
範例 9

正向測試案例

strings.extract_domain("https://google.co.in") = "google.co.in"

strings.extract_hostname

支援的國家/地區:
strings.extract_hostname(string)

說明

從字串中擷取主機名稱。這項函式會區分大小寫。

參數資料類型

STRING

傳回類型

STRING

程式碼範例

範例 1

這個範例會傳回空字串。

strings.extract_hostname("") = ""
範例 2

隨機字串,而非網址

strings.extract_hostname("1234") = "1234"
範例 3

多個反斜線

strings.extract_hostname("\\\\") = ""
範例 4

妥善處理非英文字元

strings.extract_hostname("http://例子.卷筒纸.中国") = "例子.卷筒纸.中国"
範例 5

處理 URI

strings.extract_hostname("mailto:?to=&subject=&body=") = "mailto"
範例 6

實際網址前有多個字元

strings.extract_hostname("     \t   !$5*^)&dahgsdfs;http://www.google.com") = "www.google.com"
範例 7

URI 中的特殊字元 #

strings.extract_hostname("test#@google.com") = "test"
範例 8

網址中的特殊字元 #

strings.extract_hostname("https://test#@google.com") = "test"

strings.from_base64

支援的國家/地區:
strings.from_base64(base64_encoded_string)

說明

函式會將 Base64 編碼的 STRING 值轉換為原始二進位 BYTES 值。如果函式呼叫的值無法轉換,系統預設會傳回空白的 BYTES

參數資料類型

STRING

傳回類型

BYTES

程式碼範例

將 Base64 編碼字串轉換為位元組

這個函式會將 Base64 編碼的字串轉換為原始二進位位元組表示法。

strings.from_base64("AAAAAG+OxVhtAm+d2sVuny/hW4oAAAAAAQAAAM0AAAA=") = b'000000006f8ec5586d026f9ddac56e9f2fe15b8a0000000001000000cd000000
轉換失敗 (預設為空白位元組)

如果提供的值無效,函式預設為空白位元組。

strings.from_base64("invalid-value") = b'

strings.from_hex

支援的國家/地區:
strings.from_hex(hex_string)

說明

傳回與指定十六進位字串相關聯的位元組。

參數資料類型

STRING

傳回類型

BYTES

程式碼範例

取得與特定十六進位字串相關聯的位元組。

範例 1

這個範例顯示非十六進位字元的轉換。

strings.from_hex("str") // returns empty bytes
範例 2

這個範例顯示輸入內容為空字串。

strings.from_hex("") // returns empty bytes
範例 3

這個範例顯示十六進位字串轉換。

strings.from_hex("1234") // returns 1234 bytes
範例 4

這個範例顯示非 ASCII 字元的轉換。

strings.from_hex("筒纸.中国") // returns empty bytes

strings.length

支援的國家/地區:
strings.length(string_value)

說明

傳回輸入字串中的字元數。

參數資料類型

STRING

傳回類型

INT

程式碼範例

範例 1

以下是字串測試的範例。

strings.length("str") = 3
範例 2

以下是輸入空字串的範例。

strings.length("") = 0
範例 3

以下是含有特殊字元字串的範例。

strings.length("!@#$%^&*()-_") = 12
範例 4

以下是含有空格的字串範例。

strings.length("This is a test string") = 21

strings.ltrim

支援的國家/地區:
strings.ltrim(string_to_trim, cutset)

說明

從指定字串中移除前置空格。這個函式會移除該剪除集中的開頭字元。

參數資料類型

STRINGSTRING

傳回類型

STRING

程式碼範例

以下是應用範例。

範例 1

這個範例使用相同的第一個和第二個引數。

strings.ltrim("str", "str") = ""
範例 2

這個範例使用空字串做為第二個引數。

strings.ltrim("str", "") = "str"
範例 3

這個範例使用空字串做為第一個引數,並使用字串做為第二個引數。

strings.ltrim("", "str") = ""
範例 4

這個範例使用含有空格的字串,以及做為第二個引數的字串。

strings.ltrim("a aastraa aa ", " a") = "straa aa "

strings.reverse

支援的國家/地區:
strings.reverse(STRING)

說明

傳回與輸入字串相反的字串。

參數資料類型

STRING

傳回類型

STRING

程式碼範例

範例 1

以下範例會傳遞短字串。

strings.reverse("str") = "rts"  // The function returns 'rts'.
範例 2

以下範例會傳遞空字串。

strings.reverse("") = ""
範例 3

以下範例會傳遞迴文。

strings.reverse("tacocat") = "tacocat"

strings.rtrim

支援的國家/地區:
strings.rtrim(string_to_trim, cutset)

說明

從指定字串中移除結尾的空白字元。移除該剪除集中的尾隨字元。

參數資料類型

STRINGSTRING

傳回類型

STRING

程式碼範例

以下是應用範例。

範例 1

下列範例會將相同字串做為第一個和第二個引數傳遞。

strings.rtrim("str", "str") = ""
範例 2

以下範例會將空字串做為第二個引數傳遞。

strings.rtrim("str", "") = "str"
範例 3

以下範例會將空字串做為第一個引數,並將非空字串做為第二個引數。

strings.rtrim("", "str") = ""
範例 4

在下列範例中,第一個引數會傳遞含有空白字元的字串,第二個引數則會傳遞非空白字串。

strings.rtrim("a aastraa aa ", " a") = "a aasstr"

strings.to_lower

支援的國家/地區:
strings.to_lower(stringText)

說明

這個函式會接收輸入字串,並將所有字元轉換為小寫,然後傳回字串

參數資料類型

STRING

傳回類型

STRING

程式碼範例

範例 1

以下範例會傳回 true

"test@google.com" = strings.to_lower($e.network.email.to)

strings.to_upper

支援的國家/地區:
strings.to_upper(string_val)

說明

傳回所有字母字元都是大寫的原始字串。

參數資料類型

STRING

傳回類型

STRING

程式碼範例

範例 1

以下範例會以大寫形式傳回提供的引數。

strings.to_upper("example") = "EXAMPLE"

strings.trim

支援的國家/地區:
strings.trim(string_to_trim, cutset)

說明

從指定字串中移除前置和後置空格。此外,也會從輸入字串中移除不需要的字元 (由 cutset 引數指定)。

參數資料類型

STRINGSTRING

傳回類型

STRING

程式碼範例

以下是應用範例。

範例 1

在下列範例中,系統會將同一個字串當做輸入字串和 cutset 傳遞,因此會產生空字串。

strings.trim("str", "str") // ""
範例 2

在下列範例中,系統會將空字串當做 cutset 傳遞,因此會產生原始字串 str,因為 cutset 中未指定要移除的字元。

strings.trim("str", "") = "str"
範例 3

在下列範例中,函式會產生空字串,因為輸入字串已為空白,且沒有要移除的字元。

strings.trim("", "str") = ""
範例 4

在下列範例中,函式會產生 str,因為 trim 函式會移除下列項目:

  • 「a aastraa aa 」中的尾端空白字元
  • cutset 中指定的字元 (空格、a)
strings.trim("a aastraa aa ", " a") = "str"

strings.url_decode

支援的國家/地區:
strings.url_decode(url_string)

說明

提供網址字串後,解碼逸出字元並處理已編碼的 UTF-8 字元。如果解碼失敗,則傳回空白字串。

參數資料類型

STRING

傳回類型

STRING

程式碼範例

範例 1

這個範例顯示正向測試案例。

strings.url_decode("three%20nine%20four") = "three nine four"
範例 2

這個範例顯示空字串案例。

strings.url_decode("") // ""
範例 3

這個範例顯示如何處理非字母字元。

strings.url_decode("%E4%B8%8A%E6%B5%B7%2B%E4%B8%AD%E5%9C%8B") // "上海+中國"
範例 4

這個範例顯示網址解碼範例。

strings.url_decode("http://www.google.com%3Fparam1%3D%22+1+%3E+2+%22%26param2%3D2%3B") // 'http://www.google.com?param1="+1+>+2+"&param2=2;'

timestamp.as_unix_seconds

支援的國家/地區:
timestamp.as_unix_seconds(timestamp [, time_zone])

說明

這個函式會傳回整數,代表指定時間戳記字串自 Unix 紀元開始至今經過的秒數。

  • timestamp 是代表有效紀元時間戳記的字串。格式必須為 %F %T
  • time_zone 為選用項目,代表時區的字串。如果省略,預設值為 GMT。您可以使用字串常值指定時區。選項如下:
    • TZ 資料庫名稱,例如 America/Los_Angeles。詳情請參閱 Wikipedia 的 tz 資料庫時區清單
    • 與世界標準時間的時區偏移量,格式為 (+|-)H[H][:M[M]],例如「-08:00」。

以下是有效的 time_zone 規範符示例,您可以將這些規範符做為第二個引數傳遞至時間擷取函式:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

參數資料類型

STRINGSTRING

傳回類型

INT

程式碼範例

範例 1

有效的紀元時間戳記

timestamp.as_unix_seconds("2024-02-22 10:43:00") = 1708598580
範例 2

有效的 Unix 時間戳記,時區為 America/New_York

timestamp.as_unix_seconds("2024-02-22 10:43:00", "America/New_York") = 1708616580

timestamp.current_seconds

支援的國家/地區:
timestamp.current_seconds()

說明

傳回代表目前時間的整數 (以 Unix 秒數為單位)。這大約等於偵測時間戳記,且以規則的執行時間為準。這個函式是 timestamp.now() 函式的同義詞。

參數資料類型

NONE

傳回類型

INT

程式碼範例

範例 1

以下範例會在憑證過期超過 24 小時時傳回 true。方法是先減去目前的 Unix 秒數,然後使用大於運算子進行比較,計算出時間差。

86400 < timestamp.current_seconds() - $e.network.tls.certificate.not_after

timestamp.get_date

支援的國家/地區:
timestamp.get_date(unix_seconds [, time_zone])

說明

這個函式會傳回 YYYY-MM-DD 格式的字串,代表時間戳記所在的日期。

  • unix_seconds 是代表 Unix 紀元後經過秒數的整數,例如 $e.metadata.event_timestamp.seconds,或是包含該值的預留位置。
  • time_zone 為選用項目,代表 time_zone 的字串。如果省略,預設值為「GMT」。您可以使用字串常值指定時區。選項包括:

以下是有效的時區指定符範例,您可以將這些指定符做為第二個引數傳遞至時間擷取函式:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

參數資料類型

INTSTRING

傳回類型

STRING

程式碼範例

範例 1

在本範例中,我們省略了 time_zone 引數,因此預設為「GMT」。

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_date($ts) = "2024-02-19"
範例 2

這個範例使用字串常值定義 time_zone

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_date($ts, "America/Los_Angeles") = "2024-02-20"

timestamp.get_minute

支援的國家/地區:
timestamp.get_minute(unix_seconds [, time_zone])

說明

這個函式會傳回介於 [0, 59] 之間的整數,代表分鐘。

  • unix_seconds 是代表 Unix 紀元後經過秒數的整數,例如 $e.metadata.event_timestamp.seconds,或是包含該值的預留位置。
  • time_zone 為選用項目,代表時區的字串。如果省略,預設值為「GMT」。您可以使用字串常值指定時區。選項包括:

以下是有效的 time_zone 規範符示例,您可以將這些規範符做為第二個引數傳遞至時間擷取函式:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

參數資料類型

INTSTRING

傳回類型

INT

程式碼範例

範例 1

在本範例中,我們省略了 time_zone 引數,因此預設為「GMT」。

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_hour($ts) = 15
範例 2

這個範例使用字串常值定義 time_zone

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_hour($ts, "America/Los_Angeles") = 15

timestamp.get_hour

支援的國家/地區:
timestamp.get_hour(unix_seconds [, time_zone])

說明

這個函式會傳回 [0, 23] 範圍內的整數,代表小時。

  • unix_seconds 是代表 Unix 紀元後經過秒數的整數,例如 $e.metadata.event_timestamp.seconds,或是包含該值的預留位置。
  • time_zone 為選用項目,代表時區的字串。如果省略,預設值為「GMT」。您可以使用字串常值指定時區。選項包括:

以下是有效的 time_zone 規範符示例,您可以將這些規範符做為第二個引數傳遞至時間擷取函式:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

參數資料類型

INTSTRING

傳回類型

INT

程式碼範例

範例 1

在本範例中,我們省略了 time_zone 引數,因此預設為「GMT」。

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_hour($ts) = 15
範例 2

這個範例使用字串常值定義 time_zone

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_hour($ts, "America/Los_Angeles") = 15

timestamp.get_day_of_week

支援的國家/地區:
timestamp.get_day_of_week(unix_seconds [, time_zone])

說明

這個函式會傳回 [1, 7] 範圍內的整數,代表星期幾 (以週日做為每週起始日)。例如 1 代表星期日,2 代表星期一。

  • unix_seconds 是代表 Unix 紀元後經過秒數的整數,例如 $e.metadata.event_timestamp.seconds,或是包含該值的預留位置。
  • time_zone 為選用項目,代表 time_zone 的字串。如果省略,預設值為「GMT」。您可以使用字串常值指定時區。選項包括:

以下是有效的時區指定符範例,您可以將這些指定符做為第二個引數傳遞至時間擷取函式:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

參數資料類型

INTSTRING

傳回類型

INT

程式碼範例

範例 1

在本範例中,我們省略了 time_zone 引數,因此預設為「GMT」。

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_day_of_week($ts) = 6
範例 2

這個範例使用字串常值定義 time_zone

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_day_of_week($ts, "America/Los_Angeles") = 6

timestamp.get_timestamp

支援的國家/地區:
timestamp.get_timestamp(unix_seconds, optional timestamp_format/time_granularity, optional timezone)

說明

這個函式會傳回 YYYY-MM-DD 格式的字串,代表時間戳記所在的日期。

  • unix_seconds 是代表 Unix 紀元後經過秒數的整數,例如 $e.metadata.event_timestamp.seconds,或是包含該值的預留位置。
  • timestamp_format 為選用項目,是代表時間戳記格式的字串。如未填寫此欄位,則預設值為 %F %T。您可以透過日期時間格式字串或下列任一時間精細度指定格式:SECONDMINUTEHOURDATEWEEKMONTHYEAR。如需更多格式設定選項,請參閱日期和時間部分的格式元素
  • time_zone 為選用項目,代表時區的字串。如果省略,預設值為 GMT。您可以使用字串常值指定時區。選項如下:
    • IANA 時區 (TZ) 資料庫名稱,例如 America/Los_Angeles。詳情請參閱 Wikipedia 上的 tz 資料庫時區清單
    • 與世界標準時間的時區偏移量,格式為 (+|-)H[H][:M[M]],例如「-08:00」。

以下是有效的 time_zone 規範符示例,您可以將這些規範符做為第二個引數傳遞至時間擷取函式:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

參數資料類型

INTSTRINGSTRING

傳回類型

STRING

程式碼範例

範例 1

在本例中,系統省略了 time_zone 引數,因此預設為 GMT

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_timestamp($ts) = "2024-02-22 10:43:51"
範例 2

這個範例使用字串常值定義 time_zone

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_timestamp($ts, "%F %T", "America/Los_Angeles") = "2024-02-22 10:43:51"
範例 3

這個範例使用字串常值定義 timestamp_format

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_timestamp($ts, "%Y-%m", "GMT") = "2024-02"
範例 4

這個範例會將 Unix 時間戳記格式化為字串,精確度為秒。

timestamp.get_timestamp(1708598631, "SECOND", "GMT") = "2024-02-22 10:43:51"
範例 5

這個範例會將 UNIX 時間戳記格式化為字串,精確度為分鐘。

timestamp.get_timestamp(1708598631, "MINUTE", "GMT") = "2024-02-22 10:43"
範例 6

這個範例會將 Unix 時間戳記格式化為字串,精確度為小時。

timestamp.get_timestamp(1708598631, "HOUR", "GMT") = "2024-02-22 10"
範例 7

這個範例會將 Unix 時間戳記格式化為字串,精細程度為天。

timestamp.get_timestamp(1708598631, "DATE", "GMT") = "2024-02-22"
範例 8

這個範例會將 Unix 時間戳記格式化為字串,並以週為單位。

timestamp.get_timestamp(1708598631, "WEEK", "GMT") = "2024-02-18"
範例 9

這個範例會將 UNIX 時間戳記格式化為字串,精確度為月份。

timestamp.get_timestamp(1708598631, "MONTH", "GMT") = "2024-02"
範例 10

這個範例會將 Unix 時間戳記格式化為字串,精確度為年。

timestamp.get_timestamp(1708598631, "YEAR", "GMT") = "2024"

timestamp.get_week

支援的國家/地區:
timestamp.get_week(unix_seconds [, time_zone])

說明

這個函式會傳回 [0, 53] 範圍內的整數,代表一年中的週次。一週以星期日開始。一年中第一個星期日之前的日期為第 0 週。

  • unix_seconds 是代表 Unix 紀元後經過秒數的整數,例如 $e.metadata.event_timestamp.seconds,或是包含該值的預留位置。
  • time_zone 為選用項目,代表時區的字串。如果省略,預設值為「GMT」。您可以使用字串常值指定時區。選項包括:

以下是有效的 time_zone 規範符示例,您可以將這些規範符做為第二個引數傳遞至時間擷取函式:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

參數資料類型

INTSTRING

傳回類型

INT

程式碼範例

範例 1

在本範例中,我們省略了 time_zone 引數,因此預設為「GMT」。

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_week($ts) = 0
範例 2

這個範例使用字串常值定義 time_zone

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_week($ts, "America/Los_Angeles") = 0

timestamp.now

支援的國家/地區:
timestamp.now()

說明

傳回從 1970-01-01 00:00:00 UTC 算起的秒數。這也稱為 Unix Epoch 時間

傳回類型

INT

程式碼範例

範例 1

以下範例會傳回 2024 年 5 月 22 日 18:16:59 執行的程式碼時間戳記。

timestamp.now() = 1716401819 // Unix epoch time in seconds for May 22, 2024 at 18:16:59

window.avg

支援的國家/地區:
window.avg(numeric_values [, should_ignore_zero_values])

說明

傳回輸入值的平均值 (可以是整數或浮點數)。將選用的第二個引數設為 true,即可忽略零值。

參數資料類型

INT|FLOAT

傳回類型

FLOAT

程式碼範例

範例 1

這個範例顯示整數平均值。

// This rule sets the outcome $size_mode to the average
// file size in the 5 minute match window.
events:
 $e.user.userid = $userid
match:
 $userid over 5m
outcome:
  $size_mode = window.avg($e.file.size) // yields 2.5 if the event file size values in the match window are 1, 2, 3 and 4
範例 2

這個範例顯示浮點數平均值。

events:
 $e.user.userid = $userid
match:
 $userid over 5m
outcome:
  $size_mode = window.avg($e.file.size) // yields 1.75 if the event file size values in the match window are 1.1 and 2.4
範例 3

負數輸入平均值

events:
 $e.user.userid = $userid
match:
 $userid over 5m
outcome:
  $size_mode = window.avg($e.file.size) // yields 0.6 if the event file size values in the match window are -1.1, 1.1, 0.0 and 2.4
範例 4

0 returns 0

events:
 $e.user.userid = $userid
match:
 $userid over 5m
outcome:
  $size_mode = window.avg($e.file.size) // yields 0 if the event file size values in the match window is 0
範例 5

忽略 0 個值

events:
 $e.user.userid = $userid
match:
 $userid over 5m
outcome:
  $size_mode = window.avg($e.file.size, true) // yields 394 if the event file size values in the match window are 0, 0, 0 and 394

window.first

支援的國家/地區:
window.first(values_to_sort_by, values_to_return)

說明

這項匯總函式會傳回字串值,該值衍生自相符時間範圍內相關性最低的整數值事件。舉例來說,您可從比對時間範圍內時間戳記最低的事件 (最早的事件) 取得使用者 ID。

參數資料類型

INTSTRING

傳回類型

STRING

程式碼範例

在比對視窗中,取得與最低相關整數值相關聯的事件所衍生的字串值。

// This rule sets the outcome $first_event to the lowest correlated int value
// in the 5 minute match window.
events:
 $e.user.userid = $userid
match:
 $userid over 5m
outcome:
  $first_event = window.first($e.metadata.timestamp.seconds, $e.metadata.event_type) // yields v1 if the events in the match window are 1, 2 and 3 and corresponding values v1, v2, and v3.

window.last

支援的國家/地區:
window.last(values_to_sort_by, values_to_return)

說明

這項匯總函式會傳回字串值,該值衍生自相符視窗中相關性最高的整數值事件。舉例來說,您可以在相符時間範圍內,從時間戳記最低 (時間戳記最高) 的事件取得使用者 ID。

參數資料類型

INTSTRING

傳回類型

STRING

程式碼範例

在比對視窗中,取得與最高相關 int 值衍生自事件的字串值。

// This rule sets the outcome $last_event to the highest correlated int value
// in the 5 minute match window.
events:
 $e.user.userid = $userid
match:
 $userid over 5m
outcome:
  $last_event = window.first($e.metadata.timestamp.seconds, $e.metadata.event_type) // yields v3 if the events in the match window are 1, 2 and 3 and corresponding values v1, v2, and v3.

window.median

支援的國家/地區:
window.median(numeric_values, should_ignore_zero_values)

說明

傳回輸入值的中位數。如有 2 個中位數,系統會隨機選擇 1 個做為傳回值。

參數資料類型

INT|FLOATBOOL

傳回類型

FLOAT

程式碼範例

範例 1

這個範例會在輸入值不為零時傳回中位數。

rule median_file_size {
    meta:
    events:
      $e.metadata.event_type = "FILE_COPY"
        $userid = $e.principal.user.userid
    match:
      $userid over 1h
    outcome:
      $median_file_size = window.median($e.principal.file.size) // returns 2 if the file sizes in the match window are [1, 2, 3]
  condition:
      $e
}
範例 2

如果輸入內容包含不應忽略的零值,這個範例會傳回中位數。

rule median_file_size {
    meta:
    events:
      $e.metadata.event_type = "FILE_COPY"
        $userid = $e.principal.user.userid
    match:
      $userid over 1h
    outcome:
      $median_file_size = window.median($e.principal.file.size) // returns 1 if the file sizes in the match window are [0,0, 1, 2, 3]
  condition:
      $e
}
範例 3

這個範例會在輸入內容包含應忽略的零值時,傳回中位數。

rule median_file_size {
    meta:
    events:
      $e.metadata.event_type = "FILE_COPY"
        $userid = $e.principal.user.userid
    match:
      $userid over 1h
    outcome:
      $median_file_size = window.median($e.principal.file.size, true) // returns 2 if the file sizes in the match window are [0,0, 1, 2, 3]
  condition:
      $e
}
範例 4

如果輸入內容包含應忽略的所有零值,這個範例會傳回中位數。

rule median_file_size {
    meta:
    events:
      $e.metadata.event_type = "FILE_COPY"
        $userid = $e.principal.user.userid
    match:
      $userid over 1h
    outcome:
      $median_file_size = window.median($e.principal.file.size) // returns 0 if the file sizes in the match window are [0,0]
  condition:
      $e
}
範例 5

這個範例顯示,如果有多個中位數,系統只會傳回一個中位數。

rule median_file_size {
    meta:
    events:
      $e.metadata.event_type = "FILE_COPY"
        $userid = $e.principal.user.userid
    match:
      $userid over 1h
    outcome:
      $median_file_size = window.median($e.principal.file.size) // returns 1 if the file sizes in the match window are [1, 2, 3, 4]
  condition:
      $e
}

window.mode

支援的國家/地區:
window.mode(values)

說明

傳回輸入值的眾數。如果有多個可能的模式值,系統只會非決定性地選擇其中一個值做為傳回值。

參數資料類型

INT|FLOAT|STRING

傳回類型

STRING

程式碼範例

範例 1

取得比對視窗中值的模式。

// This rule sets the outcome $size_mode to the most frequently occurring
// file size in the 5 minute match window.
events:
 $e.user.userid = $userid
match:
 $userid over 5m
outcome:
  $size_mode = window.mode($e.file.size) // yields 1.6 if the event file size values in the match window are 1.6, 2, and 1.6

window.stddev

支援的國家/地區:
window.stddev(numeric_values)

說明

傳回相符視窗中輸入值的標準差。

參數資料類型

INT|FLOAT

傳回類型

FLOAT

程式碼範例

範例 1

這個範例會傳回相符視窗中整數的標準差。

// This rule creates a detection when the file size stddev in 5 minutes for a user is over a threshold.
events:
 $e.user.userid = $userid
match:
 $userid over 5m
outcome:
  $p1 = window.stddev($e.file.size) // yields 4.0 if the event file size values in the match window are [10, 14, 18].
condition:
  $e and #p1 > 2
範例 2

這個範例會傳回比對視窗中浮點數的標準差。

events:
 $e.user.userid = $userid
match:
 $userid over 5m
outcome:
  $p1 = window.stddev($e.file.size) // yields 4.488686 if the event file size values in the match window are [10.00, 14.80, 18.97].
condition:
  $e and #p1 > 2
範例 3

這個範例會傳回含有負數的相符時間範圍內的標準差。

events:
 $e.user.userid = $userid
match:
 $userid over 5m
outcome:
  $p1 = window.stddev($e.file.size) // yields 48.644972 if the event file size values in the match window are [-1, -56, -98].
condition:
  $e and #p1 > 2
範例 4

如果比對視窗中的所有值都相同,這個範例會傳回零標準差。

events:
 $e.user.userid = $userid
match:
 $userid over 5m
outcome:
  $p1 = window.stddev($e.file.size) // yields 0.000000 if the event file size values in the match window are [1, 1, 1].
condition:
  $e and #p1 > 2
範例 5

這個範例會傳回含有正數和負數的相符視窗標準差。

events:
 $e.user.userid = $userid
match:
 $userid over 5m
outcome:
  $p1 = window.stddev($e.file.size) // yields 1.000000 if the event file size values in the match window are [1, 0, -1].
condition:
  $e and #p1 > 10

window.variance

支援的國家/地區:
window.variance(values)

說明

這個函式會傳回輸入值的指定變異數。

參數資料類型

INT|FLOAT

傳回類型

FLOAT

程式碼範例

範例 1

這個範例會傳回所有整數的變異數。

// This rule creates a detection when the file size variance in 5 minutes for a user is over a threshold.
events:
 $e.user.userid = $userid
match:
 $userid over 5m
outcome:
  $p1 = window.variance($e.file.size) // yields 16 if the event file size values in the match window are [10, 14, 18].
condition:
  $e and #p1 > 10
範例 2

這個範例會傳回所有浮點數的變異數。

events:
 $e.user.userid = $userid
match:
 $userid over 5m
outcome:
  $p1 = window.variance($e.file.size) // yields 20.148300 if the event file size values in the match window are [10.00, 14.80, 18.97].
condition:
  $e and #p1 > 10
範例 3

這個範例會傳回負數的變異數。

events:
 $e.user.userid = $userid
match:
 $userid over 5m
outcome:
  $p1 = window.variance($e.file.size) // yields 2366.333333 if the event file size values in the match window are [-1, -56, -98].
condition:
  $e and #p1 > 10
範例 4

這個範例會傳回較小的變異數值。

events:
 $e.user.userid = $userid
match:
 $userid over 5m
outcome:
  $p1 = window.variance($e.file.size) // yields 0.000000 if the event file size values in the match window are [0.000000, 0.000000, 0.000100].
condition:
  $e and #p1 > 10
範例 5

這個範例會傳回零變異數。

events:
 $e.user.userid = $userid
match:
 $userid over 5m
outcome:
  $p1 = window.variance($e.file.size) // yields 0.000000 if the event file size values in the match window are [1, 1, 1].
condition:
  $e and #p1 > 10
範例 6

這個範例會傳回正數和負數的變異數。

events:
 $e.user.userid = $userid
match:
 $userid over 5m
outcome:
  $p1 = window.variance($e.file.size) // yields 1.000000 if the event file size values in the match window are [1, 0, -1].
condition:
  $e and #p1 > 10

bytes.to_base64

支援的國家/地區:
bytes.to_base64(bytes, optional_default_string)

說明

函式會將 bytes 值轉換為 base64 encoded string。如果函式呼叫的值無法轉換,預設會傳回空字串。

參數資料類型

BYTESSTRING

傳回類型

STRING

程式碼範例

將原始二進位位元組轉換為 Base64 編碼字串

這個函式會將原始二進位位元組轉換為 Base64 編碼字串。

bytes.to_base64(b'000000006f8ec5586d026f9ddac56e9f2fe15b8a0000000001000000cd000000) = "AAAAAG+OxVhtAm+d2sVuny/hW4oAAAAAAQAAAM0AAAA="
轉換失敗 (預設為選填字串)

如果提供的位元組值無效,函式會預設為 "invalid bytes"

bytes.to_base64(b'000000006f8ec5586d", "invalid bytes") = "invalid bytes"

函式到預留位置的指派

您可以將函式呼叫的結果指派給 events 區段中的預留位置。例如:

$placeholder = strings.concat($e.principal.hostname, "my-string").

接著,您可以在 matchconditionoutcome 區段中使用預留位置變數。 不過,函式指派給預留位置時有兩項限制:

  1. 函式中每個預留位置的預留位置指派作業,都必須指派給含有事件欄位的運算式。舉例來說,以下範例皆有效:

    $ph1 = $e.principal.hostname
    $ph2 = $e.src.hostname
    
    // Both $ph1 and $ph2 have been assigned to an expression containing an event field.
    $ph1 = strings.concat($ph2, ".com")
    
    $ph1 = $e.network.email.from
    $ph2 = strings.concat($e.principal.hostname, "@gmail.com")
    
    // Both $ph1 and $ph2 have been assigned to an expression containing an event field.
    $ph1 = strings.to_lower($ph2)
    

    但下列範例無效:

    $ph1 = strings.concat($e.principal.hostname, "foo")
    $ph2 = strings.concat($ph1, "bar") // $ph2 has NOT been assigned to an expression containing an event field.
    
  2. 函式呼叫應取決於一個且僅一個事件。不過,您可以在函式呼叫引數中使用來自同一事件的多個欄位。 舉例來說,以下是有效值:

    $ph = strings.concat($event.principal.hostname, "string2")

    $ph = strings.concat($event.principal.hostname, $event.src.hostname)

    但下列項目無效:

    $ph = strings.concat("string1", "string2")

    $ph = strings.concat($event.principal.hostname, $anotherEvent.src.hostname)

參照清單語法

如要進一步瞭解參考清單行為和參考清單語法,請參閱參考清單頁面

您可以在 eventsoutcome 區段中使用參照清單。以下是在規則中使用各種參照清單的語法:

// STRING reference list
$e.principal.hostname in %string_reference_list

// REGEX reference list
$e.principal.hostname in regex %regex_reference_list

// CIDR reference list
$e.principal.ip in cidr %cidr_reference_list

您也可以搭配參照清單使用 not 運算子和 nocase 運算子,如下列範例所示:

// Exclude events whose hostnames match substrings in my_regex_list.
not $e.principal.hostname in regex %my_regex_list

// Event hostnames must match at least 1 string in my_string_list (case insensitive).
$e.principal.hostname in %my_string_list nocase

nocase 運算子與 STRING 清單和 REGEX 清單相容。

基於效能考量,Detection Engine 會限制參考清單的使用。

  • 規則中的 in 陳述式上限 (無論是否使用特殊運算子):7
  • 使用 regex 運算子的 in 陳述式數量上限:4
  • 使用 cidr 運算子的 in 陳述式數量上限:2

型別檢查

在介面中建立規則時,Google SecOps 會對 YARA-L 語法執行型別檢查。顯示的型別檢查錯誤可協助您修訂規則,確保規則能正常運作。

以下是無效述詞的範例:

// $e.target.port is of type integer which cannot be compared to a string.
$e.target.port = "80"

// "LOGIN" is not a valid event_type enum value.
$e.metadata.event_type = "LOGIN"

偵測事件取樣

多事件規則的偵測結果包含事件樣本,可提供導致偵測結果的事件相關背景資訊。規則中定義的每個事件變數最多可有 10 個事件樣本。舉例來說,如果規則定義了 2 個事件變數,每次偵測最多可有 20 個事件樣本。這項限制適用於每個事件變數。如果一個事件變數在這個偵測中適用 2 個事件,另一個事件變數適用 15 個事件,則產生的偵測會包含 12 個事件樣本 (2 + 10)。

超過上限的事件樣本不會納入偵測範圍。

如要進一步瞭解導致偵測結果的事件,您可以在結果部分使用匯總,在偵測結果中輸出額外資訊。

如果您在使用者介面中查看偵測結果,可以下載偵測到的所有事件樣本。詳情請參閱「下載活動」。

還有其他問題嗎?向社群成員和 Google SecOps 專業人員尋求答案。