Joins in der Suche und in Dashboards anwenden
Mithilfe von Joins lassen sich Daten aus mehreren Quellen korrelieren, um mehr Kontext für eine Untersuchung zu liefern. Durch das Verknüpfen zusammengehöriger Ereignisse, Entitäten und anderer Daten können Sie komplexe Angriffsszenarien untersuchen und Trends visualisieren.
In diesem Dokument wird erläutert, wie Sie den Join-Vorgang in der Google Security Operations-Suche und in Dashboards verwenden. Außerdem werden unterstützte Join-Typen, Anwendungsfälle und Best Practices behandelt.
Join erstellen
Es werden nur statistische Joins unterstützt. Sie müssen sie im Abschnitt match einer Abfrage definieren.
Das Korrelationszeitfenster (Abgleichszeitfenster) hängt davon ab, ob Sie die Suche oder Dashboards verwenden:
- Suche: Bis zu 48 Stunden.
- Dashboards: Bis zu 365 Tage (für die meisten Datenquellen).
Sie können einen Join erstellen, indem Sie Felder direkt verbinden (z. B. $e1.hostname = $e2.hostname) oder Platzhaltervariablen verwenden. Wenn Sie einen Join im Abschnitt match definieren, müssen Sie Platzhaltervariablen verwenden.
Im folgenden Beispiel werden zwei Felder mit einem Gleichheitszeichen (=) und einer gemeinsamen Platzhaltervariablen verknüpft:
Beispiel 1:
events: // Assign a value from the first event to the placeholder variable $user $user = $e1.principal.user.userid // The second assignment creates an implicit join, linking $e2 to $e1 // where the user ID is the same. $user = $e2.principal.user.userid match: $user over 1h condition: $e1 and $e2Beispiel 2:
$e1.principal.ip = $ip $e1.metadata.event_type = "USER_LOGIN" $e1.principal.hostname = $host $e2.target.ip = $ip $e2.principal.hostname = "altostrat" $e2.target.hostname = $host match: $ip, $host over 5m
Unterstützte Join-Typen
In diesem Abschnitt werden die verschiedenen Arten von Joins beschrieben, die Sie verwenden können. Die Beispiele in diesem Abschnitt veranschaulichen die in der Suche verwendete Syntax. Informationen zu Joins in Dashboards finden Sie unter Joins in Dashboards.
Join zwischen Ereignissen
Bei einem Event-Event-Join werden zwei verschiedene Universal Data Model-Ereignisse (UDM) verknüpft. Im folgenden Beispiel wird ein
USER_LOGIN-Ereignis mit einem anderen Ereignis verknüpft, um den Hostnamen (altostrat) zu ermitteln, mit dem der Nutzer interagiert hat. Die Verknüpfung erfolgt auf Grundlage einer gemeinsamen IP-Adresse:$e1.principal.ip = $ip $e1.metadata.event_type = "USER_LOGIN" $e2.target.ip = $ip $e2.principal.hostname = "altostrat" match: $ip over 5m
Ereignis-EKG-Join
Bei einem Event-ECG-Join wird ein UDM-Ereignis mit einer Entität aus dem Entity Context Graph (ECG) verknüpft. Mit der folgenden Beispielabfrage wird ein
NETWORK_CONNECTION-Ereignis und einASSETaus dem Entity-Diagramm gefunden, die innerhalb eines Zeitfensters von einer Stunde denselben Hostnamen haben:events: $e1.metadata.event_type = "NETWORK_CONNECTION" $g1.graph.metadata.entity_type = "ASSET" $e1.principal.asset.hostname = $g1.graph.entity.asset.hostname $x = $g1.graph.entity.asset.hostname match: $x over 1h condition: $e1 and $g1
Verknüpfung von Datentabellenereignissen
Bei einem Datatable-Event-Join werden UDM-Ereignisse mit Einträgen in einer benutzerdefinierten Datentabelle verknüpft. Das ist nützlich, um Live-Ereignisdaten mit einer benutzerdefinierten Liste abzugleichen, z. B. mit bekannten schädlichen IP-Adressen oder Bedrohungsakteuren. In der folgenden Beispielabfrage werden
NETWORK_CONNECTION-Ereignisse mit einer Datentabelle verknüpft, um Verbindungen mit bestimmten IP-Adressen aus dieser Liste zu finden:$ip = %DATATABLE_NAME.COLUMN_NAME $ip = $e1.principal.ip $e1.metadata.event_type = "NETWORK_CONNECTION" match: $ip over 1h
Best Practices
Join-Abfragen können ressourcenintensiv sein, da sie viele Ergebnisse kombinieren. Allgemeine Filter können dazu führen, dass Abfragen fehlschlagen, manchmal nach langer Verzögerung, z. B.:
target.ip != ""metadata.event_type = "NETWORK_CONNECTION"(wenn dieser Ereignistyp in Ihrer Umgebung sehr häufig vorkommt)
Wir empfehlen, allgemeine Filter mit spezifischeren zu kombinieren, um die Gesamtzahl der Ereignisse zu reduzieren, die von der Abfrage verarbeitet werden müssen. Ein allgemeiner Filter wie
target.ip != ""sollte mit spezifischeren Filtern kombiniert werden, um die Leistung der Abfrage zu verbessern, z. B.:$e1.metadata.log_type = $log $e1.metadata.event_type = "USER_LOGIN" $e1.target.ip != "" $e2.metadata.log_type = $log $e2.principal.ip = "10.0.0.76" $e2.target.hostname != "altostrat" match: $log over 5m
Wenn die Abfrage immer noch langsam ist, können Sie auch den gesamten Zeitraum der Abfrage verkürzen (z. B. von 30 Tagen auf eine Woche).
Weitere Informationen finden Sie unter Best Practices für YARA-L.
Joins in Dashboards
Dashboards unterstützen eine größere Auswahl an Datenquellen und längere Korrelationszeiträume als die Suche.
Unterstützte Datenquellen
In Dashboards können Sie Daten aus den folgenden Quellen mit den entsprechenden YARA-L-Präfixen zusammenführen:
| Präfix | Datenquelle |
|---|---|
case |
Anfragen und Benachrichtigungen |
case_history |
Aktivitätstrends im gesamten Falllebenszyklus |
detection |
Verlauf von Regelerkennungen und Analystenfeedback |
ingestion |
Messwerte für Logvolumen und Aufnahmeintegrität |
ioc |
IoC-Übereinstimmungen (Kompromittierungsindikator) |
playbook |
Messwerte für automatisierte Reaktionen und Playbook-Ausführung |
ruleset/rules |
Metadaten zu aktiven Regelsätzen |
graph |
Daten aus dem Entitätsdiagramm (EKG) |
events |
UDM-Ereignisse |
Berücksichtigung der Groß-/Kleinschreibung
Im Gegensatz zur Suche, bei der standardmäßig nicht zwischen Groß- und Kleinschreibung unterschieden wird, wird bei Dashboards zwischen Groß- und Kleinschreibung unterschieden. Wenn Sie in einem Dashboard einen Join oder eine Suche ausführen möchten, bei dem bzw. bei der die Groß- und Kleinschreibung ignoriert wird, verwenden Sie den Modifikator nocase.
Beispiel: Join für „case“ und „case_history“
Sie können Fallmetadaten mit dem zugehörigen Aktivitätsverlauf in Beziehung setzen, indem Sie die eindeutige Fall-ID verwenden.
Im folgenden Beispiel werden die Datenquellen
caseundcase_historyzusammengeführt, um die Gesamtzahl der bisherigen Aktionen für jeden Fall mit hoher Priorität zu ermitteln.// 1. Establish the Join using a shared placeholder variable ($case_id) $h.case_history.case_response_platform_info.case_id = $case_id $c.case.response_platform_info.response_platform_id = $case_id // 2. Apply Filters $c.case.priority = "PRIORITY_HIGH" // 3. Group the correlated data by the Case ID match: $case_id // 4. Calculate the selected metrics to display on the dashboard outcome: $case_name = array_distinct($c.case.display_name) $total_historical_actions = count($h.case_history.case_activity)
Erweiterter Anwendungsfall: MTTR berechnen
Für komplexere Messwerte wie „Mittlere Zeit bis zur Problemlösung“ (Mean Time to Resolve, MTTR) oder „Mittlere Zeit bis zum Schließen“ (Mean Time to Close, MTTC) können Sie eine mehrstufige Abfrage verwenden. So können Sie die Dauer für jeden einzelnen Fall in der ersten Phase berechnen und diese Dauern dann im endgültigen Ergebnisblock global mitteln.
Mit der folgenden Abfrage wird die durchschnittliche Zeit zum Schließen von Anfragen (in Minuten) für alle Anfragen in der Standardumgebung berechnet.
stage stage1 { // 1. Establish the Join $h.case_history.case_response_platform_info.case_id = $case_id $c.case.response_platform_info.response_platform_id = $case_id // 2. Filter by specific environment $c.case.environment = "Default Environment" // 3. Group by Case ID to process per case match: $case_id // 4. Calculate the Time to Close (TTC) for each case individually outcome: $case_close_time = max(if($h.case_history.case_activity = "CLOSE_CASE", $h.case_history.event_time.seconds, 0)) $status = array_distinct($h.case_history.case_activity) // Subtract the very first event time (creation) from the close time $TTC = $case_close_time - min($h.case_history.event_time.seconds) // 5. Filter to ensure the case has a complete lifecycle condition: arrays.contains($status, "CREATE_CASE") and arrays.contains($status, "CLOSE_CASE") } // 6. Global Aggregation: Calculate the Mean (Average) across all processed cases outcome: $case_count = count($stage1.case_id) $MTTC = (math.round(avg($stage1.TTC) / 60))
Beschränkungen
Bei der Verwendung von Joins gelten die folgenden Einschränkungen:
Sie können maximal zwei UDM-Ereignisse pro Suchanfrage verwenden.
Sie können pro Anfrage in der Suche maximal ein EKG-Ereignis verwenden.
Pro Abfrage können maximal zwei Datatables verwendet werden.
Sie können Datentabellen-, UDM- und EKG-Ereignisse nicht in einer einzigen Abfrage zusammenführen.
Der maximale Zeitraum für Abfragen beträgt 90 Tage.
Das maximale
match-Zeitfenster beträgt 48 Stunden für die Suche und 365 Tage für Dashboards.Joins werden in der Benutzeroberfläche und in der
EventService.UDMSearchAPI, aber nicht in derSearchService.UDMSearchAPI unterstützt.
Gängige Anwendungsfälle
In diesem Abschnitt werden einige gängige Möglichkeiten zur Verwendung von Joins aufgeführt.
Diebstahl und Verwendung von Anmeldedaten erkennen
Ziel: Instanzen finden, in denen sich ein Nutzer erfolgreich anmeldet und dann schnell eine wichtige Systemdatei löscht. Das könnte auf eine Kontoübernahme oder böswillige Insideraktivitäten hindeuten.
Join-Typ: Event-Event-Join
Beschreibung: Bei dieser Abfrage werden zwei unterschiedliche Ereignisse verknüpft, die für sich genommen nicht verdächtig sind, aber in Kombination sehr verdächtig werden. Zuerst wird nach einem USER_LOGIN-Ereignis und dann nach einem FILE_DELETION-Ereignis gesucht. Diese werden durch die gemeinsame user.userid mit einem kurzen Zeitfenster ergänzt.
Beispielabfrage:
// Event 1: A user successfully logs in $e1.metadata.event_type = "USER_LOGIN" $e1.security_result.action = "ALLOW" $e1.principal.user.userid = $user // Event 2: The same user deletes a critical file $e2.metadata.event_type = "FILE_DELETION" $e2.target.file.full_path = /etc\/passwd|C:\\Windows\\System32\\/ $e2.principal.user.userid = $user match: $user over 10m condition: $e1 and $e2
Riskante Verbindungen von kritischen Assets identifizieren
Ziel: Live-Netzwerkdaten mit Asset-Informationen anreichern, um ausgehende Verbindungen von Servern zu finden, die nicht mit externen Domänen mit geringer Prävalenz kommunizieren sollten (z. B. ein Produktionsdatenbankserver).
Join-Typ: Event-ECG join
Beschreibung: Eine einzelne Netzwerkverbindung zu einer seltenen Domain hat möglicherweise keine hohe Priorität. Durch diese Anfrage wird die Bedeutung des Ereignisses jedoch erhöht, da es mit dem Entity Context Graph (ECG) verknüpft wird. Es wird speziell nach NETWORK_CONNECTION-Ereignissen gesucht, die von Assets stammen, die im Entity-Diagramm als „Critical Database Server“ (Kritischer Datenbankserver) gekennzeichnet sind.
Beispielabfrage:
events: $e.metadata.event_type = "NETWORK_CONNECTION" $e.target.domain.prevalence.day_count <= 5 $asset.graph.metadata.entity_type = "ASSET" $asset.graph.entity.asset.labels.value = "Critical Database Server" $e.principal.asset.hostname = $asset.graph.entity.asset.hostname $host = $e.principal.asset.hostname match: $host over 1h condition: $e and $asset
Nach IOCs von Angreifern suchen
Ziel: Aktiv nach Indicators of Compromise (IoCs) suchen, indem alle aktiven DNS-Abfragen mit einer Liste von Domains abgeglichen werden, die bekanntermaßen von einem bestimmten Bedrohungsakteur verwendet werden.
Join-Typ: Datatable-Event-Join
Beschreibung: Ihr Threat Intelligence-Team verwaltet eine Datentabelle namens ThreatActor_Domains, in der schädliche Domains aufgeführt sind. In dieser Abfrage werden alle NETWORK_DNS_QUERY-Ereignisse in Echtzeit mit dieser Datentabelle zusammengeführt. Es wird sofort angezeigt, wenn ein Host in Ihrem Netzwerk versucht, eine Domain aus Ihrer Liste mit Threat Intelligence aufzulösen.
Beispielabfrage:
// Datatable: Get the list of malicious domains $domain = %DATATABLE_NAME.COLUMN_NAME // Event: A DNS query is made $e.metadata.event_type = "NETWORK_DNS" $e.network.dns.questions.name = $domain match: $domain over 5m condition: $e
Benötigen Sie weitere Hilfe? Antworten von Community-Mitgliedern und Google SecOps-Experten erhalten