YARA-L 2.0 已知問題和限制
本文說明 YARA-L 2.0 的已知問題和限制。結果匯總 (含重複欄位取消巢狀結構)
如果規則參照事件變數中含有多個元素的可重複欄位,每個元素都會分割成獨立的事件資料列。
舉例來說,事件 $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.20、192.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),系統會在父項和子項層級取消巢狀結構。從單一事件取消巢狀結構產生的執行個體,會形成父項和子項欄位中元素的笛卡兒積。
在下列範例規則中,$e 事件在 security_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 |
封鎖 |
解決方法
忽略或排除重複值的匯總作業不會受到這項取消巢狀結構行為影響。如果因取消巢狀結構而導致結果值不符預期,請使用匯總的相異版本。
下列匯總作業不會受到先前所述的取消巢狀結構行為影響。
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_distinct 或 array_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)
GeoIP 擴充功能的最終一致性和誤判
在初始擴充階段 (串流和延遲時間敏感) 中,系統會優先考量速度而非立即準確度,因此可能會遺漏資料,也可能出現誤判。系統會在背景繼續擴充資料,但執行規則時可能無法使用資料。這是正常最終一致性程序的一部分。 為避免這類偽陽性結果,請勿依賴事件中是否存在擴充欄位來觸發偵測。
舉例來說,假設有以下規則事件:
$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 觸發,但這些 IP 位於英國境外。這有助於提升規則的整體準確度。
還有其他問題嗎?向社群成員和 Google SecOps 專業人員尋求答案。