YARA-L 2.0 语言语法

本部分介绍 YARA-L 语法的主要元素。另请参阅 YARA-L 2.0 语言概览

注释

使用两个斜杠字符 (// comment) 或用斜杠星号 (/* comment */) 发出的多行注释来指定注释,就像在 C 中那样。

常量

支持整数、字符串、浮点和正则表达式常量。对于字符串常量,使用双引号。使用 /regex/ 作为正则表达式常量。

计数

# 字符是条件部分中的特殊字符。如果用于任何事件或占位符变量名称之前,它表示满足所有 events 部分条件的不同事件或值的数量。

您可以使用 YARA-L 通过 net.ip_in_range_cidr() 语句搜索子网内所有 IP 地址中的 UDM 事件。支持使用 IPv4 和 IPv6。

如需在 IP 地址范围中搜索,请指定 IP UDM 字段和无类别域间路由 (CIDR) 范围。YARA-L 可以处理单数和重复 IP 地址字段。

IPv4 示例:

net.ip_in_range_cidr($e.principal.ip, "192.0.2.0/24")

IPv6 示例:

net.ip_in_range_cidr($e.network.dhcp.yiaddr, "2001:db8::/32")

如需查看使用 net.ip_in_range_cidr() 语句的示例规则,请参阅示例规则:IP 地址范围内的单个事件

运算符

您可以在 YARA-L 中使用以下运算符:

运算符 说明
= 等于
!= 不等于
< 小于
<= 小于或等于
> 大于
>= 大于或等于

字符串的引号

您可以使用以下任一引号字符将字符串括在 YARA-L 2.0 中。不过,引用文字的解释方式因所使用的文字而异。

  1. 双引号 (") - 用于普通字符串。必须包含转义字符。例如:“hello\tworld”-\t 将被解释为一个标签页

  2. 反引号 (`) - 用于按字面解释所有字符。例如:“hello\tworld”-\t 不会被解释为标签页

对于正则表达式,通常需要在字符串中包含反斜杠 (\) 字符。但是,如果您使用双引号,则需要使用反斜线字符来转义反斜杠字符,这可能会看起来比较。

例如,以下正则表达式是等效的:

  • re.regex($e.network.email.from, `.*altostrat\.com`)
  • re.regex($e.network.email.from, ".*altostrat\\.com")

为便于阅读,我们建议对正则表达式中的字符串使用英文反引号字符。

变量

在 YARA-L 2.0 中,所有变量均表示为 $<variable name>

您可以定义以下类型的变量:

  • 事件变量 - 以标准化形式 (UDM) 表示事件组。在 events 部分指定事件变量的条件。使用变量后面的事件字段标识事件变量。事件字段表示为 .<field name> 链(例如 $e.field1.field2)。事件字段链始终从顶级 UDM 开始。

  • 匹配变量 - 在匹配部分声明。匹配变量会成为查询的分组字段,因为对于每组唯一的匹配变量(以及每个时间范围),都会返回一行。当规则找到匹配项时,将返回匹配变量值。指定每个匹配变量在 events 部分中表示的内容。

  • 占位符变量 - 在 events 部分声明和定义。占位符变量与匹配变量类似。不过,您可以使用 condition 部分中的占位符变量来指定匹配条件。

使用匹配变量和占位符变量可以通过传递联接条件来声明事件字段之间的关系(请参阅事件部分语法了解更多详情)。

“事件”部分语法

events 部分中,列出谓词以指定以下内容:

  • 每个匹配项或占位符变量代表什么
  • 单个事件变量的过滤条件
  • 两个事件变量的联接条件。

变量声明

对于变量声明,请使用以下语法:

  • EVENT_FIELD = VAR
  • VAR = EVENT_FIELD

这两个示例是等效的,如以下示例所示:

  • $e.source.hostname = $hostname
  • $userid = $e.principal.user.userid

此声明表明此变量表示事件变量的指定字段。当事件字段是数组字段时,匹配变量可以表示数组中的任何值。也可以将多个事件字段分配给单个匹配或占位符变量。这是一个传递性联接条件。

例如,以下方法:

  • $e1.source.ip = $ip
  • $e2.target.ip = $ip

等效于:

  • $e1.source.ip = $ip
  • $e1.source.ip = $e2.target.ip

事件变量的过滤条件

对于单个事件变量的过滤条件,请使用以下语法:

  • [EVENT_FIELD] [OP] [CONST]
  • [CONST] [OP] [EVENT_FIELD]

虽然两者是等效的,但我们建议您使用前者 ([EVENT_FIELD] [OP] [CONST]),以方便阅读。

例如:

  • $e.source.hostname = "host1234"
  • $e.source.port < 1024
  • 1024 < $e.source.port

这个谓词被用作事件变量的过滤条件,也就是说,由事件变量表示的事件组应满足相应条件。

事件变量的联接条件

如需表示两个事件变量的联接条件,请使用以下语法:

[EVENT_FIELD] [OP] [EVENT_FIELD]

例如:

  • $e1.source.hostname = $e2.target.hostname
  • $e1.metadata.timestamp < $e2.metadata.timestamp

使用此谓词将两个事件变量与条件联接。

以下是无效谓词的示例:

  • $e.source.hostname != $hostname //comparison over match/placeholder var
  • $hostname != "host1234" //comparison over match/placeholder var
  • $var1 //variable itself does not mean anything

逻辑运算符

您可以在 events 部分中使用逻辑 and 和逻辑 or 运算符,如以下示例所示:

  • $e.metadata.event_type = "NETWORK_DNS" or $e.metadata.event_type = "NETWORK_DHCP"
  • ($e.metadata.event_type = "NETWORK_DNS" and $e.principal.ip = "192.0.2.12") or ($e.metadata.event_type = "NETWORK_DHCP" and $e.principal.mac = "AB:CD:01:10:EF:22")
  • not $e.metadata.event_type = "NETWORK_DNS"

默认情况下,优先级从高到低的顺序是 notandor

例如,"a or b and c" 的求值结果为 "a or (b and c)"。如果需要,您可以使用括号更改优先级。

匹配部分语法

在匹配部分中,列出群组事件的匹配变量,然后再检查匹配条件。这些字段随每个匹配项返回。

  • 指定每个匹配变量在 events 部分中表示的内容。
  • 指定用于在 over 关键字之后关联事件的时间范围。时间范围之外的事件会被忽略。
  • 使用以下语法指定时间范围:<number><s/m/h/d>,其中 s/m/h/d 分别表示秒、分钟、小时和天。
  • 您可以指定的最短时间为 1 分钟。
  • 可指定的最长时间为 48 小时。

以下是有效 match 的示例:

$var1, $var2 over 5m

当规则找到匹配项时,此语句返回 $var1$var2(在 events 部分中定义)。指定时间为 5 分钟。相互间隔超过 5 分钟的事件是不相关的,因此规则会忽略这些事件。

下面是有效 match 的另一个示例:

$user over 1h

当规则找到匹配项时,此语句会返回 $user。指定的时间窗口为 1 小时。相互间隔超过一小时的活动之间没有关联。该规则不会将其视为检测。

下面是有效 match 的另一个示例:

$source_ip, $target_ip, $hostname over 2m

当规则找到匹配项时,此语句会返回 $source_ip$target_ip$hostname。指定的时间窗口为 2 分钟。间隔超过 2 分钟的事件是不相关的。该规则不会将其视为检测。

以下示例展示了无效的 match

  • var1, var2 over 5m // invalid variable name
  • $user 1h // missing keyword

条件部分语法

condition 部分,指定 events 部分中定义的事件和变量的匹配条件。此处的匹配谓词与关键字 andor 联接。

以下条件即为边界条件。它们强制关联事件变量的存在,这意味着任何检测都必须显示相应事件的发生实例。

  • $var // equivalent to #var > 0
  • #var > n // where n is >= 0
  • #var >= m // where m > 0

以下条件为无界限条件。它们允许关联的事件变量不存在,这意味着检测中可能不会出现该事件。这样,就可以实现不存在的规则,以搜索缺少变量而不是变量的存在。

  • !$var // equivalent to #var = 0
  • #var < n // where n is > 0
  • #var <= m // where m >= 0

在以下示例中,变量(事件变量或占位符变量)上的特殊字符 # 表示该变量的不同事件或值的计数:

$e and #port > 50 or #event1 > 2 or #event2 > 1 or #event3 > 0

以下不存在示例也是有效的,如果 $event1 中有两个不同的事件,且 $event2 中没有任何不同的事件,则计算结果为 true:

#event1 > 2 and !$event2

以下是无效谓词的示例:

  • $e, #port > 50 // incorrect keyword usage
  • $e or #port < 50 // or keyword not supported with non-bounding conditions

正则表达式

您可以使用以下任一语法在 YARA-L 2.0 中定义正则表达式:

  • 使用 YARA 语法 - 与事件相关。以下是此语法的通用表示形式:$e.field = /regex/
  • 使用 YARA-L 语法 - 作为接受以下参数的函数:
    • 要应用正则表达式的字段。
    • 以字符串指定的正则表达式。您可以在字符串之后使用 nocase 修饰符,以指示搜索应忽略大小写。以下是此语法的通用表示形式:re.regex($e.field, `regex`)

如需匹配确切的字符串,或仅匹配前缀或后缀,请在正则表达式中添加 ^(开头)和 $(结尾)定位字符。

例如,/^full$/"full" 完全匹配,而 /full/ 可以与 "fullest""lawfull""joyfully" 匹配。

原始字符串

您可以使用 YARA-L 2.0 在企业事件数据中搜索原始字符串。

如需搜索原始字符串,请将字符串用英文反引号 (`) 括起来,而不要用双引号 (")。

反引号表示将按字面解释字符串的内容(无法解析转义字符)。