外部結合を使用してデータを関連付ける
このドキュメントでは、外部結合(左結合と右結合)について説明します。結合オペレーションは、共通のフィールド値に基づいて複数のソースのデータを関連付けて結合するために使用されます。関連するセキュリティ イベントとエンティティを 1 つの包括的なビューに統合することで、効果的な脅威の検出と調査を実現できます。
両方のデータソースに一致するエントリが必要な標準(内部)結合とは異なり、外部結合では、他方に一致するエントリがない場合でも、結合の一方のすべてのレコードが取得されます。通常、もう一方の側で一致しないフィールドは 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 分間の時間枠でホストごとに結果を集計します。
結合結果
結果のデータには、2 つのイベントの組み合わせが表示されます。左側のテーブル($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
一致条件のない結合
Event-event
$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 分間の時間枠でホストごとに結果を集計します。
結合結果
結果のデータセットには、2 つのイベントの組み合わせが表示されます。右側のテーブル($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
|
一致なし |
右結合クエリの例
このセクションでは、右結合クエリの例を示します。
一致条件を含む結合
Event-event
$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
一致条件のない結合
Event-event
$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 日間に制限されます。
2 つのコンテキスト ソース(エンティティからデータテーブルなど)を直接結合することはできません。
プライマリ統合データモデル(UDM)イベントは、外部結合の保持側である必要があります。プライマリ イベントが「nullable」側にある場合、クエリは無効です。
イベントとエンティティの結合は左結合である必要があります。これにより、イベント(
$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 のプロフェッショナルから回答を得ることができます。