Syntaxe du langage YARA-L 2.0
Cette section décrit les principaux éléments de la syntaxe YARA-L. Consultez également la présentation du langage YARA-L 2.0.
Structure des règles
Pour YARA-L 2.0, vous devez spécifier les déclarations, définitions et utilisations de variables dans l'ordre suivant :
- méta
- en direct
- match (facultatif)
- résultat (facultatif)
- condition
- options (facultatif)
L'exemple suivant illustre 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 "Meta" est composée de plusieurs lignes, chacune définissant 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 :
meta:
author = "Google"
severity = "HIGH"
Syntaxe de la section "Events" (Événements)
Dans la section events
, listez les prédicats pour spécifier les éléments suivants :
- Déclarations de variables
- Filtres de variables d'événement
- Jointures de 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 équivalents, comme le montrent 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 seule 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
Équivalent à :
$e1.source.ip = $ip
$e1.source.ip = $e2.target.ip
Lorsqu'une variable est utilisée, elle doit être déclarée. Si une variable est utilisée sans déclaration, elle est considérée comme une erreur de compilation.
Filtres de variables d'événement
Une expression booléenne qui agit sur une seule variable d'événement est considérée comme un filtre.
Jointures de variables d'événement
Toutes les variables d'événement utilisées dans la règle doivent être associées à toutes les autres variables d'événement de l'une des manières suivantes :
Directement via une comparaison d'égalité entre les champs d'événement des deux variables d'événement jointes, par exemple :
$e1.field = $e2.field
. L'expression ne doit pas inclure d'arithmétique.Indirectement, par le biais d'une jointure transitive n'impliquant qu'un champ d'événement (voir Déclaration de variable pour la définition de "jointure transitive"). L'expression ne doit pas inclure d'arithmétique.
Par exemple, en supposant que $e1, $e2 et $e3 soient 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
Voici toutefois 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 "Correspondance"
Dans la section match
, listez les variables de correspondance pour les événements de groupe avant de rechercher les conditions de correspondance. Ces champs sont renvoyés avec chaque correspondance.
- Spécifiez ce que représente chaque variable de correspondance dans la section
events
. - Spécifiez la durée à utiliser pour corréler les événements après le mot clé
over
. Les événements en dehors de la période sont ignorés. Utilisez la syntaxe suivante pour spécifier la durée :
<number><m/h/d>
Où
m/h/d
signifie respectivement 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 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. Le délai spécifié est de cinq minutes. Les événements qui sont espacé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 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 qui se produisent à plus d'une heure d'intervalle ne sont pas corrélés. La règle ne les considère pas comme 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 qui sont espacé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 sections match
non valides :
var1, var2 over 5m // invalid variable name
$user 1h // missing keyword
Gestion des valeurs nulles dans la section "Correspondance"
Le moteur de règles filtre implicitement les valeurs nulles pour tous les espaces réservés utilisés dans la section "Correspondance" (""
pour les chaînes, 0
pour les nombres, false
pour les valeurs booléennes et la valeur à la position 0 pour les types énumérés).
L'exemple suivant illustre des 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 nulles des espaces réservés utilisés dans la section "Correspondance". L'exemple suivant illustre des 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 plage de temps d'exécution de la règle est divisée en un ensemble de fenêtres de saut qui se chevauchent, chacune 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 la plage horaire [1:00, 2:00], avec une section match
sur 30m
, un ensemble possible de fenêtres de chevauchement pouvant être générées est [1:00, 1:30], [1:03, 1:33] et [1:06, 1:36].
Ces périodes permettent de corréler plusieurs événements.
Fenêtre glissante
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'à deux 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 produisent dans la même fenêtre de saut générée.
Pour rechercher plus efficacement de telles séquences d'événements, il est préférable d'utiliser des fenêtres glissantes.
Des 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 pivot 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 suivant 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 dans 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 pivot est la variable d'événement sur laquelle sont basées les périodes glissantes. Si vous utilisez le mot clé before
, des fenêtres glissantes sont générées, se terminant à chaque occurrence de l'événement pivot. Si le mot clé after
est utilisé, des fenêtres glissantes sont générées à partir de chaque occurrence de l'événement pivot.
Voici des exemples d'utilisations valides de la fenêtre glissante :
$var1, $var2 over 5m after $e1
$user over 1h before $e2
Consultez un exemple de règle de fenêtre glissante.
Nous vous recommandons de ne pas utiliser de fenêtres glissantes pour les règles à événement unique, car elles sont conçues pour détecter plusieurs événements. Si l'une de vos règles appartient à cette catégorie, nous vous recommandons l'une des solutions de contournement suivantes :
- Convertissez la règle pour qu'elle utilise plusieurs variables d'événement, puis mettez à jour la section des conditions si la règle nécessite plusieurs occurrences de l'événement.
- Vous pouvez également 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
- Vous pouvez également ajouter des filtres d'horodatage au lieu d'utiliser une fenêtre glissante.
Par exemple :
- Retirez la fenêtre coulissante.
Syntaxe de la section "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 différentes pour les résultats.
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 être de type entier ou flottant. Si la valeur est renseignée, l'icône risk_score
s'affiche dans la vue Enterprise Insights pour les alertes provenant de détections de règles.
Si vous n'incluez pas de variable $risk_score
dans la section "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 des variables 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 la calculer. Nous acceptons les types de données de résultats suivants :
- entier
- nombres à virgule flottante
- chaîne
- listes d'entiers
- listes de nombres à virgule flottante
- 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 : "si BOOL_CLAUSE est true, 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
. Par exemple, il peut contenir :
Noms de champs UDM avec opérateur de comparaison, par 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")
les fonctions 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)
comparaison des agrégations, par exemple :
if(count($login.metadata.event_timestamp.seconds) > 5, 100, 0)
THEN_CLAUSE et ELSE_CLAUSE doivent correspondre au même type de données. Nous acceptons les entiers, les nombres à virgule flottante et les chaînes.
Vous pouvez omettre ELSE_CLAUSE si le type de données est un entier ou un float. Si elle est omise, ELSE_CLAUSE renvoie 0. Exemple :
`if($e.field = "a", 5)` is equivalent to `if($e.field = "a", 5, 0)`
Vous devez fournir 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 des types de données entiers ou flottants dans les sections outcome
et events
d'une règle. Google Security Operations accepte l'addition, la soustraction, la multiplication, la division et le modulo en tant qu'opérateurs de premier niveau dans un calcul.
L'extrait 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 Agrégations) :
- Champs d'événements 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 nombres entiers ou à virgule flottante
- Agrégations renvoyant des entiers ou des nombres à virgule flottante
Le module n'est pas autorisé sur les nombres à virgule flottante.
Variables d'espace réservé dans les résultats
Lorsque vous calculez des variables de résultat, vous pouvez utiliser des variables de substitution 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 d'événement unique :
// 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 multi-événement :
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 des résultats
Les variables de résultat peuvent être utilisées pour dériver d'autres variables de résultat, de la même manière que les 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 (voir Agrégations).
Dans l'exemple suivant, la variable de résultat $risk_score
tire sa valeur de la variable de résultat $event_count
:
Exemple multi-événement :
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
ouall
Agrégations
Les champs d'événement répétés sont des valeurs non scalaires. Autrement dit, 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 avoir zéro, une ou plusieurs valeurs d'adresse IP. Il s'agit d'une valeur non scalaire. En revanche, 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énement non répétés et les champs d'événement répétés utilisés dans la section "Résultat" d'une règle avec une période 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 de résultat :
rule OutcomeAndMatchWindow{
...
match:
$userid over 5m
outcome:
$hostnames = array($e.principal.hostname)
...
}
Chaque période de cinq minutes pendant laquelle la règle s'exécute peut contenir zéro, un ou plusieurs événements. La section "Résultat" fonctionne sur tous les événements d'une fenêtre de correspondance. Toute variable de champ d'événement mentionnée dans la section "Résultat" peut pointer vers zéro, une ou plusieurs valeurs du champ pour chaque événement de la période de correspondance.
Par exemple, si un intervalle de cinq minutes contient cinq événements $e
, $e.principal.hostname
dans la section "Résultat" pointe vers cinq noms d'hôte différents. La variable de champ d'événement $e.principal.hostname
est traitée comme une valeur non scalaire dans la section outcome
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 sur les résultats, les valeurs suivantes ne sont pas 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 pour les événements (répétés ou non) lorsque la règle utilise une section de correspondance
- Champs d'événement répétés lorsque la règle n'utilise pas de section de correspondance
- Espaces réservés pour les événements répétés lorsque la règle n'utilise pas de section de correspondance
Les champs d'événements scalaires, les espaces réservés pour les événements scalaires et les constantes peuvent être encapsulés dans des fonctions d'agrégation dans les règles qui n'incluent pas de section de correspondance. Toutefois, dans la plupart des cas, ces agrégations renvoient la valeur encapsulée, ce qui les rend inutiles.
Une exception est l'agrégation array()
, que vous pouvez utiliser pour convertir explicitement 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 référencées dans une autre attribution de résultat.
Vous pouvez utiliser les fonctions d'agrégation suivantes :
max()
: génère la valeur maximale parmi toutes les valeurs possibles. Ne fonctionne qu'avec les nombres entiers et à virgule flottante.min()
: génère la valeur minimale parmi toutes les valeurs possibles. Ne fonctionne qu'avec les nombres entiers et à virgule flottante.sum()
: génère la somme de toutes les valeurs possibles. Ne fonctionne qu'avec les nombres entiers et à virgule flottante.count_distinct()
: collecte toutes les valeurs possibles, puis génère le nombre distinct de valeurs possibles.count()
: se comporte commecount_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 des valeurs distinctes sera tronquée à 1 000 éléments aléatoires. La déduplication permettant d'obtenir une liste distincte est appliquée en premier, puis la troncature.array()
: se comporte commearray_distinct()
, mais renvoie une liste de valeurs non distinctes. Il tronque également la liste des valeurs à 1 000 éléments aléatoires.period_start_for_max()
: début de la période au cours de laquelle la valeur listée a atteint son maximum.period_start_for_min()
: début de la période au cours de laquelle la valeur minimale de la valeur listée s'est produite.
La fonction d'agrégation est importante lorsqu'une règle inclut une section condition
qui spécifie que plusieurs événements doivent exister, car la fonction d'agrégation fonctionnera sur tous les événements qui ont généré la détection.
Par exemple, si vos sections outcome
et condition
contiennent les éléments suivants :
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 de condition exige qu'il y ait plus d'un event
pour chaque détection, les fonctions d'agrégation fonctionneront 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 les suivantes :
- $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 à connaître lorsque vous utilisez la section "Résultat" :
Autres remarques et restrictions :
- La section
outcome
ne peut pas faire référence à une nouvelle variable d'espace réservé qui n'a pas déjà été définie dans la sectionevents
ou dans la sectionoutcome
. - La section
outcome
ne peut pas utiliser de variables d'événement qui n'ont pas été définies dans la sectionevents
. - La section
outcome
peut utiliser un champ d'événement qui n'a pas été utilisé dans la sectionevents
, à condition que la variable d'événement à laquelle appartient le champ d'événement ait déjà été définie dans la sectionevents
. - La section
outcome
ne peut corréler que les variables d'événement qui ont déjà été corrélées dans la sectionevents
. Les corrélations se produisent lorsque deux champs d'événement provenant de variables d'événement différentes sont mis en équation.
Vous trouverez un exemple utilisant la section "Résultat" dans Présentation de YARA-L 2.0. Pour en savoir plus sur la déduplication des détections avec la section "Résultat", consultez Créer des analyses contextuelles.
Syntaxe de la section "Conditions"
- 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, Conditions liées aux événements et aux 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 sectionoutcome
. Pour en savoir plus, consultez la section suivante, Conditions de résultat.
Nombre de caractères
Le caractère #
est un caractère spécial dans la section condition
. S'il est utilisé avant un nom de variable d'événement ou d'espace réservé, il représente le nombre d'événements ou de valeurs distincts qui répondent à toutes les conditions de la section events
.
Par exemple, #c > 1
signifie que la variable c
doit se produire 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 le nom d'une variable de résultat, elle représente la valeur de ce résultat.
S'il est utilisé avant un nom de variable d'événement ou d'espace réservé (par exemple, $event
), il représente #event > 0
.
Conditions d'événement et d'espace réservé
Listez les prédicats de condition pour les événements et les variables de substitution à l'aide des mots clés and
ou or
. Vous pouvez utiliser and
pour joindre n'importe quelle combinaison de conditions. Toutefois, vous ne pouvez utiliser or
que lorsque toutes les conditions font référence à la même variable d'événement.
Voici un exemple valide d'utilisation de or
entre deux espaces réservés sur 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 des conditions limitées. 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 >= 0
#var >= m // where m > 0
Les conditions suivantes sont des conditions non liées. Elles permettent à la variable d'événement associée de ne pas exister, 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 sur la variable d'événement génère une valeur nulle. Les conditions non liées peuvent être utilisées pour détecter l'absence d'un événement sur une période donnée. Par exemple, un événement de menace sans événement d'atténuation dans un intervalle 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 de non-existence
Pour qu'une règle avec non-existence soit compilée, elle doit répondre aux exigences suivantes :
- Au moins un événement UDM doit comporter une condition limitée (c'est-à-dire qu'au moins un événement UDM doit exister).
- Si un espace réservé comporte une condition illimitée, il doit être associé à au moins un événement UDM limité.
- Si une entité comporte une condition non limitée, elle doit être associée à au moins un événement UDM limité.
Prenons l'exemple de la règle suivante, dont la section "Condition" est omise :
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
n'est pas limité, ce qui est autorisé, car il est associé à$u1
, qui est limité. Si$e2
n'était pas associé à$u1
, cela ne serait pas valide.
#port > 50 and #ip = 0
- Aucun événement ni aucune entité UDM n'est présent dans la section "Condition". Toutefois, les espaces réservés présents couvrent tous les événements et entités UDM.
$ip
est attribué à$u1
et$u2
, et#ip = 0
est une condition non limitée. Toutefois, les conditions limitées sont plus strictes que les conditions non limitées. Étant donné que$port
est attribué à$u1
et que#port > 50
est une condition limitée,$u1
reste limité.
Voici des exemples non valides pour <condition_section>
:
$u1 and $e1
- Chaque événement et entité UDM figurant dans la section "Événements" doit figurer dans la section "Conditions" (ou avoir un espace réservé qui lui est attribué et qui apparaît dans la section "Conditions").
$u1, $u2, $e1, $u2, #port > 50
- Les virgules ne sont pas autorisées comme séparateurs de conditions.
!$u1 and !$u2 and $e1 and $e2
- Ne respecte pas la première exigence selon laquelle au moins un événement UDM doit être limité.
($u1 or #port < 50) and $u2 and $e1 and $e2
- Le mot clé
or
n'est pas compatible avec les conditions non liées.
- Le mot clé
($u1 or $u2) and $e1 and $e2
- Le mot clé
or
n'est pas compatible entre différentes variables d'événement.
- Le mot clé
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é.
- Le mot clé
#port < 50 and #ip = 0
- Les espaces réservés présents couvrent tous les événements et entités UDM. Toutefois, toutes les conditions sont illimitées. Cela signifie qu'aucun des événements UDM n'est limité, ce qui empêche la compilation de la règle.
Conditions de résultat
Indiquez 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 selon le type de variable de résultat :
integer : comparer à un littéral entier avec les opérateurs
=, >, >=, <, <=, !=
, par exemple :$risk_score > 10
float : comparer à un littéral float avec les opérateurs
=, >, >=, <, <=, !=
, par exemple :$risk_score <= 5.5
string : comparez à un littéral de chaîne avec
=
ou!=
, 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 une condition de résultat dans une règle comportant une section "Correspondance", la règle sera classée comme règle multi-événement pour le quota de règles. Pour en savoir plus sur les classifications d'événements uniques et multiples, consultez Règle d'événement unique et Règle d'événements multiples.
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 indiqué 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 allow_zero_values = true
à la section des options de votre règle. Cela empêchera la règle de filtrer implicitement les valeurs nulles des espaces réservés utilisés dans la section "Correspondance", comme décrit dans la section Gestion des valeurs nulles dans la section "Correspondance".
suppression_window
L'option suppression_window
vous permet de contrôler la fréquence à laquelle une règle déclenche une détection. Il empêche la même règle de générer plusieurs détections au cours d'une période spécifiée, même si les conditions de la règle sont remplies plusieurs fois.
Le fenêtrage de suppression utilise une approche de fenêtre Tumbling, qui supprime les doublons sur une fenêtre de taille fixe et sans chevauchement.
Vous pouvez éventuellement fournir un suppression_key
pour affiner davantage les instances de la règle qui sont supprimées pendant la période de suppression. Si aucune valeur n'est spécifiée, toutes les instances de la règle sont supprimées. Cette clé est définie comme une variable de résultat.
Dans l'exemple suivant, suppression_window
est défini sur 5m
et suppression_key
est défini sur la variable $hostname
. Une fois que la règle a déclenché une détection pour $hostname
, toute détection supplémentaire pour $hostname
est supprimée pendant les cinq minutes suivantes. Toutefois, si la règle se déclenche sur un événement avec un nom d'hôte différent, une détection est créée.
La valeur par défaut de suppression_window
est 0
, ce qui signifie que la période de suppression est désactivée par défaut. Cette option ne fonctionne que pour les règles d'événement unique qui ne comportent pas de section match
.
Exemple :
rule SuppressionWindowExample {
// Other rule sections
outcome:
$suppression_key = $hostname
options:
suppression_window = 5m
}
Règles de détection composites
La détection composite dans Google SecOps consiste à connecter plusieurs règles YARA-L. Cette section explique comment créer une règle composite. Pour obtenir un aperçu des détections composites, consultez Présentation des détections composites.
Structure des règles
Les règles de détection composites sont toujours des règles multi-événements et suivent la même structure et syntaxe. Les exigences suivantes s'appliquent aux règles de détection composites :
- Les règles composites doivent utiliser une section
match
pour définir les conditions de déclenchement de la détection. - Les règles qui utilisent à la fois des champs de détection et des événements UDM doivent joindre explicitement ces sources de données.
Pour en savoir plus sur les limites des règles, consultez Limites.
Utiliser les détections comme entrée pour les règles
Les règles composites peuvent faire référence aux détections de règles générées par n'importe quelle règle personnalisée ou sélectionnée. Google SecOps propose deux méthodes pour ce faire.
Faire référence au contenu de détection à l'aide de variables de résultat, de variables de correspondance ou de métalibellés
Pour accéder aux données d'une détection sans faire référence aux événements UDM d'origine, utilisez les variables outcome
, match
ou les libellés meta
. Nous vous recommandons cette approche, car elle offre une plus grande flexibilité et une meilleure compatibilité entre les différents types de règles.
Par exemple, plusieurs règles peuvent stocker une chaîne (telle qu'une URL, un nom de fichier ou une clé de registre) dans une variable outcome
commune si vous recherchez cette chaîne dans différents contextes. Pour accéder à cette chaîne à partir d'une règle composite, commencez par detection
et recherchez les informations pertinentes à l'aide des éléments de la ressource Collection.
Exemple : Supposons qu'une règle de détection génère les informations suivantes :
- Variable de résultat :
dest_domain = "cymbal.com"
- Champ UDM :
target.hostname = "cymbal.com"
Dans la règle composite, vous pouvez accéder à ces données à l'aide des chemins suivants :
detection.detection.outcomes["dest_domain"]
pour accéder à la variable de résultatdest_domain
.detection.collection_elements.references.event.target.hostname
pour accéder au champ UDMtarget.hostname
.detection.time_window.start_time.seconds
pour accéder au code temporel de la détection.
L'API Collection et l'API SecurityResult
permettent d'accéder aux deux :
- Valeurs des métadonnées et des résultats de la détection (
detection.detection
) - Événements UDM sous-jacents des règles référencées (
collection_elements
)
Faire référence à du contenu de détection à l'aide de l'ID ou du nom de la règle
Vous pouvez faire référence à une règle par son nom ou son ID. Nous vous recommandons cette approche lorsque votre logique de détection dépend de règles spécifiques. Faire référence aux règles pertinentes par leur nom ou leur ID permet d'améliorer les performances et d'éviter les délais d'expiration en réduisant les données analysées. Par exemple, vous pouvez interroger directement des champs tels que target.url
ou principal.ip
à partir d'une détection précédente connue.
Faire référence à une règle par son ID (recommandé) : utilisez le champ
detection.detection.rule_id
pour faire référence à une règle par son ID. Vous trouverez l'ID de la règle dans l'URL de la règle dans Google SecOps. Les règles générées par les utilisateurs ont des ID au formatru_UUID
, tandis que les détections organisées ont des ID au formatur_UUID
. Exemple :detection.detection.rule_id = "ru_e0d3f371-6832-4d20-b0ad-1f4e234acb2b"
Faire référence à une règle par son nom : utilisez le champ
detection.detection.rule_name
pour faire référence à une règle par son nom. Vous pouvez spécifier le nom exact de la règle ou utiliser une expression régulière pour la faire correspondre. Exemple :detection.detection.rule_name = "My Rule Name"
detection.detection.rule_name = "/PartOfName/"
Remarque : Nous vous recommandons d'utiliser les ID de règles pour les références, car ils sont uniques et ne changent pas. Les noms de règles peuvent être modifiés, ce qui peut potentiellement interrompre votre détection composite.
Combiner des événements et des détections
Les règles composites peuvent combiner différentes sources de données, y compris des événements UDM, des données de graphiques d'entités et des champs de détection. Les consignes suivantes s'appliquent :
- Utilisez des variables distinctes par source : attribuez des variables d'événement uniques à chaque source de données (par exemple,
$e
pour les événements,$d
pour les détections), où la source de données inclut des événements, des entités et des détections. - Associer des sources sur un contexte partagé : associez des sources de données à l'aide de valeurs communes, telles que des ID utilisateur, des adresses IP ou des noms de domaine dans les conditions de votre règle.
- Définissez une période de correspondance : incluez toujours une clause
match
avec une période ne dépassant pas 48 heures.
Exemple :
rule CheckCuratedDetection_with_EDR_and_EG {
meta:
author = "noone@cymbal.com"
events:
$d.detection.detection.rule_name = /SCC: Custom Modules: Configurable Bad Domain/
$d.detection.collection_elements.references.event.network.dns.questions.name = $domain
$d.detection.collection_elements.references.event.principal.asset.hostname = $hostname
$e.metadata.log_type = "LIMACHARLIE_EDR"
$e.metadata.product_event_type = "NETWORK_CONNECTIONS"
$domain = re.capture($e.principal.process.command_line, "\\s([a-zA-Z0-9.-]+\\.[a-zA-Z0-9.-]+)$")
$hostname = re.capture($e.principal.hostname, "([^.]*)")
$prevalence.graph.metadata.entity_type = "DOMAIN_NAME"
$prevalence.graph.metadata.source_type = "DERIVED_CONTEXT"
$prevalence.graph.entity.hostname = $domain
$prevalence.graph.entity.domain.prevalence.day_count = 10
$prevalence.graph.entity.domain.prevalence.rolling_max <= 5
$prevalence.graph.entity.domain.prevalence.rolling_max > 0
match:
$hostname over 1h
outcome:
$risk_score = 80
$CL_target = array($domain)
condition:
$e and $d and $prevalence
}
Créer des détections composites séquentielles
Les détections composites séquentielles identifient des schémas d'événements associés où la séquence de détections est importante, comme une détection de tentative de connexion par force brute, suivie d'une connexion réussie. Ces modèles peuvent combiner plusieurs détections de base, événements UDM bruts ou les deux.
Pour créer une détection composite séquentielle, vous devez appliquer cet ordre dans votre règle. Pour appliquer la séquence attendue, utilisez l'une des méthodes suivantes :
- Fenêtres glissantes : définissez la séquence de détections à l'aide de fenêtres glissantes dans vos conditions
match
. - Comparaisons des codes temporels : comparez les codes temporels des détections dans la logique de votre règle pour vérifier qu'elles se produisent dans l'ordre sélectionné.
Exemple :
events:
$d1.detection.detection.rule_name = "fileEvent_rule"
$userid = $d1.detection.detection.outcomes["user"]
$hostname = $d1.detection.detection.outcomes["hostname"]
$d2.detection.detection.rule_name = "processExecution_rule"
$userid = $d2.detection.detection.outcomes["user"]
$hostname = $d2.detection.detection.outcomes["hostname"]
$d3.detection.detection.rule_name = "networkEvent_rule"
$userid = $d3.detection.detection.outcomes["user"]
$hostname = $d3.detection.detection.outcomes["hostname"]
$d3.detection.collection_elements.references.event.metadata.event_timestamp.seconds > $d2.detection.collection_elements.references.event.metadata.event_timestamp.seconds
match:
$userid over 24h after $d1
Expressions booléennes
Les expressions booléennes sont des expressions de type booléen.
Comparaisons
Pour utiliser une expression binaire 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, il s'agit d'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
. Voici quelques exemples de ces fonctions :
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")
Expressions de liste de référence
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érence.
Expressions logiques
Vous pouvez utiliser les opérateurs logiques and
et or
dans la section events
, comme illustré 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 faible) est not
, and
, or
.
Par exemple, "a or b and c" est évalué comme "a or (b and 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 de manière explicite.
L'ordre d'évaluation peut être différent si l'opérateur and
est implicite dans l'expression.
Par exemple, considérons les expressions de comparaison suivantes où or
est défini de manière explicite. 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 de manière explicite, les prédicats entourant or
sont regroupés et évalués en premier.
Le dernier prédicat, $e2.field = "bar"
, est joint de manière implicite à l'aide de and
. L'ordre d'évaluation est donc modifié.
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 (utiliser un opérateur au lieu de listes de référence).
Dans l'exemple suivant, "USER_UNCATEGORIZED" et "USER_RESOURCE_DELETION" correspondent à 15000 et 15014. La règle recherchera donc tous les événements listé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 avez 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éreront des erreurs de compilation :
$e.metadata.event_type = "NETWORK_DNS" nocase
$e.network.ip_protocol = "TCP" nocase
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.
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 :
- Modifié
- Non modifié
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
Les sections suivantes décrivent l'objectif et l'utilisation des modificateurs any
et all
dans les expressions.
tous
Si un élément du champ répété remplit la condition, l'événement dans son ensemble remplit la condition.
event_original
satisfaitany $e.principal.ip = "192.0.2.1"
.event_original
échoueany $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
satisfaitnet.ip_in_range_cidr(all $e.principal.ip, "192.0.2.0/8")
.event_original
échoueall $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 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 que 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
etall
ne sont compatibles qu'avec les champs répétés (et non avec les champs scalaires). any
etall
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
etall
ne 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 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 s'applique aux copies suivantes :
copie d'é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 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. Autrement dit, si vous définissez plusieurs conditions sur un champ répété, la copie de l'événement doit toutes les remplir. 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
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 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
any
ouall
fonctionnent sur la liste dansevent_original
. - Les expressions sur les champs répétés qui n'utilisent pas
any
niall
fonctionnent sur des événementsevent_copy_n
individuels.
Champs répétés et espaces réservé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.
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 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. Le code de substitution $ip
est égal à différentes valeurs pour chacune des 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. Ainsi, lorsqu'ils sont utilisés dans la section "Résultat", 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" | "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" filtrera ensuite les lignes qui ne correspondent pas aux filtres :
copie d'é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 "Correspondances" regroupe ensuite les données par variables de correspondance, et la section "Résultats" effectue une agrégation sur chaque groupe :
$host | $o | $e |
---|---|---|
"hôte" | ["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 des conditions 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 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 prises en compte. - L'indexation de tableaux ne peut pas être combinée avec
any
niall
. 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, carintermediary
etip
sont 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.
Commentaires
Désignez les commentaires avec deux barres obliques (// comment
) ou des commentaires multilignes délimités par des barres obliques et des astérisques (/* comment */
), comme vous le feriez en C.
Littéraux
Les littéraux entiers et flottants non négatifs, de chaîne, booléens et d'expression régulière sont acceptés.
Littéraux de chaîne et d'expression régulière
Vous pouvez utiliser l'un des caractères de guillemets suivants pour encadrer les chaînes dans YARA-L 2.0. Toutefois, le texte entre guillemets est interprété différemment selon celui que vous utilisez.
Guillemets doubles (") : à utiliser pour les chaînes normales. Doit inclure des caractères d'échappement.
Par exemple : "hello\tworld" —\t est interprété comme une tabulationAccents graves (`) : à utiliser pour interpréter tous les caractères de manière littérale.
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 comme littéraux d'expression régulière lorsque vous utilisez la fonction re.regex()
. Notez que pour les littéraux de chaîne à guillemets doubles, vous devez échapper les barres obliques inverses avec des 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")
$e.network.email.from = /.*altostrat\.com/
Pour faciliter la lecture, Google recommande d'utiliser des guillemets inversés 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 ou égal à |
> | supérieur à |
>= | supérieur ou égal à |
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é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 identifiez les variables d'événement à l'aide d'un nom, d'une source d'événement et de champs d'événement. Les sources autorisées sontudm
(pour les événements normalisés) etgraph
(pour les événements d'entité). Si la source est omise,udm
est définie comme source par défaut. Les champs d'événement sont représentés sous la forme d'une chaîne .<nom de champ> (par exemple, $e.field1.field2). Les chaînes de champs d'événement commencent toujours à partir de la source de premier niveau (UDM ou entité).Variables de correspondance : déclarez-les 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 représente chaque variable de correspondance dans la sectionevents
.Variables d'espace réservé : déclarez-les et définissez-les dans la section
events
. Les variables d'espace réservé sont semblables aux variables de correspondance. Toutefois, vous pouvez utiliser des variables d'espace réservé dans la sectioncondition
pour spécifier des 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énement via des conditions de jointure transitive (pour en savoir plus, consultez Syntaxe de la section "Événements").
Mots clés
Les mots clés de YARA-L 2.0 ne sont pas sensibles à la casse. Par exemple, and
et AND
sont équivalents. Les noms de variables ne doivent pas entrer en conflit avec les mots clés. Par exemple, $AND
ou $outcome
ne sont pas valides.
Voici les mots clés pour les 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
, max
, min
, sum
, array
, array_distinct
, count
, count_distinct
, is
et null
.
Maps
YARA-L est compatible avec l'accès aux cartes pour les structs et les libellés.
Structs 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.
Demandes acceptées
Voici des exemples d'utilisation des mots clés acceptés.
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"])
Attribuer une valeur de carte à 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 acceptées 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 la carte ne peut renvoyer qu'une valeur de chaîne. Dans le cas des types de données Struct, la syntaxe de la carte ne peut accéder qu'aux clés dont les valeurs sont des chaînes. Il n'est pas possible d'accéder aux clés dont les valeurs sont d'autres types primitifs, comme les entiers.
Gestion des valeurs en double
Les accès aux cartes renvoient toujours une seule valeur. Dans le cas limite peu courant où l'accès à la carte peut faire référence à plusieurs valeurs, l'accès à la carte renverra de manière déterministe la première valeur.
Cela peut se produire dans les cas suivants :
Un libellé comporte une clé en double.
La structure des libellés représente une carte, mais n'impose pas l'unicité des clés. Par convention, une carte doit comporter des clés uniques. Google SecOps ne recommande donc pas de remplir un libellé avec des clés en double.
Le texte de la règle
$e.metadata.ingestion_labels["dupe-key"]
renverrait la première valeur possible,val1
, s'il était exécuté 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" } } }
Un libellé possède un champ répété ancêtre.
Un champ répété peut contenir un libellé en tant que champ enfant. Deux entrées différentes dans le champ répété de premier niveau peuvent contenir des libellés ayant la même clé. Le texte de la 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 que vous pouvez utiliser dans les règles et la recherche du moteur de détection.
Ces fonctions peuvent être utilisées dans les parties suivantes d'une règle YARA-L :
- Section
events
. BOOL_CLAUSE
d'une condition dans la section "Résultat".
arrays.concat
arrays.concat(string_array, string_array)
Description
Renvoie un tableau de chaînes en copiant les éléments des tableaux de chaînes d'origine.
Types de données des paramètres
ARRAY_STRINGS
– ARRAY_STRINGS
Type renvoyé
ARRAY_STRINGS
Exemples de code
Exemple 1
L'exemple suivant concatène deux tableaux de chaînes différents.
arrays.concat(["test1", "test2"], ["test3"]) = ["test1", "test2", "test3"]
Exemple 2
L'exemple suivant concatène des tableaux avec une chaîne vide.
arrays.concat([""], [""]) = ["", ""]
Exemple 3
L'exemple suivant concatène des tableaux vides.
arrays.concat([], []) = []
arrays.join_string
arrays.join_string(array_of_strings, optional_delimiter)
Description
Convertit un tableau de chaînes en une seule chaîne séparée par le paramètre facultatif. Si aucun délimiteur n'est fourni, la chaîne vide est utilisée.
Types de données des paramètres
ARRAY_STRINGS
, STRING
Type renvoyé
STRING
Exemples de code
Voici quelques exemples d'utilisation de la fonction :
Exemple 1
Cet exemple joint un tableau avec des éléments non nuls et un délimiteur.
arrays.join_string(["foo", "bar"], ",") = "foo,bar"
Exemple 2
Cet exemple joint un tableau avec un élément nul et un délimiteur.
arrays.join_string(["foo", NULL, "bar"], ",") = "foo,bar"
Exemple 3
Cet exemple joint un tableau avec des éléments non nuls et sans délimiteur.
arrays.join_string(["foo", "bar"]) = "foobar"
arrays.length
arrays.length(repeatedField)
Description
Renvoie le nombre d'éléments de champ répétés.
Types de données des 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 plusieurs champs répétés se trouvent sur le chemin d'accès, renvoie le nombre total d'éléments de champ répétés.
arrays.length($e.intermediary.ip) = 3
arrays.max
arrays.max(array_of_ints_or_floats)
Description
Renvoie l'élément le plus grand d'un tableau ou zéro si le tableau est vide.
Types de données des paramètres
ARRAY_INTS|ARRAY_FLOATS
Type renvoyé
FLOAT
Exemples de code
Voici quelques exemples d'utilisation de la fonction :
Exemple 1
Cet exemple renvoie l'élément le plus grand dans un tableau d'entiers.
arrays.max([10, 20]) = 20.000000
Exemple 2
Cet exemple renvoie l'élément le plus grand dans un tableau de valeurs flottantes.
arrays.max([10.000000, 20.000000]) = 20.000000
arrays.min
arrays.min(array_of_ints_or_floats[, ignore_zeros=false])
Description
Renvoie le plus petit élément d'un tableau ou zéro si le tableau est vide. Si le deuxième argument facultatif est défini sur "true", les éléments égaux à zéro sont ignorés.
Types de données des paramètres
ARRAY_INTS|ARRAY_FLOATS
, BOOL
Type renvoyé
FLOAT
Exemples de code
Voici quelques exemples d'utilisation de la fonction :
Exemple 1
Cet exemple renvoie le plus petit élément d'un tableau d'entiers.
arrays.min([10, 20]) = 10.000000
Exemple 2
Cet exemple renvoie le plus petit élément d'un tableau de valeurs flottantes.
arrays.min([10.000000, 20.000000]) = 10.000000
Exemple 3
Cet exemple renvoie le plus petit élément d'un tableau de nombres à virgule flottante, en ignorant les zéros.
arrays.min([10.000000, 20.000000, 0.0], true) = 10.000000
arrays.size
arrays.size( array )
Description
Renvoie la taille du tableau. Renvoie 0 pour un tableau vide.
Types de données des paramètres
ARRAY_STRINGS|ARRAY_INTS|ARRAY_FLOATS
Type renvoyé
INT
Exemples de code
Exemple 1
Cet exemple utilise un tableau de chaînes contenant deux éléments.
arrays.size(["test1", "test2"]) = 2
Exemple 2
Cet exemple utilise un tableau int contenant trois éléments.
arrays.size([1, 2, 3]) = 3
Exemple 3
Cet exemple utilise un tableau float contenant un élément.
arrays.size([1.200000]) = 1
Exemple 4
Cet exemple utilise un tableau vide.
arrays.size([]) = 0
arrays.index_to_float
arrays.index_to_float(array, index)
Description
Renvoie l'élément à l'index donné d'un tableau. L'élément à cet index est renvoyé sous forme de float.
L'index est une valeur entière qui représente la position d'un élément dans le tableau. Par défaut, le premier élément d'un tableau a un index de 0 et le dernier élément a un index de n-1, où n est la taille du tableau. L'indexation négative permet d'accéder aux éléments de tableau par rapport à la fin du tableau. Par exemple, un index de -1 fait référence au dernier élément du tableau et un index de -2 fait référence à l'avant-dernier élément du tableau.
Types de données des paramètres
ARRAY_STRINGS|ARRAY_INTS|ARRAY_FLOATS
, INT
Type renvoyé
FLOAT
Exemples de code
Exemple 1
L'exemple suivant récupère un élément à l'index 1 à partir d'un tableau de valeurs float.
arrays.index_to_float([1.2, 2.1, 3.5, 4.6], 1) // 2.1
Exemple 2
L'exemple suivant récupère un élément à l'index -1 à partir d'un tableau de valeurs float.
arrays.index_to_float([1.2, 2.1, 3.5, 4.6], 0-1) // 4.6
Exemple 3
L'exemple suivant récupère un élément pour un index supérieur à la taille du tableau.
arrays.index_to_float([1.2, 2.1, 3.5, 4.6], 6) // 0.0
Exemple 4
L'exemple suivant récupère un élément à partir d'un tableau vide.
arrays.index_to_float([], 0) // 0.0
Exemple 5
L'exemple suivant récupère un élément à l'index 1 d'un tableau de chaînes.
arrays.index_to_float(["1.2", "3.3", "2.4"], 1) // 3.3
Exemple 6
L'exemple suivant récupère un élément à l'index 2 d'un tableau d'entiers.
arrays.index_to_float([1, 3, 2], 2) // 2.0
arrays.index_to_int
arrays.index_to_int(array_of_inputs, index)
Description
Renvoie la valeur à un index donné dans un tableau sous forme d'entier.
L'index est une valeur entière qui représente la position d'un élément dans le tableau. Par défaut, le premier élément d'un tableau a un index de 0 et le dernier élément a un index de n-1, où n est la taille du tableau. L'indexation négative permet d'accéder aux éléments de tableau par rapport à la fin du tableau. Par exemple, un index de -1 fait référence au dernier élément du tableau et un index de -2 fait référence à l'avant-dernier élément du tableau.
Types de données des paramètres
ARRAY_STRINGS|ARRAY_INTS|ARRAY_FLOATS
, INT
Type renvoyé
INT
Exemples de code
Exemple 1
Cet appel de fonction renvoie 0 lorsque la valeur à l'index est une chaîne non numérique.
arrays.index_to_int(["str0", "str1", "str2"], 1) = 0
Exemple 2
Cette fonction renvoie l'élément à l'index -1.
arrays.index_to_int(["44", "11", "22", "33"], 0-1) = 33
Exemple 3
Renvoie 0 pour l'élément hors limites.
arrays.index_to_int(["44", "11", "22", "33"], 5) = 0
Exemple 4
Cette fonction récupère l'élément du tableau float à l'index 1.
arrays.index_to_int([1.100000, 1.200000, 1.300000], 1) = 1
Exemple 5
Cette fonction récupère l'élément du tableau d'entiers à l'index 0.
arrays.index_to_int([1, 2, 3], 0) = 1
arrays.index_to_str
arrays.index_to_str(array, index)
Description
Renvoie l'élément à l'index donné du tableau sous forme de chaîne. L'index est une valeur entière qui représente la position d'un élément dans le tableau. Par défaut, le premier élément d'un tableau a un index de 0 et le dernier élément a un index de n-1, où n est la taille du tableau. L'indexation négative permet d'accéder aux éléments du tableau à partir de la fin du tableau. Par exemple, un index de -1 fait référence au dernier élément du tableau et un index de -2 fait référence à l'avant-dernier élément du tableau.
Types de données des paramètres
ARRAY_STRINGS|ARRAY_INTS|ARRAY_FLOATS
, INT
Type renvoyé
STRING
Exemples de code
Exemple 1
L'exemple suivant récupère un élément à l'index 1 à partir d'un tableau de chaînes.
arrays.index_to_str(["test1", "test2", "test3", "test4"], 1) // "test2"
Exemple 2
L'exemple suivant récupère un élément à l'index -1 (dernier élément du tableau) à partir d'un tableau de chaînes.
arrays.index_to_str(["test1", "test2", "test3", "test4"], 0-1) // "test4"
Exemple 3
L'exemple suivant récupère un élément pour un index supérieur à la taille du tableau, ce qui renvoie une chaîne vide.
arrays.index_to_str(["test1", "test2", "test3", "test4"], 6) // ""
Exemple 4
L'exemple suivant récupère un élément à partir d'un tableau vide.
arrays.index_to_str([], 0) // ""
Exemple 5
L'exemple suivant récupère un élément à l'index 0 à partir d'un tableau de valeurs float. Le résultat est renvoyé sous forme de chaîne.
arrays.index_to_str([1.200000, 3.300000, 2.400000], 0) // "1.2"
Exemple 6
L'exemple suivant récupère un élément à l'index 2 d'un tableau d'entiers. Le résultat se présente sous la forme d'une chaîne.
arrays.index_to_str([1, 3, 2], 2) // "2"
cast.as_bool
cast.as_bool(string_or_int)
Description
La fonction convertit une valeur int ou string en valeur booléenne. Les appels de fonction avec des valeurs qui ne peuvent pas être converties renvoient FALSE. Renvoie TRUE uniquement pour l'entier 1 et la chaîne "true" (non sensible à la casse).
Types de données des paramètres
INT|STRING
Type renvoyé
BOOL
Exemples de code
Exemple 1
Cet exemple montre comment caster une chaîne non booléenne.
cast.as_bool("123") = false
Exemple 2
Entier "truthy" (1)
cast.as_bool(1) = true
Exemple 3
Chaîne "truthy"
cast.as_bool("true") = true
Exemple 4
Chaîne "truthy" en majuscules
cast.as_bool("TRUE") = true
Exemple 5
Entier négatif
cast.as_bool(0-1) = false
Exemple 6
Entier "false" (0)
cast.as_bool(0) = false
Exemple 7
chaîne vide
cast.as_bool("") = false
cast.as_float
cast.as_float(string_to_cast)
Description
Convertit une chaîne numérique en float. Tous les appels de fonction avec des valeurs qui ne peuvent pas être converties renvoient 0. Les valeurs float conservent une précision allant jusqu'à sept chiffres décimaux.
Types de données des paramètres
STRING
Type renvoyé
FLOAT
Exemples de code
Exemple 1
La conversion d'une chaîne non numérique renvoie 0.
cast.as_float("str") = 0.0000000
Exemple 2
La conversion d'une chaîne vide renvoie 0.
cast.as_float("") = 0.0000000
Exemple 3
Le casting d'une chaîne numérique valide renvoie une valeur float.
cast.as_float("1.012345678") = 1.0123456
cast.as_string
cast.as_string(int_or_bytes_or_bool, optional_default_string)
Description
La fonction cast.as_string
transforme une valeur INT
, BYTES
ou BOOL
en sa représentation sous forme de chaîne. Vous pouvez fournir un argument default_string
facultatif pour gérer les cas où le cast échoue. Si vous omettez l'argument default_string
ou si l'entrée est une séquence d'octets UTF-8
ou BASE64
non valide, la fonction renvoie une chaîne vide.
Types de données des paramètres
INT|BYTES|BOOL
, STRING
Type renvoyé
STRING
Exemples de code
Conversion d'un entier en chaîne
La fonction convertit l'entier 123
en chaîne "123"
.
cast.as_string(123) = "123"
Conversion de float en chaîne
La fonction convertit le float 2.25
en chaîne "2.25"
.
cast.as_string(2.25) = "2.25"
Conversion d'octets en chaîne
La fonction convertit le code binaire brut b'01
en chaîne "\x01"
.
cast.as_string(b'01, "") = "\x01"
Conversion de booléen en chaîne
La fonction convertit le booléen true
en chaîne "true"
.
cast.as_string(true, "") = "true"
Échec de la conversion (par défaut, la chaîne fournie en option)
La fonction utilise par défaut la chaîne "casting error"
lorsque la valeur fournie n'est pas valide.
cast.as_string(9223372036854775808, "casting error") = "casting error"
fingerprint
hash.fingerprint2011(byteOrString)
Description
Cette fonction calcule le hachage fingerprint2011
d'une séquence d'octets ou d'une chaîne d'entrée. Cette fonction renvoie une valeur INT
non signée dans la plage [2, 0xFFFFFFFFFFFFFFFF]
.
Types de données des paramètres
BTYE
, STRING
Type renvoyé
INT
Exemple de code
id_fingerprint = hash.fingerprint2011("user123")
groupe
group(field1, field2, field3, ...)
Description
Regroupez les champs de type similaire dans une variable d'espace réservé.
Dans la recherche UDM, les champs groupés sont utilisés pour effectuer des recherches dans plusieurs champs de type similaire. La fonction de groupe est semblable aux champs groupés, sauf qu'elle vous permet de sélectionner les champs que vous souhaitez regrouper pour déclencher une détection. Vous pouvez utiliser la fonction group pour collecter des informations sur une entité spécifique (par exemple, un nom d'hôte, une adresse IP ou un ID utilisateur) pour différents types de noms.
Exemples de code
Exemple 1
Regroupez toutes les adresses IP et fournissez un décompte décroissant des adresses IP les plus fréquentes dans la plage de temps analysée.
$ip = group(principal.ip, about.ip, target.ip)
$ip != ""
match:
$ip
outcome:
$count = count_distinct(metadata.id)
order:
$count desc
hash.sha256
hash.sha256(string)
Description
Renvoie un hachage SHA-256 de la chaîne d'entrée.
Types de données des paramètres
STRING
Type renvoyé
STRING
Exemples de code
Exemple 1
Cet exemple montre le hachage SHA-256 lorsque l'entrée est une chaîne valide.
hash.sha256("str") = "8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a"
Exemple 2
Cet exemple montre le hachage SHA-256 lorsque l'entrée est une chaîne vide.
hash.sha256("") = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
math.abs
math.abs(numericExpression)
Description
Renvoie la valeur absolue d'une expression entière ou à virgule flottante.
Types de données des paramètres
NUMBER
Type renvoyé
NUMBER
Exemples de code
Exemple 1
Cet exemple renvoie la valeur "True" si l'événement s'est produit plus de cinq minutes avant ou après l'heure spécifiée (en secondes depuis l'epoch Unix). Un appel à math.abs
ne peut pas dépendre de plusieurs variables ou espaces réservés. Par exemple, vous ne pouvez pas remplacer la valeur temporelle codée en dur 1643687343 dans l'exemple suivant par $e2.metadata.event_timestamp.seconds
.
300 < math.abs($e1.metadata.event_timestamp.seconds - 1643687343)
math.ceil
math.ceil(number)
Description
Renvoie le plus petit nombre entier qui n'est pas inférieur au nombre donné (arrondi à l'entier supérieur). Renvoie 0 si l'entrée est nulle ou trop grande pour tenir dans un int64.
Types de données des paramètres
FLOAT
Type renvoyé
INT
Exemples de code
Cette section contient des exemples d'utilisation de math.ceil
.
Exemple 1
Cet exemple renvoie le plafond d'un nombre entier.
math.ceil(2.000000) = 2
Exemple 2
Cet exemple renvoie le plafond d'un nombre négatif.
math.ceil(0-1.200000) = -1
Exemple 3
Cet exemple renvoie 0 comme plafond d'un nombre trop grand pour un entier de 64 bits.
math.ceil(184467440737095516160.0) = 0
math.floor
math.floor(float_val)
Description
Renvoie la plus grande valeur entière qui n'est pas supérieure à la valeur fournie (arrondi à l'entier inférieur). Renvoie 0 si l'entrée est nulle ou trop grande pour tenir dans un int64.
Types de données des paramètres
FLOAT
Type renvoyé
INT
Exemples de code
Exemple 1
Cet exemple montre un cas de nombre positif.
math.floor(1.234568) = 1
Exemple 2
Cet exemple montre un cas de nombre négatif.
math.floor(0-1.234568) = -2
Exemple 3
Cet exemple montre un cas nul.
math.floor(0.000000) = 0
math.geo_distance
math.geo_distance(longitude1, latitude1, longitude2, latitude2))
Description
Renvoie la distance en mètres entre deux positions géographiques (coordonnées). Renvoie -1 si les coordonnées ne sont pas valides.
Types de données de paramètre
FLOAT
, FLOAT
, FLOAT
, FLOAT
Type renvoyé
FLOAT
Exemples de code
Exemple 1
L'exemple suivant renvoie la distance lorsque tous les paramètres sont des coordonnées valides :
math.geo_distance(-122.020287, 37.407574, -122.021810, 37.407574) = 134.564318
Exemple 2
L'exemple suivant renvoie la distance lorsque l'un des paramètres est une coordonnée tronquée :
math.geo_distance(-122.000000, 37.407574, -122.021810, 37.407574) = 1926.421905
Exemple 3
L'exemple suivant renvoie -1
lorsqu'un des paramètres est une coordonnée non valide :
math.geo_distance(0-122.897680, 37.407574, 0-122.021810, 97.407574) = -1.000000
Exemple 4
L'exemple suivant renvoie 0
lorsque les coordonnées sont identiques :
math.geo_distance(-122.897680, 37.407574, -122.897680, 37.407574) = 0.000000
math.is_increasing
math.is_increasing(num1, num2, num3)
Description
Prend une liste de valeurs numériques (entiers ou doubles) et renvoie True
si les valeurs sont dans l'ordre croissant, et False
dans le cas contraire.
Types de données des paramètres
INT|FLOAT
, INT|FLOAT
, INT|FLOAT
Type renvoyé
BOOL
Exemples de code
Exemple 1
Cet exemple inclut des valeurs de type code temporel en secondes.
math.is_increasing(1716769112, 1716769113, 1716769114) = true
Exemple 2
Cet exemple inclut une valeur double négative, une valeur INT64 nulle et une valeur INT64 positive.
math.is_increasing(-1.200000, 0, 3) = true
Exemple 3
Cet exemple inclut une valeur double négative, une valeur INT64 nulle et une valeur INT64 négative.
math.is_increasing(0-1.200000, 0, 0-3) = false
Exemple 4
Cet exemple inclut deux valeurs doubles négatives et une valeur INT64 nulle.
math.is_increasing(0-1.200000, 0-1.50000, 0) = false
Exemple 5
Cet exemple inclut un double négatif et deux valeurs identiques.
math.is_increasing(0-1.200000, 0, 0) = false
math.log
math.log(numericExpression)
Description
Renvoie la valeur du logarithme naturel d'une expression entière ou à virgule flottante.
Types de données des paramètres
NUMBER
Type renvoyé
NUMBER
Exemples de code
Exemple 1
math.log($e1.network.sent_bytes) > 20
math.pow
math.pow(base, exponent)
Description
Renvoie la valeur du premier argument élevée à la puissance du deuxième argument. Renvoie 0 en cas de débordement.
Types de données des paramètres
base : INT|FLOAT
exposant : INT|FLOAT
Type renvoyé
FLOAT
Exemples de code
Exemple 1
Cet exemple montre un cas d'entier.
math.pow(2, 2) // 4.00
Exemple 2
Cet exemple montre un cas de base de fraction.
math.pow(2.200000, 3) // 10.648
Exemple 3
Cet exemple montre un cas de base et de puissance fractionnaires.
math.pow(2.200000, 1.200000) // 2.575771
Exemple 4
Cet exemple montre un cas de puissance négative.
math.pow(3, 0-3) // 0.037037
Exemple 5
Cet exemple montre un cas de puissance fractionnaire.
math.pow(3, 0-1.200000) // 0.267581
Exemple 6
Cet exemple montre un cas de base négatif.
math.pow(0-3, 0-3) // -0.037037
Exemple 7
Cet exemple montre un cas de base nul.
math.pow(0, 3) // 0
Exemple 8
Cet exemple montre un cas de puissance nulle.
math.pow(9223372036854775807, 0) // 1
Exemple 9
Cet exemple montre un cas de base important.
math.pow(9223372036854775807, 1.200000) // 57262152889751593549824
math.random
math.random()
Description
Génère une valeur pseudo-aléatoire de type DOUBLE dans la plage [0, 1)
, 0 étant inclus et 1 étant exclu.
Type renvoyé
FLOAT
Exemples de code
L'exemple suivant vérifie si la valeur aléatoire se trouve dans la plage [0, 1)
.
none
if(math.random() >= 0 and math.random() < 1) = true
math.round
math.round(numericExpression, decimalPlaces)
Description
Renvoie une valeur arrondie à l'entier le plus proche ou au nombre de décimales spécifié.
Types de données des paramètres
NUMBER
Type renvoyé
NUMBER
Exemples de code
math.round(10.7) // returns 11
math.round(1.2567, 2) // returns 1.25
math.round(0-10.7) // returns -11
math.round(0-1.2) // returns -1
math.round(4) // returns 4, math.round(integer) returns the integer
math.sqrt
math.sqrt(number)
Description
Renvoie la racine carrée du nombre donné. Renvoie 0 en cas de nombre négatif.
Types de données des paramètres
INT|FLOAT
Type renvoyé
FLOAT
Exemples de code
Exemple 1
Cet exemple renvoie la racine carrée d'un argument int.
math.sqrt(3) = 1.732051
Exemple 2
Cet exemple renvoie la racine carrée d'un argument int négatif.
math.sqrt(-3) = 0.000000
Exemple 3
Cet exemple renvoie la racine carrée de l'argument zéro.
math.sqrt(0) = 0.000000
Exemple 4
Cet exemple renvoie la racine carrée d'un argument float.
math.sqrt(9.223372) = 3.037000
Exemple 5
Cet exemple renvoie la racine carrée d'un argument float négatif.
math.sqrt(0-1.200000) = 0.000000
métrique
Les fonctions de métriques peuvent agréger de grandes quantités de données historiques. Vous pouvez l'utiliser dans votre règle à l'aide de metrics.functionName()
dans la section "Résultat".
Pour en savoir plus, consultez Métriques YARA-L.
net.ip_in_range_cidr
net.ip_in_range_cidr(ipAddress, subnetworkRange)
Description
Renvoie true
lorsque l'adresse IP indiqué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 acceptées.
Pour effectuer une recherche dans une plage d'adresses IP, spécifiez un champ UDM d'adresse IP et une plage CIDR. YARA-L peut gérer les champs d'adresses IP uniques et répétées.
Pour effectuer une recherche dans 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 uniques et répétées.
Types de données des paramètres
STRING
– STRING
Type renvoyé
BOOL
Exemples de code
Exemple 1
Exemple IPv4 :
net.ip_in_range_cidr($e.principal.ip, "192.0.2.0/24")
Exemple 2
Exemple 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 É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-L : concerne les événements. Voici une représentation générique de cette syntaxe :
$e.field = /regex/
En utilisant 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 sous forme de chaîne.
Voici une représentation générique de cette syntaxe :
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.
Remarques
- Pour faire 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 forcer la correspondance complète des champs UDM, ajoutez(?s)
à l'expression régulière. Par exemple, remplacez/.*allUDM.*/
par/(?s).*allUDM.*/
. - Vous pouvez utiliser le modificateur
nocase
après les chaînes pour indiquer que la recherche doit ignorer la casse.
Types de données des paramètres
STRING
– STRING
Types d'expressions de paramètre
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) des données d'une chaîne à l'aide du modèle d'expression régulière fourni dans l'argument.
Cette fonction utilise 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 zéro ou un groupe de capture entre parenthèses. Si l'expression régulière ne contient aucun 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. Définir deux groupes de capture ou plus renvoie une erreur de compilation.
Types de données des paramètres
STRING
– STRING
Type renvoyé
STRING
Exemples de code
Exemple 1
Dans cet exemple, si $e.principal.hostname
contient "aaa1bbaa2", l'instruction suivante sera vraie, 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 une adresse e-mail. Si le champ $e.network.email.from
est 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 trouvée en excluant la chaîne vide. Cela 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 utilise 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 chaîne stringText
d'origine, dans laquelle 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 associé au groupe entre parenthèses correspondant dans le schéma replaceRegex
. Utilisez \0
pour faire référence à l'ensemble du texte correspondant.
La fonction remplace les correspondances qui ne se chevauchent pas et donne la priorité au remplacement de la première occurrence trouvée. Par exemple, re.replace("banana", "ana", "111")
renvoie la chaîne "b111na".
Types de données des paramètres
STRING
, STRING
, STRING
Type renvoyé
STRING
Exemples de code
Exemple 1
Cet exemple capture tout ce qui se trouve après le symbole @
dans une adresse 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 faire référence aux correspondances avec le 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 re.replace()
:
Utiliser 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")
sample_rate
optimization.sample_rate(byteOrString, rateNumerator, rateDenominator)
Description
Cette fonction détermine s'il faut inclure un événement en fonction d'une stratégie d'échantillonnage déterministe. Cette fonction renvoie :
true
pour une fraction des valeurs d'entrée, équivalente à (rateNumerator
/rateDenominator
), indiquant que l'événement doit être inclus dans l'échantillon.false
indiquant que l'événement ne doit pas être inclus dans l'échantillon.
Cette fonction est utile pour les scénarios d'optimisation dans lesquels vous ne souhaitez traiter qu'un sous-ensemble d'événements. Équivalent à :
hash.fingerprint2011(byteOrString) % rateDenominator < rateNumerator
Types de données des paramètres
- byteOrString : expression qui renvoie
BYTE
ouSTRING
. - rateNumerator : "INT"
- rateDenominator: 'INT'
Type renvoyé
BOOL
Exemple de code
events:
$e.metadata.event_type = "NETWORK_CONNECTION"
$asset_id = $e.principal.asset.asset_id
optimization.sample_rate($e.metadata.id, 1, 5) // Only 1 out of every 5 events
match:
$asset_id over 1h
outcome:
$event_count = count_distinct($e.metadata.id)
// estimate the usage by multiplying by the inverse of the sample rate
$usage_past_hour = sum(5.0 * $e.network.sent_bytes)
condition:
// Requiring a certain number of events after sampling avoids bias (e.g. a
// device with just 1 connection will still show up 20% of the time and
// if we multiply that traffic by 5, we'll get an incorrect estimate)
$e and ($usage_past_hour > 1000000000) and $event_count >= 100
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 prend une chaîne encodée en base64 comme argument. Si encodedString
n'est pas une chaîne valide encodée en base64, la fonction renvoie encodedString
sans le modifier.
Types de données des 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 n'est pas évaluée comme 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 des 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 définie sur "true" lorsque (1) $e.network.email.from
est suspicious@gmail.com
ou (2) $e.network.email.from
est vide et $e.network.email.to
est 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 fusionnés dans cet appel est le même que celui dans lequel ils sont énumérés dans la condition de la règle :
$e.principal.ip
est évalué en premier.$e.src.ip
est ensuite évalué.$e.target.ip
est ensuite évalué.- Enfin, la chaîne "No IP" est renvoyée comme valeur 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 regrouper principal.hostname
à partir de l'événement $e1
et de l'événement $e2
. Une erreur de compilation sera renvoyée, 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 float.
Si des arguments sont des champs d'événement, les attributs doivent provenir du même événement.
Types de données des paramètres
STRING
, FLOAT
, 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 float comme arguments. Lorsqu'ils sont représentés sous forme de chaînes, les nombres à virgule flottante entiers sont mis en forme sans point décimal (par exemple, 1.0 est représenté par "1"). De plus, les nombres à virgule flottante qui dépassent seize chiffres après la virgule sont tronqués au seizième chiffre après la virgule.
"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 flottant 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
. Une erreur de compilation sera renvoyée, car les arguments sont des variables d'événement différentes.
// Will not compile
"test" = strings.concat($e1.principal.port, $e2.principal.hostname)
strings.contains
strings.contains( str, substr )
Description
Renvoie "true" si une chaîne donnée contient la sous-chaîne spécifiée. Sinon, elle renvoie la valeur "false".
Types de données des paramètres
STRING
– STRING
Type renvoyé
BOOL
Exemples de code
Exemple 1
Cet exemple renvoie "true" car la chaîne contient la sous-chaîne "is".
strings.contains("thisisastring", "is") = true
Exemple 2
Cet exemple renvoie "false" (faux), car la chaîne ne contient pas la sous-chaîne "that".
strings.contains("thisisastring", "that") = false
strings.count_substrings
strings.count_substrings(string_to_search_in, substring_to_count)
Description
Lorsqu'une chaîne et une sous-chaîne sont fournies, renvoie un int64 du nombre d'occurrences sans chevauchement de la sous-chaîne dans la chaîne.
Types de données des paramètres
STRING
– STRING
Type renvoyé
INT
Exemples de code
Cette section contient des exemples qui calculent le nombre de fois qu'une sous-chaîne apparaît dans une chaîne donnée.
Exemple 1
Cet exemple utilise une chaîne non nulle et un caractère de sous-chaîne unique non nul.
strings.count_substrings("this`string`has`four`backticks", "`") = 4
Exemple 2
Cet exemple utilise une chaîne non nulle et une sous-chaîne non nulle de plus d'un caractère.
strings.count_substrings("str", "str") = 1
Exemple 3
Cet exemple utilise une chaîne non nulle et une sous-chaîne vide.
strings.count_substrings("str", "") = 0
Exemple 4
Cet exemple utilise une chaîne vide et une sous-chaîne non nulle de plus d'un caractère.
strings.count_substrings("", "str") = 0
Exemple 5
Cet exemple utilise une chaîne vide et une sous-chaîne vide.
strings.count_substrings("", "") = 0
Exemple 6
Cet exemple utilise une chaîne non nulle et une sous-chaîne non nulle comportant plus d'un caractère et plus d'une occurrence.
strings.count_substrings("fooABAbarABAbazABA", "AB") = 3
Exemple 7
Cet exemple utilise une chaîne non nulle et une sous-chaîne non nulle comportant plus d'un caractère et plus d'une occurrence. Elle met en évidence la limite avec les occurrences de sous-chaînes qui se chevauchent.
strings.count_substrings("ABABABA", "ABA") = 2
strings.extract_domain
strings.extract_domain(url_string)
Description
Extrait le domaine d'une chaîne.
Types de données des paramètres
STRING
Type renvoyé
STRING
Exemples de code
Exemple 1
Cet exemple montre une chaîne vide
strings.extract_domain("") = ""
Exemple 2
Chaîne aléatoire, pas une URL
strings.extract_domain("1234") = ""
Exemple 3
plusieurs barres obliques inverses
strings.extract_domain("\\\\") = ""
Exemple 4
Gestion optimale des caractères non alphabétiques
strings.extract_domain("http://例子.卷筒纸.中国") = "卷筒纸.中国"
Exemple 5
Gestion des URI
strings.extract_domain("mailto:?to=&subject=&body=") = ""
Exemple 6
plusieurs caractères avant l'URL réelle.
strings.extract_domain(" \t !$5*^)&dahgsdfs;http://www.google.com") = "google.com"
Exemple 7
Caractères spéciaux dans l'URI #
strings.extract_domain("test#@google.com") = ""
Exemple 8
Caractères spéciaux dans l'URL #
strings.extract_domain("https://test#@google.com") = ""
Exemple 9
scénario de test positif
strings.extract_domain("https://google.co.in") = "google.co.in"
strings.extract_hostname
strings.extract_hostname(string)
Description
Extrait le nom d'hôte d'une chaîne. Cette fonction est sensible à la casse.
Types de données des paramètres
STRING
Type renvoyé
STRING
Exemples de code
Exemple 1
Cet exemple renvoie une chaîne vide.
strings.extract_hostname("") = ""
Exemple 2
Chaîne aléatoire, pas une URL
strings.extract_hostname("1234") = "1234"
Exemple 3
plusieurs barres obliques inverses
strings.extract_hostname("\\\\") = ""
Exemple 4
Gestion optimale des caractères non anglais
strings.extract_hostname("http://例子.卷筒纸.中国") = "例子.卷筒纸.中国"
Exemple 5
Gestion des URI
strings.extract_hostname("mailto:?to=&subject=&body=") = "mailto"
Exemple 6
plusieurs caractères avant l'URL réelle.
strings.extract_hostname(" \t !$5*^)&dahgsdfs;http://www.google.com") = "www.google.com"
Exemple 7
Caractères spéciaux dans l'URI #
strings.extract_hostname("test#@google.com") = "test"
Exemple 8
Caractères spéciaux dans l'URL #
strings.extract_hostname("https://test#@google.com") = "test"
strings.from_base64
strings.from_base64(base64_encoded_string)
Description
La fonction convertit une valeur STRING
encodée en base64 en valeur BYTES
binaire brute. Les appels de fonction avec des valeurs qui ne peuvent pas être converties renvoient un BYTES
vide par défaut.
Types de données des paramètres
STRING
Type renvoyé
BYTES
Exemples de code
Conversion d'une chaîne encodée en base64 en octets
La fonction convertit une chaîne encodée en base64 en sa représentation brute en octets binaires.
strings.from_base64("AAAAAG+OxVhtAm+d2sVuny/hW4oAAAAAAQAAAM0AAAA=") = b'000000006f8ec5586d026f9ddac56e9f2fe15b8a0000000001000000cd000000
Échec de la conversion (valeur par défaut : octets vides)
Si la valeur fournie n'est pas valide, la fonction renvoie par défaut des octets vides.
strings.from_base64("invalid-value") = b'
strings.from_hex
strings.from_hex(hex_string)
Description
Renvoie les octets associés à la chaîne hexadécimale donnée.
Types de données des paramètres
STRING
Type renvoyé
BYTES
Exemples de code
Obtenez les octets associés à une chaîne hexadécimale donnée.
Exemple 1
Cet exemple montre les conversions de caractères non hexadécimaux.
strings.from_hex("str") // returns empty bytes
Exemple 2
Cet exemple montre une entrée avec une chaîne vide.
strings.from_hex("") // returns empty bytes
Exemple 3
Cet exemple montre la conversion d'une chaîne hexadécimale.
strings.from_hex("1234") // returns 1234 bytes
Exemple 4
Cet exemple montre la conversion de caractères non ASCII.
strings.from_hex("筒纸.中国") // returns empty bytes
strings.length
strings.length(string_value)
Description
Renvoie le nombre de caractères dans la chaîne d'entrée.
Types de données des paramètres
STRING
Type renvoyé
INT
Exemples de code
Exemple 1
Voici un exemple avec un test de chaîne.
strings.length("str") = 3
Exemple 2
Voici un exemple avec une chaîne vide comme entrée.
strings.length("") = 0
Exemple 3
Voici un exemple avec une chaîne de caractères spéciaux.
strings.length("!@#$%^&*()-_") = 12
Exemple 4
Voici un exemple avec une chaîne contenant des espaces.
strings.length("This is a test string") = 21
strings.ltrim
strings.ltrim(string_to_trim, cutset)
Description
Supprime les espaces blancs de début d'une chaîne donnée. Cette fonction supprime les caractères de début présents dans ce jeu de caractères.
Types de données des paramètres
STRING
– STRING
Type renvoyé
STRING
Exemples de code
Voici quelques exemples de cas d'utilisation.
Exemple 1
Cet exemple utilise les mêmes premier et deuxième arguments.
strings.ltrim("str", "str") = ""
Exemple 2
Cet exemple utilise une chaîne vide comme deuxième argument.
strings.ltrim("str", "") = "str"
Exemple 3
Cet exemple utilise une chaîne vide comme premier argument et une chaîne comme deuxième argument.
strings.ltrim("", "str") = ""
Exemple 4
Cet exemple utilise des chaînes contenant des espaces et une chaîne comme deuxième argument.
strings.ltrim("a aastraa aa ", " a") = "straa aa "
strings.reverse
strings.reverse(STRING)
Description
Renvoie une chaîne qui est l'inverse de la chaîne d'entrée.
Types de données des paramètres
STRING
Type renvoyé
STRING
Exemples de code
Exemple 1
L'exemple suivant transmet une chaîne courte.
strings.reverse("str") = "rts" // The function returns 'rts'.
Exemple 2
L'exemple suivant transmet une chaîne vide.
strings.reverse("") = ""
Exemple 3
L'exemple suivant transmet un palindrome.
strings.reverse("tacocat") = "tacocat"
strings.rtrim
strings.rtrim(string_to_trim, cutset)
Description
Supprime les espaces blancs de fin d'une chaîne donnée. Supprime les caractères de fin présents dans ce cutset.
Types de données des paramètres
STRING
– STRING
Type renvoyé
STRING
Exemples de code
Voici quelques exemples de cas d'utilisation.
Exemple 1
L'exemple suivant transmet la même chaîne en tant que premier et deuxième arguments.
strings.rtrim("str", "str") = ""
Exemple 2
L'exemple suivant transmet une chaîne vide comme deuxième argument.
strings.rtrim("str", "") = "str"
Exemple 3
L'exemple suivant transmet une chaîne vide comme premier argument et une chaîne non vide comme deuxième argument.
strings.rtrim("", "str") = ""
Exemple 4
L'exemple suivant transmet une chaîne contenant des espaces blancs comme premier argument et une chaîne non vide comme deuxième argument.
strings.rtrim("a aastraa aa ", " a") = "a aasstr"
strings.to_lower
strings.to_lower(stringText)
Description
Cette fonction prend une chaîne d'entrée et renvoie une chaîne après avoir converti tous les caractères en minuscules.
Types de données des 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(string_val)
Description
Renvoie la chaîne d'origine avec tous les caractères alphabétiques en majuscules.
Types de données des paramètres
STRING
Type renvoyé
STRING
Exemples de code
Exemple 1
L'exemple suivant renvoie l'argument fourni en majuscules.
strings.to_upper("example") = "EXAMPLE"
strings.trim
strings.trim(string_to_trim, cutset)
Description
Supprime les espaces blancs de début et de fin d'une chaîne donnée. Supprime également les caractères indésirables (spécifiés par l'argument cutset) de la chaîne d'entrée.
Types de données des paramètres
STRING
– STRING
Type renvoyé
STRING
Exemples de code
Voici quelques exemples de cas d'utilisation.
Exemple 1
Dans l'exemple suivant, la même chaîne est transmise en tant que chaîne d'entrée et cutset, ce qui donne une chaîne vide.
strings.trim("str", "str") // ""
Exemple 2
Dans l'exemple suivant, une chaîne vide est transmise en tant qu'ensemble de caractères à supprimer, ce qui donne la chaîne d'origine "str", car aucun caractère n'est spécifié dans l'ensemble de caractères à supprimer.
strings.trim("str", "") = "str"
Exemple 3
Dans l'exemple suivant, la fonction génère une chaîne vide, car la chaîne d'entrée est déjà vide et qu'il n'y a aucun caractère à supprimer.
strings.trim("", "str") = ""
Exemple 4
Dans l'exemple suivant, la fonction génère "str", car la fonction trim supprime les éléments suivants :
- Espace blanc de fin dans "a aastraa aa "
- les caractères spécifiés dans le cutset (espace, a).
strings.trim("a aastraa aa ", " a") = "str"
strings.url_decode
strings.url_decode(url_string)
Description
Étant donné une chaîne d'URL, décodez les caractères d'échappement et gérez les caractères UTF-8 qui ont été encodés. Renvoie une chaîne vide en cas d'échec du décodage.
Types de données des paramètres
STRING
Type renvoyé
STRING
Exemples de code
Exemple 1
Cet exemple montre un cas de test positif.
strings.url_decode("three%20nine%20four") = "three nine four"
Exemple 2
Cet exemple montre un cas de chaîne vide.
strings.url_decode("") // ""
Exemple 3
Cet exemple montre comment gérer les caractères non alphabétiques.
strings.url_decode("%E4%B8%8A%E6%B5%B7%2B%E4%B8%AD%E5%9C%8B") // "上海+中國"
Exemple 4
Cet exemple montre un décodage d'URL.
strings.url_decode("http://www.google.com%3Fparam1%3D%22+1+%3E+2+%22%26param2%3D2%3B") // 'http://www.google.com?param1="+1+>+2+"¶m2=2;'
timestamp.as_unix_seconds
timestamp.as_unix_seconds(timestamp [, time_zone])
Description
Cette fonction renvoie un entier représentant le nombre de secondes écoulées depuis l'epoch Unix pour la chaîne d'horodatage donnée.
timestamp
est une chaîne représentant un code temporel Unix valide. Le format doit être%F %T
.time_zone
est facultatif et correspond à une chaîne représentant un fuseau horaire. Si aucune valeur n'est spécifiée, la valeur par défaut estGMT
. Vous pouvez spécifier des fuseaux horaires à l'aide de littéraux de chaîne. Vous disposez des options suivantes :- Nom de la base de données TZ (par exemple,
America/Los_Angeles
). Pour en savoir plus, consultez la liste des fuseaux horaires de la base de données tz sur Wikipédia. - Décalage du fuseau horaire par rapport à l'heure UTC, au format
(+|-)H[H][:M[M]]
, par exemple "-08:00".
- Nom de la base de données TZ (par exemple,
Voici des exemples de spécificateurs time_zone
valides que vous pouvez transmettre en tant que 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 des paramètres
STRING
– STRING
Type renvoyé
INT
Exemples de code
Exemple 1
Code temporel epoch valide
timestamp.as_unix_seconds("2024-02-22 10:43:00") = 1708598580
Exemple 2
Code temporel Unix valide avec le fuseau horaire America/New_York
timestamp.as_unix_seconds("2024-02-22 10:43:00", "America/New_York") = 1708616580
timestamp.current_seconds
timestamp.current_seconds()
Description
Renvoie un entier représentant l'heure actuelle en secondes Unix. Elle est approximativement égale au code temporel de la détection et est basée sur le moment où la règle est exécutée. Cette fonction est un synonyme de la fonction timestamp.now()
.
Types de données des 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
, représentant le jour auquel appartient un code temporel.
unix_seconds
est un entier représentant le nombre de secondes écoulées depuis l'époque Unix, comme$e.metadata.event_timestamp.seconds
, ou un espace réservé contenant cette valeur.time_zone
est facultatif et correspond à une chaîne représentant un fuseau horaire. Si elle est omise, 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 :- Nom de la base de données TZ, par exemple "America/Los_Angeles". Pour en savoir plus, consultez la colonne "Nom de la base de données TZ" sur cette page.
- Décalage du fuseau horaire par rapport à l'heure UTC, au format
(+|-)H[H][:M[M]]
, par exemple "-08:00".
Voici des exemples de spécificateurs time_zone valides que vous pouvez transmettre en tant que 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 des 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 "GMT" est donc utilisée.
$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 le 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 écoulées depuis l'époque Unix, comme$e.metadata.event_timestamp.seconds
, ou un espace réservé contenant cette valeur.time_zone
est facultatif et correspond à une chaîne représentant un fuseau horaire. Si elle est omise, 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 :- Nom de la base de données TZ, par exemple "America/Los_Angeles". Pour en savoir plus, consultez la colonne "Nom de la base de données TZ" sur cette page.
- Décalage du fuseau horaire par rapport à l'heure UTC, au format
(+|-)H[H][:M[M]]
, par exemple "-08:00".
Voici des exemples de spécificateurs time_zone
valides que vous pouvez transmettre en tant que 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 des 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 "GMT" est donc utilisée.
$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 le 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 écoulées depuis l'époque Unix, comme$e.metadata.event_timestamp.seconds
, ou un espace réservé contenant cette valeur.time_zone
est facultatif et correspond à une chaîne représentant un fuseau horaire. Si elle est omise, 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 :- Nom de la base de données TZ, par exemple "America/Los_Angeles". Pour en savoir plus, consultez la colonne "Nom de la base de données TZ" sur cette page.
- Décalage du fuseau horaire par rapport à l'heure UTC, au format
(+|-)H[H][:M[M]]
, par exemple "-08:00".
Voici des exemples de spécificateurs time_zone
valides que vous pouvez transmettre en tant que 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 des 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 "GMT" est donc utilisée.
$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 le 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 (le dimanche étant le premier jour). Par exemple, 1 = dimanche et 2 = lundi.
unix_seconds
est un entier représentant le nombre de secondes écoulées depuis l'époque Unix, comme$e.metadata.event_timestamp.seconds
, ou un espace réservé contenant cette valeur.time_zone
est facultatif et correspond à une chaîne représentant un fuseau horaire. Si elle est omise, 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 :- Nom de la base de données TZ, par exemple "America/Los_Angeles". Pour en savoir plus, consultez la colonne "Nom de la base de données TZ" sur cette page.
- Décalage du fuseau horaire par rapport à l'heure UTC, au format
(+|-)H[H][:M[M]]
, par exemple "-08:00".
Voici des exemples de spécificateurs time_zone valides que vous pouvez transmettre en tant que 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 des 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 "GMT" est donc utilisée.
$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 le time_zone
.
$ts = $e.metadata.collected_timestamp.seconds
timestamp.get_day_of_week($ts, "America/Los_Angeles") = 6
timestamp.get_timestamp
timestamp.get_timestamp(unix_seconds, optional timestamp_format/time_granularity, optional timezone)
Description
Cette fonction renvoie une chaîne au format YYYY-MM-DD
, représentant le jour auquel appartient un code temporel.
unix_seconds
est un entier représentant le nombre de secondes écoulées depuis l'époque Unix, comme$e.metadata.event_timestamp.seconds
, ou un espace réservé contenant cette valeur.timestamp_format
est facultatif et correspond à une chaîne représentant le format de l'horodatage. Si aucune valeur n'est spécifiée, la valeur par défaut est%F %T
. Vous pouvez spécifier le format à l'aide d'une chaîne de format de date et d'heure ou de l'une des granularités temporelles suivantes :SECOND
,MINUTE
,HOUR
,DATE
,WEEK
,MONTH
ouYEAR
. Pour plus d'options de mise en forme, consultez Mettre en forme les éléments des parties date et heure.time_zone
est facultatif et correspond à une chaîne représentant un fuseau horaire. Si aucune valeur n'est spécifiée, la valeur par défaut estGMT
. Vous pouvez spécifier des fuseaux horaires à l'aide de littéraux de chaîne. Vous disposez des options suivantes :- Nom de la base de données des fuseaux horaires IANA (TZ), par exemple
America/Los_Angeles
. Pour en savoir plus, consultez la liste des fuseaux horaires de la base de données tz sur Wikipédia. - Décalage du fuseau horaire par rapport à l'heure UTC, au format
(+|-)H[H][:M[M]]
, par exemple "-08:00".
- Nom de la base de données des fuseaux horaires IANA (TZ), par exemple
Voici des exemples de spécificateurs time_zone
valides que vous pouvez transmettre en tant que 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 des paramètres
INT
, STRING
, STRING
Type renvoyé
STRING
Exemples de code
Exemple 1
Dans cet exemple, l'argument time_zone
est omis. Il est donc défini par défaut sur GMT
.
$ts = $e.metadata.collected_timestamp.seconds
timestamp.get_timestamp($ts) = "2024-02-22 10:43:51"
Exemple 2
Cet exemple utilise un littéral de chaîne pour définir le time_zone
.
$ts = $e.metadata.collected_timestamp.seconds
timestamp.get_timestamp($ts, "%F %T", "America/Los_Angeles") = "2024-02-22 10:43:51"
Exemple 3
Cet exemple utilise un littéral de chaîne pour définir le timestamp_format
.
$ts = $e.metadata.collected_timestamp.seconds
timestamp.get_timestamp($ts, "%Y-%m", "GMT") = "2024-02"
Exemple 4
Cet exemple met en forme un code temporel Unix sous forme de chaîne avec une précision à la seconde.
timestamp.get_timestamp(1708598631, "SECOND", "GMT") = "2024-02-22 10:43:51"
Exemple 5
Cet exemple met en forme un horodatage Unix sous forme de chaîne à la minute près.
timestamp.get_timestamp(1708598631, "MINUTE", "GMT") = "2024-02-22 10:43"
Exemple 6
Cet exemple formate un code temporel Unix sous forme de chaîne avec une précision à l'heure près.
timestamp.get_timestamp(1708598631, "HOUR", "GMT") = "2024-02-22 10"
Exemple 7
Cet exemple met en forme un code temporel Unix sous forme de chaîne avec une précision au jour près.
timestamp.get_timestamp(1708598631, "DATE", "GMT") = "2024-02-22"
Exemple 8
Cet exemple formate un code temporel Unix sous forme de chaîne avec une précision hebdomadaire.
timestamp.get_timestamp(1708598631, "WEEK", "GMT") = "2024-02-18"
Exemple 9
Cet exemple met en forme un horodatage Unix sous forme de chaîne avec une précision au mois près.
timestamp.get_timestamp(1708598631, "MONTH", "GMT") = "2024-02"
Exemple 10
Cet exemple formate un code temporel Unix sous forme de chaîne avec une précision annuelle.
timestamp.get_timestamp(1708598631, "YEAR", "GMT") = "2024"
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 écoulées depuis l'époque Unix, comme$e.metadata.event_timestamp.seconds
, ou un espace réservé contenant cette valeur.time_zone
est facultatif et correspond à une chaîne représentant un fuseau horaire. Si elle est omise, 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 :- Nom de la base de données TZ, par exemple "America/Los_Angeles". Pour en savoir plus, consultez la colonne "Nom de la base de données TZ" sur cette page.
- Décalage du fuseau horaire par rapport à l'heure UTC, au format
(+|-)H[H][:M[M]]
, par exemple "-08:00".
Voici des exemples de spécificateurs time_zone
valides que vous pouvez transmettre en tant que 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 des 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 "GMT" est donc utilisée.
$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 le time_zone
.
$ts = $e.metadata.collected_timestamp.seconds
timestamp.get_week($ts, "America/Los_Angeles") = 0
timestamp.now
timestamp.now()
Description
Renvoie le nombre de secondes écoulées depuis le 1er janvier 1970 à 00:00:00 UTC. On parle également d'heure epoch UNIX.
Type renvoyé
INT
Exemples de code
Exemple 1
L'exemple suivant renvoie un code temporel pour le code exécuté le 22 mai 2024 à 18:16:59.
timestamp.now() = 1716401819 // Unix epoch time in seconds for May 22, 2024 at 18:16:59
window.avg
window.avg(numeric_values [, should_ignore_zero_values])
Description
Renvoie la moyenne des valeurs d'entrée (qui peuvent être des nombres entiers ou à virgule flottante). Si vous définissez le deuxième argument facultatif sur "true", les valeurs nulles sont ignorées.
Types de données des paramètres
INT|FLOAT
Type renvoyé
FLOAT
Exemples de code
Exemple 1
Cet exemple montre la moyenne des nombres entiers.
// This rule sets the outcome $size_mode to the average
// file size in the 5 minute match window.
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$size_mode = window.avg($e.file.size) // yields 2.5 if the event file size values in the match window are 1, 2, 3 and 4
Exemple 2
Cet exemple montre la moyenne flottante.
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$size_mode = window.avg($e.file.size) // yields 1.75 if the event file size values in the match window are 1.1 and 2.4
Exemple 3
Moyenne des entrées négatives
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$size_mode = window.avg($e.file.size) // yields 0.6 if the event file size values in the match window are -1.1, 1.1, 0.0 and 2.4
Exemple 4
0 retourne 0
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$size_mode = window.avg($e.file.size) // yields 0 if the event file size values in the match window is 0
Exemple 5
Ignorer les valeurs nulles
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$size_mode = window.avg($e.file.size, true) // yields 394 if the event file size values in the match window are 0, 0, 0 and 394
window.first
window.first(values_to_sort_by, values_to_return)
Description
Cette fonction d'agrégation renvoie une valeur de chaîne dérivée d'un événement avec la valeur int corrélée la plus faible dans la fenêtre de correspondance. Par exemple, vous pouvez obtenir l'ID utilisateur à partir de l'événement dont le code temporel est le plus bas dans la fenêtre de correspondance (événement le plus ancien).
Types de données des paramètres
INT
, STRING
Type renvoyé
STRING
Exemples de code
Obtenez une valeur de chaîne dérivée d'un événement avec la valeur int corrélée la plus faible dans la fenêtre de correspondance.
// This rule sets the outcome $first_event to the lowest correlated int value
// in the 5 minute match window.
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$first_event = window.first($e.metadata.timestamp.seconds, $e.metadata.event_type) // yields v1 if the events in the match window are 1, 2 and 3 and corresponding values v1, v2, and v3.
window.last
window.last(values_to_sort_by, values_to_return)
Description
Cette fonction d'agrégation renvoie une valeur de chaîne dérivée d'un événement avec la valeur int la plus corrélée dans la fenêtre de correspondance. Un cas d'utilisation consiste à obtenir l'ID utilisateur à partir de l'événement avec le code temporel le plus bas dans la fenêtre de correspondance (code temporel le plus élevé).
Types de données des paramètres
INT
, STRING
Type renvoyé
STRING
Exemples de code
Obtenez une valeur de chaîne dérivée d'un événement avec la valeur int la plus corrélée dans la fenêtre de correspondance.
// This rule sets the outcome $last_event to the highest correlated int value
// in the 5 minute match window.
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$last_event = window.first($e.metadata.timestamp.seconds, $e.metadata.event_type) // yields v3 if the events in the match window are 1, 2 and 3 and corresponding values v1, v2, and v3.
window.median
window.median(numeric_values, should_ignore_zero_values)
Description
Renvoie la médiane des valeurs d'entrée. S'il existe deux valeurs médianes, une seule sera choisie de manière non déterministe comme valeur renvoyée.
Types de données des paramètres
INT|FLOAT
, BOOL
Type renvoyé
FLOAT
Exemples de code
Exemple 1
Cet exemple renvoie la médiane lorsque les valeurs d'entrée ne sont pas nulles.
rule median_file_size {
meta:
events:
$e.metadata.event_type = "FILE_COPY"
$userid = $e.principal.user.userid
match:
$userid over 1h
outcome:
$median_file_size = window.median($e.principal.file.size) // returns 2 if the file sizes in the match window are [1, 2, 3]
condition:
$e
}
Exemple 2
Cet exemple renvoie la médiane lorsque l'entrée inclut des valeurs nulles qui ne doivent pas être ignorées.
rule median_file_size {
meta:
events:
$e.metadata.event_type = "FILE_COPY"
$userid = $e.principal.user.userid
match:
$userid over 1h
outcome:
$median_file_size = window.median($e.principal.file.size) // returns 1 if the file sizes in the match window are [0,0, 1, 2, 3]
condition:
$e
}
Exemple 3
Cet exemple renvoie la médiane lorsque l'entrée inclut des valeurs nulles qui doivent être ignorées.
rule median_file_size {
meta:
events:
$e.metadata.event_type = "FILE_COPY"
$userid = $e.principal.user.userid
match:
$userid over 1h
outcome:
$median_file_size = window.median($e.principal.file.size, true) // returns 2 if the file sizes in the match window are [0,0, 1, 2, 3]
condition:
$e
}
Exemple 4
Cet exemple renvoie la médiane lorsque l'entrée inclut toutes les valeurs nulles qui doivent être ignorées.
rule median_file_size {
meta:
events:
$e.metadata.event_type = "FILE_COPY"
$userid = $e.principal.user.userid
match:
$userid over 1h
outcome:
$median_file_size = window.median($e.principal.file.size) // returns 0 if the file sizes in the match window are [0,0]
condition:
$e
}
Exemple 5
Cet exemple montre que, lorsqu'il existe plusieurs médianes, une seule est renvoyée.
rule median_file_size {
meta:
events:
$e.metadata.event_type = "FILE_COPY"
$userid = $e.principal.user.userid
match:
$userid over 1h
outcome:
$median_file_size = window.median($e.principal.file.size) // returns 1 if the file sizes in the match window are [1, 2, 3, 4]
condition:
$e
}
window.mode
window.mode(values)
Description
Renvoie le mode des valeurs d'entrée. En cas de valeurs de mode multiples possibles, une seule de ces valeurs sera choisie de manière non déterministe comme valeur de retour.
Types de données des paramètres
INT|FLOAT|STRING
Type renvoyé
STRING
Exemples de code
Exemple 1
Obtenez le mode des valeurs dans la fenêtre de correspondance.
// This rule sets the outcome $size_mode to the most frequently occurring
// file size in the 5 minute match window.
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$size_mode = window.mode($e.file.size) // yields 1.6 if the event file size values in the match window are 1.6, 2, and 1.6
window.stddev
window.stddev(numeric_values)
Description
Renvoie l'écart type des valeurs d'entrée dans une fenêtre de correspondance.
Types de données des paramètres
INT|FLOAT
Type renvoyé
FLOAT
Exemples de code
Exemple 1
Cet exemple renvoie l'écart-type des nombres entiers dans une fenêtre de correspondance.
// This rule creates a detection when the file size stddev in 5 minutes for a user is over a threshold.
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$p1 = window.stddev($e.file.size) // yields 4.0 if the event file size values in the match window are [10, 14, 18].
condition:
$e and #p1 > 2
Exemple 2
Cet exemple renvoie l'écart type des valeurs float dans une fenêtre de correspondance.
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$p1 = window.stddev($e.file.size) // yields 4.488686 if the event file size values in the match window are [10.00, 14.80, 18.97].
condition:
$e and #p1 > 2
Exemple 3
Cet exemple renvoie l'écart type dans une fenêtre de correspondance contenant des nombres négatifs.
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$p1 = window.stddev($e.file.size) // yields 48.644972 if the event file size values in the match window are [-1, -56, -98].
condition:
$e and #p1 > 2
Exemple 4
Cet exemple renvoie un écart type nul lorsque toutes les valeurs de la fenêtre de correspondance sont identiques.
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$p1 = window.stddev($e.file.size) // yields 0.000000 if the event file size values in the match window are [1, 1, 1].
condition:
$e and #p1 > 2
Exemple 5
Cet exemple renvoie l'écart-type d'une fenêtre de correspondance contenant des nombres positifs et négatifs.
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$p1 = window.stddev($e.file.size) // yields 1.000000 if the event file size values in the match window are [1, 0, -1].
condition:
$e and #p1 > 10
window.variance
window.variance(values)
Description
Cette fonction renvoie la variance spécifiée des valeurs d'entrée.
Types de données des paramètres
INT|FLOAT
Type renvoyé
FLOAT
Exemples de code
Exemple 1
Cet exemple renvoie la variance de tous les nombres entiers.
// This rule creates a detection when the file size variance in 5 minutes for a user is over a threshold.
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$p1 = window.variance($e.file.size) // yields 16 if the event file size values in the match window are [10, 14, 18].
condition:
$e and #p1 > 10
Exemple 2
Cet exemple renvoie la variance de tous les nombres à virgule flottante.
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$p1 = window.variance($e.file.size) // yields 20.148300 if the event file size values in the match window are [10.00, 14.80, 18.97].
condition:
$e and #p1 > 10
Exemple 3
Cet exemple renvoie la variance des nombres négatifs.
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$p1 = window.variance($e.file.size) // yields 2366.333333 if the event file size values in the match window are [-1, -56, -98].
condition:
$e and #p1 > 10
Exemple 4
Cet exemple renvoie une petite valeur de variance.
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$p1 = window.variance($e.file.size) // yields 0.000000 if the event file size values in the match window are [0.000000, 0.000000, 0.000100].
condition:
$e and #p1 > 10
Exemple 5
Cet exemple renvoie une variance nulle.
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$p1 = window.variance($e.file.size) // yields 0.000000 if the event file size values in the match window are [1, 1, 1].
condition:
$e and #p1 > 10
Exemple 6
Cet exemple renvoie la variance des nombres positifs et négatifs.
events:
$e.user.userid = $userid
match:
$userid over 5m
outcome:
$p1 = window.variance($e.file.size) // yields 1.000000 if the event file size values in the match window are [1, 0, -1].
condition:
$e and #p1 > 10
bytes.to_base64
bytes.to_base64(bytes, optional_default_string)
Description
La fonction convertit une valeur bytes
en base64 encoded string
. Les appels de fonction avec des valeurs qui ne peuvent pas être converties renvoient une chaîne vide par défaut.
Types de données des paramètres
BYTES
, STRING
Type renvoyé
STRING
Exemples de code
Octets binaires bruts vers chaîne encodée en base64
La fonction convertit les octets binaires bruts en chaîne encodée en base64.
bytes.to_base64(b'000000006f8ec5586d026f9ddac56e9f2fe15b8a0000000001000000cd000000) = "AAAAAG+OxVhtAm+d2sVuny/hW4oAAAAAAQAAAM0AAAA="
Échec de la conversion (par défaut, la chaîne fournie en option)
La fonction est définie par défaut sur "invalid bytes"
lorsque la valeur d'octets fournie n'est pas valide.
bytes.to_base64(b'000000006f8ec5586d", "invalid bytes") = "invalid bytes"
Association 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, l'attribution de fonctions à des espaces réservés présente deux limites :
Chaque espace réservé dans l'attribution de fonction à espace réservé doit être attribué à une expression contenant un champ d'événement. Par exemple, 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.
L'appel de fonction doit dépendre d'un et un seul événement. Toutefois, plusieurs champs du même événement peuvent être utilisés dans les arguments d'appel de fonction. Par exemple, l'élément suivant est valide :
$ph = strings.concat($event.principal.hostname, "string2")
$ph = strings.concat($event.principal.hostname, $event.src.hostname)
En revanche, 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
Pour en savoir plus sur le comportement et la syntaxe des listes de référence, consultez notre page sur les listes de référence.
Vous pouvez utiliser des listes de référence dans les sections events
ou outcome
. Voici la syntaxe à utiliser pour 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 illustré dans l'exemple suivant :
// Exclude events whose hostnames match substrings in my_regex_list.
not $e.principal.hostname in regex %my_regex_list
// Event hostnames must match at least 1 string in my_string_list (case insensitive).
$e.principal.hostname in %my_string_list nocase
L'opérateur nocase
est compatible avec les listes STRING
et REGEX
.
Pour des raisons de performances, le moteur de détection limite l'utilisation des listes de référence.
- Nombre maximal d'instructions
in
dans une règle, avec ou sans opérateurs spéciaux : 7 - Nombre maximal d'instructions
in
avec l'opérateurregex
: 4 - Nombre maximal d'instructions
in
avec l'opérateurcidr
: 2
Vérification du type
Google SecOps effectue une vérification des types par rapport à votre syntaxe YARA-L lorsque vous créez des règles dans l'interface. Les erreurs de vérification du type qui s'affichent vous aident à modifier la règle de manière à vérifier qu'elle fonctionnera 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 des événements de détection
Les détections issues de règles multi-événements contiennent des exemples d'événements pour fournir un contexte sur les événements qui ont déclenché la détection. La limite est de 10 exemples d'événements maximum pour chaque variable d'événement définie dans la règle. Par exemple, si une règle définit deux variables d'événement, chaque détection peut comporter jusqu'à 20 échantillons d'événement. 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 variable d'événement comporte 15 événements applicables, la détection résultante contient 12 échantillons d'événement (2 + 10).
Tous les échantillons d'événements dépassant la limite sont exclus de la détection.
Si vous souhaitez obtenir plus d'informations sur les événements qui ont déclenché la détection, vous pouvez utiliser des agrégations dans la section "Résultat" pour afficher des informations supplémentaires dans la détection.
Si vous consultez les détections dans l'UI, vous pouvez télécharger tous les exemples d'événements pour une détection. Pour en savoir plus, consultez Télécharger des événements.
Vous avez encore besoin d'aide ? Obtenez des réponses de membres de la communauté et de professionnels Google SecOps.