Appliquer des jointures dans la recherche et les tableaux de bord
Les jointures permettent de corréler les données provenant de plusieurs sources pour fournir plus de contexte à 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 et visualiser les tendances.
Ce document explique comment utiliser l'opération de jointure dans le champ Rechercher et les panneaux du tableau de bord Google SecOps. Il aborde les types de jointures compatibles, les cas d'utilisation et les bonnes pratiques.
Concepts fondamentaux des jointures
Vous pouvez créer une jointure en connectant des sources de données à l'aide de variables d'espace réservé partagées ou d'instructions d'égalité explicites (par exemple, $e1.hostname = $e2.hostname). Lorsque vous définissez une jointure dans la section match d'une requête basée sur des statistiques, vous devez utiliser des variables d'espace réservé.
Les exemples suivants montrent comment associer des sources de données à l'aide de deux champs avec un signe égal (=) et une variable d'espace réservé partagée.
Exemple 1 : Jointure implicite à l'aide de variables d'espace réservé
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 $e2Exemple 2 : Jointure explicite utilisant l'égalité et des espaces réservés
$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
Jointures dans la recherche
Les exemples de cette section illustrent la syntaxe utilisée dans Recherche.
Les requêtes dans Recherche ne sont pas sensibles à la casse par défaut.
Jointure événement-événement
Une jointure d'événement à événement connecte deux événements différents du modèle de données unifié (UDM). 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
Joindre 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_CONNECTIONet unASSETdu 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
Joindre un événement de tableau de données
Une jointure entre une table de données et un événement permet d'associer des événements UDM à des entrées dans 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
Utiliser la clause IN avec des tables de données
Vous pouvez également utiliser la clause in pour vérifier si une valeur de champ existe dans une colonne du tableau de données. Cette syntaxe est compatible avec toutes les sources de données (par exemple, ioc.type in %abc.type). Elle permet de filtrer facilement les événements en fonction de listes de référence sans définir de variables d'espace réservé explicites pour la jointure.
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 dans lesquelles 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. Ils sont rejoints par le user.userid commun avec une courte période.
Requête de détection du vol d'identifiants
// 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 participation : participation à un événement ECG
Description : une connexion réseau unique à 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 d'entité (ECG, Entity Context Graph). Il recherche spécifiquement les événements NETWORK_CONNECTION provenant d'éléments libellés "Serveur de base de données critique" dans le graphique d'entités.
Requête sur les connexions à risque
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 (IoC) 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 des renseignements 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 dans laquelle un hôte de votre réseau tente de résoudre un domaine à partir de votre liste de renseignements sur les menaces.
Requête de recherche d'IoC d'acteur malveillant
// 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
Jointures dans les tableaux de bord
Les tableaux de bord sont compatibles avec un plus grand nombre de sources de données et des périodes de corrélation plus longues que dans Recherche. Contrairement aux requêtes SQL standard, YARA-L 2.0 n'utilise pas d'instructions JOIN explicites. Il connecte plutôt les sources de données en corrélant les variables d'espace réservé partagées ou en utilisant des requêtes à plusieurs étapes.
Sensibilité à la casse
Les requêtes de tableau de bord sont sensibles à la casse. Pour effectuer une jointure ou une recherche non sensible à la casse dans un tableau de bord, utilisez le modificateur nocase.
Sources de données prises en charge
Dans les tableaux de bord, vous pouvez joindre des données à partir de combinaisons de jointures de sources de données compatibles. (Toutes les combinaisons de sources de données ne peuvent pas être jointes dans une même requête.)
Chaque référence de données dans une requête de tableau de bord multisource doit inclure son qualificatif de préfixe YARA-L (par exemple, $u1), et pas seulement les champs associés. Cela permet au système d'identifier correctement la propriété des champs dans les sources de données qui se chevauchent.
Combinaisons de jointures acceptées
Les jointures vous permettent de corréler les événements UDM, le contexte des entités et les tables de données dans les tableaux de bord intégrés. Pour maintenir les performances du système, consultez les combinaisons et les limites techniques acceptées dans cette section avant de créer vos requêtes.
- Événement UDM vers événement UDM (événement multiple)
- Contexte d'événement UDM vers entité
- Événement UDM vers tableau de données
Historique des cas : cette combinaison est strictement limitée à une source
caseet une sourcecase_history. Vous ne pouvez inclure aucune autre source de données dans cette jointure.
Pour en savoir plus sur les limites et les mesures de protection, consultez Limites et contraintes techniques.
Exemple : Joindre les tables "case" et "case_history"
Vous pouvez mettre en corrélation les métadonnées d'une demande avec son historique d'activité en les associant à l'ID unique de la demande.
L'exemple suivant joint les sources de données
caseetcase_historypour comptabiliser le nombre total d'actions historiques pour chaque demande à priorité élevée.// 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)
Cas d'utilisation avancé : calculer le MTTR
Pour les métriques plus complexes, comme le délai moyen de résolution (MTTR) ou le délai moyen de clôture (MTTC), vous pouvez utiliser une requête à plusieurs étapes. Cela vous permet de calculer la durée de chaque cas individuel lors de la première étape, puis de faire la moyenne de ces durées au niveau global dans le bloc de résultat final.
La requête suivante calcule le temps moyen de résolution des demandes (en minutes) pour toutes les demandes de l'environnement par défaut.
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))
Bonnes pratiques
Pour optimiser les performances de vos requêtes de jointure et vous assurer qu'elles sont traitées efficacement, suivez ces bonnes pratiques pour filtrer les événements et gérer le champ d'application de la recherche.
Utilisez des filtres spécifiques pour réduire le nombre d'événements.
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 != ""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 != ""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 de la requête (par exemple, de 30 jours à une semaine).
Pour en savoir plus, consultez les bonnes pratiques concernant YARA-L.
Limites et contraintes techniques
Les limites et restrictions suivantes s'appliquent lorsque vous utilisez des jointures dans Rechercher et dans les tableaux de bord.
Limites de la fenêtre de correspondance et des requêtes
La fenêtre de correspondance définit la période spécifique pendant laquelle les événements doivent être corrélés. Elle est différente de la période de recherche que vous sélectionnez dans l'interface utilisateur.
Limites dans la recherche
La recherche est optimisée pour les investigations en direct ou rapides sur des périodes plus courtes.
| Limite de requêtes | Utilisation |
|---|---|
| Jusqu'à 48 heures (certaines requêtes peuvent accepter des périodes plus longues). | Corréler des événements lors d'investigations rapides. |
Limites dans les tableaux de bord
Les tableaux de bord permettent d'analyser l'historique à plus long terme.
| Type de jointure | Limite de requêtes | Utilisation |
|---|---|---|
| UDM vers UDM et UDM vers entité | 31 jours | Requêtes télémétriques à fort volume. |
| Case-to-CaseHistory | 90 jours | Requêtes de suivi du cycle de vie. |
| Autres configurations compatibles | Jusqu'à 365 jours | Solution de repli pour les sources non UDM ou basées sur des métriques (par exemple, les métriques d'ingestion). |
Limites des sources de données et des tableaux
Le nombre maximal de sources de données et de tableaux que vous pouvez joindre dans une même requête dépend de l'utilisation de la recherche ou des tableaux de bord.
Contraintes de recherche
- Vous pouvez utiliser au maximum deux événements UDM par requête.
- Vous ne pouvez utiliser qu'un événement ECG par requête.
- Vous pouvez utiliser au maximum deux tables de données par requête.
- Vous ne pouvez pas joindre directement une table de données à une table de contexte d'entité. Vous devez utiliser un événement UDM comme pont intermédiaire (par exemple, corréler
$event.target.hostnameavec$datatable.hostnameet$asset.graph.entity.asset.hostname).
Contraintes du tableau de bord
| Type de jointure | Nombre maximal de tables d'événements (UDM ou table de données) | Nombre maximal de tables d'entités |
|---|---|---|
| Multi-événement (UDM à UDM) | 2 | N/A |
| UDM vers entité | 2 | 1 |
| UDM vers table de données | 2 | N/A |
| Requêtes multistages | 2 | 1 |
Performances et garde-fous
Le système surveille les requêtes de jointure complexes pour détecter une consommation excessive de ressources. Pour protéger les performances globales de l'environnement, le système peut mettre en veille ou mettre en quarantaine automatiquement les requêtes qui dépassent les seuils de sécurité des ressources.
Si une requête échoue ou renvoie des erreurs indiquant qu'elle a dépassé les limites de ressources, essayez les optimisations suivantes :
- Réduisez la période de la requête.
- Ajoutez des filtres plus spécifiques pour réduire la taille de l'ensemble de données avant la jointure.
- Simplifiez vos agrégations.
Contraintes concernant les types d'API et de requêtes
- Les jointures sont acceptées dans l'interface utilisateur et l'API
EventService.UDMSearch, mais pas dans l'APISearchService.UDMSearch.
Vous avez encore besoin d'aide ? Obtenez des réponses de membres de la communauté et de professionnels Google SecOps.