Syntaxe du langage YARA-L 2.0

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

Commentaires

Désignez les commentaires à deux barres obliques (// comment) ou sur plusieurs lignes à l'aide d'une barre oblique (/* comment */), comme vous le feriez dans la section C.

Constantes

Les constantes de type entier, chaîne, valeur flottante et expression régulière sont acceptées. Pour les constantes de chaîne, utilisez des guillemets doubles. Utilisez /regex/ pour les constantes d'expression régulière.

Nombre

Le caractère # est un caractère spécial de la section de 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.

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

Pour effectuer une recherche dans une plage d'adresses IP, spécifiez un champ IPU UMP et une plage CIDR (Classless Inter-Domain Routing) YARA-L peut gérer les champs d'adresses IP au singulier et à la répétition.

Exemple avec IPv4:

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

Exemple avec 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 Événement unique dans une plage d'adresses IP.

Opérateurs

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

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

Citations pour les chaînes

Vous pouvez utiliser l'un des guillemets suivants pour délimiter les chaînes dans YARA-L 2.0. Cependant, les citations sont interprétées différemment selon la fonction utilisée.

  1. Guillemets droits (") : à utiliser pour les chaînes normales. Doit inclure des caractères d'échappement. Par exemple: "hello\tworld" est considéré comme un onglet.

  2. Guillemets inversés (`) : permet d'interpréter littéralement tous les caractères. Par exemple : "hello\tworld".\t n'est pas interprété comme un onglet.

Pour les expressions régulières, vous devez souvent inclure la barre oblique inverse (\) dans les chaînes. Toutefois, si vous utilisez des guillemets doubles, vous devez échapper les barres obliques inverses avec les barres obliques inverses, ce qui peut sembler étrange.

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")

Nous vous recommandons d'utiliser des guillemets droits dans les expressions régulières pour les chaînes afin de faciliter la lecture.

Variables

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

Vous pouvez définir les types de variables suivants:

  • Variables d'événements : représentent des groupes d'événements sous une forme normalisée (UDM). Spécifiez les conditions des variables d'événement dans la section events. Vous identifiez les variables d'événement à l'aide des champs d'événement situés après la variable. Les champs d'événement sont représentés par une chaîne de .<nom de champ> (par exemple, $e.field1.field2). Les chaînes de champs d'événement commencent toujours par l'UDM de premier niveau.

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

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

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

Syntaxe de la section "Événements"

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

  • Que représente chaque correspondance ou variable d'espace réservé ?
  • Condition de filtre sur une seule variable d'événement
  • Condition de jointure sur deux variables d'événement.

Déclarations de variables

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

  • EVENT_FIELD = VAR
  • VAR = EVENT_FIELD

Les deux sont équivalentes, 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 de tableau, la variable de correspondance peut représenter n'importe quelle valeur du tableau. Il est également possible d'attribuer plusieurs champs d'événements à une seule correspondance ou variable à l'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

Sont équivalents à:

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

Conditions de filtre pour les variables d'événements

Pour une condition de filtre sur une seule variable d'événement, utilisez la syntaxe suivante:

  • [EVENT_FIELD] [OP] [CONST]
  • [CONST] [OP] [EVENT_FIELD]

Bien que les deux soient équivalentes, nous vous recommandons d'utiliser la première ([EVENT_FIELD] [OP] [CONST]) pour des raisons de lisibilité.

Exemple :

  • $e.source.hostname = "host1234"
  • $e.source.port < 1024
  • 1024 < $e.source.port

Ce prédicat est utilisé comme filtre sur la variable d'événement, ce qui signifie qu'un groupe d'événements représenté par la variable d'événement doit le satisfaire.

Conditions de jointure pour les variables d'événements

Pour représenter une condition de jointure pour deux variables d'événement, utilisez la syntaxe suivante:

[EVENT_FIELD] [OP] [EVENT_FIELD]

Exemple :

  • $e1.source.hostname = $e2.target.hostname
  • $e1.metadata.timestamp < $e2.metadata.timestamp

Ce prédicat permet de joindre les deux variables d'événement avec la condition.

Voici des exemples de prédicats non valides:

  • $e.source.hostname != $hostname //comparison over match/placeholder var
  • $hostname != "host1234" //comparison over match/placeholder var
  • $var1 //variable itself does not mean anything

Opérateurs logiques

Vous pouvez utiliser les opérateurs logiques and et or logiques 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é croissant est not, and, or.

Par exemple, "a or b and c" est évaluée comme "a or (b and c)". Si nécessaire, vous pouvez utiliser des parenthèses pour modifier la priorité.

Syntaxe de la section de correspondance

Dans la section de correspondance, 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 pour chaque correspondance.

  • Spécifiez ce que chaque variable de correspondance représente dans la section events.
  • Indiquez la période à utiliser pour mettre en corrélation les événements après le mot clé over. Les événements en dehors de cette période sont ignorés.
  • Utilisez la syntaxe suivante pour spécifier la période: <number><s/m/h/d>s/m/h/d signifie respectivement secondes, minutes, heures et 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 valeur 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 séparés de plus de cinq minutes ne sont pas corrélés et sont donc ignorés par la règle.

Voici un autre exemple de 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 séparés de plus d'une heure ne sont pas corrélés. La règle ne les considère pas comme une détection.

Voici un autre exemple de 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 séparés de plus de deux minutes ne sont pas corrélés. La règle ne les considère pas comme une détection.

Les exemples suivants illustrent des valeurs match non valides:

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

Syntaxe de la section de condition

Dans la section condition, spécifiez la condition de correspondance sur les événements et les variables définis dans la section events. Répertoriez les prédicats de correspondance ici, associés au mot clé and ou or.

Les conditions suivantes sont des conditions de délimitation. Elles 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 is >= 0
  • #var >= m // where m > 0

Les conditions suivantes ne sont pas illimitées. Ils permettent l'absence de la variable d'événement associée, ce qui signifie qu'aucune occurrence de l'événement n'apparaît dans la détection. Cela permet de créer des règles de non-existence, qui recherchent l'absence de variable au lieu de la présence d'une variable.

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

Dans l'exemple suivant, le caractère spécial # sur une variable (variable d'événement ou variable d'espace réservé) représente le nombre d'événements ou de valeurs distincts de cette variable:

$e and #port > 50 or #event1 > 2 or #event2 > 1 or #event3 > 0

L'exemple suivant qui n'existe pas est également valide et renvoie la valeur "true" s'il existe plus de deux événements distincts dans $event1 et zéro événement distinct de $event2:

#event1 > 2 and !$event2

Voici des exemples de prédicats non valides:

  • $e, #port > 50 // incorrect keyword usage
  • $e or #port < 50 // or keyword not supported with non-bounding conditions

Expressions régulières

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

  • Avec la syntaxe YARA : liée aux événements. Voici une représentation générique de cette syntaxe : $e.field = /regex/
  • Avec la syntaxe YARA-L : en tant que fonction acceptant les paramètres suivants :
    • Champ auquel appliquer l'expression régulière.
    • Expression régulière spécifiée sous forme de 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 : re.regex($e.field, `regex`)

Pour mettre en correspondance la chaîne exacte ou 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".

Chaînes brutes

Vous pouvez utiliser YARA-L 2.0 pour rechercher une chaîne brute dans vos données d'événements d'entreprise.

Pour rechercher une chaîne brute, placez-la entre accents graves (`) au lieu de guillemets doubles (").

L'accent grave indique que le contenu de la chaîne doit être interprété de façon littérale (les caractères d'échappement ne seront pas analysés).