Joins in Suchanfragen und Dashboards verwenden

Unterstützt in:

Mit Joins lassen sich Daten aus mehreren Quellen korrelieren, um mehr Kontext für eine Untersuchung zu erhalten. Durch das Verknüpfen von zugehörigen Ereignissen, Entitäten und anderen 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 statistikbasierte Joins unterstützt. Sie müssen sie im Abschnitt match einer Abfrage definieren.

Der Zeitraum für die Korrelation (Match-Zeitraum) 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.

In der folgenden Beispielabfrage 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 $e2
    
    
  • Beispiel 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 zeigen die Syntax, die in der Suche verwendet wird. Informationen zu Joins in Dashboards finden Sie unter Joins in Dashboards.

Ereignis-Ereignis-Join

  • Ein Ereignis-Ereignis-Join verbindet zwei verschiedene Ereignisse des Universal Data Model (UDM). In der folgenden Beispielabfrage wird ein USER_LOGIN-Ereignis mit einem anderen Ereignis verknüpft, um den Hostnamen (altostrat) zu finden, mit dem der Nutzer interagiert hat. Die Verknüpfung erfolgt anhand 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-ECG-Join

  • Ein Ereignis-ECG-Join verbindet ein UDM-Ereignis mit einer Entität aus dem Entity Context Graph (ECG). In der folgenden Beispielabfrage werden ein NETWORK_CONNECTION-Ereignis und ein ASSET aus dem Entitätendiagramm gefunden, die innerhalb eines Zeitraums 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
    
    

Datentabelle-Ereignis-Join

  • Ein Datentabelle-Ereignis-Join verbindet UDM-Ereignisse mit Einträgen in einer benutzerdefinierten Datentabelle. Das ist nützlich, um Live-Ereignisdaten mit einer benutzerdefinierten Liste zu vergleichen, z. B. mit bekannten schädlichen IP-Adressen oder Angreifern. 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. Breite, allgemeine Filter können dazu führen, dass Abfragen fehlschlagen, manchmal nach einer langen Verzögerung. Beispiele:

    • 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 breiter Filter wie target.ip != "" sollte mit spezifischeren Filtern kombiniert werden, um die Leistung der Abfrage zu verbessern. Beispiele:

    $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 Ihre Abfrage immer noch langsam ist, können Sie auch den Gesamtzeitraum der Abfrage reduzieren (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 verknüpfen:

Präfix Datenquelle
case Anfragen und Benachrichtigungen
case_history Aktivitätstrends über den gesamten Lebenszyklus von Anfragen hinweg
detection Verlauf der Regelerkennungen und Analystenfeedback
ingestion Logvolumen und Messwerte zur Ingestion-Integrität
ioc Übereinstimmungen mit Kompromittierungsindikatoren (IoCs)
playbook Messwerte zur automatisierten Reaktion und zur Playbook-Ausführung
ruleset / rules Metadaten zu aktiven Regelsätzen
graph Entitätendiagrammdaten (Entity Context Graph, ECG)
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 durchführen möchten, bei der die Groß-/Kleinschreibung nicht berücksichtigt wird, verwenden Sie den Modifikator nocase.

Beispiel: Join von „case“ und „case_history“

Sie können Fallmetadaten mit dem zugehörigen Aktivitätsverlauf korrelieren, indem Sie anhand der eindeutigen Fall-ID einen Join durchführen.

  • Im folgenden Beispiel werden die Datenquellen case und case_history verknüpft, 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 die durchschnittliche Zeit bis zur Lösung (Mean Time to Resolve, MTTR) oder die durchschnittliche Zeit bis zum Abschluss (Mean Time to Close, MTTC) können Sie eine mehrstufige Abfrage verwenden. So können Sie in der ersten Phase die Dauer für jeden einzelnen Fall berechnen und diese Dauern dann im letzten Ergebnisblock global mitteln.

  • Mit der folgenden Abfrage wird die durchschnittliche Zeit bis zum Abschluss von Fällen (in Minuten) für alle Fälle 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:

  • In der Suche können Sie maximal zwei UDM-Ereignisse pro Abfrage verwenden.

  • In der Suche können Sie maximal ein ECG-Ereignis pro Abfrage verwenden.

  • Sie können maximal zwei Datentabellen pro Abfrage verwenden.

  • Sie können Datentabellen-, UDM- und ECG-Ereignisse nicht in einer einzigen Abfrage verknüpfen.

  • Der maximale Zeitraum für die Abfrage beträgt 90 Tage.

  • Der maximale Zeitraum für match beträgt 48 Stunden für die Suche und 365 Tage für Dashboards.

  • Joins werden in der Benutzeroberfläche und in der EventService.UDMSearch API unterstützt, nicht jedoch in der SearchService.UDMSearch API.

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 kritische Systemdatei löscht. Das könnte auf eine Kontoübernahme oder böswillige Insideraktivitäten hindeuten.

Join-Typ: Ereignis-Ereignis-Join

Beschreibung: Mit dieser Abfrage werden zwei unterschiedliche Ereignisse verknüpft, die für sich genommen nicht verdächtig sind, aber sehr verdächtig werden, wenn sie zusammen auftreten. Zuerst wird nach einem USER_LOGIN-Ereignis und dann nach einem FILE_DELETION-Ereignis gesucht. Diese werden mit dem gemeinsamen user.userid und einem kurzen Zeitraum verknüpft.

  • 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
    

Risikoreiche Verbindungen von kritischen Assets erkennen

Ziel: Live-Netzwerkdaten mit Asset-Informationen anreichern, um ausgehende Verbindungen von Servern zu finden, die nicht mit externen Domains mit geringer Prävalenz kommunizieren sollten (z. B. ein Produktionsdatenbankserver).

Join-Typ: Ereignis-ECG-Join

Beschreibung: Eine einzelne Netzwerkverbindung zu einer seltenen Domain hat möglicherweise keine hohe Priorität. Mit dieser Abfrage wird die Bedeutung dieses Ereignisses jedoch erhöht, indem es mit dem Entity Context Graph (ECG) verknüpft wird. Es wird speziell nach NETWORK_CONNECTION-Ereignissen gesucht, die von Assets stammen, die im Entitätendiagramm als „Critical Database Server“ 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 Kompromittierungsindikatoren (Indicators of Compromise, IoCs) suchen, indem alle Live-DNS-Abfragen mit einer Liste von Domains verglichen werden, die bekanntermaßen von einem bestimmten Angreifer verwendet werden.

Join-Typ: Datentabelle-Ereignis-Join

Beschreibung: Ihr Threat Intelligence-Team verwaltet eine Datentabelle mit dem Namen ThreatActor_Domains, in der schädliche Domains aufgeführt sind. Mit dieser Abfrage werden alle NETWORK_DNS_QUERY-Ereignisse in Echtzeit mit dieser Datentabelle verknüpft. So wird sofort jede Instanz angezeigt, in der ein Host in Ihrem Netzwerk versucht, eine Domain aus Ihrer Threat Intelligence-Liste 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