通过外联接关联数据

支持的平台:

本文档介绍了外联接(左联接和右联接)。联接操作用于根据共同的字段值关联和合并来自多个来源的数据。通过将相关的安全事件和实体整合到单个全面的视图中,您可以提供有效的威胁检测和调查。

标准(内)联接(要求两个数据源中都有匹配的条目)不同,外联接会从联接的一侧检索所有记录,即使另一侧没有匹配的条目也是如此。另一侧的不匹配字段通常会填充 null。这样可以防止您丢失没有匹配项的数据。

外联接的运作方式

YARA-L 2.0 中的外联接概念与标准 SQL 外联接相同:

  • 左外联接会保留联接左侧的所有记录。

  • 右外联接会保留联接右侧的所有记录。

所有查询(无论是否带有 match 条件)均支持外联接语法(左联接和右联接)。

了解左外联接

左外联接(或左联接)会保留 left join 关键字左侧的数据源中的所有记录。

  • 如果左侧的记录在右侧事件中没有匹配项,则右侧事件中的字段将以 null 形式返回。

  • 占位符含义match 部分中使用的任何占位符变量都必须引用左侧事件中的字段,以确保在整个结果集中准确汇总数据。

活动到活动的左联接示例

以下示例演示了如何使用左外部联接来关联用户登录事件与同一主机上发生的后续网络连接事件。左联接可确保结果集中保留所有 USER_LOGIN 事件。如果找到匹配的 NETWORK_CONNECTION 事件 ($e2),则会合并其数据。如果未找到任何匹配项,则 $e2 的字段为 null


$e1.metadata.event_type = "USER_LOGIN"
$e2.metadata.event_type = "NETWORK_CONNECTION"
left join $e1.principal.hostname = $e2.principal.hostname

定义左侧事件

以下查询示例定义了联接的左侧 ($e1),即最终结果中保留的事件集:

$e1.metadata.event_type = "USER_LOGIN"

下表显示了查询结果,其中确定了初始的一组用户登录事件:

活动类型 主账号主机名 IP 地址
USER_LOGIN workstation-01 192.168.1.101
USER_LOGIN laptop-hr-02 192.168.1.102
USER_LOGIN server-db-03 10.0.0.50
USER_LOGIN kiosk-4 192.168.1.104

定义合适的活动

以下查询示例定义了联接的右侧 ($e2),即与左侧事件匹配的事件集:

$e2.metadata.event_type = "NETWORK_CONNECTION"

下表列出了可用于匹配的网络连接事件:

活动类型 主账号主机名 IP 地址
NETWORK_CONNECTION workstation-01 192.168.1.101
NETWORK_CONNECTION laptop-hr-02 192.168.1.101
NETWORK_CONNECTION kiosk-4 203.0.113.3

参加活动

包含“比赛”部分

以下示例演示了如何使用 principal.hostname 字段上的左外连接来执行匹配查询:


  $e1.metadata.event_type = "USER_LOGIN"

  $e2.metadata.event_type = "NETWORK_CONNECTION"

  left join $e1.principal.hostname = $e2.principal.hostname

  $host = $e1.principal.hostname

  match:
    $host over 5m

  • 左外联接可确保最终结果集中包含每个 USER_LOGIN 事件 ($e1)。

  • 占位符 $host 会分配来自 $e1.principal.hostname 的值。左外连接可确保存在事件 $e1,从而确保始终为聚合填充 $host 变量。

  • 该规则按主机在 5 分钟的时间窗口内汇总结果。

联接结果

生成的数据会显示这两个事件的组合。左侧表 ($e1) 中的所有记录都会保留,如果找不到匹配的主机名(例如,对于 server-db-03),则右侧表 ($e2) 中的字段会设置为 null

活动类型 ($e1) 主主机名 ($host) IP 地址 ($e1) 活动类型 ($e2) IP 地址 ($e2) 比赛状态
USER_LOGIN workstation-01 192.168.1.101 NETWORK_CONNECTION 192.168.1.101 找到了匹配项
USER_LOGIN laptop-hr-02 192.168.1.102 NETWORK_CONNECTION 192.168.1.101 找到了匹配项
USER_LOGIN server-db-03 10.0.0.50 null null 不匹配
USER_LOGIN kiosk-4 192.168.1.104 NETWORK_CONNECTION 203.0.113.3 找到了匹配项

左联接查询示例

本部分提供了左联接查询示例。

使用匹配条件进行联接

  • 活动实体

    
    $e1.metadata.event_type = "NETWORK_CONNECTION"
    $g1.graph.metadata.entity_type = "ASSET"
    left join $e1.principal.asset.hostname = $g1.graph.entity.asset.hostname
    $host = $e1.principal.asset.hostname
    
    match:
      $host over 5m
    
    
  • Event-datatable

    
    $host = $e1.principal.hostname
    left join $e1.principal.hostname = %all_dt_column_types.hostname
    
    match:
      $host by 5m
    

没有匹配条件的联接

  • 事件-事件

    
    $e1.metadata.event_type = "USER_LOGIN"
    $e1.principal.ip = "114.241.96.87"
    $e2.metadata.event_type = "NETWORK_CONNECTION"
    left join $e1.principal.hostname = $e2.principal.hostname
    
    
  • 活动实体

    
    $e1.metadata.event_type = "NETWORK_CONNECTION"
    $g1.graph.metadata.entity_type = "ASSET"
    left join $e1.principal.asset.hostname = $g1.graph.entity.asset.hostname
    $host = $e1.principal.asset.hostname
    
    
  • Event-datatable

    
    $host = $e1.principal.hostname
    left join $e1.principal.hostname = %all_dt_column_types.hostname
    
    

右外联接

右外联接(或右联接)会保留 right join 关键字右侧的数据源中的所有记录。

  • 如果右侧事件中的记录在左侧事件中没有匹配项,则左侧事件中的字段会以 null 的形式返回。

  • 占位符含义match 部分中使用的任何占位符变量都必须引用正确事件中的字段,以确保在整个结果集中准确汇总数据。

Event-to-Event 右联接示例

以下示例展示了如何使用 right outer join 将用户登录事件与同一主机上发生的后续网络连接事件相关联。right join可确保在结果集中保留所有 NETWORK_CONNECTION 事件。如果找到匹配的 USER_LOGIN 事件,则会联接其数据。 如果未找到匹配项,则 $e1 的字段为 null


$e1.metadata.event_type = "USER_LOGIN"

$e2.metadata.event_type = "NETWORK_CONNECTION"

right join $e1.principal.hostname = $e2.principal.hostname

定义左侧事件

以下查询定义了联接的左侧 ($e1),即最终结果中的可选事件集:


$e1.metadata.event_type = "USER_LOGIN"

下表显示了查询结果,其中确定了初始用户登录事件集:

活动类型 主账号主机名 IP 地址
USER_LOGIN workstation-01 192.168.1.101
USER_LOGIN laptop-hr-02 192.168.1.102
USER_LOGIN server-db-03 10.0.0.50

定义正确的事件

以下查询定义了联接的右侧 ($e2),即最终结果中保留的事件集。


$e2.metadata.event_type = "NETWORK_CONNECTION"

下表列出了可用于匹配的网络连接事件。

活动类型 主账号主机名 IP 地址
NETWORK_CONNECTION workstation-01 192.168.1.101
NETWORK_CONNECTION laptop-hr-02 192.168.1.101
NETWORK_CONNECTION vm-unauth-05 203.0.113.3

参加活动

以下示例展示了对 principal.hostname 字段进行右外连接的匹配查询:


$e1.metadata.event_type = "USER_LOGIN"

$e2.metadata.event_type = "NETWORK_CONNECTION"

right join $e1.principal.hostname = $e2.principal.hostname

$host = $e1.principal.hostname

match:
  $host over 5m

  • 右外联接可确保每个 NETWORK_CONNECTION 事件 ($e2) 都包含在最终结果集中。

  • 占位符 $host 会被分配 $e2.principal.hostname 中的值。 右外联接可确保存在事件 $e2,从而确保始终为汇总填充 $host 变量。

  • 该规则按主机在 5 分钟的时间窗口内汇总结果。

联接结果

生成的数据集显示了这两个事件的组合。右侧表 ($e2) 中的所有记录都会保留,如果找不到匹配的主机名(例如 vm-unauth-05),则左侧表 ($e1) 中的字段会设置为 null。

活动类型 ($e1) 主主机名 ($e1) IP 地址 ($e1) 活动类型 ($e2) 主主机名 ($host) IP 地址 ($e2) 比赛状态
USER_LOGIN workstation-01 192.168.1.101 NETWORK_CONNECTION workstation-01 192.168.1.101 找到了匹配项
USER_LOGIN laptop-hr-02 192.168.1.102 NETWORK_CONNECTION laptop-hr-02 192.168.1.101 找到了匹配项
null null null NETWORK_CONNECTION vm-unauth-05 203.0.113.4 不匹配

右联接查询示例

本部分提供了右联接查询示例。

使用匹配条件进行联接

  • 事件-事件

    
    $e1.metadata.event_type = "USER_LOGIN"
    
    $e2.metadata.event_type = "NETWORK_CONNECTION"
    
    right join $e1.principal.hostname = $e2.principal.hostname
    
    $host = $e2.principal.hostname
    
    match:
      $host over 5m
    
    
  • 实体-事件

    
    $e1.metadata.event_type = "NETWORK_CONNECTION"
    
    $g1.graph.metadata.entity_type = "ASSET"
    
    right join $g1.graph.entity.asset.hostname = $e1.principal.asset.hostname
    
    $host = $e1.principal.asset.hostname
    
    match:
      $host over 5m
    
    
  • Datatable-event

    
    $host = $e1.principal.hostname
    
    right join %all_dt_column_types.hostname = $e1.principal.hostname
    
    match:
      $host by 5m
    
    

没有匹配条件的联接

  • 事件-事件

    
    $e1.metadata.event_type = "USER_LOGIN"
    
    $e1.principal.ip = "114.241.96.87"
    
    $e2.metadata.event_type = "NETWORK_CONNECTION"
    
    right join $e1.principal.hostname = $e2.principal.hostname
    
    
  • 实体-事件

    
    $e1.metadata.event_type = "NETWORK_CONNECTION"
    
    $g1.graph.metadata.entity_type = "ASSET"
    
    right join $g1.graph.entity.asset.hostname = $e1.principal.asset.hostname
    
    $host = $e1.principal.asset.hostname
    
    
  • Datatable-event

    
    $host = $e1.principal.hostname
    
    right join %all_dt_column_types.hostname = $e1.principal.hostname
    
    

限制

创建外连接时,请考虑以下限制:

  • 不支持全外联接(左联接和右联接的组合)。

  • 无匹配联接的查询时间范围最长为 14 天。

  • 您无法直接联接两个情境来源(例如,直接将实体联接到数据表)。

  • 主要统一数据模型 (UDM) 事件必须是外连接的保留侧。如果主事件位于“可为 null”的一侧,则查询无效。

    • 事件-实体联接必须是左联接。这样可以正确保留事件 ($e1)。

    • 实体-事件联接必须是右联接。这样可以正确保留事件 ($e1)。

    以下示例无效,因为 UDM 事件 ($e1) 位于左侧,但右联接会保留右侧 ($g1),这违反了必须保留 UDM 事件的规则:

    
    // Invalid query
    $e1.metadata.event_type = "NETWORK_CONNECTION"
    $g1.graph.metadata.entity_type = "ASSET"
    right join $e1.principal.asset.hostname = $g1.graph.entity.asset.hostname
    
    

最佳做法

为避免外连接查询出现性能缓慢和查询超时的情况,请使用具体且范围较窄的过滤条件。

例如,以下宽泛的查询:


$e1.metadata.event_type = "USER_LOGIN"
$e2.metadata.event_type = "NETWORK_CONNECTION"
right join $e1.principal.hostname = $e2.principal.hostname

可以通过添加以下特定条件进行优化:


$e1.metadata.event_type = "USER_LOGIN"
$e1.principal.ip = "121.121.121.121"
$e1.principal.user.userid = "alex"
$e2.metadata.event_type = "NETWORK_CONNECTION"
$e2.src.hostname = "altostrat.com"
$e1.principal.hostname = $e2.principal.hostname

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