Champs répétés
Dans le modèle de données unifié (UDM), 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. Ce document explique comment utiliser des expressions, des espaces réservés, l'indexation de tableaux et les messages répétés pour les champs UDM répétés.
Expressions booléennes et champs répétés
Les expressions booléennes modifiées et non modifiées peuvent agir sur les champs répétés.
Prenons l'exemple 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
Utilisez les modificateurs any et all dans les expressions des champs répétés.
any: si un élément du champ répété remplit la condition, l'événement dans son ensemble remplit la condition. Exemple :event_originalsatisfaitany $e.principal.ip = "192.0.2.1"- Échec de
event_originalany $e.repeated_field.field_a = "9.9.9.9"
all: si tous les éléments du champ répété remplissent la condition, l'événement dans son ensemble remplit la condition. Exemple :event_originalsatisfaitnet.ip_in_range_cidr(all $e.principal.ip, "192.0.2.0/8")- Échec de
event_originalall $e.principal.ip = "192.0.2.2"
Lorsque vous écrivez une condition avec any ou all, sachez que nier la condition avec not peut ne pas avoir la même signification que d'utiliser l'opérateur de négation.
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 requête vérifie qu'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 requête vérifie qu'aucune adresse IP ne correspond à192.168.12.16.
Contraintes :
- Les opérateurs
anyetallne sont compatibles qu'avec les champs répétés (et non avec les champs scalaires). anyetallne peuvent pas être utilisés pour joindre deux champs répétés. Par exemple,any $e1.principal.ip = $e2.principal.ipn'est pas valide.- Les opérateurs
anyetallne sont pas compatibles avec l'expression de la liste de référence.
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 requête 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 s'applique aux copies suivantes :
| copie d'événement | principal.ip | principal.hostname |
|---|---|---|
| event_copy_1 | "192.0.2.1" | "host" |
| event_copy_2 | "192.0.2.2" | "host" |
| event_copy_3 | "192.0.2.3" | "host" |
Si une copie d'événement répond à toutes les conditions non modifiées du champ répété, l'événement dans son ensemble répond à toutes les conditions. Par conséquent, si vous avez plusieurs conditions sur un champ répété, une seule copie d'événement doit satisfaire toutes ces conditions. Les exemples de requêtes suivants utilisent l'ensemble de données précédent pour illustrer ce comportement.
Exemple : Expressions non modifiées
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 satisfait à 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 aucune correspondance lorsqu'elle est exécutée sur l'exemple de jeu de données event_original, car aucune copie d'événement dans $e.principal.ip ne satisfait _tous_ les prédicats d'événement.
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 les champs répétés sont compatibles avec les expressions non modifiées sur les champs répétés, car la liste des éléments est la même pour chaque copie d'événement. Prenons l'exemple de règle suivant :
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 s'applique aux copies suivantes :
| copie d'événement | principal.ip | any $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 satisfont any $e.principal.ip = "192.0.2.1", mais seule event_copy_3 satisfait $e.principal.ip = "192.0.2.3". L'événement dans son ensemble correspondrait alors.
Voici une autre façon de considérer ces types d'expressions :
- Les expressions sur les champs répétés qui utilisent
anyouallfonctionnent sur la liste dansevent_original. - Les expressions sur les champs répétés qui n'utilisent pas
anyniallfonctionnent sur des événementsevent_copy_nindividuels.
Espaces réservés et champs répétés
Les champs répétés fonctionnent avec les attributions d'espace réservé. Comme pour les expressions non modifiées sur les champs répétés, une copie de l'événement est créée pour chaque élément. En reprenant l'exemple de event_copy, le code de substitution prend la valeur du champ répété de event_copy_n, pour chacune des copies d'événement où n correspond au numéro de la copie d'événement. Si l'espace réservé est utilisé dans la section "Correspondance", cela peut entraîner plusieurs correspondances.
Exemple : Espace réservé pour un champ répété
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 satisfait les prédicats de la règle. Les exemples d'événements de la correspondance ne contiennent qu'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 est égal à différentes valeurs pour chacune des différentes copies event_copy_n.
Le regroupement est effectué sur $ip, car il se trouve dans la section "Correspondances". Vous obtenez donc 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 utilisant des espaces réservés attribués à des champs répétés
Des espaces réservés sont attribués à chaque élément de chaque champ répété, et non à la liste entière. Lorsqu'ils sont utilisés dans la section outcome, le résultat est calculé en utilisant uniquement les éléments qui ont satisfait aux sections précédentes.
Prenons l'exemple de règle suivant :
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 consiste à copier les événements :
| copie d'événement | $ip | $host | $e |
|---|---|---|---|
| event_copy_1 | "192.0.2.1" | "host" | event_id |
| event_copy_2 | "192.0.2.2" | "host" | event_id |
| event_copy_3 | "192.0.2.3" | "host" | event_id |
La section "Événements" filtrera ensuite les lignes qui ne correspondent pas aux filtres :
| copie d'événement | $ip | $host | $e |
|---|---|---|---|
| event_copy_1 | "192.0.2.1" | "host" | event_id |
| event_copy_2 | "192.0.2.2" | "host" | event_id |
event_copy_3 est filtré, car "192.0.2.3" ne respecte pas $ip = "192.0.2.1" or $ip = "192.0.2.2".
La section match regroupe ensuite les données par variables de correspondance, et la section outcome effectue l'agrégation sur chaque groupe :
| $host | $o | $e |
|---|---|---|
| "host" | ["192.0.2.1", "192.0.2.2"] | event_id |
$o = array_distinct($ip) est calculé à l'aide de $ip de l'étape précédente, et non de l'étape de copie des événements.
Enfin, la section condition filtrera chaque groupe. Étant donné que cette règle vérifie simplement l'existence de $e, la ligne précédente générera une seule détection.
$o ne contient pas tous les éléments de $e.principal.ip, car tous les éléments ne remplissaient pas toutes les conditions de la section "É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 tableau
Vous pouvez effectuer l'indexation de tableaux 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 à partir de 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 renvoyée esttrue.
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 surint) ne sont pas comptabilisées. - L'indexation de tableaux ne peut pas être combinée avec
anyniall. Par exemple,any $e.intermediary.ip[0]n'est pas valide. - L'indexation de tableaux ne peut pas être combinée à la syntaxe de carte. Par exemple,
$e.additional.fields[0]["key"]n'est pas valide. - Si le chemin d'accès au 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, carintermediaryetipsont tous les deux des champs répétés, mais il n'existe qu'un index pourip.
Messages répétés
Lorsqu'un champ message est répété, cela réduit involontairement la probabilité d'une correspondance. Ce processus est illustré dans les exemples suivants.
Prenons l'exemple 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 les 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 l'exemple de règle suivant :
rule repeated_message_1 {
meta:
events:
$e.about.ip = "192.0.2.1"
$e.about.hostname = "bob"
condition:
$e
}
La règle s'applique aux copies suivantes :
| copie d'é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 qui satisfasse toutes les expressions.
Messages répétés et indexation de tableaux
Un autre comportement inattendu peut se produire lorsque vous utilisez l'indexation de tableaux avec des expressions non modifiées sur des champs de messages 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 d'événement | about.ip | about[1].hostname |
|---|---|---|
| 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 satisfait 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 ne comportait pas d'indexation de tableau et n'a produit aucune correspondance, tandis que la règle repeated_message_2 utilisait l'indexation de tableau et a produit une correspondance.
Vous avez encore besoin d'aide ? Obtenez des réponses de membres de la communauté et de professionnels Google SecOps.