使用 YARA-L 2.0 在 UDM 搜索中生成统计信息和汇总

支持的平台:

本页介绍了如何对 UDM 事件运行统计查询,以及如何使用 YARA-L 2.0 对结果进行分组以进行分析。

概览

在处理环境中生成的大量 UDM 事件时,请务必了解 UDM 搜索数据的趋势。您可以使用统计函数和汇总函数从 UDM 日志中获取富有实用价值的数据分析。UDM 搜索支持 YARA-L 2.0 中的所有汇总函数

您可以将统计查询用于以下用例:

  • 跟踪关键指标:您可以衡量 UDM 事件的传播和频率,以及涉及的资源(例如与已知恶意 IP 地址通信的主机)。

  • 检测异常行为:您可以检测可能表明存在安全事件的异常模式或活动高峰,例如异常的网络流量或非正常时间段内的意外登录活动。

  • 分析一段时间内的趋势:您可以确定安全状况的变化,以评估控制措施的影响或找出需要改进的方面,例如跟踪一段时间内漏洞数量的变化。

您可以使用与检测引擎规则中的 YARA-L 结构类似的语法对 UDM 搜索查询结果进行分组和排序。如需了解详情,请参阅 YARA-L 2.0 语言语法

查询结构如下所示:

  1. 过滤语句:过滤语句用于指定过滤事件的条件。

  2. Match(可选):Match 部分用于指定要按哪些字段进行分组。如需了解详情,请参阅匹配部分语法

  3. 结果:结果部分指定查询的输出。如需了解详情,请参阅结果部分语法

  4. Order:Order 部分用于指定返回的查询结果的顺序。如果未指定顺序(ascdesc),则默认为 asc

  5. Limit(可选):Limit 部分用于指定查询返回的行数上限。

以下是使用排序和限制的示例:

metadata.log_type = "OKTA"

match:
    principal.ip
Outcome:
    $user_count_by_ip = count(principal.user.userid)

order:
 $user_count_by_ip desc

limit:
    20

聚合

UDM 搜索支持以下汇总函数:

总和

sum(numericExpression)

说明

sum 函数会返回数字列中的值总和。它会在计算过程中忽略 NULL 值。它通常与 match 搭配使用,用于计算数据中不同组内的总和。

参数数据类型

NUMBER

返回类型

NUMBER

代码示例

示例

查找 target.ip 不为空的所有事件。对于与 principal.ip 匹配的所有事件,将 network.sent_bytes 的总和存储在一个名为 sent_bytes 的变量中。

  target.ip != ""
  match:
    principal.ip
  outcome:
    $sent_bytes = sum(network.sent_bytes)

分钟

min(numericExpression)

说明

min 函数用于返回数值列中的最小值。它通常与 match 搭配使用,用于获取数据中每个组中的最小值。

参数数据类型

NUMBER

返回类型

NUMBER

代码示例

示例

查找 target.ip 不为空的所有事件。对于与 principal.ip 匹配的所有事件,将 metadata.event_timestamp.seconds 的最小值存储在一个名为 min_seconds 的变量中。

  target.ip != ""
  match:
    principal.ip
  outcome:
    $min_seconds = min(metadata.event_timestamp.seconds)

max

max(numericExpression)

说明

max 函数会返回数值列中的最大值。它通常与 match 搭配使用,用于获取数据中每个组内的最大值。

参数数据类型

NUMBER

返回类型

NUMBER

代码示例

示例

查找 target.ip 不为空的所有事件。对于与 principal.ip 匹配的所有事件,将 metadata.event_timestamp.seconds 的最大值存储在一个名为 max_seconds 的变量中。

  target.ip != ""
  match:
    principal.ip
  outcome:
    $max_seconds = max(metadata.event_timestamp.seconds)

平均值

avg(numericExpression)

说明

avg 函数会返回数字列中值的平均值。它会在计算期间忽略 NULL 值。它通常与 match 搭配使用,用于计算数据中特定组内的平均值。

参数数据类型

NUMBER

返回类型

NUMBER

代码示例

示例

查找 target.ip 不为空的所有事件。对于与 principal.ip 匹配的所有事件,将 metadata.event_timestamp.seconds 的平均值存储在一个名为 avg_seconds 的变量中。

  target.ip != ""
  match:
    principal.ip
  outcome:
    $avg_seconds = avg(metadata.event_timestamp.seconds)

计数

count(expression)

说明

count 函数用于返回组中的行数。它通常与 match 搭配使用,以获取数据中特定组的计数。

参数数据类型

STRING

返回类型

NUMBER

代码示例

示例

返回一段时间内成功登录的用户数。

  metadata.event_type = "USER_LOGIN"
  $security_result = security_result.action
  $security_result = "ALLOW"
  $date = timestamp.get_date(metadata.event_timestamp.seconds, "America/Los_Angeles")
  match:
      $security_result, $date
  outcome:
      $event_count = count(metadata.id)

count_distinct

count_distinct(expression)

说明

count_distinct 函数用于返回组中具有不同值的行数。它通常与 match 搭配使用,以获取数据中特定组的计数。

参数数据类型

STRING

返回类型

NUMBER

代码示例

示例

返回一段时间内唯一身份用户成功登录的次数。

  metadata.event_type = "USER_LOGIN"
  $security_result = security_result.action
  $security_result = "ALLOW"
  $date = timestamp.get_date(metadata.event_timestamp.seconds, "America/Los_Angeles")
  match:
      $security_result, $date
  outcome:
      $event_count = count_distinct(metadata.id)

数组

array(expression)

说明

array 函数会以列表的形式返回所有值。它会将列表截断为最多 25 个随机元素。

参数数据类型

STRING

返回类型

LIST

代码示例

示例

返回一个包含事件类型的数组。

  $event_type = metadata.event_type
  outcome:
    $event_type_array = array($event_type)

array_distinct

array_distinct(expression)

说明

array_distinct 函数会以列表的形式返回所有不同的值。它会将列表截断为最多 25 个随机元素。系统会先应用去重操作来获取不重复的列表,然后再截断。

参数数据类型

STRING

返回类型

LIST

代码示例

示例

返回一个包含不同事件类型的数组。

  $event_type = metadata.event_type
  outcome:
    $event_type_array = array_distinct($event_type)

stddev

stddev(numericExpression)

说明

stddev 函数会返回所有可能值的标准差。

参数数据类型

NUMBER

返回类型

NUMBER

代码示例

示例

查找 target.ip 不为空的所有事件。对于与 principal.ip 匹配的所有事件,将 metadata.event_timestamp.seconds 的标准差存储在名为 stddev_seconds 的变量中。

  target.ip != ""
  match:
    principal.ip
  outcome:
    $stddev_seconds = stddev(metadata.event_timestamp.seconds)

在搜索中使用 YARA-L 2.0 与在 UDM 中使用 YARA-L 2.0 之间的区别

  • over 关键字(用于搜索特定时间范围内的事件)不适用于搜索。

  • UDM 搜索查询结构不包含 conditionoption 部分。

按时间粒度分组

您可以按指定的时间精度对 match 部分中的所有事件字段和占位符进行分组,这类似于您在 SQL 中按列进行分组。

语法如下:

match:
  ... [BY|OVER EVERY] [FIRST] [TIME_GRANULARITY]

如需按时间粒度进行分组,您可以使用关键字 byover every。允许的时间精度如下:

  • MINUTEm
  • HOURh
  • DAYd
  • WEEKw
  • MONTHmo

byover every 关键字在功能上等效。您可以选择使用其中一种。

示例

按小时对 IP 地址和主机名进行分组。

$hostname = principal.hostname
match:
  $hostname, target.ip by hour

按主机名和事件发生日期对所有事件的计数进行分组。

$hostname = target.hostname
match:
  $hostname over every day
outcome:
  $events_count = count($hostname)

某些数据源(例如实体情境)在一个时间范围内(<start_time><end_time>)有效,并且不带单个时间戳。

first 关键字是一个可选关键字,用于将在时间范围内有效的数据源视为仅在单个时间戳有效的数据源。这意味着,对于在某个时间范围内有效的数据源,关键字 first 仅会考虑开始时间 (<start_time>),而会忽略时间范围的结束时间。

例如,假设某个实体的时间范围为 (1m, 5m),时间粒度为 1 分钟。假设结果按主机分组(即 (h1, h2))。然后,返回的列为 (h1, 1m) 和 (h2, 1m),因为系统会忽略时间范围的其余部分。

first 关键字可同时添加到 byover every,这会导致这两个关键字的行为相同。使用 by first 的效果等同于 over every first

以下是将 by 运算符与在时间范围内有效的实体上下文数据源搭配使用的查询示例。在此查询中,系统会考虑整个时间范围,因为省略了 first 关键字。

graph.entity.hostname != ""
match:
  graph.entity.ip by hour
outcome:
  $min_seconds = min(graph.metadata.event_metadata.event_timestamp.seconds)

搜索中的可视化内容

本部分简要介绍了 Google SecOps 统一数据模型 (UDM) 搜索中的可视化数据功能。借助此功能,安全运营中心 (SOC) 分析师可以根据搜索结果创建可视化图表并将其保存到信息中心,从而高效检测、调查和响应威胁。

创建可视化图表并将其保存到“预览”信息中心

如需将可视化图表保存到预览信息中心,请执行以下操作:

  1. 编写包含 matchoutcome 部分的 YARA-L 查询。

  2. 选择日期范围,然后点击运行搜索以运行查询。 查询结果显示在两个标签页中:统计标签页和可视化标签页。

  3. 可视化标签页中,从图表类型列表中选择图表类型。

  4. 对于所选图表类型,更改数据设置下的设置以自定义图表。

  5. 添加到信息中心界面上,添加图表名称、图表说明和图表时间范围。

  6. 选择相应选项,将图表添加到现有信息中心或新信息中心。

  7. 点击添加到信息中心将图表添加到信息中心。