Syntaxe de la section "Correspondance"

Compatible avec :

Dans YARA-L 2.0, la section match fournit le mécanisme de corrélation multi-événements. Elle définit la logique de regroupement des événements en une seule détection en associant des attributs communs, tels que les utilisateurs, les adresses IP ou les hachages de fichiers, dans une limite temporelle spécifique.

Vous utilisez la section match pour les cas d'utilisation suivants :

  • Associez deux événements distincts ou plus dans une règle.
  • Agréger des données dans la recherche et les tableaux de bord, par exemple en comptant les tentatives de connexion infructueuses sur une période spécifique.

Définir les critères de corrélation

Utilisez-le pour définir les critères de cette corrélation en spécifiant les éléments suivants :

  • Champs de regroupement (clés) : variables (comme $user ou $ip) dont les valeurs doivent être identiques pour tous les événements (définies dans la section events) afin de déclencher une correspondance.

  • Contrainte temporelle : période pendant laquelle les événements groupés doivent se produire pour satisfaire la règle ou l'agrégation. Dans "Règles", cela définit la fenêtre de détection. Dans "Recherche" et "Tableaux de bord", cela définit la fenêtre d'agrégation ou de corrélation.

Comparer les exigences des fonctionnalités

Le tableau suivant détaille les comparaisons pour les règles de recherche et les tableaux de bord.

Fonctionnalité Exigences concernant les règles Assistance pour la recherche et les tableaux de bord
Types de variables Doit utiliser les espaces réservés définis dans la section events. Compatible avec les espaces réservés et les champs UDM directs.
Période Définit la limite de détection. Définit le bucket d'agrégation ou de corrélation.
Syntaxe over <number><m/h/d> (par exemple, 10m, 2h, 1d) over <number><m/h/d>
Limites Min. : 1m / Max. : 48h Min. : 1m / Max. : 48h

Types de fenêtres compatibles

YARA-L 2.0 utilise différents comportements de fenêtrage pour déterminer comment le temps est découpé et comment les événements sont regroupés. Vous pouvez regrouper les champs et les espaces réservés d'événement dans la section match par une précision temporelle spécifiée à l'aide de l'une des fenêtres compatibles suivantes.

Type de fenêtre compatible Syntaxe Description Cas d'utilisation courant
Saut $key over <duration> Les intervalles de temps se chevauchent (comportement par défaut). Corrélation générale de plusieurs événements.
Tumbling $key by <duration> tumbling Intervalles de temps de taille fixe, sans chevauchement et continus. Quantifier l'activité par blocs d'une heure maximum (par exemple, $user by 30m).
Glissement $key over <duration> [before|after] $pivot Intervalles de temps ancrés à un événement "pivot" spécifique. Séquence stricte (par exemple, File Download after Login).

Exemple de syntaxe :

match:
  $user, $source_ip over 5m  // Groups events by user and IP within a 5-minute window

Fenêtre de saut

Une période de chevauchement est le comportement par défaut des règles multi-événements. Il crée des intervalles de temps qui se chevauchent pour s'assurer que les événements qui se produisent près des limites d'une fenêtre ne sont pas manqués.

  • Syntaxe : $key over <duration> (par exemple, $user over 30m)
  • Cas d'utilisation : idéal pour la détection lorsque vous devez vous assurer qu'un scénario spécifique est détecté, quelle que soit l'heure exacte de début ou de fin de la période.
  • Assistance : compatible avec l'agrégation dans la recherche et les tableaux de bord (par exemple, count).

Par défaut, les requêtes YARA-L avec une section match utilisent des fenêtres de saut pour corréler plusieurs événements au fil du temps. La période d'exécution de la requête est divisée en un ensemble de fenêtres de saut fixes et qui se chevauchent. Bien que la durée de ces fenêtres soit spécifiée dans la section match, l'intervalle de chevauchement et l'alignement des fenêtres sont définis par le système et ne peuvent pas être configurés par l'utilisateur. Les événements sont ensuite corrélés dans chacune de ces périodes prédéterminées.

Exemple : Fenêtres de saut qui se chevauchent pour une corrélation continue

L'exemple suivant montre une requête exécutée sur la plage de temps [1:00, 2:00], avec une section match $user over 30m, où un ensemble possible de fenêtres de saut qui pourraient être générées est [1:00, 1:30], [1:03, 1:33] et [1:06, 1:36].

rule hop_window_brute_force_example {
meta:
  description = "Detects multiple failed logins within a shifting 30-minute window."
  severity = "Medium"

events:
  $login.metadata.event_type = "USER_LOGIN"
  $login.extensions.auth.auth_status = "FAILURE"
  $login.principal.user.userid = $user

match:
  // This creates the overlapping windows (e.g., 1:00-1:30, 1:03-1:33)
  $user over 30m

condition:
  // This will trigger if 10 or more failures fall into any single 30m hop
  #login >= 10
}

Exemple : Corrélation multi-événements à l'aide d'une fenêtre de déplacement

L'exemple suivant représente la valeur par défaut pour la plupart des règles multi-événements. Il capture les événements qui se produisent au cours de la même période générale.

rule hop_window_example {
meta:
  description = "Detect a user with a failed login followed by a success within 30m"

events:
  $e1.metadata.event_type = "USER_LOGIN"
  $e1.extensions.auth.auth_status = "FAILURE"
  $e1.principal.user.userid = $user

  $e2.metadata.event_type = "USER_LOGIN"
  $e2.extensions.auth.auth_status = "SUCCESS"
  $e2.principal.user.userid = $user

match:
  $user over 30m  // This is a hop window

condition:
  $e1 and $e2
}

Exemple : comparaison des fenêtres de saut

Pour identifier une tentative de piratage par force brute, une fenêtre 10m regroupe tous les échecs USER_LOGIN. condition évalue ensuite si le nombre (#e) dans ce bucket de 10 minutes spécifique dépasse votre seuil.

rule failed_logins
{
meta:
  author = "Security Team"
  description = "Detects multiple failed user logins within 10-minute windows."
  severity = "HIGH"

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

match:
  $user over 10m

condition:
  #e >= 5
}

La section match permet de trouver les utilisateurs dont la connexion a échoué dans un nouveau lieu au cours d'un intervalle de 10 minutes (10m) :

match:
  $user over 10m

Fenêtre bascule

Une fenêtre bascule segmente un flux de données en intervalles de temps de taille fixe, non chevauchants et continus. Chaque événement de données n'est attribué qu'à une seule fenêtre. Cela diffère d'une fenêtre glissante ou récurrente, qui peut avoir des intervalles de temps qui se chevauchent.

  • Syntaxe : utilisez l'opérateur by ($key by <duration>), par exemple $user by 30m.
  • Cas d'utilisation : idéal pour les rapports et la création de tableaux de bord lorsque vous souhaitez comptabiliser les événements dans des blocs distincts (par exemple, "How many alerts per hour?").
  • Recherche et tableaux de bord : souvent utilisés pour créer des graphiques à barres clairs sans déduplication des événements.

Exemple : Comptage à intervalle fixe avec fenêtres glissantes

L'exemple suivant montre une fenêtre cumulée de 30 minutes, où les événements qui se produisent entre 1:00:00 et 1:29:59 sont traités ensemble. Ensuite, l'ensemble suivant d'événements, de 1:30:00 à 1:59:59, est traité séparément.

rule tumbling_window_threshold_example {
meta:
  description = "Detect more than 50 failed logins from a single IP within a fixed 1-hour block."
  severity = "Medium"

events:
  $login.metadata.event_type = "USER_LOGIN"
  $login.extensions.auth.auth_status = "FAILURE"
  $login.principal.ip = $ip

match:
// This creates distinct, 1-hour blocks (e.g., 1:00-1:59, 2:00-2:59)
  $ip by 1h

condition:
  #login > 50
}

Fenêtre glissante

Utilisez une fenêtre coulissante lorsque vous devez rechercher des événements qui se produisent dans un ordre strict et relatif (par exemple, e1 se produit jusqu'à deux minutes après e2). Contrairement aux fenêtres fixes, une fenêtre coulissante est déclenchée par chaque occurrence de l'$pivot_event désigné à l'aide de cette syntaxe :

  • after : la période commence à l'horodatage de l'événement pivot et s'étend vers l'avant.
  • before : la fenêtre se termine à l'horodatage de l'événement pivot et s'étend vers le passé.

Spécifiez des fenêtres glissantes dans la section match d'une requête comme suit :

<match-var-1>, <match-var-2>, ... over <duration> [before|after] <pivot-event-var>

  • Syntaxe : $key over <duration> before|after $<pivot_event>
  • Clés de regroupement : champs communs (par exemple, $user, $ip) utilisés pour associer des événements.
  • Durée : décalage temporel par rapport à l'événement pivot (par exemple, 5m, 1h).
  • Cas d'utilisation :
    • Séquence stricte : détectez une chaîne d'attaque où l'ordre est requis (par exemple, la création d'un utilisateur suivie d'une élévation des privilèges).
    • Timing relatif : trouvez un événement qui se produit dans un décalage spécifique d'un "déclencheur" (par exemple, un événement Process Start suivi d'un événement Network Connection dans les 30 secondes).
    • Détection d'absence : identifiez quand un événement de "nettoyage" ou de "battement de cœur" requis ne se produit pas après un événement de début (par exemple, un Database Backup Start sans événement End correspondant).

Exemples de fenêtres glissantes valides

Les exemples suivants montrent des fenêtres glissantes valides :

$var1, $var2 over 5m after $e1 $user over 1h before $e2 $host, $ip over 1h before $e2

Exemple : Corrélation prospective avec des fenêtres glissantes (after)

L'exemple suivant montre comment détecter une séquence d'événements dans laquelle le deuxième événement doit se produire dans un délai spécifique après un événement "déclencheur" ou pivot principal. Cela permet de détecter les déplacements latéraux rapides ou les actions de suivi automatisées.

rule sliding_window_after_example {
meta:
  description = "Detect a network connection occurring within 1 minute after a suspicious process launch."
  severity = "High"

events:
  $proc.metadata.event_type = "PROCESS_LAUNCH"
  $proc.principal.hostname = $host

  $net.metadata.event_type = "NETWORK_HTTP"
  $net.principal.hostname = $host

match:
  // $proc is the pivot; the 1-minute window starts at the $proc timestamp
  $host over 1m after $proc

condition:
  $proc and $net
}

Exemple : Corrélation rétrospective avec des fenêtres glissantes (before)

Utilisez une fenêtre glissante "before" pour examiner l'activité ayant précédé une alerte spécifique. Cette fonctionnalité est souvent utilisée dans l'analyse des causes premières pour identifier ce qui s'est passé immédiatement avant une détection critique.

rule sliding_window_before_example {
meta:
  description = "Identify file modifications occurring in the 5 minutes before a ransomware alert."
  severity = "Critical"

events:
  $file.metadata.event_type = "FILE_MODIFICATION"
  $file.principal.hostname = $host

  $alert.metadata.event_type = "ANTIVIRUS_DETECTION"
  $alert.metadata.product_name = "Premium_AV"
  $alert.principal.hostname = $host

match:
  // $alert is the pivot; the 5-minute window ends at the $alert timestamp
  $host over 5m before $alert

condition:
  $file and $alert
}

Performances et bonnes pratiques

Les fenêtres glissantes nécessitent plus de puissance de traitement que les fenêtres standards (avec saut), car elles sont calculées pour chaque occurrence de l'événement pivot et peuvent entraîner des performances plus lentes.

Suivez ces consignes pour optimiser les performances des règles, de la recherche et des tableaux de bord :

  • Prioriser les fenêtres de saut : utilisez la fenêtre de saut par défaut, sauf si la séquence d'événements spécifique (commande A, puis commande B) est requise pour la logique de détection. N'utilisez les fenêtres glissantes que lorsque le séquençage des événements est essentiel ou lorsque vous recherchez des événements manquants.

  • Utiliser des filtres d'horodatage pour les performances : si vous avez uniquement besoin de vous assurer qu'un événement s'est produit après un autre, une comparaison d'horodatage dans la section events ou condition est souvent plus efficace qu'une fenêtre glissante. Par exemple :

$e1.metadata.event_timestamp.seconds < $e2.metadata.event_timestamp.seconds

  • Conception multi-événements : évitez d'utiliser des fenêtres glissantes pour les requêtes à événement unique. Les fenêtres glissantes sont conçues pour la corrélation de plusieurs événements. Pour la logique d'événement unique, les consignes suivantes s'appliquent :

    • Utilisez plusieurs variables d'événement et mettez à jour la section condition.
    • Supprimez entièrement la section match si la corrélation n'est pas requise.
    • Vous pouvez également ajouter des filtres d'horodatage au lieu d'utiliser une fenêtre glissante, par exemple :
      $permission_change.metadata.event_timestamp.seconds < $file_creation.metadata.event_timestamp.seconds

Comprendre la limite temporelle

La section match partitionne les événements en groupes en fonction de vos clés de regroupement. La durée spécifiée définit la limite temporelle pour chaque groupe :

  • Inclusion : seuls les événements survenus au cours de la période sont transmis à l'évaluation condition pour cette correspondance spécifique.
  • Exclusion : les événements en dehors de la période sont ignorés pour ce groupe de correspondance spécifique, ce qui empêche les événements non liés de déclencher un faux positif.

Valeurs nulles dans la section match

Google SecOps filtre implicitement les valeurs nulles pour tous les espaces réservés utilisés dans la section match ("" pour les chaînes, 0 pour les nombres, false pour les valeurs booléennes et la valeur à la position 0 pour les types énumérés).

Exemple : Filtrer les valeurs nulles

L'exemple suivant illustre les requêtes qui filtrent les valeurs nulles.

rule ZeroValuePlaceholderExample {

events:
  // Because $host is used in the match section, the query behaves
  // as if the following predicate was added to the events section:
  // $host != ""
  $host = $e.principal.hostname

  // Because $otherPlaceholder was not used in the match,
  // there is no implicit filtering of zero values for $otherPlaceholder.
  $otherPlaceholder = $e.principal.ip

match:
  $host over 5m

condition:
  $e
}

Toutefois, si un espace réservé est attribué à une fonction, les requêtes ne filtrent pas implicitement les valeurs nulles des espaces réservés utilisés dans la section match.

Pour désactiver le filtrage implicite des valeurs nulles, vous pouvez utiliser l'option allow_zero_values dans la section des options. L'option allow_zero_values n'est disponible que dans les règles.

Exemple : Autoriser les valeurs nulles

L'exemple suivant illustre les requêtes qui ne filtrent pas implicitement les valeurs nulles des espaces réservés utilisés dans la section match :

rule AllowZeroValuesExample {

events:
  // Because allow_zero_values is set to true, there is no implicit filtering
  // of zero values for $host.
  $host = $e.principal.hostname

  // Because $otherPlaceholder was not used in the match,
  // there is no implicit filtering of zero values for $otherPlaceholder.
  $otherPlaceholder = $e.principal.ip

match:
  $host over 5m

condition:
  $e

options:
  allow_zero_values = true
}

Étapes suivantes

Explorez les ressources suivantes pour poursuivre votre logique YARA-L ou approfondir les fonctions de requête avancées :

Syntaxe et logique

Références et exemples

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