使用 YARA-L 2.0 在 UDM 搜索和信息中心内设置条件

支持的语言:

condition 部分定义了在搜索结果中包含数据的条件。 系统会根据 events 部分中定义的事件和占位变量来评估这些条件。您可以使用 and 关键字组合这些条件。

限制

搜索中的条件具有以下限制:

  • 必需match 部分是强制性的。或者,您也可以直接在 events 部分中定义未分组的过滤条件。

  • 必需:事件变量和占位变量必须在 condition 部分中进行汇总。

  • 仅支持整数和浮点数比较表达式。这些表达式的左侧必须是变量,右侧必须是整数或浮点数(例如 #c > 1$port = 80)。支持的运算符包括 <>=

  • condition 部分中变量和子句的顺序不会影响结果。

  • 如需在 condition 部分中使用结果变量,请定义并汇总这些变量。您可以在 events 部分中过滤未汇总的结果变量。

  • 不支持直接对变量执行数学运算(例如 #e1 + 5 > 6$o1.sum($pl) > 0)。

  • 如果 OR 条件适用于相同的基本事件,则不会有其他限制。在不同事件中使用 OR 时,存在以下限制:

    • OR 不支持不存在比较。例如,不支持 math.log($outcome1_sent_bytes) > 5 OR (#placeholder2) < 10

    • 跨不同事件的 OR 子句不支持非 UDM 变量。 不过,OR 在单个事件上下文中或与 AND 分组时受支持。例如 $entity and ($udm_event_1 or $placeholder_derived_from_udm_event_1)。再举一个例子,$entity and ($udm_event_1 or $outcome_udm_event_1_bytes > 1000)

统计字符数 (#)

# 字符如果位于事件或占位符变量名称(例如 #c)之前,则表示相应事件的不同发生次数,或满足与相应变量关联的 events 部分中所有条件的不同值的数量。例如,#c > 1 表示事件或占位符 c 必须出现多次。

查询示例

$e1.principal.hostname = $hostname
$e1.target.hostname = "fedex.com"
$e1.target.port = 3042 // tcp/udp

$e2.principal.hostname = $hostname
$e2.target.hostname = "homedepot.com"
$e2.target.port = 3042 // tcp/udp

match:
$hostname over 1h

condition:
#e1 > 0 or #e2 > 1

值字符 ($)

$ 字符的功能取决于上下文。

  • 结果变量:如果放在结果变量名称(例如 $risk_score)之前,则表示相应变量的值。

  • 事件或占位符变量:当放在事件或占位符变量名称(例如 $event)之前时,它等同于 #event > 0,表示必须至少存在一次相应事件。

活动和占位符条件

您可以使用 and 关键字组合多个事件和占位变量条件谓词。

or 用法示例(单个事件)

condition:
  $ph2 and $ph3

重要提示:在 eventscondition 部分中编写逻辑时,请使用 ! 进行否定。仅在 outcome 部分中使用 not 关键字。

有界限和无界限条件

事件变量条件可以是有界限的,也可以是无界限的。

有界限的条件要求存在关联的事件变量。这意味着任何检测都必须显示相应事件的发生实例。

示例:

  • $var(相当于 #var > 0
  • #var > n(其中 n >= 0
  • #var >= m(其中 m > 0

查询示例

$e1.principal.hostname = $hostname
$e1.target.hostname = "fedex.com"

match:
$hostname over 1h

condition:
#e1 > 0

无界限条件允许关联的事件变量不存在。这意味着检测中可能不会出现该事件。 对事件变量中的字段的任何引用都会产生零值。将这些用于不存在性搜索。

示例:

  • !$var(相当于 #var = 0
  • #var >= 0
  • #var < n(其中 n > 0
  • #var <= m(其中 m >= 0

查询示例

$e1.principal.hostname = $hostname
$e1.target.hostname = "fedex.com"
$e1.target.port = 3042 // tcp/udp

match:
$hostname over 1h

outcome:
$bytes_sent = sum($e1.network.sent_bytes)

condition:
$bytes_sent >= 0

注意:对于不存在性搜索查询(使用无界条件),检测引擎会在预期延迟时间的基础上增加 1 小时的延迟。

具有无界限条件的搜索查询必须满足以下条件:

  • 至少一个 UDM 事件必须具有有界条件;也就是说,必须至少存在一个 UDM 事件。

  • 具有无界限条件的占位符必须与至少一个有界限 UDM 事件相关联。

  • 具有无界条件的实体必须与至少一个有界 UDM 事件相关联。

结果条件

您可以使用结果变量定义结果条件,并使用逻辑运算符(andornot)将它们组合起来。比较语法取决于结果变量的数据类型。

  • 整数和浮点数:使用 =>>=<<=!=(例如 $risk_score > 10$risk_score <= 5.5)。
  • 字符串:使用 =!=(例如 $severity = "HIGH")。
  • 整数或数组列表:使用 arrays.contains()(例如 arrays.contains($event_ids, "id_1234"))。

查询示例:

$e1.principal.hostname = $hostname
$e1.target.hostname = "fedex.com"
$e1.target.port = 3042 // tcp/udp
match:
$hostname over 1h

outcome:
$bytes_sent = sum($e1.network.sent_bytes)

condition:
$e1

UDM 搜索条件支持“N of X”语法,可灵活评估多个条件。此语法可让您指定,如果 N(特定数量)个 X(布尔值表达式列表)的计算结果为 true,则满足条件。

示例:假设您想从 VirusTotal (VT) 丰富功能提供的预定义标记列表中,识别出表现出多种可疑行为(但不一定全部)的进程。“N of X”语法可让您指定必须满足的最低条件数,从而解决此问题。

以下 UDM 搜索查询会查找满足至少三个条件的进程:


$e.metadata.event_type = "PROCESS_LAUNCH"
$e.target.process.file.full_path = $process

match:
    $process

outcome:
    $first_seen = earliest($e.metadata.event_timestamp)
    $last_seen = latest($e.metadata.event_timestamp)
    $total_events = count($e.metadata.id)
    // Collect all unique tags associated with this process from all its launch events
    $tags = array_distinct($e.target.process.file.tags)

condition:
    // Trigger if at least 3 of the following conditions (tag checks) are true
    3 of [
      arrays.contains($tags, "malware"),
      arrays.contains($tags, "detect-debug-environment"),
      arrays.contains($tags, "checks-disk-space"),
      arrays.contains($tags, "checks-cpu-name"),
      arrays.contains($tags, "invalid-signature"),
      arrays.contains($tags, "self-delete")
    ]

order:
    $total_events desc

ANY OF 和 ALL OF 运算符

如果列出的布尔值表达式中至少有一个的计算结果为 true,则 ANY of [expressions] 的计算结果为 trueALL of [expressions] 要求列出的每个表达式都为 true。您可以使用 AND 等关键字将这些运算符与其他条件结合使用。

示例:


$e.metadata.event_type = "PROCESS_LAUNCH"
$e.target.process.file.full_path = $process

match:
 $process

outcome:
  $first_seen = timestamp.get_timestamp(min($e.metadata.event_timestamp.seconds))
  $last_seen = timestamp.get_timestamp(max($e.metadata.event_timestamp.seconds))
  $total = count($e.metadata.id)
  $tags = array_distinct($e.target.process.file.tags)
  $vt_first_seen_time = max(if((timestamp.current_seconds() - $e.target.process.file.first_seen_time.seconds) < 86400, 1 , 0))
  $vt_last_analysis_time = max(if((timestamp.current_seconds() - $e.target.process.file.last_analysis_time.seconds) < 86400, 1 , 0))
  $vt_last_modification_time = max(if((timestamp.current_seconds() - $e.target.process.file.last_modification_time.seconds) < 86400, 1 , 0))
  $vt_last_seen_time = max(if((timestamp.current_seconds() - $e.target.process.file.last_seen_time.seconds) < 86400, 1 , 0))

condition:
  3 of [
    arrays.contains($tags, "malware"),
    arrays.contains($tags, "detect-debug-environment"),
    arrays.contains($tags, "checks-disk-space"),
    arrays.contains($tags, "checks-cpu-name"),
    arrays.contains($tags, "invalid-signature"),
    arrays.contains($tags, "self-delete")
  ]
  and ANY of [
    $vt_first_seen_time = 1,
    $vt_last_analysis_time = 1,
    $vt_last_modification_time = 1,
    $vt_last_seen_time = 1
  ]

order:
  $total desc

unselect:
    $vt_first_seen_time,
    $vt_last_analysis_time,
    $vt_last_modification_time,
    $vt_last_seen_time

需要更多帮助?从社区成员和 Google SecOps 专业人士那里获得解答。