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

因此,总和可能最多为 6,即使 $e2 只能 对应于 3 个不同的事件。

这会影响求和、计数和数组。对于计数和数组,使用 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)