重複欄位

支援的國家/地區:

在 Unified Data Model (UDM) 中,部分欄位標示為重複,表示這些欄位是值或其他類型訊息的清單。本文說明如何針對重複的 UDM 欄位使用運算式、預留位置、陣列索引和重複訊息。

布林運算式和重複欄位

修改過和未修改的布林運算式都可以作用於重複欄位。

請參考下列事件:

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

    hostname: "host"
  }
}

已修改的運算式

在重複欄位的運算式中使用 any 和 all 修飾符。

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

    • 「event_original」滿足「any $e.principal.ip = "192.0.2.1"」
    • event_original失敗any $e.repeated_field.field_a = "9.9.9.9"
  • all - 如果重複欄位的所有元素都符合條件,則整個事件都符合條件。例如:

    • 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"

使用 any 或 all 編寫條件時,請注意,使用 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

限制:

  • any 和 all 運算子僅與重複欄位 (而非純量欄位) 相容。
  • any 和 all 無法用於彙整兩個重複欄位。舉例來說,any $e1.principal.ip = $e2.principal.ip 無效。
  • 參考清單運算式不支援 any 和 all 運算子。

未經修改的運算式

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

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

活動副本 principal.ip principal.hostname
event_copy_1 「192.0.2.1」 「主機」
event_copy_2 "192.0.2.2" "host"
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"。因此,整個事件會視為相符。

另一種思考這些運算式類型的方式如下:

  • 使用 any 或 all 的重複欄位運算式會在 event_original 的清單上運作。
  • 重複欄位上的運算式 (不使用 any 或 all) 會對個別 event_copy_n 事件執行運算。

預留位置和重複欄位

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

範例:重複欄位預留位置

以下範例會產生一個相符項目。`$ip` 預留位置等於 `event_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
}

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

系統會為每個重複欄位的每個元素指派預留位置,而非整個清單。在 outcome 區段中使用時,系統只會使用滿足先前區段的元素計算結果。

請參考以下規則:

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
}

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

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

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

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

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

「match」部分會依比對變數分組,而「outcome」部分則會對每個群組執行彙整作業:

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

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

最後,condition 區段會篩選每個群組。由於這項規則只會檢查 $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 的預留位置) 不會計入。
  • 陣列索引無法與 any 或 all 合併使用。舉例來說,any $e.intermediary.ip[0] 無效。
  • 陣列索引無法與對應語法合併使用。舉例來說,$e.additional.fields[0]["key"] 無效。
  • 如果欄位路徑包含多個重複欄位,所有重複欄位都必須使用陣列索引。舉例來說,$e.intermediary.ip[0] 無效,因為 intermediary 和 ip 都是重複欄位,但只有 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 使用陣列索引,因此產生相符項目。

還有其他問題嗎?向社群成員和 Google SecOps 專業人員尋求解答。