条件部分语法
本文档介绍了如何使用 YARA-L 查询的 condition 部分。condition 部分用于搜索和信息中心,是规则所必需的,并且包含用于进一步过滤结果的逻辑。在搜索或信息中心查询中使用时,它只会显示满足条件的输出。在检测规则中使用时,必须满足条件才能触发提醒。
在 condition 部分中,您可以使用布尔运算符、比较运算符和 outcome 变量的结果来确定是否应触发查询。
定义 condition 部分
在 condition 部分中,为事件和占位符变量定义条件表达式。您还可以为 events 部分中定义的事件和占位符指定匹配条件,并可选择使用 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 $e1events部分中显示的每个 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 $e2or关键字不支持无界条件。($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 关键字。
结果条件变量的指定方式因结果变量的类型而异:
整数:使用运算符
=, >, >=, <, <=, !=与整数文字进行比较 例如:$risk_score > 10浮点数:使用运算符
=, >, >=, <, <=, !=与浮点数文字进行比较 例如:$risk_score <= 5.5string:与字符串字面量进行比较,使用
=或!=例如:$severity = "HIGH"整数或数组列表:使用
arrays.contains函数指定条件 例如:arrays.contains($event_ids, "id_1234")
如果您在包含 match 部分的查询中指定结果条件,则该查询会被归类为多事件查询,并计入查询配额。如需详细了解单个事件和多个事件分类,请参阅匹配语法。
限制
避免在
condition部分中使用match变量。这是由于match变量值对事件进行分组而导致的语义错误。避免仅对分配给
match变量的所有event变量指定无边界条件。这是语义错误。要返回match变量值,必须至少存在一个包含该值的事件。如果使用了滑动窗口,则透视事件变量必须至少涉及一个边界条件。
后续步骤
其他信息
需要更多帮助?获得社区成员和 Google SecOps 专业人士的解答。