YARA-L 的已知問題和限制

本文說明 YARA-L 的已知問題和限制。

含有重複欄位解除巢狀結構的結果匯總

如果規則參照含有多個元素的事件變數中重複的欄位,每個元素都會拆成個別的事件資料列。

舉例來說,事件 $e 中重複欄位 target.ip 的兩個 IP 位址會分成兩個 $e 例項,每個例項都有不同的 target.ip 值。

rule outbound_ip_per_app {
  meta:
  events:
    $e.principal.application = $app
  match:
    $app over 10m
  outcome:
    $outbound_ip_count = count($e.target.ip) // yields 2.
  condition:
    $e
}

重複欄位展開前事件記錄

下表顯示解除重複欄位的事件記錄:

metadata.id principal.application target.ip
aaaaaaaaa Google SecOps [192.0.2.20192.0.2.28]

解除重複欄位的巢狀結構後的事件記錄

下表顯示解除重複欄位的事件記錄:

metadata.id principal.application target.ip
aaaaaaaaa Google SecOps 192.0.2.20
aaaaaaaaa Google SecOps 192.0.2.28

如果規則參照巢狀重複欄位 (例如 security_results.action),則會在父項和子項層級中進行解巢。從單一事件展開所產生的例項,會形成父項和子項欄位中元素的笛卡兒積。在以下規則範例中,事件 $esecurity_results 上有兩個重複值,在 security_results.actions 上有兩個重複值,因此會展開為四個例項。

rule security_action_per_app {
  meta:
  events:
    $e.principal.application = $app
  match:
    $app over 10m
  outcome:
    $security_action_count = count($e.security_results.actions) // yields 4.
  condition:
    $e
}

重複欄位展開前事件記錄

下表顯示解除重複欄位的事件記錄:

metadata.id principal.application security_results
aaaaaaaaa Google SecOps [ { actions: [ ALLOW, FAIL ] }{ actions: [ CHALLENGE, BLOCK ] } ]

重複欄位展開後的事件記錄

下表顯示解除重複欄位的事件記錄:

metadata.id principal.application security_results.actions
aaaaaaaaa Google SecOps 允許
aaaaaaaaa Google SecOps 失敗
aaaaaaaaa Google SecOps 挑戰
aaaaaaaaa Google SecOps 封鎖

當規則參照一或多個重複欄位,且父欄位也是重複欄位時,規則評估中的這種展開行為可能會產生非預期的結果匯總。sum()array()count() 等非明確匯總無法考量同一個事件中其他欄位產生的重複值,這些值是由於取消巢狀行為而產生。在以下範例規則中,事件 $e 有單一主機名稱 google.com,但結果 hostnames 會匯總相同事件 $e 的四個未巢狀例項,每個例項都有重複的 principal.hostname 值。由於 security_results.actions 上重複的值已解除巢狀結構,因此這個結果會產生四個主機名稱,而不是一個。

rule security_action_per_app {
  meta:
  events:
    $e.principal.application = $app
  match:
    $app over 10m
  outcome:
    $hostnames = array($e.principal.hostname) // yields 4.
    $security_action_count = count($e.security_results.action) // yields 4.
  condition:
    $e
}

重複欄位展開前事件記錄

下表顯示解除重複欄位的事件記錄:

metadata.id principal.application principal.hostname security_results
aaaaaaaaa Google SecOps google.com [ { action: [ ALLOW, FAIL ] }{ action: [ CHALLENGE, BLOCK ] } ]

重複欄位展開後的事件記錄

下表顯示解除重複欄位的事件記錄:

metadata.id principal.application principal.hostname security_results.action
aaaaaaaaa Google SecOps google.com 允許
aaaaaaaaa Google SecOps google.com 失敗
aaaaaaaaa Google SecOps google.com 挑戰
aaaaaaaaa Google SecOps google.com 封鎖

解決方法

忽略重複值或移除重複值的匯總作業不會受到這項展開行為的影響。如果因為取消巢狀結構而遇到非預期的結果值,請使用匯總的 distinct 版本。

以下匯總不會受到先前所述的展開行為影響。

  • max()
  • min()
  • array_distinct()
  • count_distinct()

包含多個事件變數的結果匯總

如果規則包含多個事件變數,則在匯總中,每個偵測到的事件組合都會顯示為一個項目。舉例來說,如果下列範例規則針對列出的事件執行:

events:
  $e1.field = $e2.field
  $e2.somefield = $ph

match:
  $ph over 1h

outcome:
   $some_outcome = sum(if($e1.otherfield = "value", 1, 0))

condition:
  $e1 and $e2
event1:
  // UDM event 1
  field="a"
  somefield="d"

event2:
  // UDM event 2
  field="b"
  somefield="d"

event3:
  // UDM event 3
  field="c"
  somefield="d"

系統會根據每個事件組合計算總和,讓您在結果值計算中使用兩個事件變數。計算時會使用下列元素:

1: $e1 = event1, $e2 = event2
2: $e1 = event1, $e2 = event3
3: $e1 = event2, $e2 = event1
4: $e1 = event2, $e2 = event3
5: $e1 = event3, $e2 = event1
5: $e1 = event3, $e2 = event2

因此,即使 $e2 只能對應至 3 個不同的事件,但可能的總和上限仍為 6。

這會影響加總、計數和陣列。針對計數和陣列,使用 count_distinctarray_distinct 即可解決問題,但對於求和,目前沒有任何解決方法。

運算式開頭的半形括號

在運算式開頭使用括號會觸發下列錯誤:

parsing: error with token: ")"
invalid operator in events predicate

以下範例會產生這類錯誤:

($event.metadata.ingested_timestamp.seconds -
$event.metadata.event_timestamp.seconds) / 3600 > 1

以下語法變化會傳回相同結果,但使用有效的語法:

$event.metadata.ingested_timestamp.seconds / 3600 -
$event.metadata.event_timestamp.seconds / 3600 > 1
    1 / 3600 * ($event.metadata.ingested_timestamp.seconds -
$event.metadata.event_timestamp.seconds) > 1
    1 < ($event.metadata.ingested_timestamp.seconds -
$event.metadata.event_timestamp.seconds) / 3600

結果中的索引陣列需要匯總重複欄位的單一值

結果部分的陣列索引仍需要匯總。舉例來說,下列操作無法運作:

outcome:
  $principal_user_dept = $suspicious.principal.user.department[0]

不過,您可以將陣列索引的輸出內容儲存在預留位置變數中,並在結果部分使用該變數,如下所示:

events:
  $principal_user_dept = $suspicious.principal.user.department[0]

outcome:
  $principal_user_department = $principal_user_dept

含有非存在條件的 OR 條件

如果在兩個獨立事件變數之間套用 OR 條件,且規則符合不存在的情況,則規則會成功編譯,但可能會產生誤判。舉例來說,下列規則語法可比對含有 $event_a.field = "something" 的事件,即使不應如此也一樣。

events:
     not ($event_a.field = "something" **or** $event_b.field = "something")
condition:
     $event_a and #event_b >= 0

解決方法是將條件分成兩個區塊,每個區塊只會將篩選器套用至單一變數,如下所示:

events:
     not ($event_a.field = "something")
     not ($event_b.field = "something")
condition:
     $event_a and #event_b >= 0

使用無符號事件欄位的算術運算

如果您嘗試在算術運算中使用整數常數,且該運算使用的是型別為無號整數的 UDM 欄位,系統會傳回錯誤。例如:

events:
  $total_bytes = $e.network.received_bytes * 2

udm.network.received_bytes 欄位是不帶正負號的整數。這是因為整數常數預設為帶正負號的整數,而這類整數無法在算術運算中與無號整數搭配使用。

解決方法是將整數常數強制設為浮點值,這樣就能與無符號整數搭配使用。例如:

events:
  $total_bytes = $e.network.received_bytes * (2/1)

地理位置資訊強化功能的最終一致性和偽陽性

在初始豐富階段 (串流和延遲敏感),系統會優先考量速度,而非即時準確度,因此可能會遺漏資料,並產生偽陽性。系統會繼續在背景強化資料,但在執行規則時,資料可能無法使用。這是正常的最終一致性程序的一部分。為避免這類誤判,請勿依賴事件中是否包含經過強化的欄位來觸發偵測。

舉例來說,請看以下規則事件:

$e.principal.ip_geo_artifact.network.asn = "16509" AND
$e.principal.ip_geo_artifact.location.country_or_region = "United Kingdom"

這個規則依賴以下事實:事件必須包含 $e.principal.ip_geo_artifact.network.asn = "16509"$e.principal.ip_geo_artifact.location.country_or_region = "United Kingdom",這兩個欄位都已加值。如果無法及時完成豐富化,規則就會產生誤報。

為避免這種情況,建議您改用以下規則:

$e.principal.ip_geo_artifact.network.asn != "" AND 
$e.principal.ip_geo_artifact.network.asn = "16509" AND
$e.principal.ip_geo_artifact.location.country_or_region != "" AND
$e.principal.ip_geo_artifact.location.country_or_region = "United Kingdom"

這項規則可避免由位於英國境外的 ASN 16509 IP 觸發事件。這有助於提升規則的整體精確度。