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。
这会影响 sum、count 和 array。对于 count 和 array,使用 count_distinct 或 array_distinct 可以解决问题,但对于 sum,没有解决方法。
表达式开头的圆括号
在表达式开头使用圆括号会触发以下错误:
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"
此规则消除了以下可能性:IP 地址具有 ASN 16509,但位于英国境外,从而触发了相应事件。这有助于提高规则的总体精确度。
需要更多帮助?获得社区成员和 Google SecOps 专业人士的解答。