通过外联接关联数据
本文档介绍了外联接(左联接和右联接)。联接操作用于根据共同的字段值关联和合并来自多个来源的数据。通过将相关的安全事件和实体整合到单个全面的视图中,您可以提供有效的威胁检测和调查。
与标准(内)联接(要求两个数据源中都有匹配的条目)不同,外联接会从联接的一侧检索所有记录,即使另一侧没有匹配的条目也是如此。另一侧的不匹配字段通常会填充 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 5mEvent-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.hostnameEvent-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 5mDatatable-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.hostnameDatatable-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 专业人士的解答。