Utiliser des jointures dans la recherche
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'APISearchService.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.