Utiliser des jointures dans la recherche

Compatible avec :

Les jointures permettent de corréler des données provenant de plusieurs sources afin de fournir plus de contexte pour une investigation. En associant des événements, des entités et d'autres données connexes, vous pouvez examiner des scénarios d'attaque complexes.

Ce document explique comment utiliser l'opération de jointure dans Google Security Operations. Il aborde également les types de jointure compatibles, les cas d'utilisation et les bonnes pratiques.

Créer une jointure

Seules les jointures basées sur des statistiques sont acceptées. Vous devez les définir dans la section "match" d'une requête avec une période de corrélation pouvant aller jusqu'à 48 heures. Vous pouvez créer une jointure en connectant directement des champs (par exemple, $e1.hostname = $e2.hostname) ou en utilisant des variables d'espace réservé. Lorsque vous définissez une jointure dans la section match, vous devez utiliser des variables d'espace réservé.

L'exemple suivant interroge deux champs avec un signe égal (=) et une variable d'espace réservé partagée :

Exemple 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

Exemple 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

Types de jointures acceptés

Cette section décrit les différents types de jointures que vous pouvez utiliser.

Jointure événement-événement

Une jointure d'événement à événement associe deux événements UDM (Universal Data Model) différents. L'exemple de requête suivant associe un événement USER_LOGIN à un autre événement pour trouver le nom d'hôte (altostrat) avec lequel l'utilisateur a interagi, en fonction d'une adresse IP commune :


$e1.principal.ip = $ip

$e1.metadata.event_type = "USER_LOGIN"

$e2.target.ip = $ip

$e2.principal.hostname = "altostrat"

match:

  $ip over 5m

Rejoindre un événement ECG

Une jointure Event-ECG associe un événement UDM à une entité du graphique de contexte d'entité (ECG). L'exemple de requête suivant recherche un événement NETWORK_CONNECTION et un ASSET du graphique d'entités qui partagent le même nom d'hôte dans une fenêtre d'une heure :


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

Jointure d'événement de tableau de données

Une jointure d'événement de table de données associe les événements UDM aux entrées d'une table de données personnalisée. Cela permet de comparer les données d'événements en direct à une liste définie par l'utilisateur, comme les adresses IP ou les acteurs malveillants connus. L'exemple de requête suivant joint les événements NETWORK_CONNECTION à une table de données pour trouver les connexions impliquant des adresses IP spécifiques de cette liste :


$ip = %DATATABLE_NAME.COLUMN_NAME

$ip = $e1.principal.ip

$e1.metadata.event_type = "NETWORK_CONNECTION"

match:

   $ip over 1h

Bonnes pratiques

Les requêtes de jointure peuvent être gourmandes en ressources, car elles combinent de nombreux résultats. Les filtres généraux et larges peuvent entraîner l'échec des requêtes, parfois après un long délai. Par exemple :

  • target.ip != null

  • metadata.event_type = "NETWORK_CONNECTION" (si ce type d'événement est très courant dans votre environnement)

Nous vous recommandons de combiner des filtres généraux avec des filtres plus spécifiques pour réduire le nombre total d'événements que la requête doit traiter. Un filtre large tel que target.ip != null doit être associé à des filtres plus spécifiques pour améliorer les performances de la requête. Par exemple :

$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

Si votre requête est toujours lente, vous pouvez également réduire la plage de dates globale (par exemple, de 30 jours à une semaine).

Pour en savoir plus, consultez les bonnes pratiques concernant YARA-L.

Limites

Les limites suivantes s'appliquent lorsque vous utilisez des jointures :

  • Vous pouvez utiliser au maximum deux événements UDM par requête.

  • Vous ne pouvez utiliser qu'un seul événement ECG par requête.

  • Vous pouvez utiliser au maximum deux tables de données par requête.

  • Vous ne pouvez pas joindre des événements de table de données, UDM et ECG dans une même requête.

  • La période maximale pour une requête est de 90 jours.

  • La période maximale de match est de 48 heures.

  • Les jointures sont compatibles avec l'interface utilisateur et l'API EventService.UDMSearch, mais pas avec l'API SearchService.UDMSearch.

Cas d'utilisation courants

Cette section présente quelques utilisations courantes des jointures.

Détecter le vol et l'utilisation d'identifiants

Objectif : trouver les instances où un utilisateur se connecte avec succès, puis supprime rapidement un fichier système critique. Cela peut suggérer une prise de contrôle de compte ou une activité malveillante d'un employé.

Type de jointure : jointure événement-événement

Description : cette requête associe deux événements distincts qui ne sont pas suspects en soi, mais qui le deviennent lorsqu'ils se produisent ensemble. Il recherche d'abord un événement USER_LOGIN, puis un événement FILE_DELETION. Elles sont rejointes par le user.userid commun avec une courte période.

Exemple de requête :


// 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

Identifier les connexions à risque à partir des ressources critiques

Objectif : enrichir les données réseau en direct avec des informations sur les composants pour trouver les connexions sortantes à partir de serveurs qui ne devraient pas communiquer avec des domaines externes à faible prévalence (par exemple, un serveur de base de données de production).

Type de jointure : jointure événement-ECG

Description : une seule connexion réseau à un domaine rare n'est peut-être pas une priorité élevée. Toutefois, cette requête augmente l'importance de cet événement en le joignant au graphique de contexte des entités (ECG). Il recherche spécifiquement les événements NETWORK_CONNECTION provenant de composants libellés "Serveur de base de données critique" dans le graphique des entités.

Exemple de requête :


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

Rechercher les IoC des acteurs malveillants

Objectif : rechercher activement les indicateurs de compromission en vérifiant toutes les requêtes DNS en direct par rapport à une liste de domaines connus pour être utilisés par un acteur malveillant spécifique.

Type de jointure : jointure table de données-événement

Description : votre équipe chargée du renseignement sur les menaces gère une table de données appelée ThreatActor_Domains qui liste les domaines malveillants. Cette requête associe tous les événements NETWORK_DNS_QUERY en temps réel à cette table de données. Il affiche immédiatement toute instance où un hôte de votre réseau tente de résoudre un domaine à partir de votre liste d'informations sur les menaces.

Exemple de requête :


// Datatable: Get the list of malicious domains

$domain = $ip = %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

Vous avez encore besoin d'aide ? Obtenez des réponses de membres de la communauté et de professionnels Google SecOps.