YARA-L 使用入门

支持:

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.userid、target.ip、principal.hostname 或变量,例如 $host、$user)对重复事件进行分组来移除重复事件。详细了解事件变量以及如何在搜索和信息中心内使用重复信息删除功能。
8 order 不适用 可选 对由特定字段(例如 asc)定义的结果进行排序。详细了解事件变量。可选(仅在使用 match 时适用)。
9 limit 不适用 可选 限制查询返回的事件数量上限。
10 select 不适用 可选 指定要包含在查询结果中的 UDM 字段列表。
11 unselect 不适用 可选 指定要从查询结果中排除的 UDM 字段列表。

YARA-L 数据源可用性

YARA-L 可以访问不同的数据源,具体取决于您在平台中的位置。事件、实体 (ECG) 和数据表在搜索、信息中心和规则中完全可用。如需详细了解示例查询,请参阅支持的数据源。

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

功能 支持的语言
支持请求和支持请求历史记录 信息中心
数据表 搜索、信息中心、规则
实体 (ECG) 搜索、信息中心、规则
注入指标 信息中心
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. 使用每个用户 ($failed_login_count) 的登录失败次数 (count),由 outcome 变量定义:

    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:
      $user 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(用于计算输出和汇总)。

例如,您可以创建一个包含 events 和 match 部分的信息中心,其中信息中心会显示按 by hour 存储桶分组的检测结果的严重级别 ($severity)。

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

  • 您可以使用 events 和 match 部分创建一个信息中心,以显示归入 hour 存储桶的检测结果的严重程度 ($severity):

    detection.detection.severity != "UNKNOWN_SEVERITY"
    $severity = detection.detection.severity
    
    match:
      $severity by hour
    

示例:汇总严重影响总数

  • 同样,您可以使用 events 和 outcome 部分创建信息中心,以跟踪高严重性检测结果:

    detection.detection.severity = "CRITICAL"
    $severity = detection.detection.severity
    
    outcome:
      $detection_count = count_distinct($severity)
    

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

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

    detection.detection.severity != "UNKNOWN_SEVERITY"
    $severity = detection.detection.severity
    
    match:
      $severity by hour
    
    outcome:
      $detection_count = count_distinct(detection.id)
    

示例:计算用户登录频率

  • 以下示例重点介绍如何使用 match 和 outcome 部分计算特定用户的 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"
    

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

整理规则结构和语法

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

元素 说明 示例
规则结构 将查询封装在 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 分组会正确地按每个 24 小时时间段 (1d) 内的用户 ID 对事件进行分组。

编写规则时,您必须指定支持的时间范围来定义回溯期。您可以根据逻辑要求实现跳跃、滑动或翻滚窗口。使用 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 部分:用于指定分组键并定义时间参数(例如 5m 或 1d)。注意:如果您在规则中使用 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 专业人士的解答。