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_resultssecurity_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 BLOCK

当规则引用一个或多个重复字段,且父级字段也是重复字段时,规则评估中的这种取消嵌套行为可能会产生意外的结果汇总。非不重复汇总(例如 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 BLOCK

临时解决方法

忽略重复值或消除重复值的汇总不会受到此取消嵌套行为的影响。如果您因取消嵌套而遇到意外的结果值,请使用汇总的唯一值版本。

以下汇总不会受到上述取消嵌套行为的影响。

  • 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 和 array,使用 count_distinctarray_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"

此规则可排除由位于英国境外的 ASN 16509 IP 触发事件的可能性。这有助于提高规则的整体准确性。