Passer de SPL à YARA-L 2.0

Compatible avec :

Ce guide est destiné aux utilisateurs qui connaissent déjà le langage de traitement des recherches Splunk (SPL). 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 créer des règles de détection haute fidélité sur toutes vos données de journaux d'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 pipe (|), 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édure) YARA-L (déclaratif)
Concept de base 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é, identifiant les menaces et extrayant des insights précieux.
Flux des 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 les modèles de manière optimale à grande échelle. Vous n'avez plus besoin de penser à l'efficacité.
Corrélation d'événements Repose 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 impose 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.

Commande Action Obligatoire | Facultatif
meta Définit les métadonnées descriptives de la règle, telles que l'auteur, la description et la gravité. Requis uniquement pour les règles.
events Ce composant définit et filtre les événements. Obligatoire (logique principale de la requête).
match Regroupe les événements et vous permet de spécifier la période (par exemple, by 5m). Facultatif. Obligatoire uniquement pour les requêtes de corrélation multi-événements.
outcome Calculer les métriques clés et obtenir des insights. Facultatif.
condition Évalue les critères de la variable de requête pour déterminer si un résultat s'applique (par exemple, #event >5). Requis uniquement pour les règles. Facultatif dans la recherche et les tableaux de bord.
dedup Supprime les événements en double en les regroupant en fonction de variables clés (par exemple, target.user.userid, target.ip>, principal.hostname). Facultatif.
order Trie les résultats des événements collectés définis par des champs spécifiques (par exemple, asc). Facultatif.
limit Limite le nombre maximal d'événements renvoyés par la requête. Facultatif.

Commandes courantes dans SPL et YARA-L

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

Commande SPL search = section YARA-L events

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. Bien que d'autres sections (comme match ou outcome) soient 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 correspondant à 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 d'un utilisateur au cours d'une journée. La règle se déclenche alors 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 correspondant aux critères existe.

Commande SPL eval = section YARA-L outcome

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

  • Objectif : calculer et définir de nouvelles valeurs de champ.
  • Fonctionnalité : elle évalue les 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. Calculez les octets en additionnant 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 caractère 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 en tant que 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(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 sur les échecs de connexion, l'exemple suivant vous permet de trouver les utilisateurs pour lesquels cinq tentatives de connexion ou plus ont échoué à moins de 10 minutes (10m) d'intervalle (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. Dans la section events, vous pouvez déclarer des événements et spécifier des attributs spécifiques pour chacun d'eux (par exemple, priniciapal.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

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

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êtrage temporel : 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 résultante 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 à 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 YARA-L
search Filtrage initial des données Section events Définissez les champs et les conditions de l'événement. Aucun préfixe events n'est nécessaire pour la recherche ou les tableaux de bord. Voir un exemple

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

        
where Filtrer davantage les résultats Sections events et condition Appliquez la logique booléenne, souvent aux 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 l'exemple de SPL eval.

metadata.event_type = "USER_LOGIN"

outcome:
  $login_count = count(metadata.id)
        
stats Agrégations (count, sum, moyenne) match ou outcome Champs "Grouper par" dans match. Calculez les agrégats dans outcome. Consultez des exemples dans Agrégations et requêtes statistiques et dans la commande SPL stats.

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 du tableau. 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 Liste les résultats par ordre croissant ou décroissant Section order Consultez l'exemple dans la cellule du tableau ci-dessous.
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 suivante.

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 l'imbrication des tableaux dans la section "events" (événements).
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 dans l'UI de recherche, utilisez match: $field by 5m. Consultez des exemples dans Fenêtres temporelles.

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 brutes des événements en métriques de sécurité synthétisé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 YARA-L
count 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 pour 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() Trouve 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.stddv

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 à plusieurs étapes et Créer des requêtes à plusieurs étapes en 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 et par heure. Elle 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 à valeurs multiples (lecture d'un tableau)

La syntaxe de YARA-L est conçue pour comprendre qu'un champ peut avoir plusieurs valeurs. Lorsque vous écrivez 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 de fonction spéciale pour filtrer le tableau. Il vous suffit d'indiquer la condition à respecter. 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 dans la section de requête outcome. Vous n'avez pas besoin de supprimer 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 les 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 l'event_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 répond à la condition si l'une des valeurs du tableau $principal.user.group_identifiers est égale à "admin".
  • Aucune commande explicite n'est nécessaire : contrairement à SPL, vous n'avez pas besoin d'une commande d'annulation de l'imbrication spécifique comme mvexpand.

La section sur l'impact sur l'agrégation (outcome) signifie que l'annulation de l'imbrication implicite est essentielle dans la section outcome (par exemple, outcome: $admin_login_count = count(metadata.id))). Notez l'impact suivant :

  • Un seul événement UDM contenant plusieurs valeurs correspondantes dans un champ répété peut générer plusieurs lignes internes à des fins d'évaluation des requêtes.
  • Étant donné que la section events a déjà supprimé 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 : Comptabiliser 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)
      $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 en continu avec les données entrantes, ce qui permet de détecter en temps réel et en continu les tendances 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 5 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 (à l'aide de by) et une fenêtre temporelle glissante (à l'aide de over) dans YARA-L.

Période de bascule (by <time_unit>)

  • Concept : utilisées dans la recherche YARA-L, les fenêtres glissantes créent des intervalles de temps de taille fixe, non chevauchants. Le système traite chaque événement en l'attribuant à un seul bucket temporel 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 dans des segments temporels distincts.

Exemple : Nombre quotidien de connexions réussies par utilisateur

Cette requête de recherche regroupe les événements de connexion réussie par utilisateur unique et par jour du calendrier. L'exemple suivant illustre une fenêtre glissante 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 a effectué 10 connexions réussies sur Nov 17 et 15 sur 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 provenant 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 et 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 dans un laps de temps continu.

Exemple : Détecter plusieurs échecs de connexion en 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 tient compte des événements des cinq dernières minutes pour chaque utilisateur. Par exemple, si l'utilisateur jdoe accumule six tentatives de connexion infructueuses entre 10:02:30 et 10:07:30, une détection est déclenchée. Cette période glisse constamment vers l'avant, ce qui permet de détecter les tendances 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.