Logique de fenêtrage YARA-L 2.0

Compatible avec :

Ce guide aide les ingénieurs en sécurité à choisir le type de fenêtre approprié pour les requêtes afin d'éviter les erreurs de compilation "variable non liée". Le passage des fenêtres glissantes aux fenêtres basculantes vous permet de créer une logique qui dépend de l'absence d'événements, comme un signal de présence manquant ou une source de journaux défaillante.

Avant de commencer

Vérifiez que votre compte dispose de l'un des rôles suivants pour créer et modifier des requêtes YARA-L :

  • Administrateur Detection Engine (roles/chronicle.detectionEngineAdmin)
  • Éditeur SecOps (roles/chronicle.editor)

Types de fenêtres compatibles

YARA-L 2.0 utilise différents comportements de fenêtrage pour déterminer comment le temps est segmenté 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 des périodes acceptées suivantes :

Type de fenêtre compatible Syntaxe Description Cas d'utilisation courant
Saut $key over <duration> Crée des intervalles de temps fixes et qui se chevauchent. Le système définit le chevauchement et l'alignement pour détecter les événements proches des limites. Corrélation générale de plusieurs événements, quelles que soient les heures de début exactes.
Tumbling $key by <duration> Segmente les données en blocs de taille fixe, continus et non chevauchants. Évalue indépendamment de l'arrivée de l'événement. Quantifier l'activité dans des créneaux horaires fixes (par exemple, $user by 30m) ou détecter l'absence d'événements.
Glissement $key over <duration> [before|after] $pivot Ancre la fenêtre à un événement "pivot" spécifique. Nécessite l'existence d'un pivot pour déclencher une analyse rétrospective ou prospective. Séquence stricte où l'ordre des événements est essentiel (par exemple, File Download after Login).

Comprendre la logique window_start et window_end

Google Security Operations fournit deux mots clés universels réservés qui renvoient directement aux codes temporels GoogleSQL à utiliser dans les requêtes. Ces mots clés vous permettent d'accéder aux limites de vos buckets temporels :

  • window_start : limite de début du bucket temporel.
  • window_end : limite de fin du bucket temporel.

Contraintes d'utilisation

  • Exigence de correspondance : vous devez définir une fenêtre (by ou over) dans la section match pour utiliser ces mots clés.
  • Restriction de section : utilisez ces mots clés dans condition, order ou outcome. Elles ne sont pas valides dans la section events.
  • Espace de noms : n'utilisez pas ces noms comme noms de variables personnalisées (par exemple, $window_start).

Déterminer le type et la syntaxe de votre fenêtre

Utilisez ce tableau comme référence rapide pour déterminer le type de fenêtre et la syntaxe à utiliser pour vos règles de détection.

Scénario Fenêtre recommandée Mots clés recommandés Avantage clé
Détections à haute fréquence (par exemple, les attaques par force brute) Fenêtre coulissante (over) window_start, window_end Se déclenche immédiatement lorsque le seuil est atteint au cours d'une période mobile.
Absence/non-existence (par exemple, absence de battements cardiaques) Tumbling window (by) window_start, window_end Évalue les blocs de temps fixes même si aucun événement ne se produit, ce qui évite les erreurs Variable non bornée.
Rapports chronologiques Glisser ou tomber order: window_start asc Standardise les résultats des alertes pour faciliter l'analyse de la chronologie dans l'interface utilisateur Chronicle.
Filtrage limité dans le temps Glisser ou tomber condition: window_start > "2026-01-01 00:00:00Z" Limite l'évaluation des règles à des dates spécifiques à l'aide de la coercition de code temporel GoogleSQL.

Comparer les types de codes temporels et les fuseaux horaires

YARA-L permet de comparer directement window_start et window_end avec des chaînes au format d'horodatage GoogleSQL. Cela vous permet d'effectuer un filtrage précis sans conversion manuelle des types.

Remarque : Spécifiez toujours le fuseau horaire UTC à l'aide du suffixe Z (par exemple, "2026-03-17T17:35:00Z") pour l'aligner sur les codes temporels des événements UDM.

Utilisez des filtres d'horodatage pour les performances. Si vous avez uniquement besoin de confirmer qu'un événement s'est produit après un autre, une comparaison d'horodatages dans la section condition est souvent plus efficace : $e1.metadata.event_timestamp.seconds < $e2.metadata.event_timestamp.seconds.

En savoir plus sur la syntaxe de la section match et sur la syntaxe de la section condition

Exemples : window_end et window_start

  • window_end < "2026-01-01T12:30:00Z" (date, heure et suffixe UTC)
  • window_start != "2026-01-01 15:00:00+00" (avec décalage UTC)

Si votre comparaison échoue, vérifiez que votre chaîne respecte le format canonique de code temporel GoogleSQL.

Fenêtres récurrentes

Une fenêtre récurrente crée des intervalles de temps qui se chevauchent afin de ne pas manquer les événements qui se produisent près des limites d'une fenêtre.

  • Cas d'utilisation : idéal pour les détections où vous devez identifier un scénario spécifique, 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.

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. Le système divise la période d'exécution de la requête en un ensemble de fenêtres de saut fixes et chevauchantes. Bien que vous spécifiiez la durée de ces fenêtres dans la section match, le système définit l'intervalle de chevauchement et l'alignement des fenêtres. Les événements sont ensuite corrélés dans chacune de ces périodes prédéterminées.

En savoir plus sur la syntaxe de la section match

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. Un ensemble possible de fenêtres de saut qui se chevauchent et que le système génère est [1:00, 1:30], [1:03, 1:33] et [1:06, 1:36].

Règle

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
}
metadata.event_type = "USER_LOGIN"
security_result.action = "FAIL"
principal.user.userid = $user

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

Tableau de bord

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

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

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

L'exemple suivant capture les événements qui se produisent au cours de la même période générale :

Règle

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

events:
  // Event 1: Capture failed login attempts
  $fail.metadata.event_type = "USER_LOGIN"
  $fail.security_result.action = "FAIL"
  $fail.principal.user.userid = $user

  // Event 2: Capture successful login attempts
  $success.metadata.event_type = "USER_LOGIN"
  $success.security_result.action = "ALLOW"
  $success.principal.user.userid = $user

match:
  // Correlate events for the SAME $user within a rolling 30-minute window.
  $user over 30m

condition:
  // Ensure both a failed ($fail) and a successful ($success) login event occurred for the same user within the 30m window.
  $fail and $success
}

Rechercher

// Event 1: Capture failed login attempts
metadata.event_type = "USER_LOGIN"
security_result.action = "FAIL"
principal.user.userid = $user // Assign user ID to a placeholder

// Event 2: Capture successful login attempts
metadata.event_type = "USER_LOGIN"
security_result.action = "ALLOW"
principal.user.userid = $user // Link to the same user placeholder

match:
  // Correlate events for the SAME $user within a rolling 30-minute window.
  $user over 30m

Tableau de bord

// Event 1: Capture failed login attempts
metadata.event_type = "USER_LOGIN"
security_result.action = "FAIL"
principal.user.userid = $user // Assign user ID to a placeholder

// Event 2: Capture successful login attempts
metadata.event_type = "USER_LOGIN"
security_result.action = "ALLOW"
principal.user.userid = $user // Link to the same user placeholder

match:
  // Correlate events for the SAME $user within a rolling 30-minute window.
  $user over 30m

Exemple : Comparaison de la fenêtre de saut

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

Règle

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
}

Rechercher

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

match:
  $user over 10m

Tableau de bord

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

match:
  $user over 10m

Tumbling windows

Remarque : Cette fonctionnalité n'est pas disponible pour tous les clients ni dans toutes les régions.

Une fenêtre bascule segmente les données en intervalles de temps continus, de taille fixe et sans chevauchement. Le code temporel de chaque événement correspond à une seule fenêtre. Les fenêtres bascules ne se chevauchent pas. Cela contraste avec une fenêtre récurrente ou une fenêtre glissante, qui peuvent avoir des intervalles de temps qui se chevauchent.

Pour implémenter une fenêtre bascule, utilisez l'opérateur by dans la section match. Les fenêtres Tumbling divisent le temps en blocs continus et consécutifs, par exemple :

  • by 1h : crée des fenêtres pour chaque heure (par exemple, [00:00:00-00:59:59], [01:00:00-01:59:59]).
  • by 10m : crée des fenêtres pour chaque intervalle de 10 minutes (par exemple, [00:00:00-00:09:59], [00:10:00-00:19:59]).

Cas d'utilisation courants

Utilisez des fenêtres cumulatives lorsque vous devez :

  • Analysez les événements dans des blocs de temps distincts et non chevauchants.
  • Ne générez qu'une seule détection pour une entité donnée (telle que définie par les variables de correspondance) dans chaque intervalle de temps fixe, quel que soit le nombre de fois où l'événement se produit.
  • Comptez les entités uniques sur des périodes fixes.

Comportement de déduplication

Une caractéristique clé des fenêtres glissantes est la façon dont le moteur gère les détections dans chaque fenêtre pour le même ensemble de variables de correspondance :

  • Une détection par fenêtre bascule : pour un ensemble donné de valeurs pour les variables de correspondance (par exemple, un $userid spécifique), le moteur génère au maximum une détection pour chaque fenêtre bascule.
  • Le premier arrivé est le premier servi : la détection est déclenchée par les premiers événements ingérés qui remplissent les conditions de la règle pour cet ensemble de variables de correspondance au cours d'une période spécifique.
  • Déduplication : les événements ultérieurs correspondant aux critères de cette même instance de fenêtre ne généreront pas de détections supplémentaires.

Syntaxe

La syntaxe de la section match est la suivante : match: $variable by <duration>

  • $variable est la variable d'espace réservé sur laquelle vous effectuez la mise en correspondance.
  • duration est un nombre suivi d'une unité de temps : m (minute), h (heure) ou d (jour).
  • Spécifiez une durée minimale d'une minute et une durée maximale de 72 heures ou trois jours.

Exemple : Regroupement à intervalles fixes

Le groupe de règles suivant regroupe les connexions par $userid dans des fenêtres d'une heure sans chevauchement.

Règle

rule TumblingWindowExample {
meta:
  description = "Example using a 1-hour tumbling window"

events:
  $e.metadata.event_type = "USER_LOGIN"
  $e.principal.user.userid = $userid

match:
  $userid by 1h

condition:
  $e
}

Rechercher

metadata.event_type = "USER_LOGIN"
principal.user.userid = $userid

match:
  $userid by 1h

Tableau de bord

metadata.event_type = "USER_LOGIN"
principal.user.userid = $userid

match:
  $userid by 1h

Exemple : Comportement de la détection (utilisateur = "Alex")

  • Événement 1 : Alex se connecte à 00h30. Cela correspond à la fenêtre [00:00:00-00:59:59]. Le moteur génère une détection pour Alex pour cette fenêtre.
  • Événement 2 : un autre utilisateur, "Taylor", se connecte à 00:45. Cette situation relève également de la catégorie [00:00:00-00:59:59], mais comme le $userid est différent, le moteur génère une détection distincte pour Taylor.
  • Événement 3 : Alex se reconnecte à 00:40. Cette heure de réveil se trouve tout de même dans le créneau de réveil [00:00:00-00:59:59]. Comme une détection pour Alex existe déjà, cet événement est dédupliqué. Aucune nouvelle détection n'est générée.
  • Événement 4 : Alex se connecte à 1h20. Cela relève de la prochaine période, [01:00:00-01:59:59]. Le moteur génère une nouvelle détection pour Alex.

Même si l'événement 1 et l'événement 4 pour Alex se sont produits à moins d'une heure d'intervalle, ils sont classés dans des détections distinctes, car l'événement 4 dépasse la limite de la période fixe.

Configurer des fenêtres glissantes pour la détection des absences

Pour générer une alerte en cas de nombre nul et éviter les échecs de compilation, procédez comme suit :

  1. Identifiez l'objectif de la détection. Déterminez si vous recherchez une fréquence élevée ou un manque d'activité.
  2. Sélectionnez le mot clé window. Utilisez over pour la fréquence et by pour l'absence.
  3. Limites de la fenêtre de référence. Utilisez les mots clés window_start et window_end pour faire référence à des limites spécifiques du bucket temporel.

Contexte : utilisez outcome: $ext_window_end = window_end pour inclure l'heure de fin exacte d'un battement manqué dans les métadonnées de l'alerte.

Exemple : Détecter un battement de cœur manquant avec des métadonnées

Les fenêtres glissantes vous permettent de générer des alertes lorsque le nombre est nul, ce qui vous aide à éviter les échecs de compilation lorsque vous recherchez une absence d'activité.

Règle

rule missing_heartbeat_detection {
meta:
  description = "Alert when a system fails to check in within a 24h block"

events:
  $e.metadata.event_type = "STATUS_UPDATE"
  $host = $e.principal.hostname

match:
  $host by 24h  // Tumbling window lets you detect zero counts

outcome:
  $event_count = count($e.metadata.id)
  $missing_window_start = window_start
  $missing_window_end = window_end

condition:
  $event_count = 0 and window_start > "2026-01-01T12:30:00Z"
}

Rechercher

metadata.event_type = "STATUS_UPDATE"
$host = principal.hostname

match:
  $host by 24h  // Tumbling window lets you detect zero counts

outcome:
  $event_count = count(metadata.id)
  $missing_window_start = window_start
  $missing_window_end = window_end

Tableau de bord

metadata.event_type = "STATUS_UPDATE"
$host = principal.hostname

match:
  $host by 24h  // Tumbling window lets you detect zero counts

outcome:
  $event_count = count(metadata.id)
  $missing_window_start = window_start
  $missing_window_end = window_end

Fenêtres glissantes

Une fenêtre glissante est ancrée à un événement pivot spécifique et regarde vers l'avant (after) ou vers l'arrière (before).

Cas d'utilisation courants

Utilisez des fenêtres glissantes lorsque le séquençage des événements est essentiel :

  • Séquence stricte : détectez une chaîne d'attaque (par exemple, e1 se produit jusqu'à deux minutes après e2).
  • Timing relatif : recherchez un événement qui se produit dans un décalage spécifique d'un déclencheur (par exemple, un Network Connection dans les 30 secondes suivant un Process Start).
  • Détection d'absence : identifie le moment où un événement de "nettoyage" ou de "battement de cœur" requis ne se produit pas après un événement de début.

Syntaxe

match: <grouping_keys> over <duration> [before|after] <$pivot_event>

Composant Description Exemple
Clés de regroupement Champs courants utilisés pour associer des événements. $host, $user
Durée Décalage temporel par rapport à l'événement pivot. 5m, 1h, 30s
Sens Indique si la fenêtre s'étend vers l'avant ou vers l'arrière. after, before
Événement pivot Variable d'événement qui ancre la fenêtre. $proc, $alert

Voici des exemples de fenêtres glissantes valides :

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

Conditions requises et limites

  • Performances : les fenêtres glissantes nécessitent plus de puissance de traitement que les fenêtres avec chevauchement. Ne les utilisez que lorsque l'ordre des événements est strictement requis (par exemple, lorsqu'un événement doit se produire dans les cinq minutes suivant un autre événement).
  • Requêtes à événement unique : n'utilisez pas de fenêtres glissantes pour la logique à événement unique. Utilisez plutôt plusieurs variables d'événement dans la section condition.

Exemple : Corrélation prospective (after)

Règle

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
}

Rechercher

after n'est pas accepté pour la recherche.

Tableau de bord

after n'est pas compatible avec les tableaux de bord.

Exemple : Corrélation rétrospective (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 produit immédiatement avant une détection critique.

Règle

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
}

Rechercher

before n'est pas accepté pour la recherche.

Tableau de bord

before n'est pas compatible avec les tableaux de bord.

Dépannage

Utilisez cette section pour comprendre la latence, les limites et les solutions aux problèmes courants de fenêtrage dans YARA-L.

Latence et limites

  • Les règles qui utilisent des fenêtres bascules (by) ne se déclenchent qu'à la fin du bloc temporel fixe. Par exemple, une règle avec match: $user by 24h n'est évaluée qu'une fois la période de 24 heures entièrement écoulée.

  • Latence des alertes : les règles qui utilisent by (glissantes) ne se déclenchent qu'une fois le bloc de temps fixe écoulé. Une règle by 24h n'envoie pas d'alerte en cours de fenêtre.

  • Incohérence de l'UI : dans la recherche et les tableaux de bord, le mot clé window_start fait directement référence au champ TIME_BUCKET. Lorsque vous filtrez ou regroupez les données par window_start, l'en-tête de colonne s'affiche sous la forme TIME_BUCKET dans l'UI. Il s'agit d'une limite d'affichage connue de l'UI. Votre logique reste valide.

Correction des erreurs

Code d'erreur Description Corriger
Variable non bornée La règle utilise over (fenêtre glissante) avec une condition $count = 0. Remplacez le mot clé de fenêtrage par by (fenêtre bascule). Les fenêtres glissantes nécessitent un événement pour ancrer la fenêtre, contrairement aux fenêtres bascules.
Incohérence de l'en-tête de l'UI L'utilisateur voit TIME_BUCKET dans l'UI au lieu de window_start. Aucune correction n'est requise. La logique de filtrage et de tri fonctionne toujours correctement avec les mots clés.
Identifiant inconnu : window_start Le mot clé est utilisé, mais aucune fenêtre n'est définie dans match. Ajoutez une instruction de fenêtrage à votre section match (par exemple, $hostname by 1h).
Utilisation incorrecte de window_start dans les événements Le mot clé est référencé dans la section events. Déplacez la logique vers la section condition ou outcome. Les limites de la fenêtre ne sont calculées qu'après le regroupement des événements dans la phase de mise en correspondance.

Étapes suivantes

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