Passer de SPL à YARA-L 2.0

Compatible avec :

Ce guide est destiné aux utilisateurs qui connaissent déjà le langage SPL (Splunk Search Processing Language). Il présente rapidement YARA-L 2.0, le langage de base pour créer des recherches, des tableaux de bord et des règles de détection dans Google Security Operations.

Comprendre la structure de YARA-L 2.0

YARA-L 2.0 est le langage de requête unifié utilisé dans Google SecOps pour effectuer des recherches puissantes sur les menaces, créer des tableaux de bord en temps réel et établir des règles de détection de haute précision sur toutes les données de journaux de votre entreprise à mesure qu'elles sont ingérées.

Ce langage fonctionne avec le moteur de détection Google SecOps et vous permet de rechercher des menaces et d'autres événements dans de grands volumes de données.

Différences de structure de base entre SPL et YARA-L

SPL utilise une série de commandes enchaînées avec des caractères de barre verticale (|), tandis que YARA-L est basé sur des sections. Vous définissez une requête à l'aide de sections distinctes (events, outcome et condition, par exemple) pour décrire un modèle que vous souhaitez rechercher, détecter ou visualiser.

Le tableau suivant compare la structure de base entre SPL et YARA-L :

Fonction SPL (procédural) YARA-L (déclaratif)
Concept clé Transformez un flux de données étape par étape à l'aide d'un pipeline de commandes. Analyse et applique une structure multipartite de conditions et de transformations à un flux de données opérationnelles et de sécurité, en identifiant les menaces et en extrayant des insights précieux.
Flux de données Procédural Les résultats d'une commande sont transmis en tant qu'entrée à la suivante. Structure déclarative permettant de traiter et de corréler de manière optimale des modèles à grande échelle. Plus besoin de se soucier de l'efficacité.
Corrélation d'événements S'appuie sur des commandes explicites telles que join, transaction et stats. Intégrée en définissant plusieurs événements et en les corrélant en fonction d'un champ commun dans la logique de la requête.
Fenêtrage temporel Gérée comme une fenêtre de recherche statique (par exemple, last 60m). Chaque nouvelle recherche est une nouvelle requête. Gérée comme une fenêtre temporelle glissante et continue définie dans la requête (par exemple, over 5m).
Syntaxe Piloté par des commandes (par exemple, index=web). Concise et logique (par exemple, metadata.event_type= "USER_LOGIN").

Structure spécifique des requêtes

YARA-L applique une structure spécifique pour les requêtes, qui est différente des commandes séquentielles et canalisées (|) de SPL. Alors que SPL génère des résultats en enchaînant des commandes, YARA-L définit différents aspects de la requête dans des sections distinctes.

Chaque requête ou règle YARA-L est segmentée en sections distinctes et nommées, qui dictent le comportement de la requête. Cette structure permet l'analyse et la corrélation en plusieurs étapes.

Commande Action Facultatif | Obligatoire
meta Définit les métadonnées descriptives de la règle, telles que l'auteur, la description et la gravité. Facultatif pour la recherche et les tableaux de bord. Obligatoire uniquement pour les règles.
events Définit et filtre les événements. Déclare toutes les sources de données (principalement les événements UDM) à prendre en compte et les filtre à l'aide des champs UDM. En savoir plus sur la syntaxe de la section `events` Obligatoire (logique principale de la requête) pour la recherche, les tableaux de bord et les règles.
match Regroupe les événements et vous permet de spécifier la période acceptée (par exemple, by 5m). En savoir plus sur la [syntaxe de la section "match"](https://docs.cloud.google.com/chronicle/docs/yara-l/match-syntax) Facultatif pour les recherches statistiques où l'agrégation a lieu. Obligatoire uniquement pour les requêtes de corrélation multi-événements. La spécification de l'heure est obligatoire pour les règles, et facultative pour la recherche et les tableaux de bord.
outcome Calcule les métriques essentielles et obtient des insights (par exemple, count(), avg()). En savoir plus sur la [syntaxe de la section "outcome"](/chronicle/docs/yara-l/outcome-syntax) Facultatif.
condition Définit la logique à respecter pour renvoyer des résultats (dans la recherche) ou déclencher une alerte (dans une règle). Évalue les critères de la variable de requête pour déterminer si un résultat s'applique (par exemple, event > 5). En savoir plus sur la [syntaxe de la section "condition"](/chronicle/docs/yara-l/condition-syntax) Facultatif dans la recherche et les tableaux de bord. Obligatoire uniquement pour les règles.
dedup Supprime les événements en double en les regroupant en fonction de variables essentielles (par exemple, target.user.userid, target.ip, principal.hostname). Découvrez comment [utiliser la déduplication dans Search et Dashboards](/chronicle/docs/investigation/deduplication-yaral). Facultatif. Non disponible dans les règles.
order Trie les résultats des événements collectés définis par des champs spécifiques (par exemple, asc). Facultatif (ne s'applique que lorsque match est utilisé). Non disponible dans les règles.
limit Limite le nombre maximal d'événements renvoyés par la requête. Facultatif (uniquement applicable lorsque la correspondance est utilisée). Non disponible dans les règles.
select Spécifie la liste des champs UDM à inclure dans les résultats de la requête. Facultatif. Non disponible dans les règles.
unselect Spécifie la liste des champs UDM à exclure des résultats de la requête. Facultatif. Non disponible dans les règles.

Commandes courantes en SPL et YARA-L

La structure de la section YARA-L vous permet d'utiliser les mêmes commandes courantes que dans SPL. Cette section décrit les similitudes et les différences.

Commande SPL search = section events YARA-L

La commande search dans SPL équivaut à la section events dans YARA-L. La section events définit les événements et la façon dont ils sont filtrés initialement. Alors que d'autres sections (comme match ou outcome) sont facultatives, la section events est fondamentale pour chaque règle.

Exemple :

metadata.event_type = "USER_LOGIN"

ou :

principal.hostname != "" AND metadata.event_type = "NETWORK_CONNECTION"

Dans la section events des règles (et des requêtes avancées), vous utilisez des variables d'événement pour simplifier votre logique.

Une variable d'événement agit comme un regroupement logique de filtres, représentant un événement spécifique ou un groupe d'événements qui correspondent à certains critères.

Par exemple, pour définir une variable d'événement, telle que $e, utilisez-la comme préfixe pour tous les événements et filtres associés dans la section events de votre requête. Vous pouvez ensuite utiliser cette variable dans d'autres sections de la requête (comme match ou outcome) pour faire référence à ce groupe d'événements spécifique et à ses champs de données.

Les variables d'événement sont le plus souvent utilisées dans les règles de détection. L'exemple suivant montre comment utiliser la variable d'événement ($e) dans une règle pour regrouper les événements et trouver le nombre d'échecs de connexion pour un utilisateur au cours d'une journée. La règle se déclenche ensuite si elle dépasse un seuil défini.

Dans l'exemple de règle, chaque événement est défini avec la variable d'événement ($e). La variable $e est également référencée dans metadata.id pour relier les métadonnées de la règle aux événements définis.

rule DailyFailedLoginAttempts {
 meta:
   author = "Alex"
   description = "Detects a high number of failed login attempts for a single user within a day."

events:
   // Alias for each event
   $e.metadata.event_type = "USER_LOGIN"
   $e.security_result.action = "FAIL"
   $e.principal.user.userid != ""
   $userid = $e.principal.user.userid

match:
   // Group events by principal.user.userid within a 24-hour window
   $userid over 1d

outcome:
   // Count the number of unique event IDs for each user per day
   $daily_failed_login_count = count($e.metadata.id)

condition:
   // Trigger a detection if the daily failed login count exceeds a threshold
   // You should adjust this threshold based on your environment's baseline.
   #e > 0
}

Pour vous assurer que la règle se déclenche, vous devez souvent vérifier le nombre d'événements groupés. Vous pouvez spécifier un nombre minimal dans la section condition à l'aide de la variable d'événement. Par exemple, la condition (#e > 0) vérifie qu'au moins un événement correspond aux critères.

Commande SPL eval = section YARA-L outcome

La commande eval est une fonction SPL fondamentale utilisée pour manipuler et définir des valeurs de champ dans les résultats de recherche.

  • Objectif : calculer et définir de nouvelles valeurs de champ.
  • Fonctionnalité : elle évalue des expressions mathématiques, de chaîne ou booléennes.
  • Résultat : le résultat de l'évaluation crée un champ ou remplace la valeur d'un champ existant.
  • Enchaînement : plusieurs expressions peuvent être enchaînées à l'aide d'une virgule (par exemple, | eval A=1, B=A+1).
  • Traitement séquentiel : les expressions d'une chaîne sont traitées de manière séquentielle, ce qui permet aux calculs ultérieurs de référencer et de s'appuyer sur les champs créés ou modifiés par les expressions précédentes.

Les exemples du tableau suivant (et d'après) expliquent cette structure de commande :

Fonction Description Exemple YARA-L
Opérateurs booléens Utilisé dans events et condition. Consultez Utiliser "ou" dans la section "Condition".

metadata.log_type != "" or
metadata.event_type = "NETWORK_DNS"
      
Champs calculés Utilisé dans la section outcome.

metadata.event_type = "SCAN_NETWORK"
principal.hostname != ""
outcome:
  $id = metadata.id
  $host = principal.hostname
  $bytes = cast.as_int(network.sent_bytes)
  
Création de noms de champs dynamiques Utilisé dans la section outcome. Consultez des exemples dans Comparer SPL à YARA-L.

Exemple : Créer un champ contenant le résultat d'un calcul

À l'aide de YARA-L, créez un champ bytes dans chaque événement. Pour calculer les octets, additionnez les valeurs des champs bytes (envoyés) et bytes (reçus).

metadata.event_type = "SCAN_NETWORK"
principal.hostname != ""
$host = principal.hostname

match:
  $host

outcome:
  $bytes = cast.as_int(sum(network.sent_bytes))

Exemple : Concaténer les valeurs de deux champs

Utilisez le point (.) pour concaténer les valeurs du champ first_name avec celles du champ last_name. Utilisez des guillemets ("") pour insérer un espace entre les deux champs. Lors de la concaténation, les valeurs sont lues sous forme de chaînes, quelle que soit la valeur réelle.

En SPL, la requête se présenterait comme suit :

| eval full_name = first_name+" "+last_name

Dans YARA-L, la requête de recherche se présenterait comme suit :

principal.user.first_name = $first_name
principal.user.last_name = $last_name

outcome:
   $full_name = strings.concat($first_name, " ", $last_name)

En reprenant l'exemple de requête d'échec de connexion, l'exemple suivant vous permet de trouver les utilisateurs qui ont enregistré au moins cinq (5) échecs de connexion dans un intervalle de 10 minutes (10m) (en utilisant à la fois des variables d'événement et d'espace réservé) :

metadata.event_type = "USER_LOGIN"
security_result.action = "FAIL"
target.user.userid = $userid

match:
  $userid by 10m

outcome:
   $login_count= count(metadata.id)

condition:
   $login_count > 5

Commande SPL where = section YARA-L condition

La commande SPL where équivaut à un mélange des sections events, outcome ou condition dans YARA-L. La section events vous permet de déclarer des événements et de spécifier des attributs spécifiques pour ceux-ci (par exemple, principal.hostname = "xyz"). Une fois vos événements déclarés, vous pouvez utiliser des opérateurs booléens, des opérateurs de comparaison et des résultats de fonctions d'agrégation (à partir de la section outcome) pour définir les paramètres que les événements doivent respecter pour que la requête renvoie un résultat.

L'exemple suivant montre comment définir une condition de seuil sur un nombre agrégé. La requête est structurée pour comptabiliser le nombre total d'échecs de connexion par ID utilisateur, puis utilise la section condition pour n'afficher les résultats que pour les utilisateurs ayant enregistré cinq échecs de connexion ou plus.

metadata.event_type = "USER_LOGIN"
security_result.action = "FAIL"

match:
  target.user.userid

outcome:
  // metadata.id counts all unique events associated with failed logins.
  $count = count(metadata.id)
  //metadata.id counts all unique events associated with blocked logins.

condition:
  $count > 5

Commande SPL dedup = section YARA-L dedup

La commande SPL dedup équivaut à la section dedup dans YARA-L. Utilisez la section dedup pour dédupliquer les résultats en double spécifiés par un événement dans la section events.

Exemple :

principal.hostname = "foo"

dedup:
   target.ip

Découvrez comment utiliser la déduplication dans la recherche et les tableaux de bord, en particulier les consignes de performances.

Commande SPL stats = section match ou outcome (ou les deux) de YARA-L

Dans SPL, l'agrégation est généralement gérée par la famille de commandes stats, qui spécifie le type d'agrégation (tel que count, distinct count, max, min) et le champ "group by".

Dans YARA-L, les sections match et outcome fournissent conjointement cette fonctionnalité :

  • Logique d'agrégation : la section match crée des agrégations en définissant le groupe d'événements à prendre en compte (match: $grouping_field by time). La section outcome définit ensuite les fonctions d'agrégation spécifiques à calculer sur ce groupe (par exemple, count(), min(), max()).

  • Fenêtre temporelle : la section match permet de spécifier une fenêtre temporelle pour regrouper les événements. Utilisez le mot clé over (pour les règles) ou by (pour la recherche et les tableaux de bord) (par exemple, match: $userid by 1h). Cette fonctionnalité est semblable à SPL, comme "timechart", "streamstats" et "eventstats". Pour en savoir plus, consultez Fenêtrage temporel.

Exemple : Calculer la somme des octets regroupés par nom d'hôte principal et adresse IP cible

L'exemple suivant utilise la section match pour définir un groupe d'agrégation basé sur le nom d'hôte principal et l'adresse IP cible sur une période d'un jour. La somme des octets envoyés est ensuite calculée dans la section outcome.

metadata.event_type = "NETWORK_CONNECTION"
network.sent_bytes > 0
principal.hostname != ""
target.ip != ""

// Define placeholder variables for grouping
$principal_hostname = principal.hostname
$target_ip = target.ip

// Group events by principal hostname, target IP, and day
match:
  $principal_hostname, $target_ip by day

// Calculate the sum of sent bytes for each group
outcome:
  $daily_bytes_sent = sum(network.sent_bytes)

Mapper SPL vers YARA-L

SPL traite les données étape par étape à l'aide de commandes canalisées, tandis que YARA-L utilise une structure déclarative basée sur des sections pour définir des modèles et des actions. Malgré ces différences fondamentales d'approche, la puissance expressive de YARA-L vous permet d'effectuer de nombreuses tâches que vous avez l'habitude d'effectuer dans SPL, du filtrage de base aux agrégations et corrélations complexes.

Cette section explique les différences en mappant les fonctionnalités SPL connues à leurs équivalents dans le framework YARA-L.

Comparer SPL à YARA-L

Ce tableau compare les fonctions et concepts courants du langage SPL à leurs équivalents dans YARA-L 2.0 ou à la façon dont le concept est géré dans une structure de requête YARA-L.

Commande ou concept SPL Objectif Équivalent YARA-L Description et mappage YARA-L Exemple d'implémentation de YARA-L
search Filtrage initial des données Section events Définissez les champs et les conditions d'événement. Aucun events : aucun préfixe n'est nécessaire pour la recherche ni les tableaux de bord. Consultez un exemple.

events:
  metadata.event_type = "USER_LOGIN"
  security_result.action = "FAIL"

        
where Filtrage supplémentaire des résultats Sections events et condition Appliquez une logique booléenne, souvent sur les résultats agrégés. Voir un exemple

events:
  metadata.event_type = "USER_LOGIN"
  security_result.action = "FAIL"

outcome:
  $failed_count = count(metadata.id)

condition:
  $failed_count > 5
        
eval Calculer de nouvelles valeurs à partir de champs, d'agrégations et de recherches de données existants Section outcome ou events Consultez un exemple.

metadata.event_type = "USER_LOGIN"

outcome:
  $login_count = count(metadata.id)
        
stats Agrégations (count, sum, moyenne) match ou outcome Champs "Critère de regroupement" dans match. Calculer les agrégats dans outcome. Consultez les exemples d'agrégation et les exemples de commandes SPL.

metadata.event_type = "USER_LOGIN"

outcome:
  $login_count = count(metadata.id)
        
dedup Supprime les événements en double en fonction d'un ou de plusieurs champs Section dedup Spécifiez les champs sur lesquels effectuer la déduplication.

metadata.event_type = "USER_LOGIN"
security_result.action = "FAIL"
$user = target.user.userid

dedup:
  $user
        
table Définit la sortie de la colonne de la table select ou unselect Utilisé dans les tableaux de bord. Affiche les variables outcome dans la recherche.

metadata.event_type = "USER_LOGIN"

select:
  principal.hostname
        
sort Répertorie les résultats par ordre croissant ou décroissant. Section order Consultez l'exemple dans la cellule adjacente.
metadata.event_type = "SCAN_NETWORK"
principal.hostname != ""

outcome:
  $id = metadata.id
  $host = principal.hostname
  $bytes = uint64(network.sent_bytes)

order:
  $bytes desc
limit Limite le nombre de résultats renvoyés Section limit Consultez l'exemple dans la cellule adjacente.

metadata.event_type = "SCAN_NETWORK"
principal.hostname != ""

outcome:
  $id = metadata.id
  $host = principal.hostname
  $bytes = cast.as_int(network.sent_bytes)

order:
  $bytes desc

limit:
  3
  
Fonctions à valeurs multiples Géré avec les fonctions mv* (mvexpand, mvfilter) Compatibilité intégrée YARA-L supprime automatiquement les tableaux imbriqués dans la section "events".
Les fonctions de tableau sont disponibles dans outcome, si nécessaire.
Consultez des exemples de fonctions à valeurs multiples.
Fenêtrage temporel earliest=-5m, latest=now Section match, over, by Pour les détections continues, utilisez match: $field over 5m or by 5m. Pour les tableaux de bord de l'interface utilisateur de recherche, utilisez match: $field by 5m. Consultez des exemples dans Fenêtrage temporel.

Requêtes d'agrégation et statistiques

Dans YARA-L, les fonctions d'agrégation et statistiques sont généralement placées dans la section outcome, et l'agrégation est basée dans la section match.

La commande stats est le principal mécanisme d'implémentation de l'agrégation de données dans les requêtes YARA-L. Il transforme les données d'événement brutes en métriques de sécurité résumées. Alors que la commande eval gère les transformations au niveau des champs, ligne par ligne (semblables à une expression SELECT), stats effectue une agrégation au niveau de l'ensemble (semblable à GROUP BY en SQL).

Le tableau suivant fournit la syntaxe et l'utilisation de base, et montre comment utiliser efficacement les statistiques pour implémenter une logique de sécurité sophistiquée basée sur les modèles de données et les valeurs aberrantes statistiques.

Fonction SPL Description Équivalent YARA-L Exemple d'implémentation de YARA-L
count Compte le nombre d'événements. count()

metadata.event_type= "USER_LOGIN"
security_result.action= "FAIL"

outcome:
  $event_count = count(metadata.id)

condition:
  $event_count > 2
  
dc (count_distinct) Compte le nombre de valeurs uniques d'un champ. count_distinct()

metadata.event_type = "USER_LOGIN"

outcome:
  $unique_users=count_distinct(principal.user.userid)
  
sum Calcule la somme des valeurs d'un champ.
sum()

metadata.event_type = "SCAN_NETWORK"
principal.hostname != ""
$host = principal.hostname

match:
  $host

outcome:
  $bytes = sum(network.sent_bytes)
  
avg Calcule la valeur moyenne d'un champ.
avg()

$host = principal.hostname

match:
  $host by day

outcome:
  $avg_bytes_sent = avg(network.sent_bytes)
  
min/max Recherche la valeur minimale ou maximale d'un champ. min() ou max()

metadata.event_type = "SCAN_NETWORK"
principal.hostname != ""
$host = principal.hostname

match:
  $host

outcome:
  $bytes = max(network.sent_bytes)- min(network.sent_bytes)
  
median() Recherche la valeur médiane. window.median

target.file.mime_type = "PDF"

outcome:
  $median_file_size = window.median(target.file.size, false)
  
first() and last() Renvoie des valeurs en fonction de l'ordre des événements dans les résultats de recherche. window.first/window.last

metadata.event_type = "NETWORK_CONNECTION"
principal.ip != ""

match:
  principal.ip

outcome:
  $event_count = count(metadata.id)
  $first_seen = window.first(metadata.event_timestamp.seconds, timestamp.get_timestamp(metadata.event_timestamp.seconds))
  $last_seen = window.last(metadata.event_timestamp.seconds, timestamp.get_timestamp(metadata.event_timestamp.seconds))
  
STDDEV() Calcule l'écart type, qui mesure la dispersion d'un ensemble de données. window.stddev

principal.hostname= $host

match:
  $host over 5m

outcome:
  $stddev = window.stddev(network.sent_bytes)

Pour en savoir plus, consultez Fonctions supplémentaires.

Par exemple, une requête à plusieurs étapes peut suivre plusieurs échecs de connexion dans des agrégations par couches. Pour en savoir plus, consultez l'exemple d'agrégation en plusieurs étapes et Créer des requêtes en plusieurs étapes dans YARA-L.

Agrégation en plusieurs étapes (moyenne horaire à hebdomadaire)

Cet exemple à plusieurs étapes agrège d'abord les données pour trouver les octets transférés par hôte chaque heure. Il utilise ensuite cette agrégation pour calculer la moyenne globale de ces groupes horaires pour les sept derniers jours.

stage bytes_per_host {
metadata.event_type = "SCAN_NETWORK"
principal.hostname != ""
$host = principal.hostname

match:
  $host by hour

outcome:
  $bytes = cast.as_int(sum(network.sent_bytes))
}

$host = $bytes_per_host.host

match:
  $host

outcome:
  $hour_buckets = array_distinct(timestamp.get_timestamp($bytes_per_host.window_start))
  $num_hour_buckets = count_distinct($bytes_per_host.window_start)
  $avg_hourly_bytes = avg($bytes_per_host.bytes)

Fonctions multivaluées (lire un tableau)

La syntaxe de YARA-L est conçue pour comprendre qu'un champ peut avoir plusieurs valeurs. Lorsque vous rédigez une requête qui inclut un événement avec un champ à valeurs multiples dans la section events, le langage vérifie automatiquement chaque valeur du tableau. Vous n'avez pas besoin d'utiliser une fonction spéciale pour filtrer le tableau. Il vous suffit d'indiquer la condition à remplir. Par exemple, si le champ principal.ip de l'événement de journal contient les éléments suivants, le moteur YARA-L vérifie automatiquement chaque valeur du tableau principal.ip. Si l'une des valeurs est "10.1.1.5", la condition est remplie.

["10.1.1.5", "10.2.2.6", "10.3.3.7"]

Le tableau suivant compare YARA-L et SPL pour la gestion des champs à valeurs multiples dans les données de journaux. Les champs à valeurs multiples, tels qu'un tableau d'adresses IP ou une liste de groupes d'utilisateurs, sont une fonctionnalité courante dans les journaux structurés.

Fonction SPL Purpose Équivalent YARA-L Exemple d'implémentation YARA-L
mvfilter() Filtre un champ à valeurs multiples pour ne conserver que les valeurs correspondantes. Lorsqu'il est utilisé dans la section events d'une requête YARA-L, indiquez le champ à faire correspondre. YARA-L vérifie automatiquement si une valeur du tableau de groupes correspond à"admin".

principal.user.group_identifiers = "admin"
        
mvcount() Compte le nombre de valeurs dans un champ à valeurs multiples. count() appliqué à un champ de la section de requête outcome. Il n'est pas nécessaire d'annuler l'imbrication des valeurs au préalable. Consultez l'exemple Compter le nombre d'utilisateurs appartenant au groupe du personnel informatique.
mvexpand Crée un événement pour chaque valeur d'un champ à valeurs multiples. Gère les champs à valeurs multiples de manière native et implicite ; l'annulation de l'imbrication se fait automatiquement. Consultez l'exemple Compter le nombre d'utilisateurs appartenant au groupe du personnel informatique.
mvjoin Regroupe toutes les valeurs d'un champ à valeurs multiples dans une seule chaîne à des fins de mise en forme des données. Les valeurs sont automatiquement stockées sous forme de tableau dans les résultats. La sortie de YARA-L est structurée, et non une chaîne plate. Il affiche le champ sous forme de tableau si une manipulation supplémentaire du tableau est nécessaire. Pour en savoir plus, consultez Fonctions de tableau.

Exemple : Compter le nombre de connexions admin

Dans l'exemple suivant, la condition $metadata.event_type = "USER_LOGIN" filtre les événements dont le type est "USER_LOGIN" :

events:
 metadata.event_type = "USER_LOGIN"
 // Changed to a more appropriate event type for login
 principal.user.group_identifiers = "admin"

outcome:
 // This counts each unique event ID where the principal user is in the `"admin"` group.
 $admin_login_count = count(metadata.id)

Le champ $principal.user.group_identifiers= "admin" est un champ répété (tableau).

  • Désimbrication implicite : YARA-L désimbrique automatiquement ce champ en interne lors de l'évaluation de la requête.
  • Vérification de la condition : un événement remplit la condition si l'une des valeurs du tableau $principal.user.group_identifiers est égale à "admin".
  • Aucune commande explicite n'est requise : contrairement à SPL, vous n'avez pas besoin d'une commande d'annulation de l'imbrication spécifique comme mvexpand.

La section "Impact sur l'agrégation" (outcome) signifie que l'annulation implicite de l'imbrication est cruciale dans la section outcome (par exemple, outcome: $admin_login_count = count(metadata.id))). Voici les conséquences à noter :

  • Un seul événement UDM contenant plusieurs valeurs correspondantes dans un champ répété peut générer plusieurs lignes internes pour l'évaluation de la requête.
  • Étant donné que la section events a déjà annulé l'imbrication des événements en fonction de chaque valeur correspondante dans $principal.user.group_identifiers, l'agrégation count(metadata.id) comptabilise chacune de ces instances non imbriquées.

Exemple : Compter le nombre d'utilisateurs appartenant au groupe du personnel informatique

SPL :

index=<your_index_name> user_id="jsmith"
| where match(memberOf, "Domain Admins|IT Staff|HR")
| mvexpand memberOf
| stats count by memberOf
| mvexpand actions
| table memberOf, count, actions

YARA-L (recherche) :

 principal.user.userid = "jsmith"
 additional.fields["memberOf"] = $group
   $group = /Domain Admins|IT Staff|HR/ nocase

 match:
   $group by 1h

 outcome:
   $group_count = count_distinct(metadata.id)
   $memberOf = array_distinct($group)
   $risk_score = max(50)

Exemple : Créer une règle pour générer une alerte lorsqu'un hachage de fichier spécifique est présent

SPL :

| eval file_hashes="hash12345,hash67890,hashABCDE"
| makemv delim="," file_hashes
| mvexpand file_hashes
| search file_hashes="hash67890"
| table _time, file_hashes

YARA-L (règle) :

    rule specific_file_hash_detected {

    meta:
      rule_name = "Specific File Hash Detected"
      description = "Detects events where a specific file hash is present."
      severity = "Medium"

    events:
      $e.target.file.sha256 = "hash67890"

    outcome:
      $time = array_distinct($e.metadata.event_timestamp.seconds)
      $file_hashes = array_distinct($e.target.file.sha256)

    condition:
      $e
    }

Fenêtrage temporel

Dans YARA-L, le regroupement par période est une méthode permettant de corréler des événements sur une période spécifique et glissante. Lorsqu'elle est utilisée dans des règles, cette fenêtre se déplace continuellement avec les données entrantes, ce qui permet de détecter en continu et en temps réel les schémas qui se développent au fil du temps.

Ce processus est un élément clé de la conception de la détection automatisée et constitue l'un des avantages de l'utilisation de YARA-L. En spécifiant la période, vos détections et vos tableaux de bord fonctionnent en continu avec des données en temps réel.

Fonctionnalité SPL YARA-L
Objectif principal Recherche statique, analyse ad hoc Détection continue, corrélation automatisée
Fonctions principales earliest, latest, span, transaction over, by
Exemple de cinq minutes earliest=-5m (recherche statique)
ou
transaction maxspan=5m
match :
[event] over 5m (détection continue dans les règles)
ou
[event] by 5m (recherche et tableaux de bord)

Les exemples de cette section illustrent la différence entre une fenêtre temporelle glissante (avec by) et une fenêtre temporelle glissante (avec over) dans YARA-L.

Fenêtre temporelle bascule (by <time_unit>)

  • Concept : utilisées dans la recherche YARA-L, les fenêtres bascules créent des intervalles de temps de taille fixe, sans chevauchement. Le système traite chaque événement en l'attribuant à un intervalle de temps spécifique en fonction de son code temporel. Ces intervalles fixes sont absolus et s'alignent strictement sur les repères temporels standards, tels que les jours, les heures ou les minutes.

  • Utilisation : couramment utilisé dans les requêtes de recherche et les tableaux de bord Google SecOps pour agréger les données en segments de temps distincts.

Exemple : Nombre quotidien de connexions réussies par utilisateur

Cette requête de recherche regroupe les événements de connexion réussis par utilisateur unique pour chaque jour calendaire. L'exemple suivant illustre une fenêtre cumulée de recherche YARA-L (by day) :

events:
  //Filter for successful login events
  metadata.event_type = "USER_LOGIN"
  principal.user.userid != ""

match:
  //Group by each unique user ID, aggregated over a calendar day.
  principal.user.userid by day

outcome:
  //Count how many successful logins occurred for this user on this specific day.
  $daily_success_count = count(metadata.id)

  //Get the timestamp of the FIRST event within this daily group.
  $first_event_time = window.first(metadata.event_timestamp.seconds, timestamp.get_timestamp(metadata.event_timestamp.seconds))

  //Get the timestamp of the LAST event within this daily group.
  $last_event_time = window.last(metadata.event_timestamp.seconds, timestamp.get_timestamp(metadata.event_timestamp.seconds))

Fonctionnement : si l'utilisateur jdoe s'est connecté 10 fois le Nov 17 et 15 fois le Nov 18, cette requête génère deux lignes distinctes pour jdoe, une pour chaque jour, avec les nombres respectifs. Le bucket Nov 17 inclut les événements de 2025-11-17 00:00:00 to 23:59:59 UTC.

Fenêtre à durée flexible (over <duration>)

  • Concept : utilisées dans les règles YARA-L, les fenêtres glissantes sont des fenêtres temporelles mobiles, potentiellement chevauchantes, d'une durée spécifiée. Elles sont idéales pour corréler des événements qui se produisent à une certaine proximité les uns des autres.

  • Utilisation : principalement utilisé dans les règles YARA-L pour détecter des schémas ou des séquences d'événements au cours d'une période continue.

Exemple : Détecter plusieurs échecs de connexion en l'espace de cinq minutes

Cet exemple de règle YARA-L génère une détection si un même utilisateur effectue plus de 5 failed logins tentatives au cours d'une période glissante de 5-minute :

rule TooManyFailedLogins_SlidingWindow {
 meta:
   author = "Alex"
   description = "Detects when a user has more than 5 failed logins within a 5-minute sliding window."
   severity = "Medium"

events:
   // Define an event variable $e for failed login attempts
   $e.metadata.event_type = "USER_LOGIN"
   $e.security_result.action = "FAIL"
   $e.principal.user.userid != ""
   $userid = $e.principal.user.userid

match:
   // Group events by userid over a continuous 5-minute sliding window.
   // Any events for the same $userid within 5 minutes of each other are grouped.
   $userid over 5m

outcome:
   // Count the number of failed login events within each 5-minute window for the grouped userid.
   $failed_count = count($e.metadata.id)

condition:
   // Trigger a detection if the count of failed logins in ANY 5-minute window is greater than 5.
   #e > 5
}

Fonctionnement : le système surveille en permanence les échecs de connexion. À tout moment, il prend en compte les cinq dernières minutes d'événements pour chaque utilisateur. Par exemple, si l'utilisateur jdoe accumule six échecs de connexion entre 10:02:30 et 10:07:30, une détection est déclenchée. Cette fenêtre glisse constamment vers l'avant, ce qui permet de détecter les schémas en temps réel, indépendamment des limites du calendrier.

Étapes suivantes

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