Comprendre la syntaxe de recherche
Ce guide est destiné aux analystes de sécurité qui souhaitent configurer des expressions de recherche (valeurs de données, séquences d'échappement, opérateurs, etc.) dans l'éditeur de requêtes de la page Recherche SIEM.
Lorsque vous écrivez des expressions de recherche YARA-L 2.0 ou SQL dans l'éditeur de requêtes Google Security Operations, vous devez mettre en forme vos valeurs de données, vos opérateurs et vos séquences d'échappement de chaîne en fonction du type de données exact du champ UDM cible. Une condition de recherche se compose d'un nom de champ UDM, d'un opérateur de comparaison (=, !=, >, <, <=, >=) et d'une valeur de données formatée.
Mettre en forme les valeurs de données par type de données
Cette section décrit les opérations suivantes :
Valeurs énumérées (enums)
Les énumérations doivent être écrites sous forme de chaînes de texte en majuscules correspondant exactement aux définitions valides du dictionnaire UDM, entre guillemets doubles ("), comme dans l'exemple suivant :
metadata.event_type = "NETWORK_CONNECTION" security_result.action = "BLOCK" network.ip_protocol = "TCP"
Valeurs booléennes
Les champs booléens acceptent les valeurs "true" ou "false" (sans tenir compte de la casse, sans guillemets), comme dans l'exemple suivant :
network.dns.response = true target.user.is_admin = false
Nombres entiers et valeurs numériques
Les nombres entiers et les numéros de port sont écrits sous forme de chiffres littéraux sans guillemets doubles, comme dans l'exemple suivant :
target.port = 443 network.sent_bytes > 10485760
Valeurs float et décimales
Pour les champs UDM de type float ou double, saisissez un nombre décimal ou un entier sans guillemets doubles, comme dans l'exemple suivant :
security_result.about.asset.vulnerabilities.cvss_base_score = 9.8
Chaînes de texte
Les valeurs textuelles standards doivent être placées entre guillemets doubles ("), comme dans l'exemple suivant :
metadata.product_name = "Google Cloud VPC Flow Logs" target.asset.asset_id = "srv-prod-us-central1-a"
Correspondance non sensible à la casse (nocase)
Par défaut, les comparaisons de chaînes dans YARA-L 2.0 sont sensibles à la casse. Pour faire correspondre n'importe quelle combinaison de caractères majuscules et minuscules, ajoutez l'opérateur nocase directement à la fin de la condition, comme dans l'exemple suivant :
principal.hostname != "http-server" nocase principal.user.userid = "jdoe" nocase
Échappement de chaînes (\ et ")
Si un littéral de chaîne contient des barres obliques inverses ou des guillemets doubles, vous devez échapper ces caractères à l'aide d'une barre oblique inverse (\\), comme dans l'exemple suivant :
- Utilisez
\\pour faire correspondre une barre oblique inverse littérale (\\). Utilisez
\"pour faire correspondre un guillemet double littéral (").Recherchez des chemins d'accès aux fichiers Windows avec des barres obliques inverses échappées :
principal.process.file.full_path = "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe"Recherchez les lignes de commande contenant des guillemets doubles imbriqués :
target.process.command_line = "cmd.exe /c \"c:\\program files\\malicious.exe\""
Expressions régulières (syntaxe RE2)
Pour effectuer une recherche à l'aide d'expressions régulières, placez le modèle d'expression régulière entre des barres obliques (/ /) au lieu de guillemets doubles. Google SecOps utilise le moteur d'expressions régulières RE2 standard :
Faites correspondre n'importe quelle adresse IP principale dans la plage 10.x.x.x, comme ceci :
principal.ip = /10\..*/Recherchez l'exécution de PsExec avec l'extension
.exefacultative, sans tenir compte de la casse, comme dans l'exemple suivant :target.process.command_line = /\bpsexec(\.exe)?\b/ nocaseFaites correspondre les noms d'hôte DNS dynamiques suivant un modèle numéroté, comme dans l'exemple suivant :
principal.hostname = /dns-server-[0-9]+/ nocase
Logique booléenne et priorité des opérateurs
Combinez plusieurs conditions de recherche à l'aide des opérateurs AND, OR et NOT. Vous pouvez utiliser des parenthèses () pour regrouper explicitement des expressions et contrôler la priorité d'évaluation, comme illustré dans les exemples suivants :
Recherchez des événements de connexion utilisateur spécifiques sur un hôte sensible, comme dans l'exemple suivant :
metadata.event_type = "USER_LOGIN" AND target.hostname = "finance-db-prod"Utilisez des parenthèses pour isoler les conditions OR des chaînes AND, comme dans l'exemple suivant :
metadata.event_type = "PROCESS_LAUNCH" AND principal.process.file.full_path = /winword.exe/ nocase AND (target.process.file.full_path = /cmd.exe/ OR target.process.file.full_path = /powershell.exe/)
Rechercher des paires clé/valeur dans les champs additional et labels
Les champs additional et labels servent de conteneurs flexibles pour les données d'événement personnalisées et les attributs de fournisseurs tiers qui ne correspondent pas aux champs UDM standards. Chaque entrée stocke une paire clé/valeur :
Champs
additional: peuvent contenir plusieurs paires clé/valeur par événement (additional.fields["key"] = "value").labelsfields : ne peut contenir qu'une seule paire clé-valeur par événement (labels["key"] = "value").
Correspondance exacte des paires clé/valeur (field["key"] = "value")
Utilisez la syntaxe avec crochets pour interroger directement une clé spécifique et sa valeur de chaîne correspondante, comme dans l'exemple suivant :
additional.fields["pod_name"] = "kube-scheduler-prod" metadata.ingestion_labels["MetadataKeyDeletion"] = "startup-script"
Correspondance avancée des expressions régulières et des valeurs non string dans les champs additional
Si vous devez interroger des valeurs numériques/booléennes dans les champs additional ou faire correspondre des clés et des valeurs à l'aide d'expressions régulières, utilisez le chemin d'accès complet au champ protobuf :
Faire correspondre n'importe quelle chaîne de valeur à l'intérieur du conteneur supplémentaire par expression régulière :
additional.fields.value.string_value = /suspicious_payload_.*/ nocaseFaire correspondre des valeurs booléennes ou numériques dans des champs personnalisés :
additional.fields.value.bool_value = true additional.fields.value.number_value > 500Rechercher dans plusieurs clés dynamiques correspondant à un préfixe d'expression régulière :
additional.fields.key = /^myKeyNumber_.*/Vérifiez si une clé existe, quelle que soit sa valeur :
additional.fields["pod_name"] != ""Utilisez des expressions régulières et
nocasedirectement avec la syntaxe entre crochets :additional.fields["pod_name"] = /br/ additional.fields["pod_name"] = bar nocaseCombinez plusieurs paires clé-valeur
additional.fieldsà l'aide deAND:additional.fields["pod_name"] = "kube-scheduler" AND additional.fields["namespace"] = "kube-system"
Rechercher dans les champs groupés
Les champs regroupés sont des alias pour des groupes de champs UDM associés. Vous pouvez les utiliser pour interroger plusieurs champs UDM en même temps sans avoir à saisir chaque champ individuellement.
L'exemple suivant montre comment saisir une requête pour faire correspondre les champs UDM courants susceptibles de contenir l'adresse IP spécifiée :
ip = "1.2.3.4"
Vous pouvez faire correspondre un champ groupé à l'aide d'une expression régulière et de l'opérateur nocase. Les listes de références sont également acceptées. Les champs regroupés peuvent également être utilisés en combinaison avec des champs UDM standards, comme illustré dans l'exemple suivant :
ip = "5.6.7.8" AND metadata.event_type = "NETWORK_CONNECTION"
Types de champs UDM regroupés
Vous pouvez effectuer des recherches dans tous les champs UDM groupés suivants :
| Nom du champ groupé | Champs UDM associés |
|---|---|
domain |
about.administrative_domainabout.asset.network_domainnetwork.dns.questions.namenetwork.dns_domainprincipal.administrative_domainprincipal.asset.network_domaintarget.administrative_domaintarget.asset.hostnametarget.asset.network_domaintarget.hostname |
email |
intermediary.user.email_addressesnetwork.email.fromnetwork.email.toprincipal.user.email_addressessecurity_result.about.user.email_addressestarget.user.email_addresses |
file_path |
principal.file.full_pathprincipal.process.file.full_pathprincipal.process.parent_process.file.full_pathtarget.file.full_pathtarget.process.file.full_pathtarget.process.parent_process.file.full_path |
hash |
about.file.md5about.file.sha1about.file.sha256principal.process.file.md5principal.process.file.sha1principal.process.file.sha256security_result.about.file.sha256target.file.md5target.file.sha1target.file.sha256target.process.file.md5target.process.file.sha1target.process.file.sha256 |
hostname |
intermediary.hostnameobserver.hostnameprincipal.asset.hostnameprincipal.hostnamesrc.asset.hostnamesrc.hostnametarget.asset.hostnametarget.hostname |
ip |
intermediary.ipobserver.ipprincipal.artifact.ipprincipal.asset.ipprincipal.ipsrc.artifact.ipsrc.asset.ipsrc.iptarget.artifact.iptarget.asset.iptarget.ip |
namespace |
principal.namespacesrc.namespacetarget.namespace |
process_id |
principal.process.parent_process.pidprincipal.process.parent_process.product_specific_process_idprincipal.process.pidprincipal.process.product_specific_process_idtarget.process.parent_process.pidtarget.process.parent_process.product_specific_process_idtarget.process.pidtarget.process.product_specific_process_id |
user |
about.user.useridobserver.user.useridprincipal.user.user_display_nameprincipal.user.useridprincipal.user.windows_sidsrc.user.useridtarget.user.user_display_nametarget.user.useridtarget.user.windows_sid |
Ajouter des commentaires dans une requête
Vous pouvez ajouter des commentaires dans l'éditeur de recherche pour documenter une logique de recherche complexe ou désactiver temporairement des conditions lors des tests :
- Commentaires sur une seule ligne : faites précéder le texte du commentaire de deux barres obliques (
//). Tout ce qui se trouve après les barres obliques sur cette ligne est ignoré. - Commentaires sur plusieurs lignes : placez le texte du commentaire entre
/*et*/. Les commentaires bloqués peuvent s'étendre sur plusieurs lignes.
Exemple :
metadata.event_type = "NETWORK_CONNECTION" AND
// Exclude approved corporate proxy traffic
target.ip != "192.0.2.100" AND
/* Uncomment the lines below when investigating specific lateral
movement across subnet 10.240.0.0/16 */
// principal.ip = /10.240\..*/ AND
// network.sent_bytes > 5000000
Vous avez encore besoin d'aide ? Obtenez des réponses de membres de la communauté et de professionnels Google SecOps.