条件部分语法

支持的平台:

本文档介绍了如何使用 YARA-L 查询的 condition 部分。condition 部分用于搜索和信息中心,是规则所必需的,并且包含用于进一步过滤结果的逻辑。在搜索或信息中心查询中使用时,它只会显示满足条件的输出。在检测规则中使用时,必须满足条件才能触发提醒。

condition 部分中,您可以使用布尔运算符、比较运算符和 outcome 变量的结果来确定是否应触发查询。

定义 condition 部分

condition 部分中,为事件和占位符变量定义条件表达式。您还可以为 events 部分中定义的事件和占位符指定匹配条件,并可选择使用 and 关键字来指定使用 outcome 部分中定义的结果变量的匹配条件(请参阅结果部分语法)。

您可以使用 andor 关键字联接表达式:

  • 在任何条件之间使用 and

  • 仅当查询包含单个事件变量时,才使用 or

condition 部分中的任何事件或占位符变量名称之前使用 # 字符,以表示满足 events 部分中所有条件的不同事件或值的数量。例如:

#c > 1 表示变量 c 必须出现 1 次以上。

condition 部分中的任何结果变量名称之前使用 $ 字符,以表示相应结果的值。如果在任何事件或占位符变量名称(例如 $event)之前使用,则表示 #event > 0

此规则示例会在 10 分钟窗口(如 match 部分中所定义)内,每个用户的登录失败次数超过 5 次(如 condition 部分中所定义)时返回检测结果:

rule failed_logins
{
  meta:
   author = "Security Team"
   description = "Detects multiple failed user logins within 10-minute windows."
   severity = "HIGH"

  events:
   $e.metadata.event_type = "USER_LOGIN"
   $e.security_result.action = "FAIL"
   $user = $e.target.user.userid

  match:
   $user over 10m

  outcome:
   $failed_login_count = count($e.metadata.id)
   $first_fail_time = min($e.metadata.event_timestamp.seconds)

  condition:
    #e >= 5
}

有界限条件和无界限条件

您可以在查询中使用有界限或无界限的条件:

  • 有界条件强制关联事件变量的存在,这意味着检测中必须至少出现一次相应事件。以下是有界限条件:

    $var // equivalent to #var > 0

    #var > n // where n >= 0

    #var >= m // where m > 0

  • 无界条件可用于检测一段时间内是否缺少某个事件;例如,在 10 分钟的时间范围内,是否存在威胁事件但没有缓解事件。无界条件允许关联的事件变量不存在(非存在性查询),这意味着检测中可能不会出现该事件,并且对事件变量上字段的任何引用都会产生零值。

    以下是无界限条件:

    !$var // equivalent to #var = 0

    #var >= 0

    #var < n // where n > 0

    #var <= m // where m >= 0

不存在查询的要求

为了让不存在查询能够编译,它必须满足以下要求:

  • 至少一个 UDM 事件必须具有有界条件(即必须存在至少一个 UDM 事件)。
  • 如果占位符具有无界条件,则必须与至少一个有界 UDM 事件相关联。
  • 如果实体具有无界条件,则必须与至少一个有界 UDM 事件相关联。

示例:不存在查询

请考虑以下省略了条件部分的查询:

rule NonexistenceExample {
  meta:
      author = "Google Security"
      description = "Example: non-existence query."
  events:
      $u1.metadata.event_type = "NETWORK_CONNECTION" // $u1 is a UDM event.
      $u2.metadata.event_type = "NETWORK_CONNECTION" // $u2 is a UDM event.
      $e1.graph.metadata.entity_type = "FILE"        // $e1 is an entity.
      $e2.graph.metadata.entity_type = "FILE"        // $e2 is an entity.

      $user = $u1.principal.user.userid // Match variable is required for multi-event query.

      // Placeholder Associations:
      //   u1        u2
      //   |  \    /
      // port   ip
      //   |       \
      //   e1        e2
      $u1.target.port = $port
      $e1.graph.entity.port = $port
      $u1.principal.ip = $ip
      $u2.target.ip = $ip
      $e2.graph.entity.ip = $ip

      // UDM-Entity Associations:
      // u1 - u2
      // |  \  |
      // e1   e2
      $u1.metadata.event_type = $u2.metadata.event_type
      $e1.graph.entity.hostname = $u1.principal.hostname
      $e2.graph.entity.hostname = $u1.target.hostname
      $e2.graph.entity.hostname = $u2.principal.hostname

  match:
    $user over 5m

  condition:
      //Add valid condition
}

有效的条件部分

以下是条件部分的有效示例:

  • $u1 and !$u2 and $e1 and $e2
    • 条件部分中包含所有 UDM 事件和实体。
    • 至少有一个 UDM 事件有边界。
  • $u1 and !$u2 and $e1 and !$e2
    • $e2不受限且允许,因为它与受限的$u1相关联。如果 $e2 未与 $u1 相关联,则此值无效。
  • #port > 50 and #ip = 0
    • 条件部分中没有 UDM 事件和实体;不过,其中包含的占位符涵盖了所有 UDM 事件和实体。
    • $ip 同时分配给 $u1$u2,而 #ip = 0 是无界限条件。不过,有界限条件比无界限条件更强。由于 $port 已分配给 $u1,且 #port > 50 是有界条件,因此 $u1 仍然是有界的。

条件部分无效

以下是条件部分中的无效示例:

  • $u1 and $e1
    • events 部分中显示的每个 UDM 事件和实体都必须显示在 condition 部分中(或分配给显示在 condition 部分中的占位符)。
  • $u1, $u2, $e1, $u2, #port > 50
    • 不允许使用英文逗号作为条件分隔符。
  • !$u1 and !$u2 and $e1 and $e2
    • 违反了至少有一个 UDM 事件有界的第一项要求。
  • ($u1 or #port < 50) and $u2 and $e1 and $e2
    • or 关键字不支持无界条件。
  • ($u1 or $u2) and $e1 and $e2
    • 不支持在不同的事件变量之间使用 or 关键字。
  • not $u1 and $u2 and $e1 and $e2
    • 不允许将 not 关键字用于活动和占位符条件。
  • #port < 50 and #ip = 0
    • 虽然占位符引用了所有 UDM 事件和实体,但每个关联的条件都是无界限的。这意味着没有一个 UDM 事件是有界限的,导致规则无法编译。

结果条件

您可以在 condition 部分中添加结果变量的条件,并使用 andor 关键字进行联接,或者在前面添加 not 关键字。

结果条件变量的指定方式因结果变量的类型而异:

  • 整数:使用运算符 =, >, >=, <, <=, != 与整数文字进行比较 例如:$risk_score > 10

  • 浮点数:使用运算符 =, >, >=, <, <=, != 与浮点数文字进行比较 例如:$risk_score <= 5.5

  • string:与字符串字面量进行比较,使用 =!= 例如:$severity = "HIGH"

  • 整数或数组列表:使用 arrays.contains 函数指定条件 例如:arrays.contains($event_ids, "id_1234")

如果您在包含 match 部分的查询中指定结果条件,则该查询会被归类为多事件查询,并计入查询配额。如需详细了解单个事件和多个事件分类,请参阅匹配语法

限制

  • 避免在 condition 部分中使用 match 变量。这是由于 match 变量值对事件进行分组而导致的语义错误。

  • 避免仅对分配给 match 变量的所有 event 变量指定无边界条件。这是语义错误。要返回 match 变量值,必须至少存在一个包含该值的事件。

  • 如果使用了滑动窗口,则透视事件变量必须至少涉及一个边界条件。

后续步骤

其他信息

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