YARA-L 2.0 语言概览
YARA-L 2.0 是一种计算机语言,用于创建搜索企业日志数据的规则,因为它被注入到您的 Chronicle 帐号中。YARA-L 语法派生自 VirusTotal 开发的 YARA 语言。该语言与 Chronicle Detection Engine 配合使用,让您可以在大量数据中寻找威胁和其他事件。另请参阅 YARA-L 2.0 语言语法
YARA-L 2.0 示例规则
以下示例展示了使用 YARA-L 2.0 编写的规则。每个示例都展示了如何关联规则语言中的事件。
不同城市的登录信息
以下规则会在 5 分钟内搜索从两个或多个城市登录过您的企业的用户:
rule DifferentCityLogin {
meta:
events:
$udm.metadata.event_type = "USER_LOGIN"
$udm.principal.user.userid = $user
$udm.principal.location.city = $city
match:
$user over 5m
condition:
$udm and #city > 1
}
Match 变量:$user
事件变量:$udm
占位符变量:$city
和 $user
下面介绍了此规则的工作原理:
- 对用户名为 (
$user
) 的事件进行分组,并在找到匹配项时返回该值 ($user
)。 - 时间范围为 5 分钟,表示只有间隔不到 5 分钟的事件相关联。
- 搜索事件类型为 USER_LOGIN 的事件组 (
$udm
)。 - 对于该事件组,该规则会将用户 ID 命名为
$user
,并将登录城市命名为$city.
- 如果 5 分钟时间范围内事件组 (
$udm
) 中的不同$city
值数量大于 1,则返回匹配项。
快速创建和删除用户
以下规则可搜索在 4 小时内创建然后删除的用户:
rule UserCreationThenDeletion {
meta:
events:
$create.target.user.userid = $user
$create.metadata.event_type = "USER_CREATION"
$delete.target.user.userid = $user
$delete.metadata.event_type = "USER_DELETION"
$create.metadata.event_timestamp.seconds <=
$delete.metadata.event_timestamp.seconds
match:
$user over 4h
condition:
$create and $delete
}
事件变量:$create
和 $delete
Match 变量:$user
占位符变量:不适用
下面介绍了此规则的工作原理:
- 对用户名为 (
$user
) 的事件进行分组,并在找到匹配项时返回该值 ($user
)。 - 时间范围为 4 小时,这意味着只有不到 4 小时的事件才会关联。
- 搜索两个事件组(
$create
和$delete
,其中$create
等同于#create >= 1
)。 $create
对应于USER_CREATION
事件,并将用户 ID 调用为$user
。$user
用于将两组事件联接在一起。$delete
对应于USER_DELETION
事件,并以$user
形式调用用户 ID。此规则查找两个事件组中用户标识符相同的匹配项。- 此规则查找事件
$delete
发生的时间晚于$create
事件的情况,并在发现时返回匹配项。
单事件规则
单事件规则是与单个事件相关联的规则。单事件规则可以是:
- 没有匹配部分的任何规则。
- 包含匹配部分和条件部分的规则仅检查是否存在 1 个事件(例如,“$e”“#e > 0”“#e >= 1”“1 <= #e”“0 < #e”)。
例如,以下规则仅搜索用户的登录事件,然后返回在 Chronicle 帐号中存储的企业数据中遇到的首个事件。
rule SingleEventRule {
meta:
author = "noone@altostrat.com"
events:
$e.metadata.event_type = "USER_LOGIN"
condition:
$e
}
下面是包含匹配部分的单事件规则的另一个示例。此规则会搜索在 5 分钟内至少登录过一次的用户。它只检查用户登录事件是否存在。
rule SingleEventRule {
meta:
author = "noone@google.com"
description = "windowed single event example rule"
events:
$e.metadata.event_type = "USER_LOGIN"
$e.principal.user.userid = $user
match:
$user over 5m
condition:
#e > 0
}
多事件规则
使用多事件规则对指定时间范围内的多个事件进行分组,并尝试找到事件之间的相关性。典型的多事件规则包含以下部分:
- 匹配部分,用于指定需要对事件进行分组的时间范围。
- 条件部分,用于指定应触发检测和检查多个事件是否存在的条件。
例如,以下规则会搜索在 10 分钟内至少登录了 10 次的用户:
rule MultiEventRule {
meta:
author = "noone@altostrat.com"
events:
$e.metadata.event_type = "USER_LOGIN"
$e.principal.user.userid = $user
match:
$user over 10m
condition:
#e >= 10
}
IP 地址范围内的单个事件
以下示例展示了一条规则,用于搜索两个特定用户和特定 IP 地址范围之间的匹配项:
rule OrsAndNetworkRange {
meta:
author = "noone@altostrat.com"
events:
// Checks CIDR ranges.
net.ip_in_range_cidr($e.principal.ip, "203.0.113.0/24")
// Detection when the hostname field matches either value using or.
$e.principal.hostname = /pbateman/ or $e.principal.hostname = /sspade/
condition:
$e
}
any 和 all 规则示例
以下规则会搜索所有来源 IP 地址在 5 分钟的时间内与已知安全的 IP 地址不匹配的登录事件。
rule SuspiciousIPLogins {
meta:
author = "noone@google.com"
events:
$e.metadata.event_type = "USER_LOGIN"
// Detects if all source IP addresses in an event do not match "100.97.16.0"
// For example, if an event has source IP addresses
// ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
// it will be detected since "100.97.16.1", "100.97.16.2",
// and "100.97.16.3" all do not match "100.97.16.0".
all $e.principal.ip != "100.97.16.0"
// Assigns placeholder variable $ip to the $e.principal.ip repeated field.
// There will be one detection per source IP address.
// For example, if an event has source IP addresses
// ["100.97.16.1", "100.97.16.2", "100.97.16.3"],
// there will be one detection per address.
$e.principal.ip = $ip
match:
$ip over 5m
condition:
$e
}
规则中的正则表达式
以下 YARA-L 2.0 正则表达式示例搜索从 altostrat.com 网域收到电子邮件的事件。由于 nocase
已添加到 $host
变量 regex
比较和 regex
函数,因此这些比较都不区分大小写。
rule RegexRuleExample {
meta:
author = "noone@altostrat.com"
events:
$e.principal.hostname = $host
$host = /.*HoSt.*/ nocase
re.regex($e.network.email.from, `.*altostrat\.com`) nocase
match:
$host over 10m
condition:
#e > 10
}
滑动窗口规则示例
以下 YARA-L 2.0 滑动窗口示例搜索 firewall_1
事件后缺少 firewall_2
事件。after
关键字与数据透视事件变量 $e1
结合使用,指定在关联事件时应仅检查每个 firewall_1
事件 10 分钟后。
rule SlidingWindowRuleExample {
meta:
author = "noone@google.com"
events:
$e1.metadata.product_name = "firewall_1"
$e1.principal.hostname = $host
$e2.metadata.product_name = "firewall_2"
$e2.principal.hostname = $host
match:
$host over 10m after $e1
condition:
$e1 and !$e2
}
零值排除示例
如果规则未指定 allow_zero_values
选项,则系统不会从匹配变量值返回零值。但是,对于其他引用的事件字段,除非您明确指定此类条件,否则不会排除零值。如需了解详情,请参阅此处。
rule ExcludeZeroValues {
meta:
author = "noone@google.com"
events:
$e1.metadata.event_type = "NETWORK_DNS"
$e1.principal.hostname = $hostname
// $e1.principal.user.userid may be empty string.
$e1.principal.user.userid != "Guest"
$e2.metadata.event_type = "NETWORK_HTTP"
$e2.principal.hostname = $hostname
// $e2.target.asset_id cannot be empty string as explicitly specified.
$e2.target.asset_id != ""
match:
// $hostname cannot be empty string.
$hostname over 1h
condition:
$e1 and $e2
}
具有结果部分的规则示例
您可以在 YARA-L 2.0 规则中添加可选的 outcome
部分,以提取每次检测的其他信息。在条件部分,您还可以指定结果变量的条件语句。
详情请参阅以下内容:
包含结果部分的多事件规则:
rule OutcomeRuleMultiEvent {
meta:
author = "noone@google.com"
events:
$u.udm.principal.hostname = $hostname
$asset_context.graph.entity.hostname = $hostname
$severity = $asset_context.graph.entity.asset.vulnerabilities.severity
match:
$hostname over 5m
outcome:
$risk_score =
max(
100
+ if($hostname = "my-hostname", 100, 50)
+ if($severity = "HIGH", 10)
+ if($severity = "MEDIUM", 5)
+ if($severity = "LOW", 1)
)
$asset_id_list =
array(
if($u.principal.asset_id = "",
"Empty asset id",
$u.principal.asset_id
)
)
$asset_id_distinct_list = array_distinct($u.principal.asset_id)
$asset_id_count = count($u.principal.asset_id)
$asset_id_distinct_count = count_distinct($u.principal.asset_id)
condition:
$u and $asset_context and $risk_score > 50 and not arrays.contains($asset_id_list, "id_1234")
}
包含结果部分的单事件规则:
rule OutcomeRuleSingleEvent {
meta:
author = "noone@google.com"
events:
$u.metadata.event_type = "FILE_COPY"
$u.principal.file.size = $file_size
$u.principal.hostname = $hostname
outcome:
$suspicious_host = $hostname
$severity_tag = if($file_size > 1024, "SEVERE", "MODERATE")
condition:
$u
}
将多事件结果规则重构为单事件结果规则。
您可以将结果部分用于单事件规则(没有匹配集的规则),以及多事件规则(包含匹配部分的规则)。如果您之前将规则设计为多事件规则,以便您可以使用结果部分,则可以选择重构这些规则,方法是删除匹配部分以提高性能。请注意,由于您的规则不再包含应用分组的匹配部分,因此您可能会收到更多检测。此重构仅适用于使用一个事件变量的规则,如以下示例所示。
仅使用一个事件变量(非常适合重构)的多事件结果规则:
rule OutcomeMultiEventPreRefactor {
meta:
author = "noone@google.com"
description = "Outcome refactor rule, before the refactor"
events:
$u.udm.principal.hostname = $hostname
match:
$hostname over 5m
outcome:
$risk_score = max(if($hostname = "my-hostname", 100, 50))
condition:
$u
}
您可以通过删除匹配部分来重构规则。请注意,您还必须移除结果部分的汇总,因为规则现在是单事件。如需详细了解聚合,请参阅我们的结果聚合文档。
rule OutcomeSingleEventPostRefactor {
meta:
author = "noone@google.com"
description = "Outcome refactor rule, after the refactor"
events:
$u.udm.principal.hostname = $hostname
// We deleted the match section.
outcome:
// We removed the max() aggregate.
$risk_score = if($hostname = "my-hostname", 100, 50)
condition:
$u
}
函数到占位符规则示例
您可以为函数调用的结果分配占位符变量,可以在规则的其他部分(例如匹配部分、结果部分或条件部分)使用占位符变量。请参阅以下示例:
rule FunctionToPlaceholderRule {
meta:
author = "noone@google.com"
description = "Rule that uses function to placeholder assignments"
events:
$u.metadata.event_type = "EMAIL_TRANSACTION"
// Use function-placeholder assignment to extract the
// address from an email.
// address@website.com -> address
$email_to_address_only = re.capture($u.network.email.from , "(.*)@")
// Use function-placeholder assignment to normalize an email:
// uid@??? -> uid@company.com
$email_from_normalized = strings.concat(
re.capture($u.network.email.from , "(.*)@"),
"@company.com"
)
// Use function-placeholder assignment to get the day of the week of the event.
// 1 = Sunday, 7 = Saturday.
$dayofweek = timestamp.get_day_of_week($u.metadata.event_timestamp.seconds)
match:
// Use placeholder (from function-placeholder assignment) in match section.
// Group by the normalized from email, and expose it in the detection.
$email_from_normalized over 5m
outcome:
// Use placeholder (from function-placeholder assignment) in outcome section.
// Assign more risk if the event happened on weekend.
$risk_score = max(
if($dayofweek = 1, 10, 0) +
if($dayofweek = 7, 10, 0)
)
condition:
// Use placeholder (from function-placeholder assignment) in condition section.
// Match if an email was sent to multiple addresses.
#email_to_address_only > 1
}
结果条件示例规则
在条件部分,您可以使用结果部分中定义的结果变量。以下示例演示了如何使用结果条件来过滤风险评分,以减少检测中的噪声。
rule OutcomeConditionalRule {
meta:
author = "noone@google.com"
description = "Rule that uses outcome conditionals"
events:
$u.metadata.event_type = "FILE_COPY"
$u.principal.file.size = $file_size
$u.principal.hostname = $hostname
// 1 = Sunday, 7 = Saturday.
$dayofweek = timestamp.get_day_of_week($u.metadata.collected_timestamp.seconds)
outcome:
$risk_score =
if($file_size > 500*1024*1024, 2) + // Files 500MB are moderately risky
if($file_size > 1024*1024*1024, 3) + // Files over 1G get assigned extra risk
if($dayofweek=1 or $dayofweek=7, 4) + // Events from the weekend are suspicious
if($hostname = /highly-privileged/, 5) // Check for files from highly privileged devices
condition:
$u and $risk_score >= 10
}