开始使用:SecOps 中的 YARA-L 2.0

支持的平台:

YARA-L 2.0 是一种独特的、高度结构化的查询语言,可为 Google Security Operations 提供支持,以实现所有搜索、信息中心和基于规则的威胁检测。本文档可帮助您了解 YARA-L 的核心结构,并提供有关如何使用它的实用步骤,无论您是搜寻威胁的安全分析师,还是构建稳健新逻辑的检测工程师,都可以参考本文档。

本文档介绍了 YARA-L 及其语法,并展示了如何使用它来表达各种内容,从基本过滤查询到查找复杂模式的规则。在 YARA-L 查询中使用部分来支持聚合函数、条件逻辑,并通过联接、模式匹配等方式添加上下文。

准备工作

了解 YARA-L 结构

每个 YARA-L 查询都分为不同的命名部分,这些部分决定了查询的行为。

这种结构可实现多阶段分析和相关性分析。

订单 部分 规则 搜索/信息中心 说明
1 meta 必需 可选 为规则设置描述性元数据,例如作者、说明和严重程度。例如,作者 (security team)、说明 (Detects multiple failed user logins within 10-minute windows) 和严重程度 (High)。请参阅meta 部分语法
2 events 必需 必需 定义并过滤必须跟踪的事件:用户登录、用户登录失败(事件变量)以及与用户匹配变量的链接(占位变量)。声明要考虑的所有数据源(主要是事件),并使用 UDM 字段对其进行过滤。请参阅 events 部分语法
3 match 必需 可选 按事件分组,并允许您指定支持的时间窗口(例如 by 5m)。在某些情况下,对于发生汇总的统计搜索,此参数是必需的。对于多事件相关性查询是必需的。在 match 中,时间规范对于规则是必需的,对于搜索和信息中心是可选的。请参阅 match 部分语法

注意:如果您排除 match 部分,规则就可以与单个事件进行匹配。
4 outcome 可选 可选 计算基本指标并获取数据洞见(例如 count()avg())。请参阅 outcome 部分语法
5 condition 必需 可选 定义了必须满足的逻辑,以便返回结果(在搜索中)或触发提醒(在规则中)。评估查询变量条件,以确定结果是否适用(例如,$event >5)。请参阅 condition 部分语法
6 options 可选 可选 允许启用或停用特定规则行为。请参阅 options 部分语法
7 dedup 可选 可选 通过根据关键变量或事件路径(例如 target.user.useridtarget.ipprincipal.hostname 或变量,如 $host$user)对事件进行分组,来移除重复事件。详细了解事件变量
8 dedup 不适用 可选 通过根据关键变量或事件路径(例如 target.user.useridtarget.ipprincipal.hostname 或变量,如 $host$user)对事件进行分组,来移除重复事件。详细了解事件变量
9 order 不适用 可选 按特定字段(例如 asc)对结果进行排序。详细了解事件变量。可选(仅在使用了 match 时适用)。
10 limit 不适用 可选 限制查询返回的事件数量上限。
11 select 不适用 可选 指定要包含在查询结果中的 UDM 字段列表。
12 unselect 不适用 可选 指定要从查询结果中排除的 UDM 字段列表。

YARA-L 数据源可用性

YARA-L 可以访问不同的数据源,具体取决于您在平台中的位置。事件实体 (ECG)数据表可在搜索、信息中心和规则中全面使用。

下表列出了 YARA-L 中可用的功能:

功能 支持的语言
支持请求和支持请求历史记录 信息中心
数据表格 搜索、信息中心、规则
实体(心电图) 搜索、信息中心、规则
提取指标 信息中心
IoC 匹配项 信息中心
规则检测 信息中心、规则
规则集 信息中心
事件 搜索、信息中心、规则
UEBA 指标 搜索,信息中心

Google SecOps 中的所有数据都使用两种主要方法(具体取决于您的目标)进行搜索:过滤条件搜索统计搜索(汇总)。

借助过滤搜索方法,您可以从更广泛的遥测数据流中隔离特定事件,而无需统计汇总的开销。此方法使用条件将大量安全数据(例如日志或网络流量)缩小为有针对性的结果集。该逻辑仅要求您在 events 部分中指定事件。

如需构建您的第一个 YARA-L 过滤条件搜索,请按以下步骤搜索登录失败的用户:

  1. 在 Google SecOps 中,前往搜索页面。
  2. 过滤登录事件:
    metadata.event_type = "USER_LOGIN"

    提示:您可以在搜索中省略 events: 部分标题。默认情况下,搜索语法会暗示此部分。

  3. 为来自 userid 不为空的用户的登录失败添加 event 操作。
    metadata.event_type = "USER_LOGIN"
    security_result.action = "FAIL"
    principal.user.userid != ""
  4. 运行此搜索以查看结果。

使用占位变量

使用占位变量从事件中提取特定值,例如用户名或 IP 地址。这些变量充当临时锚点,可让您比较不同事件中的数据,或在最终输出中显示这些值。

您可以应用占位变量来执行以下操作:

  • 桥接数据:使用占位符(例如 $userid$ip)查找不同事件变量之间的匹配项(例如,您可以使用 $userid 关联登录和退出事件中的用户标识符)。
  • 对结果进行分组:在 match 部分中,使用占位符变量定义查询输出的窗口,例如 match: $userid over 1h
  • 创建结果:使用占位符捕获和显示查询输出中的特定数据点。

例如,如果您分配 $user = principal.user.userid,则 $user 变量现在包含从事件中提取的特定值。然后,您可以使用match部分中的 $user 将与该特定用户相关的所有活动归为一组。

借助统计搜索方法,您可以一组事件执行计算,从而获得数据洞见、趋势或异常情况。它不会返回单个日志的列表,而是提供数据的汇总摘要。该逻辑使用 match 部分(用于分组)和 outcome 部分(用于计算)。outcome 部分支持聚合函数,例如 count()sum()avg()max()min()stddev()

以下示例使用以下查询逻辑:

  • events:过滤原始数据,以获取登录尝试失败的数据。
  • match:定义分组事件(按 userid)。
  • outcome:执行统计汇总(每位用户的事件数)。

示例:使用 outcome 函数汇总失败的登录活动

以下示例使用 outcome 部分的聚合函数(例如 count()sum())来总结登录失败活动。

  1. 使用 match 部分按 userid 对登录失败事件进行分组:

    metadata.event_type = "USER_LOGIN"
    security_result.action = "FAIL"
    principal.user.userid != ""
    
    match:
      principal.user.userid
    
  2. 使用由 outcome 变量定义的每位用户的登录失败次数 (count):$failed_login_count

    metadata.event_type = "USER_LOGIN"
    security_result.action = "FAIL"
    principal.user.userid != ""
    
    match:
      principal.$user.userid
    
    outcome:
      $failed_login_count = count(metadata.id)
    
  3. 运行此搜索以查看结果。

  4. 可选:向 match 部分添加时间元素(在本例中为 day)。然后,更新 outcome 变量,使其更明确 ($daily_failed_login_count):

    metadata.event_type = "USER_LOGIN"
    security_result.action = "FAIL"
    principal.user.userid != ""
    $user =principal.user.userid
    
    match:
      principal.$user.userid by day
    
    outcome:
      $daily_failed_login_count = count(metadata.id)
    

基于搜索查询创建信息中心微件

您可以根据汇总的搜索结果创建信息中心微件,如构建第一个搜索查询示例中所示。

验证搜索查询后,您可以将其另存为 widget 并添加到信息中心,如下所示:

  1. 看到结果后,依次点击可视化标签页 > 添加到信息中心
  2. 配置 widget:
    1. 为 widget 命名(例如,"Daily Failed Login")。
    2. 选择时间范围
    3. 选择是将其添加到现有信息中心还是信息中心。
    4. 点击 Add(添加)。
  3. 可选:直接在信息中心内构建查询。或者,您也可以复制精选信息中心,并修改其中的查询,作为起点。
  4. 可选:您可以创建自定义信息中心,并使用 YARA-L 向其中添加 widget。如需了解详情,请参阅创建自定义信息中心

配置信息中心

构建新信息中心时,events 部分是必需的起点。然后,您可以灵活地使用 match(用于对结果进行分组)或 outcome(用于计算输出和汇总)。

例如,您可以创建一个包含 eventsmatch 部分的信息中心,其中显示了按 by hour 个桶分组的检测严重程度 ($severity)。

示例:按严重程度汇总时间序列

您可以使用 eventsmatch 部分创建一个信息中心,以显示分组到 hour 存储分区中的检测严重程度 ($severity):

detection.detection.severity != "UNKNOWN_SEVERITY"
$severity = detection.detection.severity

match:
  $severity by hour

示例:汇总严重影响总数

同样,您也可以使用 eventsoutcome 部分创建信息中心,以跟踪严重程度较高的检测结果:

detection.detection.severity = "CRITICAL"
$severity = detection.detection.severity

outcome:
  $detection_count = count_distinct($severity)

示例:直观呈现检测量随时间变化的趋势(按严重程度)

在以下示例中,您可以在控制台中统计严重检测结果并指定时间范围。在许多情况下,您在信息中心内构建可视化图表时会同时使用 matchoutcome 部分:

detection.detection.severity != "UNKNOWN_SEVERITY"
$severity = detection.detection.severity

match:
  $severity by hour

outcome:
  $detection_count = count_distinct(detection.id)

示例:计算用户登录频率

以下示例重点介绍如何使用 matchoutcome 部分计算特定用户的 login_count

events:
  metadata.event_type = "USER_LOGIN"

match:
  target.user.userid

outcome:
  $login_count = count(metadata.id)

构建规则

规则需要包含以下部分:

  • meta:包含规则名称和描述性详细信息。
  • events:使用事件变量定义数据源和过滤条件。
  • condition:指定哪些事件变量必须存在才能触发规则。

定义和使用事件变量

事件变量充当逻辑容器,将过滤条件分组在一起,以便您在整个搜索、规则或信息中心内引用该特定活动。

events 部分定义逻辑时,您可以使用事件变量(例如 $e)来表示符合您条件的特定事件(或一组事件)。

示例:定义和过滤事件变量

如需定义事件变量(例如 $e),请在查询的 events 部分中使用前缀。此声明表示这些事件由该变量表示。例如,表达式 $e.principal.hostname = "dev" 会评估每个事件,以确定主机名是否完全匹配。

$e.principal.hostname = "dev"
$e.metadata.event_type = "USER_LOGIN"

然后,您可以在查询的其他部分(matchoutcomecondition 部分)中使用该变量来引用该特定事件组及其数据字段。

整理规则结构和语法

使用以下规则结构和语法来帮助您定义变量、分组逻辑和触发阈值:

元素 说明 示例
规则结构 将查询封装在 rule 块中,并分配一个唯一名称来标识检测。 rule DailyFailedLoginAttempts { }
meta 部分 必需。包含描述性元数据(例如“author”“description”“severity”),以改进规则管理并为您的团队提供上下文信息。建议将此作为规则管理的最佳实践。 author = "Alex"
severity = "Medium"
事件变量 在规则查询中,events 部分中的每个字段都以事件变量(例如 $e)作为前缀,以表示符合您条件的特定事件(或一组事件)。它们充当过滤条件的逻辑分组

将搜索内容转换为 YARA-L 规则示例中,$e 表示所有用户登录失败的情况。
$e.metadata.event_type = "USER_LOGIN"
占位符变量 将事件分配给一个通用名称,您可以在查询中引用该名称。如需了解详情,请参阅使用占位变量 $userid = $e.principal.user.userid
match 部分 定义分组并指定支持的时间窗口。在将搜索内容转换为 YARA-L 规则示例中,match: $userid over day 分组正确地按用户 ID 对每个 24 小时周期 (1d) 内的事件进行分组。

编写规则时,您必须指定支持的时间窗口来定义回溯期。您可以根据自己的逻辑要求实现跳跃窗口、滑动窗口或滚动窗口。使用 over 运算符会明确创建一个跳跃窗口。
$userid over 1d
outcome 部分 执行统计汇总或捕获特定变量,使生成的提醒包含更多信息。

$e.metadata.id 使用 count() 函数,以汇总每个 match 群组中的事件。您还可以分配变量(例如 $userid),以捕获特定的 UDM 字段,并在生成的检测输出中提供更多上下文。
$failed_count = count($e.metadata.id)
condition 部分 规则生成检测结果所必需的。

condition 部分中定义检测阈值。例如,使用 #e > 5 时,事件计数必须超过 5 (5) 才能触发提醒。如果您不执行计算,仍需要一个 condition 部分,并说明事件变量的存在(例如 #e)。

分析环境的基准,以设置可捕获可疑活动并最大限度减少误报的阈值。如果您不执行计算,仍然需要 condition 部分,只需说明事件变量的存在即可,例如 #e
#e > 5$e

如需了解此结构的运作方式,请参阅以下示例。

示例:检测暴力破解(多次登录失败)

以下示例用于检测单个用户在 24 小时内多次尝试登录失败的情况:

rule DailyFailedLoginAttempts {
  meta:
    author = "Alex"
    description = "Detects multiple failed login attempts for a single user within a day."
    severity = "Medium"

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

  match:
    $userid over 1d

  outcome:
    $daily_failed_login_count = count($e.metadata.id)

  condition:
    $daily_failed_login_count > 5
}

如需将最终确定的搜索查询转换为可靠的检测生成规则,您通常需要按以下步骤操作:

  1. 在 Google SecOps 中,前往规则编辑器
  2. 开始创建新规则。
  3. 粘贴搜索查询并对其进行修改,使其符合规则结构,包括:
    • meta 部分:定义元数据规则,包括规则名称、作者和严重程度
    • event 部分:必需。与搜索不同,您必须具有名为 event 的部分标题。
    • 事件变量:在逻辑中声明和引用特定事件(或事件组)。
    • 包含支持的时间窗口match 部分:用于指定分组键并定义时间参数(例如 5m1d)。注意:如果您在规则中使用 match 部分,则必须添加时间窗口。
    • condition 部分:定义触发规则必须满足的最终逻辑或阈值。

高级:构建多事件规则

您可以使用多事件规则来关联特定时间范围内发生的不同类型的活动。您无需查看单个事件,而是将多个事件(例如用户登录后立即执行异常文件下载)关联起来,以识别复杂的威胁。

多事件规则需要包含以下部分:

  • meta:包含规则名称和描述性详细信息。
  • events:使用事件变量定义数据源和过滤条件。
  • match:设置时间范围和用于关联事件的占位变量。
  • outcome捕获有关提醒的其他上下文。多事件规则需要聚合函数
  • condition:指定哪些事件变量必须存在才能触发规则。

如需构建多事件规则,请执行以下操作:

  1. 定义事件变量:在“事件”部分中,定义 $e1 以捕获 "PROCESS_LAUNCH" 事件,并定义 $e2 以捕获特定的恶意文件哈希。
  2. 与占位符相关联:使用 $user 占位符变量,通过共享的正文用户 ID(例如 $user = $e1.principal.user.userid and $user = $e2.principal.user.userid)将这两个不同的事件流关联起来。
  3. 对匹配项进行分组:在 match 部分,您可以指定这些事件必须在设定的时间窗口(例如 5 分钟 [5m])内针对同一 $user 发生。

示例:构建多事件规则

在以下示例中,$e1 表示 PROCESS_LAUNCH 事件,$e2 表示具有特定恶意哈希的事件。$user 占位变量会按相同的正文用户 ID 关联这些事件。

rule MultiEventExample {
  meta:
    author = "Alex"
    description = "Detects a bad hash execution or a process launch from a specific IP for the same user."

  events:
    $e1.principal.ip = "1.1.1.1"
    $e1.metadata.event_type = "PROCESS_LAUNCH"
    $e2.target.file.sha256 = "badhash..."
    $user = $e1.principal.user.userid
    $user = $e2.principal.user.userid

  match:
    $user over 5m

  condition:
    $e1 or $e2
}

以下规则组件描述了示例中使用的逻辑:

  • 事件变量:定义了两个事件变量,即 $e1$e2。使用占位变量 $user 基于共同的 userid 字段联接这些事件。
  • match 部分:为该多事件规则添加了 match 部分,以便按用户进行分组,并指定 5 分钟 (5m) 的跳跃时间窗口来关联事件。
  • condition 部分:定义了触发提醒的逻辑。此示例会在存在第一个或第二个事件时触发提醒。

使用其他工具构建查询

这些工具是编写、验证和加速采用 YARA-L 的重要帮手:

  • UDM 查找工具:直接在界面中快速搜索和参考 UDM 字段名称、定义和数据类型。如果字段 ID 未知,请优先检查此参考。
  • 自然语言到 YARA-L 的搜索:在搜索栏中输入说明,以起草初始查询或获取/翻译相应的 YARA-L 建议。
  • SPL → YARA-L 转换器(实验室工具):如果您要从竞争对手的平台迁移,请使用此工具(可在实验室部分找到)将旧版 Splunk SPL 查询转换为 YARA-L。这会生成结构化的起点,从而加快迁移速度并优化检测逻辑。如需使用实验室工具,请在 Google SecOps 中前往 yourinstancename.chronicle.security/labs。

后续步骤

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