Limites et problèmes connus de YARA-L

Ce document décrit les problèmes et les limites connus de YARA-L.

Agrégations de résultats avec désimbrication de champs répétés

Lorsqu'une règle fait référence à un champ répété dans une variable d'événement avec plusieurs éléments, chaque élément est divisé en ligne d'événement distincte.

Par exemple, les deux adresses IP du champ répété target.ip de l'événement $e sont réparties en deux instances de $e, chacune avec une valeur target.ip différente.

rule outbound_ip_per_app {
  meta:
  events:
    $e.principal.application = $app
  match:
    $app over 10m
  outcome:
    $outbound_ip_count = count($e.target.ip) // yields 2.
  condition:
    $e
}

Enregistrement d'événement avant le désimbrication du champ répété

Le tableau suivant présente l'enregistrement d'événement avant le désimbrication du champ répété:

metadata.id principal.application target.ip
aaaaaaaaa Google SecOps [192.0.2.20, 192.0.2.28]

Enregistrements d'événements après avoir désimbriqué le champ répété

Le tableau suivant présente l'enregistrement d'événement après avoir désimbriqué le champ répété:

metadata.id principal.application target.ip
aaaaaaaaa Google SecOps 192.0.2.20
aaaaaaaaa Google SecOps 192.0.2.28

Lorsqu'une règle fait référence à un champ répété imbriqué dans un autre, comme security_results.action, le désimbriquage se produit au niveau des parents et des enfants. Les instances résultant de l'extraction d'un seul événement forment un produit cartésien des éléments des champs parent et enfant. Dans l'exemple de règle suivant, l'événement $e avec deux valeurs répétées sur security_results et deux valeurs répétées sur security_results.actions sont déimbriqués en quatre instances.

rule security_action_per_app {
  meta:
  events:
    $e.principal.application = $app
  match:
    $app over 10m
  outcome:
    $security_action_count = count($e.security_results.actions) // yields 4.
  condition:
    $e
}

Enregistrement d'événement avant le désimbrication du champ répété

Le tableau suivant présente l'enregistrement d'événement avant le désimbrication du champ répété:

metadata.id principal.application security_results
aaaaaaaaa Google SecOps [ { actions: [ ALLOW, FAIL ] }, { actions: [ CHALLENGE, BLOCK ] } ]

Enregistrements d'événements après un dénouement répété de champs

Le tableau suivant présente l'enregistrement d'événement après avoir désimbriqué le champ répété:

metadata.id principal.application security_results.actions
aaaaaaaaa Google SecOps AUTORISER
aaaaaaaaa Google SecOps FAIL
aaaaaaaaa Google SecOps DÉFI
aaaaaaaaa Google SecOps BLOQUER

Ce comportement de désimbrication lors de l'évaluation des règles peut générer des agrégations de résultats inattendues lorsque la règle fait référence à un ou plusieurs champs répétés avec un champ parent qui est également un champ répété. Les agrégations non distinctes telles que sum(), array() et count() ne peuvent pas tenir compte des valeurs en double dans d'autres champs du même événement générés par le comportement de désimbrication. Dans l'exemple de règle suivant, l'événement $e ne comporte qu'un seul nom d'hôte google.com, mais le résultat hostnames est agrégé sur quatre instances non imbriquées du même événement $e, chacune avec une valeur principal.hostname en double. Ce résultat génère quatre noms d'hôte au lieu d'un en raison du désimbriquement des valeurs répétées sur security_results.actions.

rule security_action_per_app {
  meta:
  events:
    $e.principal.application = $app
  match:
    $app over 10m
  outcome:
    $hostnames = array($e.principal.hostname) // yields 4.
    $security_action_count = count($e.security_results.action) // yields 4.
  condition:
    $e
}

Enregistrement d'événement avant le désimbrication du champ répété

Le tableau suivant présente l'enregistrement d'événement avant le désimbrication du champ répété:

metadata.id principal.application principal.hostname security_results
aaaaaaaaa Google SecOps google.com [ { action: [ ALLOW, FAIL ] }, { action: [ CHALLENGE, BLOCK ] } ]

Enregistrement d'événement après désimbrication de champs répétés

Le tableau suivant présente l'enregistrement d'événement après avoir désimbriqué le champ répété:

metadata.id principal.application principal.hostname security_results.action
aaaaaaaaa Google SecOps google.com AUTORISER
aaaaaaaaa Google SecOps google.com FAIL
aaaaaaaaa Google SecOps google.com DÉFI
aaaaaaaaa Google SecOps google.com BLOQUER

Solution

Les agrégations qui ignorent ou éliminent les valeurs en double ne sont pas affectées par ce comportement de désimbrication. Utilisez la version distincte d'une agrégation si vous rencontrez des valeurs de résultat inattendues en raison d'un désimbriquement.

Les agrégations suivantes ne sont pas affectées par le comportement de désimbrication décrit précédemment.

  • max()
  • min()
  • array_distinct()
  • count_distinct()

Agrégations de résultats avec plusieurs variables d'événement

Si une règle contient plusieurs variables d'événement, un élément distinct est ajouté à l'agrégation pour chaque combinaison d'événements incluse dans la détection. Par exemple, si l'exemple de règle suivant est exécuté sur les événements listés:

events:
  $e1.field = $e2.field
  $e2.somefield = $ph

match:
  $ph over 1h

outcome:
   $some_outcome = sum(if($e1.otherfield = "value", 1, 0))

condition:
  $e1 and $e2
event1:
  // UDM event 1
  field="a"
  somefield="d"

event2:
  // UDM event 2
  field="b"
  somefield="d"

event3:
  // UDM event 3
  field="c"
  somefield="d"

La somme est calculée pour chaque combinaison d'événements, ce qui vous permet d'utiliser les deux variables d'événement dans les calculs de la valeur du résultat. Les éléments suivants sont utilisés dans le calcul:

1: $e1 = event1, $e2 = event2
2: $e1 = event1, $e2 = event3
3: $e1 = event2, $e2 = event1
4: $e1 = event2, $e2 = event3
5: $e1 = event3, $e2 = event1
5: $e1 = event3, $e2 = event2

La somme maximale potentielle est donc de 6, même si $e2 ne peut correspondre qu'à trois événements distincts.

Cela affecte la somme, le nombre et le tableau. Pour le nombre et le tableau, l'utilisation de count_distinct ou de array_distinct peut résoudre le problème, mais il n'existe aucun moyen de contourner le problème pour la somme.

Parenthèses au début d'une expression

L'utilisation de parenthèses au début d'une expression déclenche l'erreur suivante:

parsing: error with token: ")"
invalid operator in events predicate

L'exemple suivant génère ce type d'erreur:

($event.metadata.ingested_timestamp.seconds -
$event.metadata.event_timestamp.seconds) / 3600 > 1

Les variantes de syntaxe suivantes renvoient le même résultat, mais avec une syntaxe valide:

$event.metadata.ingested_timestamp.seconds / 3600 -
$event.metadata.event_timestamp.seconds / 3600 > 1
    1 / 3600 * ($event.metadata.ingested_timestamp.seconds -
$event.metadata.event_timestamp.seconds) > 1
    1 < ($event.metadata.ingested_timestamp.seconds -
$event.metadata.event_timestamp.seconds) / 3600

Le tableau d'index dans le résultat nécessite une agrégation pour les valeurs uniques dans un champ répété

L'indexation de tableaux dans la section "Résultat" nécessite toujours une agrégation. Par exemple, le code suivant ne fonctionne pas:

outcome:
  $principal_user_dept = $suspicious.principal.user.department[0]

Toutefois, vous pouvez enregistrer la sortie de l'indice de tableau dans une variable d'espace réservé et utiliser cette variable dans la section "Résultat", comme indiqué ci-dessous:

events:
  $principal_user_dept = $suspicious.principal.user.department[0]

outcome:
  $principal_user_department = $principal_user_dept

Condition OU avec non-existence

Si une condition OR est appliquée entre deux variables d'événement distinctes et si la règle correspond à une non-existence, la règle se compile correctement, mais peut générer des détections positives. Par exemple, la syntaxe de règle suivante peut correspondre à des événements avec $event_a.field = "something", même si ce n'est pas censé.

events:
     not ($event_a.field = "something" **or** $event_b.field = "something")
condition:
     $event_a and #event_b >= 0

Pour contourner ce problème, séparez les conditions en deux blocs, où chaque bloc n'applique le filtre qu'à une seule variable, comme illustré ci-dessous:

events:
     not ($event_a.field = "something")
     not ($event_b.field = "something")
condition:
     $event_a and #event_b >= 0

Arithmétique avec des champs d'événement non signés

Si vous essayez d'utiliser une constante entière dans une opération arithmétique avec un champ UDM dont le type est un entier non signé, une erreur s'affiche. Exemple :

events:
  $total_bytes = $e.network.received_bytes * 2

Le champ udm.network.received_bytes est un entier non signé. Cela se produit parce que les constantes entières sont par défaut des entiers signés, qui ne fonctionnent pas avec les entiers non signés dans les opérations arithmétiques.

Le moyen de contourner le problème consiste à forcer la constante entière à un nombre à virgule flottante, qui fonctionnera ensuite avec l'entier sans signature. Exemple :

events:
  $total_bytes = $e.network.received_bytes * (2/1)

Cohérence à terme et faux positifs dans l'enrichissement GeoIP

Le système donne la priorité à la rapidité plutôt qu'à la précision immédiate lors des premières étapes d'enrichissement (streaming et sensible à la latence), ce qui peut entraîner des données manquantes et des faux positifs potentiels. Le système continuera d'enrichir les données en arrière-plan, mais il est possible qu'elles ne soient pas disponibles au moment de l'exécution de la règle. Cela fait partie du processus normal de consistance finale. Pour éviter ces types de faux positifs, ne comptez pas sur l'existence de champs enrichis dans les événements pour déclencher des détections.

Prenons l'exemple de l'événement de règle suivant:

$e.principal.ip_geo_artifact.network.asn = "16509" AND
$e.principal.ip_geo_artifact.location.country_or_region = "United Kingdom"

La règle repose sur le fait que l'événement doit contenir $e.principal.ip_geo_artifact.network.asn = "16509" ET $e.principal.ip_geo_artifact.location.country_or_region = "United Kingdom", qui sont tous deux des champs enrichis. Si l'enrichissement n'est pas terminé à temps, la règle génère un faux positif.

Pour éviter cela, une meilleure vérification de cette règle serait la suivante:

$e.principal.ip_geo_artifact.network.asn != "" AND 
$e.principal.ip_geo_artifact.network.asn = "16509" AND
$e.principal.ip_geo_artifact.location.country_or_region != "" AND
$e.principal.ip_geo_artifact.location.country_or_region = "United Kingdom"

Cette règle empêche l'événement d'être déclenché par des adresses IP associées à l'ASN 16509, mais situées en dehors du Royaume-Uni. Cela améliore la précision globale de la règle.