Syntaxe du langage YARA-L 2.0

Cette section décrit les principaux éléments de la syntaxe YARA-L. Consultez également la page Présentation du langage YARA-L 2.0.

Structure des règles

Pour YARA-L 2.0, vous devez spécifier les déclarations, les définitions et les utilisations de variables dans l'ordre suivant:

  1. méta
  2. événement
  3. correspondance (facultatif)
  4. résultat (facultatif)
  5. condition
  6. options (facultatif)

Voici la structure générique d'une règle:

rule <rule Name>
{
    meta:
    // Stores arbitrary key-value pairs of rule details, such as who wrote
    // it, what it detects on, version control, etc.

  events:
    // Conditions to filter events and the relationship between events.

  match:
    // Values to return when matches are found.

  outcome:
    // Additional information extracted from each detection.

  condition:
    // Condition to check events and the variables used to find matches.

  options:
    // Options to turn on or off while executing this rule.
}

Syntaxe de la section Meta

La section Méta est composée de plusieurs lignes, où chaque ligne définit une paire clé-valeur. Une partie clé doit être une chaîne sans guillemets, et une partie valeur doit être une chaîne entre guillemets:

<key> = "<value>"

Voici un exemple de ligne de section meta valide : none meta: author = "Chronicle" severity = "HIGH"

Syntaxe de la section "Événements"

Dans la section events, répertoriez les prédicats pour spécifier les éléments suivants:

  • Déclarations de variables
  • Filtres de variables d'événements
  • Jointures de variable d'événement

Déclarations de variables

Pour les déclarations de variable, utilisez la syntaxe suivante:

  • <EVENT_FIELD> = <VAR>
  • <VAR> = <EVENT_FIELD>

Les deux sont équivalents, comme illustré dans les exemples suivants:

  • $e.source.hostname = $hostname
  • $userid = $e.principal.user.userid

Cette déclaration indique que cette variable représente le champ spécifié pour la variable d'événement. Lorsque le champ d'événement est un champ répété, la variable de correspondance peut représenter n'importe quelle valeur du tableau. Il est également possible d'attribuer plusieurs champs d'événement à une même variable de correspondance ou d'espace réservé. Il s'agit d'une condition de jointure transitive.

Par exemple, cette agrégation :

  • $e1.source.ip = $ip
  • $e2.target.ip = $ip

Équivaut à:

  • $e1.source.ip = $ip
  • $e1.source.ip = $e2.target.ip

Lorsqu'une variable est utilisée, elle doit être déclarée via la déclaration de variable. Si une variable est utilisée sans aucune déclaration, elle est considérée comme une erreur de compilation.

Filtres de variables d'événements

Une expression booléenne qui agit sur une seule variable d'événement est considérée comme un filtre.

Jointures de variable d'événement

Toutes les variables d'événement utilisées dans la règle doivent être jointes aux autres variables d'événement de l'une des manières suivantes:

  • Directement par le biais d'une comparaison d'égalité entre les champs d'événement des deux variables d'événement associées, par exemple: $e1.field = $e2.field. L'expression ne doit pas inclure d'éléments arithmétiques.

  • Indirectement, via une jointure transitive n'impliquant qu'un champ d'événement (voir la déclaration de variable pour une définition d'une "jointure transitive"). L'expression ne doit pas inclure d'éléments arithmétiques.

Par exemple, en supposant que $e1, $e2 et $e3 sont utilisés dans la règle, les sections events suivantes sont valides.

events:
  $e1.principal.hostname = $e2.src.hostname // $e1 joins with $e2
  $e2.principal.ip = $e3.src.ip // $e2 joins with $e3
events:
  // $e1 joins with $e2 via function to event comparison
  re.capture($e1.src.hostname, ".*") = $e2.target.hostname
events:
  // $e1 joins with $e2 via an `or` expression
  $e1.principal.hostname = $e2.src.hostname
  or $e1.principal.hostname = $e2.target.hostname
  or $e1.principal.hostname = $e2.principal.hostname
events:
  // all of $e1, $e2 and $e3 are transitively joined via the placeholder variable $ip
  $e1.src.ip = $ip
  $e2.target.ip = $ip
  $e3.about.ip = $ip
events:
  // $e1 and $e2 are transitively joined via function to event comparison
  re.capture($e2.principal.application, ".*") = $app
  $e1.principal.hostname = $app

Toutefois, voici des exemples de sections events non valides.

events:
  // Event to arithmetic comparison is an invalid join condition for $e1 and $e2.
  $e1.principal.port = $e2.src.port + 1
events:
  $e1.src.ip = $ip
  $e2.target.ip = $ip
  $e3.about.ip = "192.1.2.0" //$e3 is not joined with $e1 or $e2.
events:
  $e1.src.port = $port

  // Arithmetic to placeholder comparison is an invalid transitive join condition.
  $e2.principal.port + 800 = $port

Syntaxe de la section de correspondance

Dans la section match, répertoriez les variables de correspondance pour les événements de groupe avant de vérifier les conditions de correspondance. Ces champs sont renvoyés à chaque correspondance.

  • Spécifiez ce que chaque variable de correspondance représente dans la section events.
  • Spécifiez la durée à utiliser pour mettre en corrélation les événements après le mot clé over. Les événements en dehors de cette durée sont ignorés.
  • Utilisez la syntaxe suivante pour spécifier la durée: <number><m/h/d>

    m/h/d désigne respectivement les minutes, les heures et les jours.

  • La durée minimale que vous pouvez spécifier est d'une minute.

  • La durée maximale que vous pouvez spécifier est de 48 heures.

Voici un exemple de match valide:

$var1, $var2 over 5m

Cette instruction renvoie $var1 et $var2 (définis dans la section events) lorsque la règle trouve une correspondance. La durée spécifiée est de 5 minutes. Les événements à plus de cinq minutes d'intervalle ne sont pas corrélés et sont donc ignorés par la règle.

Voici un autre exemple de section match valide:

$user over 1h

Cette instruction renvoie $user lorsque la règle trouve une correspondance. La période spécifiée est d'une heure. Les événements espacés de plus d'une heure ne sont pas corrélés. La règle ne considère pas qu'il s'agit d'une détection.

Voici un autre exemple de section match valide:

$source_ip, $target_ip, $hostname over 2m

Cette instruction renvoie $source_ip, $target_ip et $hostname lorsque la règle trouve une correspondance. La période spécifiée est de deux minutes. Les événements espacés de plus de deux minutes ne sont pas corrélés. La règle ne considère pas qu'il s'agit d'une détection.

Les exemples suivants illustrent des sections match non valides:

  • var1, var2 over 5m // invalid variable name
  • $user 1h // missing keyword

Gestion de la valeur nulle dans la section de correspondance

Le moteur de règles filtre implicitement les valeurs zéro pour tous les espaces réservés utilisés dans la section de correspondance ("" pour la chaîne, 0 pour les nombres, false pour les valeurs booléennes, la valeur en position 0 pour les types énumérés). L'exemple suivant illustre les règles qui filtrent les valeurs nulles.

rule ZeroValuePlaceholderExample {
  meta:
  events:
    // Because $host is used in the match section, the rule 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 section,
    // 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 règles ne filtrent pas implicitement les valeurs zéro des espaces réservés utilisés dans la section de correspondance. L'exemple suivant illustre les règles qui filtrent les valeurs nulles:

rule ZeroValueFunctionPlaceholder {
  meta:
  events:
    // Even though $ph is used in the match section, there is no
    // implicit filtering of zero values for $ph, because $ph is assigned to a function.
    $ph = re.capture($e.principal.hostname, "some-regex")

  match:
    $ph over 5m

  condition:
    $e
}

Pour désactiver le filtrage implicite des valeurs nulles, vous pouvez utiliser l'option allow_zero_values dans la section des options.

Fenêtre de saut

Par défaut, les règles YARA-L 2.0 avec une section de correspondance sont évaluées à l'aide de fenêtres de saut. La période d'exécution de la règle est divisée en un ensemble de fenêtres de saut qui se chevauchent, chacune d'entre elles ayant la durée spécifiée dans la section match. Les événements sont ensuite corrélés dans chaque fenêtre de saut.

Par exemple, pour une règle exécutée sur une période [1:00, 2:00] avec une section match au-dessus de 30m, un ensemble possible de fenêtres de saut qui se chevauchent et qui pourraient être générés est [1:00, 1:30], [1:03, 1:33] et [1:06, 1:36]. Ces fenêtres permettent de mettre en corrélation plusieurs événements.

Fenêtre coulissante

L'utilisation de fenêtres de saut n'est pas un moyen efficace de rechercher des événements qui se produisent dans un ordre spécifique (par exemple, e1 se produit jusqu'à 2 minutes après e2). Une occurrence de l'événement e1 et une occurrence de l'événement e2 ne sont corrélées que si elles se situent dans la même fenêtre de saut générée.

Les fenêtres glissantes sont un moyen plus efficace de rechercher ce type de séquences d'événements. Les fenêtres glissantes dont la durée est spécifiée dans la section match sont générées lorsqu'elles commencent ou se terminent par une variable d'événement de tableau croisé dynamique spécifiée. Les événements sont ensuite corrélés dans chaque fenêtre glissante. Cela permet de rechercher des événements qui se produisent dans un ordre spécifique (par exemple, e1 se produit dans les deux minutes de e2). Une occurrence de l'événement e1 et une occurrence de l'événement e2 sont corrélées si l'événement e1 se produit pendant la durée de la fenêtre glissante après l'événement e2.

Spécifiez des fenêtres glissantes dans la section match d'une règle, comme suit:

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

La variable d'événement de tableau croisé dynamique est la variable d'événement sur laquelle reposent les fenêtres glissantes. Si vous utilisez le mot clé before, des fenêtres glissantes sont générées et se terminent par chaque occurrence de l'événement de tableau croisé dynamique. Si le mot clé after est utilisé, les fenêtres glissantes sont générées à partir de chaque occurrence de l'événement de tableau croisé dynamique.

Voici des exemples d'utilisation de fenêtre glissante valide:

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

Voir un exemple de règle de fenêtre glissante.

Google recommande de ne pas utiliser de fenêtres glissantes pour les règles concernant un seul événement, car elles sont conçues pour détecter plusieurs événements. Si l'une de vos règles appartient à cette catégorie, Google recommande l'une des solutions suivantes:

  • Convertissez la règle pour utiliser plusieurs variables d'événement et mettez à jour la section de condition si la règle nécessite plusieurs occurrences de l'événement.
    • Vous pouvez éventuellement 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
  • Supprimez la fenêtre glissante.

Syntaxe de la section du résultat

Dans la section outcome, vous pouvez définir jusqu'à 20 variables de résultat, avec des noms arbitraires. Ces résultats seront stockés dans les détections générées par la règle. Chaque détection peut avoir des valeurs de résultats différentes.

Le nom du résultat, $risk_score, est spécial. Vous pouvez éventuellement définir un résultat avec ce nom. Si vous le faites, il doit s'agir d'un entier ou d'un nombre à virgule flottante. S'il est renseigné, le champ risk_score s'affiche dans la vue Enterprise Insights pour les alertes provenant de la détection de règles.

Si vous n'incluez pas de variable $risk_score dans la section de résultat d'une règle, l'une des valeurs par défaut suivantes est définie:

  • Si la règle est configurée pour générer une alerte, $risk_score est défini sur 40.
  • Si la règle n'est pas configurée pour générer une alerte, $risk_score est défini sur 15.

La valeur de $risk_score est stockée dans le champ UDM security_result.risk_score.

Types de données de la variable de résultat

Chaque variable de résultat peut avoir un type de données différent, déterminé par l'expression utilisée pour le calculer. Les types de données de résultat suivants sont acceptés:

  • entier
  • flottants
  • chaîne
  • listes d'entiers
  • listes de flottants
  • listes de chaînes

Logique conditionnelle

Vous pouvez utiliser une logique conditionnelle pour calculer la valeur d'un résultat. Les conditions sont spécifiées à l'aide du modèle de syntaxe suivant:

if(BOOL_CLAUSE, THEN_CLAUSE)
if(BOOL_CLAUSE, THEN_CLAUSE, ELSE_CLAUSE)

Vous pouvez lire une expression conditionnelle comme suit : "if BOOL_CLAUSE est vrai, puis renvoie THEN_CLAUSE, sinon renvoie ELSE_CLAUSE".

BOOL_CLAUSE doit renvoyer une valeur booléenne. Une expression BOOL_CLAUSE prend une forme semblable à celle des expressions de la section events. Il peut par exemple contenir les éléments suivants:

  • Noms de champs UDM avec opérateur de comparaison. Exemple:

    if($context.graph.entity.user.title = "Vendor", 100, 0)

  • variable d'espace réservé définie dans la section events, par exemple:

    if($severity = "HIGH", 100, 0)

  • une autre variable de résultat définie dans la section outcome, par exemple:

    if($risk_score > 20, "HIGH", "LOW")

  • qui renvoient une valeur booléenne, par exemple:

    if(re.regex($e.network.email.from, `.*altostrat.com`), 100, 0)

  • rechercher dans une liste de référence, par exemple:

    if($u.principal.hostname in %my_reference_list_name, 100, 0)

  • d'agrégation, par exemple:

    if(count($login.metadata.event_timestamp.seconds) > 5, 100, 0)

Les clauses THEN_CLAUSE et ELSE_CLAUSE doivent être du même type. Nous acceptons les entiers, les nombres à virgule flottante et les chaînes.

Vous pouvez omettre la clause ELSE_CLAUSE si le type de données est un entier ou un nombre à virgule flottante. En cas d'omission, la clause ELSE_CLAUSE prend la valeur 0. Exemple :

`if($e.field = "a", 5)` is equivalent to `if($e.field = "a", 5, 0)`

Vous devez indiquer la clause ELSE_CLAUSE si le type de données est une chaîne ou si THEN_CLAUSE est une variable d'espace réservé ou une variable de résultat.

Opérations mathématiques

Vous pouvez utiliser des opérations mathématiques pour calculer un type de données entier ou flottant dans les sections outcome et events d'une règle. Chronicle accepte l'addition, la soustraction, la multiplication, la division et le module en tant qu'opérateurs de niveau supérieur dans un calcul.

L'extrait de code suivant est un exemple de calcul dans la section outcome:

outcome:
  $risk_score = max(100 + if($severity = "HIGH", 10, 5) - if($severity = "LOW", 20, 0))

Les opérations mathématiques sont autorisées sur les types d'opérandes suivants, à condition que chaque opérande et l'ensemble de l'expression arithmétique soient correctement agrégés (voir la section Agrégations):

  • Champs d'événement numériques
  • Variables d'espace réservé numériques définies dans la section events
  • Variables de résultat numériques définies dans la section outcome
  • Fonctions renvoyant des entiers ou des floats
  • Agrégations renvoyant des entiers ou des valeurs flottantes

Le module n'est pas autorisé sur des flottants.

Variables d'espace réservé dans les résultats

Lors du calcul des variables de résultat, vous pouvez utiliser des variables d'espace réservé définies dans la section "Événements" de votre règle. Dans cet exemple, supposons que $email_sent_bytes a été défini dans la section "Événements" de la règle:

Exemple pour un seul événement:

// No match section, so this is a single-event rule.

outcome:
  // Use placeholder directly as an outcome value.
  $my_outcome = $email_sent_bytes

  // Use placeholder in a conditional.
  $other_outcome = if($file_size > 1024, "SEVERE", "MODERATE")

condition:
  $e

Exemple pour plusieurs événements:

match:
  // This is a multi event rule with a match section.
  $hostname over 5m

outcome:
  // Use placeholder directly in an aggregation function.
  $max_email_size = max($email_sent_bytes)

  // Use placeholder in a mathematical computation.
  $total_bytes_exfiltrated = sum(
    1024
    + $email_sent_bytes
    + $file_event.principal.file.size
  )

condition:
  $email_event and $file_event

Variables de résultat dans les expressions d'attribution de résultats

Les variables de résultat peuvent être utilisées pour dériver d'autres variables de résultat, semblables aux variables d'espace réservé définies dans la section events. Vous pouvez faire référence à une variable de résultat dans l'attribution d'une autre variable de résultat avec un jeton $ suivi du nom de la variable. Les variables de résultat doivent être définies avant de pouvoir être référencées dans le texte de la règle. Lorsqu'elles sont utilisées dans une expression d'attribution, les variables de résultat ne doivent pas être agrégées (consultez la section Agrégations).

Dans l'exemple suivant, la variable de résultat $risk_score extrait sa valeur de la variable de résultat $event_count:

Exemple pour plusieurs événements:

match:
  // This is a multi event rule with a match section.
  $hostname over 5m

outcome:
  // Aggregates all timestamp on login events in the 5 minute match window.
  $event_count = count($login.metadata.event_timestamp.seconds)

  // $event_count cannot be aggregated again.
  $risk_score = if($event_count > 5, "SEVERE", "MODERATE")

  // This is the equivalent of the 2 outcomes above combined.
  $risk_score2 = if(count($login.metadata.event_timestamp.seconds) > 5, "SEVERE", "MODERATE")

condition:
  $e

Les variables de résultat peuvent être utilisées dans n'importe quel type d'expression à droite d'une attribution de résultat, sauf dans les expressions suivantes:

  • Agrégations
  • Appels de fonctions Arrays.length()
  • Avec les modificateurs any ou all

Agrégations

Les champs d'événements répétés sont des valeurs non scalaires. C'est-à-dire qu'une seule variable pointe vers plusieurs valeurs. Par exemple, la variable de champ d'événement $e.target.ip est un champ répété et peut comporter zéro, une ou plusieurs valeurs IP. Il s'agit d'une valeur non scalaire. La variable de champ d'événement $e.principal.hostname n'est pas un champ répété et ne comporte qu'une seule valeur (c'est-à-dire une valeur scalaire).

De même, les champs d'événements non répétés et les champs d'événements répétés utilisés dans la section de résultat d'une règle avec une fenêtre de correspondance sont des valeurs non scalaires. Par exemple, la règle suivante regroupe les événements à l'aide d'une section de correspondance et fait référence à un champ d'événement non répété dans la section des résultats:

rule OutcomeAndMatchWindow{
  ...
  match:
    $userid over 5m
  outcome:
    $hostnames = array($e.principal.hostname)
  ...
}

Toute fenêtre de 5 minutes sur laquelle la règle s'exécute peut contenir zéro, un ou plusieurs événements. La section de résultat s'applique à tous les événements d'une fenêtre de correspondance. Toute variable de champ d'événement référencée dans la section de résultat peut désigner zéro, une ou plusieurs valeurs du champ pour chaque événement de la fenêtre de correspondance. Dans la règle précédente, si une fenêtre de cinq minutes contient cinq événements $e, $e.principal.hostname dans la section des résultats pointe vers cinq noms d'hôte différents. La variable de champ d'événement $e.principal.hostname est donc une valeur non scalaire dans la section de résultat de cette règle.

Étant donné que les variables de résultat doivent toujours générer une seule valeur scalaire, toute valeur non scalaire dont dépend une attribution de résultat doit être agrégée pour générer une seule valeur scalaire. Dans une section de résultats, les éléments suivants sont des valeurs non scalaires et doivent être agrégées:

  • Champs d'événement (répétés ou non) lorsque la règle utilise une section de correspondance
  • Espaces réservés d'événements (répétés ou non) lorsque la règle utilise une section de correspondance
  • Champs d'événements répétés lorsque la règle n'utilise pas de section de correspondance
  • Espaces réservés d'événements répétés lorsque la règle n'utilise pas de section de correspondance

Les champs d'événement scalaires, les espaces réservés d'événements scalaires et les constantes peuvent être encapsulés dans une agrégation dans une règle qui n'utilise pas de section de correspondance. Cependant, la plupart des agrégations génèrent la valeur encapsulée et ne sont donc pas nécessaires. L'exception concerne l'agrégation array(), qui peut être utilisée pour convertir une valeur scalaire en tableau.

Les variables de résultat sont traitées comme des agrégations: elles ne doivent pas être réagrégées lorsqu'elles sont mentionnées dans une autre attribution de résultat.

Vous pouvez utiliser les fonctions d'agrégation suivantes:

  • max(): renvoie le maximum parmi toutes les valeurs possibles. Ne fonctionne qu'avec les nombres entiers et flottants.
  • min(): renvoie le minimum parmi toutes les valeurs possibles. Ne fonctionne qu'avec les nombres entiers et flottants.
  • sum(): génère la somme de toutes les valeurs possibles. Ne fonctionne qu'avec les nombres entiers et flottants.
  • count_distinct(): collecte toutes les valeurs possibles, puis génère le nombre distinct de valeurs possibles.
  • count(): se comporte comme count_distinct(), mais renvoie un nombre non distinct de valeurs possibles.
  • array_distinct(): collecte toutes les valeurs distinctes possibles, puis génère une liste de ces valeurs. La liste de valeurs distinctes sera tronquée à 25 éléments aléatoires. La déduplication pour obtenir une liste distincte est appliquée en premier, puis la troncation est appliquée.
  • array(): se comporte comme array_distinct(), mais renvoie une liste non distincte de valeurs. Il tronque également la liste de valeurs à 25 éléments aléatoires.

La fonction d'agrégation est importante lorsqu'une règle inclut une section condition spécifiant que plusieurs événements doivent exister, car elle s'applique à tous les événements qui ont généré la détection.

Par exemple, si vos sections outcome et condition contiennent:

outcome:
  $asset_id_count = count($event.principal.asset_id)
  $asset_id_distinct_count = count_distinct($event.principal.asset_id)

  $asset_id_list = array($event.principal.asset_id)
  $asset_id_distinct_list = array_distinct($event.principal.asset_id)

condition:
  #event > 1

Étant donné que la section "Condition" nécessite plusieurs event pour chaque détection, les fonctions d'agrégation opèrent sur plusieurs événements. Supposons que les événements suivants aient généré une détection:

event:
  // UDM event 1
  asset_id="asset-a"

event:
  // UDM event 2
  asset_id="asset-b"

event:
  // UDM event 3
  asset_id="asset-b"

Les valeurs de vos résultats seront alors:

  • $asset_id_count = 3
  • $asset_id_distinct_count = 2
  • $asset_id_list = ["asset-a", "asset-b", "asset-b"]
  • $asset_id_distinct_list = ["asset-a", "asset-b"]

Points à retenir lorsque vous utilisez la section des résultats:

Autres remarques et restrictions:

  • La section outcome ne peut pas référencer une nouvelle variable d'espace réservé qui n'était pas déjà définie dans la section events ou outcome.
  • La section outcome ne peut pas utiliser de variables d'événement qui n'ont pas été définies dans la section events.
  • La section outcome peut utiliser un champ d'événement qui n'a pas été utilisé dans la section events, étant donné que la variable d'événement à laquelle appartient le champ d'événement était déjà définie dans la section events.
  • La section outcome ne peut mettre en corrélation que les variables d'événement qui ont déjà été corrélées dans la section events. Des corrélations se produisent lorsque deux champs d'événement de variables d'événement différentes sont égal.

Vous trouverez un exemple en utilisant la section "Résultats" de la page Présentation de YARA-L 2.0. Pour en savoir plus sur la redondance de détection avec la section sur les résultats, consultez Créer des analyses contextuelles.

Syntaxe de la section "Condition"

  • spécifier une condition de correspondance pour les événements et les espaces réservés définis dans la section events ; Pour en savoir plus, consultez la section suivante, Expressions conditionnelles au niveau des événements et des espaces réservés.
  • (Facultatif) Utilisez le mot clé and pour spécifier une condition de correspondance à l'aide des variables de résultat définies dans la section outcome. Pour en savoir plus, consultez la section suivante, Expressions conditionnelles concernant le résultat.

Caractère de décompte

Le caractère # est un caractère spécial dans la section condition. S'il est utilisé avant tout nom d'événement ou de variable d'espace réservé, il représente le nombre d'événements ou de valeurs distincts qui remplissent toutes les conditions de la section events.

Par exemple, #c > 1 signifie que la variable c doit apparaître plus d'une fois.

Caractère de valeur

Le caractère $ est un caractère spécial dans la section condition. Si elle est utilisée avant un nom de variable de résultat, elle représente la valeur de ce résultat.

S'il est utilisé avant tout nom d'événement ou de variable d'espace réservé (par exemple, $event), il représente #event > 0.

Expressions conditionnelles relatives aux événements et aux espaces réservés

Listez ici les prédicats de condition pour les événements et les variables d'espace réservé, joints au mot clé and ou or. Le mot clé and peut être utilisé entre n'importe quelle condition, mais le mot clé or ne peut être utilisé que lorsque la règle ne comporte qu'une seule variable d'événement.

Voici un exemple valide d'utilisation de or entre deux espaces réservés dans le même événement:

rule ValidConditionOr {
  meta:
  events:
      $e.metadata.event_type = "NETWORK_CONNECTION"

      // Note that all placeholders use the same event variable.
      $ph = $e.principal.user.userid  // Define a placeholder variable to put in match section.
      $ph2 = $e.principal.ip  // Define a second placeholder variable to put in condition section.
      $ph3 = $e.principal.hostname  // Define a third placeholder variable to put in condition section.

  match:
    $ph over 5m

  condition:
    $ph2 or $ph3
}

Exemple non valide d'utilisation de or entre deux conditions sur des événements différents:

rule InvalidConditionOr {
  meta:
  events:
      $e.metadata.event_type = "NETWORK_CONNECTION"
      $e2.graph.metadata.entity_type = "FILE"
      $e2.graph.entity.hostname  = $e.principal.hostname

      $ph = $e.principal.user.userid  // Define a placeholder variable to put in match section.

  match:
    $ph over 5m

  condition:
    $e or $e2 // This line will cause an error because there is an or between events.
}

Conditions limitées et illimitées

Les conditions suivantes sont limitées. Ils forcent l'existence de la variable d'événement associée, ce qui signifie qu'au moins une occurrence de l'événement doit apparaître dans toute détection.

  • $var // equivalent to #var > 0
  • #var > n // where n >= 0
  • #var >= m // where m > 0

Les conditions suivantes sont illimitées. Ils autorisent l'absence de variable d'événement associée, ce qui signifie qu'il est possible qu'aucune occurrence de l'événement n'apparaisse dans une détection et que toute référence à des champs de la variable d'événement génère une valeur nulle. Des conditions illimitées peuvent être utilisées pour détecter l'absence d'événement sur une période donnée. (par exemple, une menace sans événement d'atténuation dans un délai de 10 minutes). Les règles utilisant des conditions illimitées sont appelées "règles de non-existence".

  • !$var // equivalent to #var = 0
  • #var >= 0
  • #var < n // where n > 0
  • #var <= m // where m >= 0

Exigences concernant la non-existence

Pour qu'une règle inexistante puisse être compilée, elle doit remplir les conditions suivantes:

  1. Au moins un événement UDM doit avoir une condition limitée (en d'autres termes, au moins un événement UDM doit exister).
  2. Si un espace réservé a une condition illimitée, il doit être associé à au moins un événement UDM limité.
  3. Si une entité possède une condition illimitée, elle doit être associée à au moins un événement UDM limité.

Prenons l'exemple de la règle suivante, sans la section "Condition" :

rule NonexistenceExample {
  meta:
  events:
      $u1.metadata.event_type = "NETWORK_CONNECTION" // $u1 is a UDM event.
      $u2.metadata.event_type = "NETWORK_CONNECTION" // $u2 is a UDM event.
      $e1.graph.metadata.entity_type = "FILE"        // $e1 is an Entity.
      $e2.graph.metadata.entity_type = "FILE"        // $e2 is an Entity.

      $user = $u1.principal.user.userid // Match variable is required for Multi-Event Rule.

      // Placeholder Associations:
      //   u1        u2
      //   |  \    /
      // port   ip
      //   |       \
      //   e1        e2
      $u1.target.port = $port
      $e1.graph.entity.port = $port
      $u1.principal.ip = $ip
      $u2.target.ip = $ip
      $e2.graph.entity.ip = $ip

      // UDM-Entity Associations:
      // u1 - u2
      // |  \  |
      // e1   e2
      $u1.metadata.event_type = $u2.metadata.event_type
      $e1.graph.entity.hostname = $u1.principal.hostname
      $e2.graph.entity.hostname = $u1.target.hostname
      $e2.graph.entity.hostname = $u2.principal.hostname

  match:
    $user over 5m

  condition:
      <condition_section>
}

Voici des exemples valides pour <condition_section>:

  • $u1 and !$u2 and $e1 and $e2
    • Tous les événements et entités UDM sont présents dans la section "Condition".
    • Au moins un événement UDM est limité.
  • $u1 and !$u2 and $e1 and !$e2
    • $e2 est illimitée, ce qui est autorisé, car elle est associée à $u1, qui est limité. Si $e2 n'était pas associé à $u1, ce champ ne serait pas valide.
  • #port > 50 and #ip = 0
    • La section "Condition" ne contient aucun événement ni aucune entité UDM. Toutefois, les espaces réservés présents couvrent tous les événements et entités UDM.
    • $ip est attribué à la fois à $u1 et à $u2, et #ip = 0 est une condition illimitée. Cependant, les conditions limitées sont plus fortes que les conditions illimitées. Étant donné que $port est attribué à $u1 et que #port > 50 est une condition limitée, $u1 est toujours limité.

Voici des exemples non valides pour l'élément <condition_section>:

  • $u1 and $e1
    • Chaque événement et entité UDM apparaissant dans la section "Événements" doivent apparaître dans la section "Condition" (ou un espace réservé doit être attribué à chaque événement qui apparaît dans la section "Condition").
  • $u1, $u2, $e1, $u2, #port > 50
    • Les virgules ne sont pas autorisées en tant que séparateurs de conditions.
  • !$u1 and !$u2 and $e1 and $e2
    • Non-respect de la première exigence selon laquelle au moins un événement UDM est limité.
  • ($u1 or #port < 50) and $u2 and $e1 and $e2
    • Le mot clé or n'est pas compatible avec les conditions illimitées.
  • ($u1 or $u2) and $e1 and $e2
    • Le mot clé or n'est pas compatible avec les différentes variables d'événement.
  • not $u1 and $u2 and $e1 and $e2
    • Le mot clé not n'est pas autorisé pour les conditions d'événement et d'espace réservé.
  • #port < 50 and #ip = 0
    • Les espaces réservés présents couvrent tous les événements et entités UDM ; cependant, toutes les conditions sont illimitées. Cela signifie qu'aucun événement UDM n'est limité, ce qui entraîne l'échec de la compilation de la règle.

Expressions conditionnelles liées au résultat

Listez ici les prédicats de condition pour les variables de résultat, joints au mot clé and ou or, ou précédés du mot clé not.

Spécifiez les conditions de résultat différemment en fonction du type de variable de résultat:

  • integer: effectuez une comparaison par rapport à un littéral entier avec les opérateurs =, >, >=, <, <=, !=, par exemple:

    $risk_score > 10

  • float: effectuez une comparaison par rapport à un littéral de type float avec les opérateurs =, >, >=, <, <=, !=, par exemple:

    $risk_score <= 5.5

  • chaîne: comparaison par rapport à un littéral de chaîne contenant soit =, soit !=, par exemple:

    $severity = "HIGH"

  • liste d'entiers ou de tableaux: spécifiez la condition à l'aide de la fonction arrays.contains, par exemple:

    arrays.contains($event_ids, "id_1234")

Classification des règles

Si vous spécifiez un résultat conditionnel dans une règle comportant une section de correspondance, la règle sera classée en tant que règle multi-événement pour le quota de règles. Pour en savoir plus sur la classification d'un seul et de plusieurs événements, consultez les articles sur les règles relatives à un seul événement et aux règles relatives à plusieurs événements.

Syntaxe de la section "Options"

Dans la section options, vous pouvez spécifier les options de la règle. Voici un exemple de spécification de la section des options:

rule RuleOptionsExample {
  // Other rule sections

  options:
    allow_zero_values = true
}

Vous pouvez spécifier des options à l'aide de la syntaxe key = value, où key doit être un nom d'option prédéfini et value doit être une valeur valide pour l'option, comme spécifié pour les options suivantes:

allow_zero_values

Les valeurs valides pour cette option sont true et false, qui déterminent si cette option est activée ou non. La valeur par défaut est false. Cette option est désactivée si elle n'est pas spécifiée dans la règle.

Pour activer ce paramètre, ajoutez le code suivant à la section des options de votre règle: allow_zero_values = true. Cela empêchera la règle de filtrer implicitement les valeurs nulles des espaces réservés utilisés dans la section de correspondance, comme décrit dans Gestion des valeurs nulles dans la section de correspondance.

Expressions booléennes

Les expressions booléennes sont des expressions de type booléen.

Comparaisons

Pour qu'une expression binaire simple puisse être utilisée comme condition, utilisez la syntaxe suivante:

  • <EXPR> <OP> <EXPR>

L'expression peut être un champ d'événement, une variable, un littéral ou une expression de fonction.

Exemple :

  • $e.source.hostname = "host1234"
  • $e.source.port < 1024
  • 1024 < $e.source.port
  • $e1.source.hostname != $e2.target.hostname
  • $e1.metadata.collected_timestamp.seconds > $e2.metadata.collected_timestamp.seconds
  • $port >= 25
  • $host = $e2.target.hostname
  • "google-test" = strings.concat($e.principal.hostname, "-test")
  • "email@google.org" = re.replace($e.network.email.from, "com", "org")

Si les deux côtés sont des littéraux, cela est considéré comme une erreur de compilation.

Fonctions

Certaines expressions de fonction renvoient une valeur booléenne, qui peut être utilisée comme prédicat individuel dans la section events. Ces fonctions sont les suivantes:

  • re.regex()
  • net.ip_in_range_cidr()

Exemple :

  • re.regex($e.principal.hostname, `.*\.google\.com`)
  • net.ip_in_range_cidr($e.principal.ip, "192.0.2.0/24")

Référencer des expressions de liste

Vous pouvez utiliser des listes de référence dans la section "Événements". Pour en savoir plus, consultez la section Listes de références.

Expressions logiques

Vous pouvez utiliser les opérateurs logiques and et logiques or dans la section events, comme indiqué dans les exemples suivants:

  • $e.metadata.event_type = "NETWORK_DNS" or $e.metadata.event_type = "NETWORK_DHCP"
  • ($e.metadata.event_type = "NETWORK_DNS" and $e.principal.ip = "192.0.2.12") or ($e.metadata.event_type = "NETWORK_DHCP" and $e.principal.mac = "AB:CD:01:10:EF:22")
  • not $e.metadata.event_type = "NETWORK_DNS"

Par défaut, l'ordre de priorité (du plus élevé au plus bas) est not, and, or.

Par exemple, "a ou b et c" est évalué comme "a ou (b et c)" lorsque les opérateurs or et and sont définis explicitement dans l'expression.

Dans la section events, les prédicats sont joints à l'aide de l'opérateur and si aucun opérateur n'est défini explicitement.

L'ordre d'évaluation peut être différent si l'opérateur and est implicite dans l'expression.

Prenons l'exemple des expressions de comparaison suivantes, où or est défini explicitement. L'opérateur and est implicite.

$e1.field = "bat"
or $e1.field = "baz"
$e2.field = "bar"

Cet exemple est interprété comme suit:

($e1.field = "bat" or $e1.field = "baz")
and ($e2.field = "bar")

Comme or est défini explicitement, les prédicats qui entourent or sont regroupés et évalués en premier. Le dernier prédicat, $e2.field = "bar", est joint implicitement à l'aide de and. L'ordre des évaluations change.

Types énumérés

Vous pouvez utiliser les opérateurs avec des types énumérés. Il peut être appliqué aux règles pour simplifier et optimiser les performances (utilisez un opérateur au lieu de listes de référence).

Dans l'exemple suivant, "USER_UNCATEGORIZED" et "USER_RESOURCE_DELETION" correspondent à 15 000 et 15014. La règle recherchera donc tous les événements répertoriés:

$e.metadata.event_type >= "USER_CATEGORIZED" and $e.metadata.event_type <= "USER_RESOURCE_DELETION"

Liste des événements:

  • USER_RESOURCE_DELETION
  • USER_RESOURCE_UPDATE_CONTENT
  • USER_RESOURCE_UPDATE_PERMISSIONS
  • USER_STATS
  • USER_UNCATEGORIZED

Modificateur Nocase

Lorsque vous disposez d'une expression de comparaison entre des valeurs de chaîne ou une expression régulière, vous pouvez ajouter "nocase" à la fin de l'expression pour ignorer la casse.

  • $e.principal.hostname != "http-server" nocase
  • $e1.principal.hostname = $e2.target.hostname nocase
  • $e.principal.hostname = /dns-server-[0-9]+/ nocase
  • re.regex($e.target.hostname, `client-[0-9]+`) nocase

Cette option ne peut pas être utilisée lorsqu'un type de champ est une valeur énumérée. Les exemples suivants ne sont pas valides et génèrent des erreurs de compilation:

  • $e.metadata.event_type = "NETWORK_DNS" nocase
  • $e.network.ip_protocol = "TCP" nocase

Champs répétés

Dans l'UDM (Unified Data Model), certains champs sont marqués comme répétés, ce qui indique qu'il s'agit de listes de valeurs ou d'autres types de messages.

Champs répétés et expressions booléennes

Il existe deux types d'expressions booléennes qui agissent sur les champs répétés:

  1. Modification
  2. Non modifié

Prenons l'exemple d'un événement suivant:

event_original {
  principal {
    // ip is a repeated field
    ip: [ "192.0.2.1", "192.0.2.2", "192.0.2.3" ]

    hostname: "host"
  }
}

Expressions modifiées

Les sections suivantes décrivent l'objectif et l'utilisation des modificateurs any et all dans les expressions.

toutes

Si n'importe quel élément du champ répété remplit la condition, l'événement dans son ensemble la remplit.

  • event_original répond aux exigences de any $e.principal.ip = "192.0.2.1".
  • event_original échoue any $e.repeated_field.field_a = "9.9.9.9.
tous

Si tous les éléments du champ répété remplissent la condition, l'événement dans son ensemble remplit la condition.

  • event_original répond aux exigences de net.ip_in_range_cidr(all $e.principal.ip, "192.0.2.0/8").
  • event_original échoue all $e.principal.ip = "192.0.2.2".

Lorsque vous écrivez une condition avec any ou all, sachez que la négociation de la condition avec not peut ne pas avoir la même signification que l'utilisation de l'opérateur d'inverse.

Exemple :

  • not all $e.principal.ip = "192.168.12.16" vérifie si toutes les adresses IP ne correspondent pas à 192.168.12.16, ce qui signifie que la règle vérifie si au moins une adresse IP ne correspond pas à 192.168.12.16.
  • all $e.principal.ip != "192.168.12.16" vérifie si toutes les adresses IP ne correspondent pas à 192.168.12.16, ce qui signifie que la règle vérifie qu'aucune adresse IP ne correspond à 192.168.12.16.

Contraintes:

  • Les opérateurs any et all ne sont compatibles qu'avec les champs répétés (pas avec les champs scalaires).
  • any et all ne peuvent pas être utilisés pour joindre deux champs répétés. Par exemple, any $e1.principal.ip = $e2.principal.ip n'est pas valide.
  • Les opérateurs any et all ne sont pas compatibles avec l'expression de la liste de références.

Expressions non modifiées

Avec les expressions non modifiées, chaque élément du champ répété est traité individuellement. Si le champ répété d'un événement contient n éléments, la règle est appliquée à n copies de l'événement, où chaque copie comporte l'un des éléments du champ répété. Ces copies sont temporaires et ne sont pas stockées.

La règle est appliquée aux copies suivantes:

copie de l'événement principal.ip principal.hostname
event_copy_1 "192.0.2.1" "hôte"
event_copy_2 "192.0.2.2" "hôte"
event_copy_3 "192.0.2.3" "hôte"

Si n'importe quelle copie d'événement satisfait toutes les conditions non modifiées du champ répété, l'événement dans son ensemble remplit toutes les conditions. Cela signifie que si vous avez plusieurs conditions sur un champ répété, la copie de l'événement doit répondre à toutes ces conditions. Les exemples de règles suivants utilisent l'ensemble de données précédent pour illustrer ce comportement.

La règle suivante renvoie une correspondance lorsqu'elle est exécutée sur l'exemple d'ensemble de données event_original, car event_copy_1 répond à tous les prédicats d'événements:

rule repeated_field_1 {
  meta:
  events:
    net.ip_in_range_cidr($e.principal.ip, "192.0.2.0/8") // Checks if IP address matches 192.x.x.x
    $e.principal.ip = "192.0.2.1"
  condition:
    $e
}

La règle suivante ne renvoie pas de correspondance lorsqu'elle est exécutée sur l'exemple d'ensemble de données event_original, car aucune copie d'événement dans $e.principal.ip ne répond à tous les prédicats d'événements.

rule repeated_field_2 {
  meta:
  events:
    $e.principal.ip = "192.0.2.1"
    $e.principal.ip = "192.0.2.2"
  condition:
    $e
}

Les expressions modifiées sur des champs répétés sont compatibles avec les expressions non modifiées des champs répétés, car la liste d'éléments est la même pour chaque copie d'événement. Prenons la règle suivante:

rule repeated_field_3 {
  meta:
  events:
    any $e.principal.ip = "192.0.2.1"
    $e.principal.ip = "192.0.2.3"
  condition:
    $e
}

La règle est appliquée aux copies suivantes:

copie de l'événement principal.ip n'importe quel $e.principal.ip
event_copy_1 "192.0.2.1" ["192.0.2.1", "192.0.2.2", "192.0.2.3"]
event_copy_2 "192.0.2.2" ["192.0.2.1", "192.0.2.2", "192.0.2.3"]
event_copy_3 "192.0.2.3" ["192.0.2.1", "192.0.2.2", "192.0.2.3"]

Dans ce cas, toutes les copies respectent any $e.principal.ip = "192.0.2.1", mais seul event_copy_3 répond aux critères $e.principal.ip = "192.0.2.3". Par conséquent, l'événement dans son ensemble correspond.

Vous pouvez également envisager ces types d'expressions:

  • Les expressions sur les champs répétés qui utilisent any ou all fonctionnent sur la liste dans event_original.
  • Les expressions sur des champs répétés qui n'utilisent pas any ni all fonctionnent sur des événements event_copy_n individuels.

Champs répétés et espaces réservés

Les champs répétés fonctionnent avec les attributions d'espaces réservés. Comme pour les expressions non modifiées sur des champs répétés, une copie de l'événement est créée pour chaque élément. Dans le même exemple que event_copy, l'espace réservé prend la valeur du champ répété de event_copy_n, pour chacune des copies d'événements, où n correspond au numéro de copie de l'événement. Si l'espace réservé est utilisé dans la section des correspondances, cela peut entraîner plusieurs correspondances.

L'exemple suivant génère une correspondance. L'espace réservé $ip est égal à 192.0.2.1 pour event_copy_1, ce qui répond aux prédicats de la règle. Les exemples d'événements de la correspondance contiennent un seul élément, event_original.

// Generates 1 match.
rule repeated_field_placeholder1 {
  meta:
  events:
    $ip = $e.principal.ip
    $ip = "192.0.2.1"
    $host = $e.principal.hostname

  match:
    $host over 5m

  condition:
    $e
}

L'exemple suivant génère trois correspondances. L'espace réservé $ip correspond à différentes valeurs, pour chacune des différentes copies event_copy_n. Le regroupement est effectué le $ip, car il se trouve dans la section de correspondance. Par conséquent, vous obtenez trois correspondances, chacune ayant une valeur différente pour la variable de correspondance $ip. Chaque correspondance comporte le même échantillon d'événement: un seul élément, event_original.

// Generates 3 matches.
rule repeated_field_placeholder2 {
  meta:
  events:
    $ip = $e.principal.ip
    net.ip_in_range_cidr($ip, "192.0.2.0/8") // Checks if IP matches 192.x.x.x

  match:
    $ip over 5m

  condition:
    $e
}

Résultats à l'aide d'espaces réservés attribués à des champs répétés

Les espaces réservés sont attribués à chaque élément de chaque champ répété, et non à la liste entière. Ainsi, lorsqu'ils sont utilisés dans la section des résultats, le résultat est calculé à l'aide uniquement des éléments qui répondent aux sections précédentes.

Prenons la règle suivante:

rule outcome_repeated_field_placeholder {
  meta:
  events:
    $ip = $e.principal.ip
    $ip = "192.0.2.1" or $ip = "192.0.2.2"
    $host = $e.principal.hostname

  match:
    $host over 5m

  outcome:
    $o = array_distinct($ip)

  condition:
    $e
}

Cette règle comporte quatre étapes d'exécution. La première étape est la copie de l'événement:

copie de l'événement $ip $host e $
event_copy_1 "192.0.2.1" "hôte" event_id
event_copy_2 "192.0.2.2" "hôte" event_id
event_copy_3 "192.0.2.3" "hôte" event_id

La section "Événements" filtre ensuite les lignes qui ne correspondent pas aux filtres:

copie de l'événement $ip $host e $
event_copy_1 "192.0.2.1" "hôte" event_id
event_copy_2 "192.0.2.2" "hôte" event_id

event_copy_3 est filtré, car "192.0.2.3" ne répond pas à $ip = "192.0.2.1" or $ip = "192.0.2.2".

La section "Correspondance" regroupe ensuite par variables de correspondance, et la section "Résultat" effectue une agrégation sur chaque groupe:

$host o $ e $
"hôte" ["192.0.2.1", "192.0.2.2"] event_id

Le calcul de $o = array_distinct($ip) repose sur la valeur $ip de l'étape précédente, et non sur la base de l'étape de copie de l'événement.

Enfin, la section des conditions filtrera chaque groupe. Comme cette règle se contente de vérifier l'existence de $e, la ligne précédente produira une détection unique.

$o ne contient pas tous les éléments de $e.principal.ip, car tous les éléments ne remplissent pas toutes les conditions de la section des événements. Toutefois, tous les éléments de e.principal.ip apparaîtront dans l'exemple d'événement, car celui-ci utilise event_original.

Indexation de tableaux

Vous pouvez effectuer une indexation d'un tableau sur des champs répétés. Pour accéder au n-ième élément de champ répété, utilisez la syntaxe de liste standard (les éléments sont indexés sur 0). Un élément hors limites renvoie la valeur par défaut.

  • $e.principal.ip[0] = "192.168.12.16"
  • $e.principal.ip[999] = "" Si le nombre d'éléments est inférieur à 1 000, la valeur est true.

Contraintes:

  • Un index doit être un littéral entier non négatif. Par exemple, $e.principal.ip[-1] n'est pas valide.
  • Les valeurs de type int (par exemple, un espace réservé défini sur int) ne comptent pas.
  • L'indexation de tableaux ne peut pas être combinée avec any ou all. Par exemple, any $e.intermediary.ip[0] n'est pas valide.
  • L'indexation de tableaux ne peut pas être combinée à la syntaxe de mappage. Par exemple, $e.additional.fields[0]["key"] n'est pas valide.
  • Si le chemin d'accès du champ contient plusieurs champs répétés, tous les champs répétés doivent utiliser l'indexation de tableau. Par exemple, $e.intermediary.ip[0] n'est pas valide, car intermediary et ip sont des champs répétés, alors qu'il n'existe qu'un index pour ip.

Messages répétés

Lorsqu'un champ message est répété, un effet inattendu est de réduire la probabilité d'une correspondance. Ceci est illustré dans les exemples suivants.

Prenons l'exemple d'un événement suivant:

event_repeated_message {
  // about is a repeated message field.
  about {
    // ip is a repeated string field.
    ip: [ "192.0.2.1", "192.0.2.2", "192.0.2.3" ]

    hostname: "alice"
  }
  about {
    hostname: "bob"
  }
}

Comme indiqué pour les expressions non modifiées sur des champs répétés, une copie temporaire de l'événement est créée pour chaque élément du champ répété. Prenons la règle suivante:

rule repeated_message_1 {
  meta:
  events:
    $e.about.ip = "192.0.2.1"
    $e.about.hostname = "bob"
  condition:
    $e
}

La règle est appliquée aux copies suivantes:

copie de l'événement about.ip about.hostname
event_copy_1 "192.0.2.1" "alice"
event_copy_2 "192.0.2.2" "alice"
event_copy_3 "192.0.2.3" "alice"
event_copy_4 "" "bob"

L'événement ne correspond pas à la règle, car il n'existe aucune copie d'événement conforme à toutes les expressions.

Messages répétés et indexation de tableaux

Un autre comportement inattendu peut se produire lors de l'utilisation de l'indexation de tableau avec des expressions non modifiées sur des champs de message répétés. Prenons l'exemple de règle suivant, qui utilise l'indexation de tableau:

rule repeated_message_2 {
  meta:
  events:
    $e.about.ip = "192.0.2.1"
    $e.about[1].hostname = "bob"
  condition:
    $e
}

La règle s'applique aux copies suivantes:

copie de l'événement about.ip about[1].nom d'hôte
event_copy_1 "192.0.2.1" "bob"
event_copy_2 "192.0.2.2" "bob"
event_copy_3 "192.0.2.3" "bob"
event_copy_4 "" "bob"

Étant donné que event_copy_1 répond à toutes les expressions de repeated_message_2, l'événement correspond à la règle.

Cela peut entraîner un comportement inattendu, car la règle repeated_message_1 manquait d'indexation de tableau et n'a produit aucune correspondance, tandis que la règle repeated_message_2 utilisait l'indexation de tableau et produisait une correspondance.

Commentaires

Désignez les commentaires à l'aide de deux barres obliques (// comment) ou de commentaires de plusieurs lignes à l'aide de barres obliques astérisques (/* comment */), comme vous le feriez en C.

Littéraux

Les nombres entiers et flottants non négatifs, les littéraux de chaîne, les valeurs booléennes et les expressions régulières sont acceptés.

Littéraux de chaîne et d'expression régulière

Vous pouvez utiliser l'un des guillemets suivants pour délimiter des chaînes dans YARA-L 2.0. Cependant, le texte entre guillemets est interprété différemment selon le texte que vous utilisez.

  1. Guillemets doubles (") : à utiliser pour les chaînes de caractères normales. Doit inclure des caractères d'échappement.
    Par exemple: "hello\tworld" —\t est interprété comme une tabulation

  2. Guillemets obliques (`) : permet d'interpréter littéralement tous les caractères.
    Par exemple: `hello\tworld` —\t n'est pas interprété comme une tabulation

Pour les expressions régulières, deux options s'offrent à vous.

Si vous souhaitez utiliser des expressions régulières directement sans la fonction re.regex(), utilisez /regex/ pour les littéraux d'expression régulière.

Vous pouvez également utiliser des littéraux de chaîne en tant que littéraux d'expression régulière lorsque vous utilisez la fonction re.regex(). Notez que pour les littéraux de chaîne avec guillemets doubles, vous devez échapper les barres obliques inverses par des barres obliques inverses, ce qui peut sembler gênant.

Par exemple, les expressions régulières suivantes sont équivalentes:

  • re.regex($e.network.email.from, `.*altostrat\.com`)
  • re.regex($e.network.email.from, ".*altostrat\\.com")
  • $e.network.email.from = /.*altostrat\.com/

Pour une meilleure lisibilité, Google recommande d'utiliser des guillemets pour les chaînes dans les expressions régulières.

Opérateurs

Vous pouvez utiliser les opérateurs suivants dans YARA-L:

Opérateur Description
= égal/déclaration
!= différent de
< inférieur à
<= inférieur(e) ou égal(e) à
> supérieur à
>= supérieur(e) ou égal(e) à

Variables

Dans YARA-L 2.0, toutes les variables sont représentées par $<variable name>.

Vous pouvez définir les types de variables suivants:

  • Variables d'événement : représentent des groupes d'événements sous forme normalisée (UDM) ou des événements d'entité. Spécifiez les conditions des variables d'événement dans la section events. Vous pouvez identifier les variables d'événement à l'aide d'un nom, de la source de l'événement et des champs d'événement. Les sources autorisées sont udm (pour les événements normalisés) et graph (pour les événements d'entité). Si la source est omise, udm est défini comme source par défaut. Les champs d'événement sont représentés par une chaîne de .<field name> (par exemple, $e.field1.field2). Les chaînes de champs d'événement commencent toujours à partir de la source de niveau supérieur (UDM ou entité).

  • Faites correspondre les variables : déclarez-le dans la section match. Les variables de correspondance deviennent des champs de regroupement pour la requête, car une ligne est renvoyée pour chaque ensemble unique de variables de correspondance (et pour chaque période). Lorsque la règle trouve une correspondance, les valeurs des variables de correspondance sont renvoyées. Spécifiez ce que chaque variable de correspondance représente dans la section events.

  • Variables d'espace réservé : déclarez et définissez-les dans la section events. Les variables d'espace réservé sont similaires aux variables de correspondance. Toutefois, vous pouvez utiliser des variables d'espace réservé dans la section condition pour spécifier des conditions de correspondance.

.

Utilisez des variables de correspondance et des variables d'espace réservé pour déclarer les relations entre les champs d'événement via des conditions de jointure transitives (pour en savoir plus, consultez la section Syntaxe de la section "Événements").

Keywords

Les mots clés de YARA-L 2.0 ne sont pas sensibles à la casse. Par exemple, and ou AND sont équivalents. Les noms des variables ne doivent pas entrer en conflit avec les mots clés. Par exemple, $AND ou $outcome n'est pas valide.

Les mots clés suivants s'appliquent aux règles du moteur de détection: rule, meta, match, over, events, condition, outcome, options, and, or, not, nocase, in, regex, cidr, before, after, all, any, if, {2/4, match, {2/4, match, match, {2/4, match, {2/4, matchmaxminsumarrayarray_distinctcountcount_distinctisnull

Maps

YARA-L prend en charge l'accès à la carte pour les objets struct et libellés.

Structures et libellés

Certains champs UDM utilisent le type de données Struct ou Label.

Pour rechercher une paire clé-valeur spécifique dans Struct et Label, utilisez la syntaxe de mappage standard:

// A Struct field.
$e.udm.additional.fields["pod_name"] = "kube-scheduler"
// A Label field.
$e.metadata.ingestion_labels["MetadataKeyDeletion"] = "startup-script"

L'accès à la carte renvoie toujours une chaîne.

Cas pris en charge

Section Événements et résultats
// Using a Struct field in the events section
events:
  $e.udm.additional.fields["pod_name"] = "kube-scheduler"

// Using a Label field in the outcome section
outcome:
  $value = array_distinct($e.metadata.ingestion_labels["MetadataKeyDeletion"])
Attribution d'une valeur de mappage à un espace réservé
$placeholder = $u1.metadata.ingestion_labels["MetadataKeyDeletion"]
Utiliser un champ de mappage dans une condition de jointure
// using a Struct field in a join condition between two udm events $u1 and $u2
$u1.metadata.event_type = $u2.udm.additional.fields["pod_name"]

Demandes non acceptées

Les cartes ne sont pas prises en charge dans les cas suivants.

Combiner des mots clés any ou all avec une carte

Par exemple, les éléments suivants ne sont pas acceptés : all $e.udm.additional.fields["pod_name"] = "kube-scheduler"

Autres types de valeurs

La syntaxe de mappage ne peut renvoyer qu'une valeur de chaîne. Dans le cas des types de données Struct, la syntaxe de mappage ne peut accéder qu'aux clés dont les valeurs sont des chaînes. Il n'est pas possible d'accéder à des clés dont les valeurs sont d'autres types primitifs tels que des entiers.

Traitement des valeurs en double

Les accès à la carte renvoient toujours une valeur unique. Dans le cas peu courant où l'accès à la carte peut faire référence à plusieurs valeurs, l'accès à la carte renvoie déterministement la première valeur.

Cela peut se produire dans les cas suivants:

  • Une étiquette possède une clé en double.

    La structure de libellés représente un mappage, mais elle n'applique pas l'unicité de clé. Par convention, un mappage doit comporter des clés uniques. Chronicle ne recommande donc pas de renseigner un libellé avec des clés en double.

    Le texte de règle $e.metadata.ingestion_labels["dupe-key"] renvoie la première valeur possible, val1, si elle est exécutée sur l'exemple de données suivant:

    // Disrecommended usage of label with a duplicate key:
    event {
      metadata{
        ingestion_labels{
          key: "dupe-key"
          value: "val1" // This is the first possible value for "dupe-key"
        }
        ingestion_labels{
          key: "dupe-key"
          value: "val2"
        }
      }
    }
    
  • Une étiquette est associée à un champ répété d'ancêtre.

    Un champ répété peut contenir un libellé en tant que champ enfant. Deux entrées différentes du champ répété de premier niveau peuvent contenir des étiquettes ayant la même clé. Le texte de règle $e.security_result.rule_labels["key"] renverrait la première valeur possible, val3, s'il était exécuté sur l'exemple de données suivant:

    event {
      // security_result is a repeated field.
      security_result {
        threat_name: "threat1"
        rule_labels {
          key: "key"
          value: "val3" // This is the first possible value for "key"
        }
      }
      security_result {
        threat_name: "threat2"
        rule_labels {
          key: "key"
          value: "val4"
        }
      }
    }
    

Fonctions

Cette section décrit les fonctions YARA-L 2.0 compatibles avec Chronicle dans Detection Engine.

Ces fonctions peuvent être utilisées dans les sections suivantes d'une règle:

arrays.length

arrays.length(repeatedField)

Description

Renvoie le nombre d'éléments de champ répétés.

Types de données de paramètres

LIST

Type renvoyé

NUMBER

Exemples de code

Exemple 1

Renvoie le nombre d'éléments de champ répétés.

arrays.length($e.principal.ip) = 2
Exemple 2

Si le chemin contient plusieurs champs répétés, cette fonction renvoie le nombre total d'éléments de champ répétés.

arrays.length($e.intermediary.ip) = 3

math.abs

math.abs(numericExpression)

Description

Renvoie la valeur absolue d'un entier ou d'une expression flottante.

Types de données de paramètres

NUMBER

Type renvoyé

NUMBER

Exemples de code

Exemple 1

Cet exemple renvoie la valeur "True" si l'événement a eu lieu plus de cinq minutes à partir de l'heure spécifiée (en secondes à partir de l'epoch Unix), que l'événement se soit produit avant ou après l'heure spécifiée. Un appel à math.abs ne peut pas dépendre de plusieurs variables ou espaces réservés. Par exemple, dans l'exemple suivant, vous ne pouvez pas remplacer la valeur de temps codée en dur de 1643687343 par $e2.metadata.event_timestamp.seconds.

300 < math.abs($e1.metadata.event_timestamp.seconds - 1643687343)

metrics

Les fonctions de métriques peuvent agréger de grandes quantités de données historiques. Vous pouvez l'utiliser dans votre règle en utilisant metrics.functionName() dans la section des résultats.

Pour en savoir plus, consultez la page Métriques YARA-L.

net.ip_in_range_cidr

net.ip_in_range_cidr(ipAddress, subnetworkRange)

Description

Renvoie true lorsque l'adresse IP donnée se trouve dans le sous-réseau spécifié.

Vous pouvez utiliser YARA-L pour rechercher des événements UDM sur toutes les adresses IP d'un sous-réseau à l'aide de l'instruction net.ip_in_range_cidr(). Les adresses IPv4 et IPv6 sont toutes deux acceptées.

Pour effectuer une recherche sur une plage d'adresses IP, spécifiez un champ IP UDM et une plage CIDR. YARA-L peut gérer les champs d'adresses IP singuliers et répétés.

Pour effectuer une recherche sur une plage d'adresses IP, spécifiez un champ UDM ip et une plage CIDR (Classless Inter-Domain Routing). YARA-L peut gérer les champs d'adresses IP singuliers et répétés.

Types de données de paramètres

STRING – STRING

Type renvoyé

BOOL

Exemples de code

Exemple 1

Exemple pour IPv4:

net.ip_in_range_cidr($e.principal.ip, "192.0.2.0/24")
Exemple 2

Exemple pour IPv6:

net.ip_in_range_cidr($e.network.dhcp.yiaddr, "2001:db8::/32")

Pour obtenir un exemple de règle utilisant l'instruction net.ip_in_range_cidr(), consultez l'exemple de règle dans la section Événement unique dans une plage d'adresses IP.)

re.regex

Vous pouvez définir la correspondance d'expressions régulières dans YARA-L 2.0 à l'aide de l'une des syntaxes suivantes:

  • Utilisation de la syntaxe YARA : liée aux événements. Voici une représentation générique de cette syntaxe : none $e.field = /regex/
  • Utilisation de la syntaxe YARA-L : en tant que fonction prenant les paramètres suivants :
    • Champ auquel l'expression régulière est appliquée.
    • Expression régulière spécifiée en tant que chaîne. Vous pouvez utiliser le modificateur nocase après les chaînes pour indiquer que la recherche doit ignorer les majuscules. Voici une représentation générique de cette syntaxe : none re.regex($e.field, `regex`)

Description

Cette fonction renvoie true si la chaîne contient une sous-chaîne qui correspond à l'expression régulière fournie. Il n'est pas nécessaire d'ajouter .* au début ou à la fin de l'expression régulière.

Notes
  • Pour correspondre à la chaîne exacte, ou uniquement à un préfixe ou à un suffixe, incluez les caractères d'ancrage ^ (début) et $ (fin) dans l'expression régulière. Par exemple, /^full$/ correspond exactement à "full", tandis que /full/ peut correspondre à "fullest", "lawfull" et "joyfully".
  • Si le champ UDM inclut des caractères de retour à la ligne, regexp ne correspond qu'à la première ligne du champ UDM. Pour appliquer une correspondance complète des champs UDM, ajoutez (?s) à l'expression régulière. Par exemple, remplacez /.*allUDM.*/ par /(?s).*allUDM.*/.

Types de données de paramètres

STRING – STRING

Types d'expressions de paramètres

ANY – ANY

Type renvoyé

BOOL

Exemples de code

Exemple 1
// Equivalent to $e.principal.hostname = /google/
re.regex($e.principal.hostname, "google")

re.capture

re.capture(stringText, regex)

Description

Capture (extrait) les données d'une chaîne à l'aide du modèle d'expression régulière fourni dans l'argument.

Cette fonction nécessite deux arguments:

  • stringText: chaîne d'origine à rechercher.
  • regex: expression régulière indiquant le modèle à rechercher.

L'expression régulière peut contenir 0 ou 1 groupe de capture entre parenthèses. Si l'expression régulière contient 0 groupe de capture, la fonction renvoie la première sous-chaîne correspondante complète. Si l'expression régulière contient un groupe de capture, elle renvoie la première sous-chaîne correspondante pour le groupe de capture. La définition de deux groupes de capture ou plus renvoie une erreur de compilation.

Types de données de paramètres

STRING – STRING

Type renvoyé

STRING

Exemples de code

Exemple 1

Dans cet exemple, si $e.principal.hostname contient "aaa1bbaa2", ce qui suit est vrai, car la fonction renvoie la première instance. Cet exemple ne comporte aucun groupe de capture.

"aaa1" = re.capture($e.principal.hostname, "a+[1-9]")
Exemple 2

Cet exemple capture tout ce qui se trouve après le symbole @ dans un e-mail. Si le champ $e.network.email.from indique test@google.com, l'exemple renvoie google.com. L'exemple suivant contient un groupe de capture.

"google.com" = re.capture($e.network.email.from , "@(.*)")
Exemple 3

Si l'expression régulière ne correspond à aucune sous-chaîne du texte, la fonction renvoie une chaîne vide. Vous pouvez omettre les événements pour lesquels aucune correspondance n'est détectée en excluant la chaîne vide, ce qui est particulièrement important lorsque vous utilisez re.capture() avec une inégalité:

// Exclude the empty string to omit events where no match occurs.
"" != re.capture($e.network.email.from , "@(.*)")

// Exclude a specific string with an inequality.
"google.com" != re.capture($e.network.email.from , "@(.*)")

re.replace

re.replace(stringText, replaceRegex, replacementText)

Description

Effectue un remplacement d'expression régulière.

Cette fonction nécessite trois arguments:

  • stringText: chaîne d'origine.
  • replaceRegex: expression régulière indiquant le modèle à rechercher.
  • replacementText: texte à insérer dans chaque correspondance

Renvoie une nouvelle chaîne dérivée de la valeur stringText d'origine, où toutes les sous-chaînes correspondant au modèle de replaceRegex sont remplacées par la valeur de replacementText. Vous pouvez utiliser des chiffres échappés par une barre oblique inverse (\1 à \9) dans replacementText pour insérer du texte correspondant au groupe entre parenthèses correspondant dans le modèle replaceRegex. Utilisez \0 pour faire référence à l'ensemble du texte correspondant.

La fonction remplace les correspondances qui ne se chevauchent pas et privilégiera le remplacement de la première occurrence trouvée. Par exemple, re.replace("banana", "ana", "111") renvoie la chaîne "b111na".

Types de données de paramètres

STRING, STRING et STRING

Type renvoyé

STRING

Exemples de code

Exemple 1

Cet exemple capture tout ce qui se trouve après le symbole @ dans un e-mail, remplace com par org, puis renvoie le résultat. Notez l'utilisation de fonctions imbriquées.

"email@google.org" = re.replace($e.network.email.from, "com", "org")
Exemple 2

Cet exemple utilise des chiffres échappés par une barre oblique inverse dans l'argument replacementText pour référencer les correspondances au modèle replaceRegex.

"test1.com.google" = re.replace(
                       $e.principal.hostname, // holds "test1.test2.google.com"
                       "test2\.([a-z]*)\.([a-z]*)",
                       "\\2.\\1"  // \\1 holds "google", \\2 holds "com"
                     )
Exemple 3

Notez les cas suivants lorsque vous traitez des chaînes vides et des re.replace():

Utilisation d'une chaîne vide comme replaceRegex:

// In the function call below, if $e.principal.hostname contains "name",
// the result is: 1n1a1m1e1, because an empty string is found next to
// every character in `stringText`.
re.replace($e.principal.hostname, "", "1")

Pour remplacer une chaîne vide, vous pouvez utiliser "^$" comme replaceRegex:

// In the function call below, if $e.principal.hostname contains the empty
// string, "", the result is: "none".
re.replace($e.principal.hostname, "^$", "none")

strings.base64_decode

strings.base64_decode(encodedString)

Description

Renvoie une chaîne contenant la version décodée en base64 de la chaîne encodée.

Cette fonction utilise une chaîne encodée en base64 comme argument. Si encodedString n'est pas une chaîne encodée en base64 valide, la fonction renvoie encodedString inchangée.

Types de données de paramètres

STRING

Type renvoyé

STRING

Exemples de code

Exemple 1
"test" = strings.base64_decode($e.principal.domain.name)

strings.coalesce

strings.coalesce(a, b, c, ...)

Description

Cette fonction accepte un nombre illimité d'arguments et renvoie la valeur de la première expression qui ne correspond pas à une chaîne vide (par exemple, "valeur non nulle"). Si tous les arguments renvoient une chaîne vide, l'appel de fonction renvoie une chaîne vide.

Les arguments peuvent être des littéraux, des champs d'événement ou des appels de fonction. Tous les arguments doivent être de type STRING. Si des arguments sont des champs d'événement, les attributs doivent provenir du même événement.

Types de données de paramètres

STRING

Type renvoyé

STRING

Exemples de code

Exemple 1

L'exemple suivant inclut des variables de chaîne en tant qu'arguments. La condition est remplie si (1) $e.network.email.from est défini sur suspicious@gmail.com ou (2) $e.network.email.from est vide et que $e.network.email.to est défini sur suspicious@gmail.com.

"suspicious@gmail.com" = strings.coalesce($e.network.email.from, $e.network.email.to)
Exemple 2

L'exemple suivant appelle la fonction coalesce avec plus de deux arguments. Cette condition compare la première adresse IP non nulle de l'événement $e aux valeurs de la liste de référence ip_watchlist. L'ordre dans lequel les arguments sont regroupés dans cet appel est le même que celui dans lequel ils sont énumérés dans la condition de règle:

  1. $e.principal.ip est évalué en premier.
  2. $e.src.ip est ensuite évalué.
  3. $e.target.ip est ensuite évalué.
  4. Enfin, la chaîne "No IP" est renvoyée par défaut si les champs ip précédents ne sont pas définis.
strings.coalesce($e.principal.ip, $e.src.ip, $e.target.ip, "No IP") in %ip_watchlist
Exemple 3

L'exemple suivant tente de fusionner principal.hostname avec les événements $e1 et $e2. Elle renverra une erreur de compilateur, car les arguments sont des variables d'événement différentes.

// returns a compiler error
"test" = strings.coalesce($e1.principal.hostname, $e2.principal.hostname)

strings.concat

strings.concat(a, b, c, ...)

Description

Renvoie la concaténation d'un nombre illimité d'éléments, chacun pouvant être une chaîne, un entier ou un nombre à virgule flottante.

Si des arguments sont des champs d'événement, les attributs doivent provenir du même événement.

Types de données de paramètres

STRING, FLOAT et INT

Type renvoyé

STRING

Exemples de code

Exemple 1

L'exemple suivant inclut une variable de chaîne et une variable entière en tant qu'arguments. principal.hostname et principal.port proviennent du même événement, $e, et sont concaténés pour renvoyer une chaîne.

"google:80" = strings.concat($e.principal.hostname, ":", $e.principal.port)
Exemple 2

L'exemple suivant inclut une variable de chaîne et un littéral de chaîne en tant qu'arguments.

"google-test" = strings.concat($e.principal.hostname, "-test") // Matches the event when $e.principal.hostname = "google"
Exemple 3

L'exemple suivant inclut une variable de chaîne et un littéral flottant en tant qu'arguments. Lorsqu'ils sont représentés sous forme de chaînes, les flottants qui sont des nombres entiers sont formatés sans la virgule (par exemple, 1.0 est représenté par "1"). En outre, les valeurs flottantes dépassant 16 chiffres décimaux sont tronquées à la seizième.

"google2.5" = strings.concat($e.principal.hostname, 2.5)
Exemple 4

L'exemple suivant inclut une variable de chaîne, un littéral de chaîne, une variable entière et un littéral de type float en tant qu'arguments. Toutes les variables proviennent du même événement, $e, et sont concaténées avec les littéraux pour renvoyer une chaîne.

"google-test802.5" = strings.concat($e.principal.hostname, "-test", $e.principal.port, 2.5)
Exemple 5

L'exemple suivant tente de concaténer principal.port de l'événement $e1 avec principal.hostname de l'événement $e2. Elle renverra une erreur de compilateur, car les arguments sont des variables d'événement différentes.

// Will not compile
"test" = strings.concat($e1.principal.port, $e2.principal.hostname)

strings.to_lower

strings.to_lower(stringText)

Description

Cette fonction prend une chaîne d'entrée et en renvoie une après avoir modifié tous les caractères en minuscules.

Types de données de paramètres

STRING

Type renvoyé

STRING

Exemples de code

Exemple 1

L'exemple suivant renvoie true.

"test@google.com" = strings.to_lower($e.network.email.to)

strings.to_upper

strings.to_upper(stringText)

Description

Cette fonction accepte une chaîne d'entrée et la renvoie après avoir modifié tous les caractères en majuscules.

Types de données de paramètres

STRING

Type renvoyé

STRING

Exemples de code

Exemple 1

L'exemple suivant renvoie true.

"TEST@GOOGLE.COM" = strings.to_upper($e.network.email.to)

timestamp.current_seconds

timestamp.current_seconds()

Description

Renvoie un nombre entier représentant l'heure actuelle en secondes Unix. Ce paramètre est à peu près égal au code temporel de détection et se base sur le moment où la règle est exécutée.

Types de données de paramètres

NONE

Type renvoyé

INT

Exemples de code

Exemple 1

L'exemple suivant renvoie true si le certificat a expiré depuis plus de 24 heures. Il calcule la différence de temps en soustrayant les secondes Unix actuelles, puis en comparant à l'aide d'un opérateur supérieur à.

86400 < timestamp.current_seconds() - $e.network.tls.certificate.not_after

timestamp.get_date

timestamp.get_date(unix_seconds [, time_zone])

Description

Cette fonction renvoie une chaîne au format YYYY-MM-DD, qui représente le jour dans lequel se trouve un horodatage.

  • unix_seconds est un entier représentant le nombre de secondes après l'epoch Unix, tel que $e.metadata.event_timestamp.seconds, ou un espace réservé contenant cette valeur.
  • time_zone est facultatif et est une chaîne représentant un fuseau horaire. En cas d'omission, la valeur par défaut est "GMT". Vous pouvez spécifier des fuseaux horaires à l'aide de littéraux de chaîne. Les options sont les suivantes :

Voici des exemples de spécificateurs time_zone valides, que vous pouvez transmettre comme deuxième argument aux fonctions d'extraction de l'heure:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

Types de données de paramètres

INT, STRING

Type renvoyé

STRING

Exemples de code

Exemple 1

Dans cet exemple, l'argument time_zone est omis. La valeur par défaut est "GMT".

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_date($ts) = "2024-02-19"
Exemple 2

Cet exemple utilise un littéral de chaîne pour définir time_zone.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_date($ts, "America/Los_Angeles") = "2024-02-20"

timestamp.get_minute

timestamp.get_minute(unix_seconds [, time_zone])

Description

Cette fonction renvoie un entier compris dans la plage [0, 59] représentant la minute.

  • unix_seconds est un entier représentant le nombre de secondes après l'epoch Unix, tel que $e.metadata.event_timestamp.seconds, ou un espace réservé contenant cette valeur.
  • time_zone est facultatif et est une chaîne représentant un fuseau horaire. En cas d'omission, la valeur par défaut est "GMT". Vous pouvez spécifier des fuseaux horaires à l'aide de littéraux de chaîne. Les options sont les suivantes :

Voici des exemples de spécificateurs time_zone valides, que vous pouvez transmettre comme deuxième argument aux fonctions d'extraction temporelle:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

Types de données de paramètres

INT, STRING

Type renvoyé

INT

Exemples de code

Exemple 1

Dans cet exemple, l'argument time_zone est omis. La valeur par défaut est "GMT".

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_hour($ts) = 15
Exemple 2

Cet exemple utilise un littéral de chaîne pour définir time_zone.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_hour($ts, "America/Los_Angeles") = 15

timestamp.get_hour

timestamp.get_hour(unix_seconds [, time_zone])

Description

Cette fonction renvoie un entier compris dans la plage [0, 23] représentant l'heure.

  • unix_seconds est un entier représentant le nombre de secondes après l'epoch Unix, tel que $e.metadata.event_timestamp.seconds, ou un espace réservé contenant cette valeur.
  • time_zone est facultatif et est une chaîne représentant un fuseau horaire. En cas d'omission, la valeur par défaut est "GMT". Vous pouvez spécifier des fuseaux horaires à l'aide de littéraux de chaîne. Les options sont les suivantes :

Voici des exemples de spécificateurs time_zone valides, que vous pouvez transmettre comme deuxième argument aux fonctions d'extraction temporelle:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

Types de données de paramètres

INT, STRING

Type renvoyé

INT

Exemples de code

Exemple 1

Dans cet exemple, l'argument time_zone est omis. La valeur par défaut est "GMT".

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_hour($ts) = 15
Exemple 2

Cet exemple utilise un littéral de chaîne pour définir time_zone.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_hour($ts, "America/Los_Angeles") = 15

timestamp.get_day_of_week

timestamp.get_day_of_week(unix_seconds [, time_zone])

Description

Cette fonction renvoie un entier compris dans la plage [1, 7] représentant le jour de la semaine en commençant par le dimanche. Par exemple, 1 = dimanche et 2 = lundi.

  • unix_seconds est un entier représentant le nombre de secondes après l'epoch Unix, tel que $e.metadata.event_timestamp.seconds, ou un espace réservé contenant cette valeur.
  • time_zone est facultatif et est une chaîne représentant un fuseau horaire. En cas d'omission, la valeur par défaut est "GMT". Vous pouvez spécifier des fuseaux horaires à l'aide de littéraux de chaîne. Les options sont les suivantes :

Voici des exemples de spécificateurs time_zone valides, que vous pouvez transmettre comme deuxième argument aux fonctions d'extraction de l'heure:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

Types de données de paramètres

INT, STRING

Type renvoyé

INT

Exemples de code

Exemple 1

Dans cet exemple, l'argument time_zone est omis. La valeur par défaut est "GMT".

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_day_of_week($ts) = 6
Exemple 2

Cet exemple utilise un littéral de chaîne pour définir time_zone.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_day_of_week($ts, "America/Los_Angeles") = 6

timestamp.get_week

timestamp.get_week(unix_seconds [, time_zone])

Description

Cette fonction renvoie un entier compris dans la plage [0, 53] représentant la semaine de l'année. Les semaines commencent le dimanche. Les dates antérieures au premier dimanche de l'année correspondent à la semaine 0.

  • unix_seconds est un entier représentant le nombre de secondes après l'epoch Unix, tel que $e.metadata.event_timestamp.seconds, ou un espace réservé contenant cette valeur.
  • time_zone est facultatif et est une chaîne représentant un fuseau horaire. En cas d'omission, la valeur par défaut est "GMT". Vous pouvez spécifier des fuseaux horaires à l'aide de littéraux de chaîne. Les options sont les suivantes :

Voici des exemples de spécificateurs time_zone valides, que vous pouvez transmettre comme deuxième argument aux fonctions d'extraction temporelle:

"America/Los_Angeles", or "-08:00". ("PST" is not supported)
"America/New_York", or "-05:00". ("EST" is not supported)
"Europe/London"
"UTC"
"GMT"

Types de données de paramètres

INT, STRING

Type renvoyé

INT

Exemples de code

Exemple 1

Dans cet exemple, l'argument time_zone est omis. La valeur par défaut est "GMT".

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_week($ts) = 0
Exemple 2

Cet exemple utilise un littéral de chaîne pour définir time_zone.

$ts = $e.metadata.collected_timestamp.seconds

timestamp.get_week($ts, "America/Los_Angeles") = 0

Attribution d'une fonction à un espace réservé

Vous pouvez attribuer le résultat d'un appel de fonction à un espace réservé dans la section events. Exemple :

$placeholder = strings.concat($e.principal.hostname, "my-string").

Vous pouvez ensuite utiliser les variables d'espace réservé dans les sections match, condition et outcome. Toutefois, il existe deux limites concernant l'attribution des fonctions à l'espace réservé:

  1. Chaque espace réservé dans une fonction d'attribution d'espace réservé doit être attribué à une expression contenant un champ d'événement. Les exemples suivants sont valides:

    $ph1 = $e.principal.hostname
    $ph2 = $e.src.hostname
    
    // Both $ph1 and $ph2 have been assigned to an expression containing an event field.
    $ph1 = strings.concat($ph2, ".com")
    
    $ph1 = $e.network.email.from
    $ph2 = strings.concat($e.principal.hostname, "@gmail.com")
    
    // Both $ph1 and $ph2 have been assigned to an expression containing an event field.
    $ph1 = strings.to_lower($ph2)
    

    Toutefois, l'exemple suivant n'est pas valide:

    $ph1 = strings.concat($e.principal.hostname, "foo")
    $ph2 = strings.concat($ph1, "bar") // $ph2 has NOT been assigned to an expression containing an event field.
    
  2. L'appel de fonction doit dépendre d'un seul et même événement. Toutefois, plusieurs champs du même événement peuvent être utilisés dans les arguments d'appel de fonction. L'exemple suivant est valide:

    $ph = strings.concat($event.principal.hostname, "string2")

    $ph = strings.concat($event.principal.hostname, $event.src.hostname)

    Toutefois, les éléments suivants ne sont pas valides:

    $ph = strings.concat("string1", "string2")

    $ph = strings.concat($event.principal.hostname, $anotherEvent.src.hostname)

Syntaxe des listes de référence

Consultez la page sur les listes de références pour en savoir plus sur le comportement et la syntaxe des listes de références.

Vous pouvez utiliser des listes de références dans les sections events ou outcome. Voici la syntaxe permettant d'utiliser différents types de listes de référence dans une règle:

// STRING reference list
$e.principal.hostname in %string_reference_list

// REGEX reference list
$e.principal.hostname in regex %regex_reference_list

// CIDR reference list
$e.principal.ip in cidr %cidr_reference_list

Vous pouvez également utiliser les opérateurs not et nocase avec des listes de référence, comme indiqué ci-dessous : ```none // Exclure les événements dont les noms d'hôte correspondent aux sous-chaînes de my_regex_list. pas $e.principal.nom d'hôte dans l'expression régulière %my_regex_list

// Les noms d'hôte des événements doivent correspondre à au moins une chaîne dans "my_string_list" (non sensible à la casse). $e.principal.hostname dans %my_string_list nocase ```

L'opérateur nocase est compatible avec les listes STRING et REGEX.

Pour des raisons de performances, Detection Engine limite l'utilisation des listes de références.

  • Nombre maximal d'instructions in par règle, avec ou sans opérateurs spéciaux: 7
  • Nombre maximal d'instructions in avec l'opérateur regex: 4
  • Nombre maximal d'instructions in avec l'opérateur cidr: 2

Vérification du type

Chronicle effectue une vérification du type par rapport à votre syntaxe YARA-L lorsque vous créez des règles dans l'interface. Les erreurs de vérification du type affichées vous aident à réviser la règle de sorte qu'elle fonctionne comme prévu.

Voici des exemples de prédicats non valides:

// $e.target.port is of type integer which cannot be compared to a string.
$e.target.port = "80"

// "LOGIN" is not a valid event_type enum value.
$e.metadata.event_type = "LOGIN"

Échantillonnage d'événements de détection

Les détections issues de règles multi-événements contiennent des exemples d'événements qui fournissent du contexte sur les événements à l'origine de la détection. Le nombre d'exemples d'événements est limité à 10 pour chaque variable d'événement définie dans la règle. Par exemple, si une règle définit deux variables d'événements, chaque détection peut comporter jusqu'à 20 échantillons d'événements. La limite s'applique à chaque variable d'événement séparément. Si une variable d'événement comporte deux événements applicables dans cette détection et que l'autre comporte 15 événements applicables, la détection qui en résulte contient 12 échantillons d'événements (2 + 10).

Tous les échantillons d'événements au-delà de la limite sont omis de la détection.

Si vous souhaitez en savoir plus sur les événements à l'origine de la détection, vous pouvez utiliser des agrégations dans la section sur les résultats pour générer des informations supplémentaires dans votre détection.

Si vous consultez les détections dans l'interface utilisateur, vous pouvez télécharger tous les exemples d'événements à des fins de détection. Pour en savoir plus, consultez Télécharger des événements.