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 des 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'é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
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 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 :
| event copy | 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 une copie d'événement satisfait toutes les conditions non modifiées du champ répété, l'événement dans son ensemble satisfait toutes les conditions. Par conséquent, si vous avez plusieurs conditions sur un champ répété, une seule copie d'événement doit toutes les satisfaire. Les exemples de requêtes suivants utilisent l'ensemble de données d'exemple 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 d'ensemble de données event_original, car il n'existe aucune copie d'événement dans $e.principal.ip qui 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 :
| event copy | 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'espaces réservés. 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, l'espace réservé prend la valeur du champ répété de event_copy_n pour chacune des copies d'événement, où n est le numéro de la copie d'événement. Si l'espace réservé est utilisé dans la section de 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. Le code de substitution `$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 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. Le code de substitution $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 "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 de l'utilisation 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. Lorsqu'elles sont utilisées dans la section outcome, le résultat est calculé à l'aide des seuls éléments qui ont satisfait aux sections précédentes.
Prenons l'exemple de 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 consiste à copier les événements :
| 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" | "host" | event_id |
La section des événements filtrera 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 match regroupera ensuite les variables de correspondance, et la section outcome effectuera 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. Comme 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 s'affichent dans l'exemple d'événement, car celui-ci utilise event_original.
Indexation de tableaux
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 tableau ne peut pas être combinée avec
anyouall. Par exemple,any $e.intermediary.ip[0]n'est pas valide. - L'indexation de tableaux ne peut pas être combinée à la syntaxe de cartes. 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'y a qu'un index pourip.
Messages répétés
Lorsqu'un champ message est répété, cela a pour effet involontaire de réduire la probabilité d'une correspondance. C'est ce que nous allons voir 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 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 s'applique 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 qui satisfait à 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 est appliquée aux copies suivantes :
| event copy | 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 n'utilisait pas l'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.