条件部分语法

支持的平台:

本文档介绍了如何使用 YARA-L 2.0 查询的 condition 部分。

condition 部分的影响取决于您是执行临时查询还是部署持久规则,如下所示:

  • 对于搜索和信息中心:充当后过滤条件,仅返回和呈现满足指定表达式的记录。
  • 检测规则(必需):用作触发逻辑。只有在指定 match 时间段内,条件解析为 true 时,系统才会触发提醒。

使用 condition 部分定义用于过滤事件和占位符变量的表达式。在搜索或信息中心查询中使用时,它仅显示满足条件的输出。在检测规则中使用时,必须满足这些条件才能触发提醒。

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

定义 condition 部分

定义 condition 部分中事件和占位符变量的条件表达式。您可以为 events 部分中的变量指定 match 条件,还可以选择使用 and 关键字来添加基于 outcome 部分的逻辑。如需了解详情,请参阅结果部分语法。

您可以使用 and 或 or 关键字联接表达式:

  • 在任何条件之间使用 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 部分中添加结果变量的条件,并使用 and 或 or 关键字进行联接,或者在前面添加 not 关键字。

效果条件因效果变量的类型而异:

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

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

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

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

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

限制

  • 避免在 condition 部分中使用 match 变量。这是一个语义错误,因为事件是按 match 变量值分组的。

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

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

接下来怎么做?

其他信息

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