Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
Sentinel-Queries — Collection organisée de requêtes KQL pour Microsoft Sentinel et de tutoriels pour la chasse aux menaces, l'analyse des journaux de connexion Azure AD, la détection d'anomalies et la création de modèles de détection efficaces. | Kitploit
Outils/GitHubGitHub/reprise99/sentinel-queries
Outils DéfensifsRenseignement sur les MenacesApprentissage et ÉducationRessources OrganiséesDétection d'AnomaliesAnalyse de Journaux
GitHubreprise99/sentinel-queries

Sentinel-Queries

Collection organisée de requêtes KQL pour Microsoft Sentinel et de tutoriels pour la chasse aux menaces, l'analyse des journaux de connexion Azure AD, la détection d'anomalies et la création de modèles de détection efficaces.

Voir le dépôt
1.6k382il y a 6 moisVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

KQL pour Microsoft Sentinel

Quelques astuces, trucs et exemples pour utiliser KQL avec Microsoft Sentinel.

  1. Introduction
  2. L'anatomie d'une requête KQL
  3. Les bases
    1. Les bases du temps
    2. Les bases de Where
    3. Les bases de Project
    4. Les bases de Summarize
    5. Les bases de Render
    6. Les bases de Parse et Split

Introduction

Kusto Query Language est le langage utilisé dans Azure Monitor, Azure Data Explorer et Azure Log Analytics (ce que Microsoft Sentinel utilise sous le capot). J'ai toujours trouvé cette visualisation de KQL utile -

KQL visualisé

Nous voulons utiliser KQL pour créer des requêtes précises et efficaces afin de détecter les menaces, les détections, les modèles et les anomalies au sein de notre jeu de données plus large.

L'anatomie d'une requête KQL

Prenons la requête ci-dessous comme exemple```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | where AppDisplayName == "Microsoft Teams" | project TimeGenerated, Location, IPAddress, UserAgent

root@kitploit:~
Lorsque nous exécutons une requête comme celle-ci, la première ligne indique à Microsoft Sentinel dans quelle table chercher les données. Dans ce cas, nous voulons interroger la table SigninLogs, qui est l'endroit où les données de connexion Azure AD sont envoyées. Vous pouvez consulter une liste des tables [ici](https://docs.microsoft.com/en-us/azure/sentinel/data-source-schema-reference).

Microsoft Sentinel exécutera ensuite votre requête de manière séquentielle, c'est-à-dire qu'il traitera chaque ligne une par une jusqu'à la fin, ou jusqu'à ce qu'une erreur survienne. Décomposons donc notre requête ligne par ligne.```kql
SigninLogs

Donc d'abord, nous avons choisi notre table SigninLogs.```kql SigninLogs | where TimeGenerated > ago(14d)

root@kitploit:~
Ensuite, nous demandons à Sentinel d'examiner les 14 derniers jours de données dans cette table.```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"

Ensuite, nous demandons à Sentinel de ne trouver que les journaux où UserPrincipalName est égal à "[email protected]"```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0"

root@kitploit:~
Ensuite, nous recherchons uniquement les journaux où ResultType == 0, ce qui correspond à une connexion réussie à Azure AD.```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| where AppDisplayName == "Microsoft Teams"

Ensuite, nous recherchons uniquement les connexions à Microsoft Teams.```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | where AppDisplayName == "Microsoft Teams" | project TimeGenerated, Location, IPAddress, UserAgent

root@kitploit:~
Notre dernière ligne utilise l'opérateur project, pour ne renvoyer que 4 champs de nos journaux, afin que nous voyions uniquement les TimeGenerated, Location, IPAddress et UserAgent renvoyés de nos données SigninLogs.

Voilà comment vous construisez des requêtes, passons maintenant aux bases.

## Les bases

### Les bases du temps

Microsoft Sentinel et KQL sont hautement optimisés pour les filtres de temps, donc si vous connaissez la période des données que vous souhaitez rechercher, vous devez filtrer la plage de temps immédiatement. Récupérer les 14 derniers jours de journaux, puis rechercher un nom d'utilisateur comme la requête ci-dessous -```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"

Est beaucoup plus efficace que de rechercher d'abord un nom d'utilisateur puis la période comme ceci -```kql SigninLogs | where UserPrincipalName == "[email protected]" | where TimeGenerated > ago(14d)

root@kitploit:~
KQL propose de nombreuses options pour interroger des périodes de temps spécifiques.```kql
SigninLogs
| where TimeGenerated > ago(14d)

Comme dans le premier exemple, cela recherchera les 14 derniers jours.```kql SigninLogs | where TimeGenerated > ago(14h)

root@kitploit:~
Vous pouvez également faire des heures.```kql
SigninLogs
| where TimeGenerated > ago(14m)

Et les minutes.

KQL prend également en charge les requêtes entre plages de temps -```kql SigninLogs | where TimeGenerated between (ago(14d) .. ago(7d))

root@kitploit:~
Cela trouvera les données SigninLogs entre il y a 14 jours et il y a 7 jours.```kql
SigninLogs
| where TimeGenerated between (ago(14h) .. ago(7h))

Entre il y a 14 heures et il y a 7 heures.```kql SigninLogs | where TimeGenerated between (ago(14m) .. ago(7m))

root@kitploit:~
Et entre il y a 14 minutes et il y a 7 minutes.

### Les bases de Where

Where est un opérateur que vous utiliserez dans pratiquement chaque requête que vous écrirez. C'est ainsi que vous indiquez à Microsoft Sentinel de rechercher des données spécifiques. La syntaxe est très importante avec l'opérateur where. Si nous utilisons notre même exemple.```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"

Cela recherchera dans notre table SigninLogs, sur les 14 derniers jours, les correspondances exactes où notre UserPrincipalName est égal à [email protected]. En KQL, == est sensible à la casse, donc si vous recherchez [email protected] alors que le nom d'utilisateur est en réalité [email protected], vous n'obtiendrez aucun résultat. L'équivalent insensible à la casse est =```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName = "[email protected]"

root@kitploit:~
Cela trouvera toutes les correspondances pour [email protected], indépendamment de la sensibilité à la casse.

Au lieu de equals, on peut aussi utiliser contains.```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName contains "reprise_99"

Cela permettra de trouver toutes les entrées de journal où le UserPrincipalName contient reprise_99 ; si vous disposiez de données [email protected] et [email protected], il les trouverait toutes les deux. L'opérateur contains n'est pas sensible à la casse, mais vous pouvez utiliser contains_cs pour le rendre sensible à la casse.

Vous pouvez utiliser startswith ou endswith si vous recherchez des modèles particuliers.```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName startswith "reprise_99"

SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName endswith "testdomain.com"

root@kitploit:~
Ni startswith ni endswith ne sont sensibles à la casse, mais vous pouvez utiliser startswith_cs ou endswith_cs pour les rendre sensibles à la casse.

Si vous recherchez des mots entiers (de plus de quatre caractères), dans KQL vous pouvez utiliser l'opérateur has. Utiliser 'has' est plus efficace que 'contains' car les données sont indexées pour vous.```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where AppDisplayName has "Teams"

Cela trouvera tous les SigninLogs où le nom d'affichage de l'application contient le mot Teams, ce qui peut inclure « Microsoft Teams » et « Microsoft Teams Web Client », les deux satisfaisant la requête.

Si vous recherchez plusieurs mots, vous pouvez utiliser has_any ou has_all.```kql SigninLogs | where TimeGenerated > ago(14d) | where AppDisplayName has_any ("Teams","Outlook")

root@kitploit:~
Cela retournera des résultats où le nom d'affichage de l'application contient soit "Teams" soit "Outlook"```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where AppDisplayName has_all ("Teams","Outlook")

Cela renverra des résultats où le nom d'affichage de l'application contient "Teams" et "Outlook".

Si vous ne savez pas dans quels champs rechercher, vous pouvez également utiliser des caractères génériques, c'est inefficace mais peut vous mettre sur la bonne voie pour trouver ce que vous voulez.```kql SigninLogs | where TimeGenerated > ago(14d) | where * contains "reprise_99"

root@kitploit:~
Ceci recherchera dans la table SigninLogs tout champ contenant reprise_99.

Un certain nombre de ces options prennent également en charge l'utilisation de ! pour inverser la requête et trouver les résultats où elle n'est pas vraie.```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName != "[email protected]"

Cette requête trouverait tous les SigninLogs dont le UserPrincipalName n'est pas égal à [email protected]```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName !contains "reprise_99"

root@kitploit:~
Cette requête trouverait tous les SigninLogs où le UserPrincipalName ne contient pas reprise_99```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where AppDisplayName !has "Teams"

Cette requête trouverait les SigninLogs où le nom d'affichage de l'application ne contient pas « Teams ».

Les bases de Project

Project nous permet de sélectionner les colonnes renvoyées dans notre requête et dans quel ordre.```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | where AppDisplayName == "Microsoft Teams" | project TimeGenerated, Location, IPAddress, UserAgent

root@kitploit:~
Cette requête recherche les données SigninLogs des 14 derniers jours, où UserPrincipalname est égal à [email protected], où ResultType est 0, où le nom d'affichage de l'application est égal à « Microsoft Teams », puis pour chaque correspondance de cette requête, elle renvoie TimeGenerated, Location, IPAddress et UserAgent.

Nous pouvons renommer les colonnes dans le cadre de la même fonction.```kql
| project LogTime=TimeGenerated, SigninLocation=Location, IP=IPAddress, Agent=UserAgent

Ceci renvoie les mêmes données, mais renomme les colonnes en LogTime, SigninLocation, IP et Agent.

Nous pouvons même manipuler la sortie en ligne avec l'opérateur project.```kql | project LocalTime=TimeGenerated+5h, Location, IPAddress, UserAgent

root@kitploit:~
Cela renvoie les mêmes données, mais change le nom TimeGenerated en LocalTime et convertit vers un fuseau horaire +5h si vous travaillez dans ce fuseau horaire.

project-away est l'opposé de project et supprimera les colonnes de votre requête.```kql
SigninLogs
| where TimeGenerated > ago(14d)
| project-away UserAgent
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| where AppDisplayName == "Microsoft Teams"

Dans cette requête, nous supprimons UserAgent. N'oubliez pas que si vous supprimez une colonne, vous ne pourrez plus y accéder plus tard dans votre requête.

Notions de base sur Summarize

Summarize produit une table qui agrège le contenu de votre requête. Summarize dispose d'un certain nombre de fonctions d'agrégation sous-jacentes. Si nous reprenons notre requête exemple, nous pouvons manipuler les résultats de différentes manières à l'aide de summarize.```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | summarize count() by AppDisplayName

root@kitploit:~
Cette requête recherche dans la table SigninLogs tous les événements des 14 derniers jours, pour toute correspondance avec [email protected], où le résultat est un succès (ResultType == 0), puis résume ces événements par le nom d'affichage de l'application.

Vous pouvez éventuellement nommer la colonne de résultat.```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| summarize AppCount=count() by AppDisplayName

Cela renvoie les mêmes données mais met à jour le nom de la colonne retournée en AppCount.

Au lieu d'un comptage total, vous pouvez résumer un comptage distinct.```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | summarize DistinctAppCount=dcount(AppDisplayName) by AppDisplayName

root@kitploit:~
Cela retournera un seul enregistrement pour chaque application distincte à laquelle [email protected] s'est connecté.

Vous pouvez utiliser les fonctions arg_max et arg_min pour renvoyer l'enregistrement le plus récent ou le plus ancien qui correspond à votre requête.```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| summarize arg_max(TimeGenerated, *) by UserPrincipalName

Cette requête recherche tous les journaux de connexion des 14 derniers jours, qui ont [email protected] comme UserPrincipalname, qui sont des connexions réussies, puis renvoie l'enregistrement le plus récent.```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | summarize arg_min(TimeGenerated, *) by UserPrincipalName

root@kitploit:~
C'est la même chose mais renvoie l'enregistrement le plus ancien.

Vous pouvez utiliser countif pour fournir une logique à vos sommes.```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| summarize TeamsLogons=countif(AppDisplayName has "Teams"), SharePointLogons=countif(AppDisplayName has "SharePoint")

Cela résume les données dans deux nouvelles colonnes, TeamsLogons où le nom d'affichage de l'application contient "Teams" et SharePointLogons où le nom d'affichage de l'application contient "SharePoint"

Vous pouvez ensuite manipuler vos données en indiquant à KQL de placer vos données dans des 'bins' de temps.```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | summarize AppCount=count() by AppDisplayName, bin(TimeGenerated, 1d)

root@kitploit:~
Cela renvoie les mêmes données que notre premier exemple de synthèse, puis regroupe ces données en bins 1D.

Vous pouvez combiner ces fonctions ensemble lorsque cela est utile.```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| summarize TeamsLogons=countif(AppDisplayName has "Teams"), SharePointLogons=countif(AppDisplayName has "SharePoint") by bin(TimeGenerated, 1d)

Il s'agit d'une combinaison de nos fonctions countif et bin, où nous résumons en fonction du nom d'affichage de notre application et plaçons également les résultats dans des bins 1d.

Vous pouvez créer un ensemble d'éléments dans une requête.```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | summarize AppList=make_set(AppDisplayName) by UserPrincipalName

root@kitploit:~
Cela produira une liste des applications auxquelles [email protected] s'est connecté, dans une liste appelée AppList.

Vous pouvez combiner cela avec notre bin temporel.```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| summarize AppList=make_set(AppDisplayName) by UserPrincipalName, bin(TimeGenerated, 1d)

Cela créera une liste des applications auxquelles [email protected] s'est connecté, séparée en une liste par jour.

Bases de Render

L'opérateur render permet à KQL de visualiser les données dans différents formats tels que des diagrammes circulaires, des graphiques temporels ou en aires, ainsi que des graphiques en colonnes et en barres.

Si nous reprenons notre exemple de la table Signinlogs, nous pouvons voir comment visualiser les données de différentes manières.```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | summarize AppCount=count()by AppDisplayName | render piechart

root@kitploit:~
Cette requête résume toutes les applications auxquelles [email protected] s'est connecté au cours des 14 derniers jours, puis affiche le résultat sous forme de graphique en secteurs.

![Graphique en secteurs KQL](https://raw.githubusercontent.com/reprise99/Sentinel-Queries/main/Diagrams/render-piechart.png?raw=true)

Vous pouvez également l'afficher sous forme de graphique en colonnes.```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| summarize AppCount=count()by AppDisplayName
| render columnchart

Graphique en colonnes KQL

Ou un graphique à barres.```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | summarize AppCount=count()by AppDisplayName | render barchart

root@kitploit:~
![KQL Bar Chart](https://raw.githubusercontent.com/reprise99/Sentinel-Queries/main/Diagrams/render-barchart.png?raw=true)

Pour les données temporelles, vous commencez par résumer vos données en 'bins' de temps, comme indiqué dans la section summarize, puis vous pouvez visualiser vos données sur une période donnée.```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| summarize SigninCount=count() by bin(TimeGenerated, 1d)
| render timechart

Ceci visualise toutes les connexions de [email protected] par jour sur les 14 derniers jours et les affiche sous forme de timechart.

KQL Timechart

Vous pouvez également utiliser render en tant qu’areachart.```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | summarize SigninCount=count() by bin(TimeGenerated, 1d) | render areachart

root@kitploit:~
![Graphique en aires KQL](https://raw.githubusercontent.com/reprise99/Sentinel-Queries/main/Diagrams/render-areachart.png?raw=true)

Les graphiques en colonnes et les graphiques en barres peuvent également être utilisés avec des données temporelles. Vous obtiendrez une colonne ou une barre par « bin » de temps sur votre période de temps plus large.```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| summarize SigninCount=count() by bin(TimeGenerated, 1d)
| render columnchart

Ceci est la même requête que notre timechart, mais rendue sous forme de graphique en colonnes avec une colonne par jour.

KQL Graphique en colonnes temporel```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | summarize SigninCount=count() by bin(TimeGenerated, 1d) | render barchart

root@kitploit:~
Et un graphique à barres.

![Graphique à barres temporel KQL](https://raw.githubusercontent.com/reprise99/Sentinel-Queries/main/Diagrams/render-timebarchart.png?raw=true)

Avec les graphiques en colonnes ou à barres, vous pouvez les empiler (ce qui est le comportement par défaut).```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| summarize SigninCount=count() by AppDisplayName, bin(TimeGenerated, 1d)
| render columnchart

Cette requête trouve toutes les connexions pour notre compte, compte les connexions par application, puis crée une seule colonne pour chaque jour.

KQL Time Column Chart Stacked

Si vous souhaitez que chaque application ait sa propre colonne, vous pouvez la définir comme non empilée.```kql SigninLogs | where TimeGenerated > ago(14d) | where UserPrincipalName == "[email protected]" | where ResultType == "0" | summarize SigninCount=count() by bin(TimeGenerated, 1d) | render columnchart with (kind=unstacked)

root@kitploit:~
![KQL Time Column Chart Unstacked](https://raw.githubusercontent.com/reprise99/Sentinel-Queries/main/Diagrams/render-timecolumnchartunstacked.png?raw=true)

Vous pouvez également renommer l'axe et le titre de votre graphique conformément à KQL.```kql
SigninLogs
| where TimeGenerated > ago(14d)
| where UserPrincipalName == "[email protected]"
| where ResultType == "0"
| summarize SigninCount=count() by AppDisplayName, bin(TimeGenerated, 1d)
| render columnchart with (kind=unstacked, ytitle="Total Sign Ins", xtitle="Day", title="Application Signins Per Day")

KQL Time Column Chart Unstacked Renamed

Vous pouvez combiner la logique dans vos actions summarize pour créer un contenu dynamique pour votre opérateur render.```kql SigninLogs | where TimeGenerated > ago(14d) | where ResultType == "0" | summarize TeamsCount=countif(AppDisplayName has "Teams"), OneDrive=countif(AppDisplayName has "OneDrive"), SharePointCount=countif(AppDisplayName has "SharePoint") by bin(TimeGenerated, 1d) | render columnchart with (kind=unstacked, ytitle="Sign In Count", xtitle="Day", title="Teams vs OneDrive vs SharePoint Sign Ins Per Day")

root@kitploit:~
Cette requête recherche toutes les connexions dans votre locataire, puis compte trois groupes - un où le nom d'affichage de l'application contient "Teams", un où le nom d'affichage de l'application contient "OneDrive" et un où le nom d'affichage de l'application contient "SharePoint" pour chaque jour sur les 14 derniers jours, puis restitue le résultat sous forme de graphique en colonnes non empilé.

![Graphique en colonnes temporel KQL pour Outlook, OneDrive, SharePoint](https://raw.githubusercontent.com/reprise99/Sentinel-Queries/main/Diagrams/render-timecolumn-outlookonedrivesharepoint.png?raw=true)

### Notions de base sur Parse et Split

Parse et split sont deux manières différentes d'étendre une chaîne de données en plusieurs colonnes en fonction des correspondances. Beaucoup de journaux ingérés dans Microsoft Sentinel peuvent arriver sous la forme d'une seule chaîne longue (comme sysmon), parse et split vous permettent de les manipuler pour en faire des données lisibles.

Pour ces exemples, nous utiliserons les données de test suivantes```kql
let ExampleText = datatable(TestData:string)
[
'Name=Reprise99,UPNSuffix=testdomain.com,AadTenantId=345c1234-a833-43e4-1d34-123440a5bcdd1,AadUserId=cf6f2df6-b754-48dc-b7bc-c8339caf211,DisplayName=Test User,Type=account'
];

Ces données ne sont qu'une simple chaîne qui ressemble à ceci.

Parse

Nous pouvons extraire des correspondances de données particulières avec ce qui suit```kql let ExampleText = datatable(TestData:string) [ 'Name=Reprise99,UPNSuffix=testdomain.com,AadTenantId=345c1234-a833-43e4-1d34-123440a5bcdd1,AadUserId=cf6f2df6-b754-48dc-b7bc-c8339caf211,DisplayName=Test User,Type=account' ]; ExampleText | parse TestData with * 'Name=' DisplayName ',' * | project DisplayName

root@kitploit:~
Ceci extraira toutes les données entre Name= et , dans une nouvelle colonne appelée 'DisplayName'.

![Parse 1](https://raw.githubusercontent.com/reprise99/Sentinel-Queries/main/Diagrams/parse1.png?raw=true)

Vous pouvez extraire plusieurs colonnes dans la même commande en cherchant des correspondances le long de la chaîne.```kql
let ExampleText = datatable(TestData:string)
[
'Name=Reprise99,UPNSuffix=testdomain.com,AadTenantId=345c1234-a833-43e4-1d34-123440a5bcdd1,AadUserId=cf6f2df6-b754-48dc-b7bc-c8339caf211,DisplayName=Test User,Type=account'
];
ExampleText
| parse TestData with * 'Name=' DisplayName ',UPNSuffix=' DomainSuffix ',AadTenantId=' AzureADTenantId ',' *
| project DisplayName, DomainSuffix, AzureADTenantId

Cela analyse trois nouvelles colonnes - DisplayName, DomainSuffix et AzureADTenantId

Parse 2

En gardant à l'esprit que KQL exécute ses opérations de manière séquentielle, une fois que nous analysons, nous pouvons ensuite analyser à nouveau sur la colonne nouvellement créée.```kql let ExampleText = datatable(TestData:string) [ 'Name=Reprise99,UPNSuffix=testdomain.com,AadTenantId=345c1234-a833-43e4-1d34-123440a5bcdd1,AadUserId=cf6f2df6-b754-48dc-b7bc-c8339caf211,DisplayName=Test User,Type=account', ]; ExampleText | parse TestData with * 'Name=' DisplayName ',UPNSuffix=' DomainSuffix ',AadTenantId=' AzureADTenantId ',' * | project DisplayName, DomainSuffix, AzureADTenantId | parse DomainSuffix with * '.' TopLevelDomain | project DisplayName, DomainSuffix, TopLevelDomain, AzureADTenantId

root@kitploit:~
Ceci analyse davantage notre domaine pour trouver le domaine de premier niveau, dans ce cas un .com

![Parse 3](https://raw.githubusercontent.com/reprise99/Sentinel-Queries/main/Diagrams/parse3.png?raw=true)

Lors de l'utilisation de l'opérateur parse, KQL parcourra toutes vos lignes de données et renverra même les résultats où il n'y a pas de correspondance. Ainsi, selon la structure de vos données, vous pourriez vous retrouver avec de nombreuses lignes de données vides. Si nous étendons nos données d'exemple pour inclure une autre ligne de données, avec des noms différents, et exécutons la même requête, vous verrez des résultats vides.```kql
let ExampleText = datatable(TestData:string)
[
'Name=Reprise99,UPNSuffix=testdomain.com,AadTenantId=345c1234-a833-43e4-1d34-123440a5bcdd1,AadUserId=cf6f2df6-b754-48dc-b7bc-c8339caf211,DisplayName=Test User,Type=account',
'Display=Reprise99,UPN=testdomain.com,AadDirectoryId=345c1234-a833-43e4-1d34-123440a5bcdd1,AadObjectId=cf6f2df6-b754-48dc-b7bc-c8339caf211,Name=Test User,AccountType=account'
]
;
ExampleText
| parse TestData with * 'Name=' DisplayName ',UPNSuffix=' DomainSuffix ',AadTenantId=' AzureADTenantId ',' *
| project DisplayName, DomainSuffix, AzureADTenantId
| parse DomainSuffix with * '.' TopLevelDomain
| project DisplayName, DomainSuffix, TopLevelDomain, AzureADTenantId

Parse 4

Pour contrer cela, vous pouvez utiliser l'opérateur 'parse-where', qui ne renvoie que les résultats où il y a des correspondances avec votre requête.```kql let ExampleText = datatable(TestData:string) [ 'Name=Reprise99,UPNSuffix=testdomain.com,AadTenantId=345c1234-a833-43e4-1d34-123440a5bcdd1,AadUserId=cf6f2df6-b754-48dc-b7bc-c8339caf211,DisplayName=Test User,Type=account', 'Display=Reprise99,UPN=testdomain.com,AadDirectoryId=345c1234-a833-43e4-1d34-123440a5bcdd1,AadObjectId=cf6f2df6-b754-48dc-b7bc-c8339caf211,Name=Test User,AccountType=account' ] ; ExampleText | parse-where TestData with * 'Name=' DisplayName ',UPNSuffix=' DomainSuffix ',AadTenantId=' AzureADTenantId ',' * | project DisplayName, DomainSuffix, AzureADTenantId | parse DomainSuffix with * '.' TopLevelDomain | project DisplayName, DomainSuffix, TopLevelDomain, AzureADTenantId

root@kitploit:~
Nous pouvons voir que nous revenons à un seul résultat où nous avions une correspondance lors de notre analyse.

![Parse 5](https://raw.githubusercontent.com/reprise99/Sentinel-Queries/main/Diagrams/parse5.png?raw=true)

Split sépare une chaîne de texte en un tableau en fonction d'un délimiteur. Si nous revenons à nos données de test d'origine, nous pouvons effectuer la séparation en fonction du signe virgule.```kql
let ExampleText = datatable(TestData:string)
[
'Name=Reprise99,UPNSuffix=testdomain.com,AadTenantId=345c1234-a833-43e4-1d34-123440a5bcdd1,AadUserId=cf6f2df6-b754-48dc-b7bc-c8339caf211,DisplayName=Test User,Type=account',
]
;
ExampleText
| extend SplitData = split(TestData,',')
| project SplitData

Nous obtiendrons un tableau avec notre chaîne découpée.

Split 1

Split est sensible à l'index, donc si vos données sont dans le même ordre, vous pouvez découper directement en nouvelles colonnes.```kql let ExampleText = datatable(TestData:string) [ 'Name=Reprise99,UPNSuffix=testdomain.com,AadTenantId=345c1234-a833-43e4-1d34-123440a5bcdd1,AadUserId=cf6f2df6-b754-48dc-b7bc-c8339caf211,DisplayName=Test User,Type=account', ] ; ExampleText | extend Name = split(TestData,',')[0] | extend DomainSuffix = split(TestData,',')[1] | extend AzureADTenantId = split(TestData,',')[2] | extend AzureADUserId = split(TestData,',')[3] | extend DisplayName = split(TestData,',')[4] | extend AccountType = split(TestData,',')[5] | project Name, DomainSuffix, AzureADTenantId, AzureADUserId, DisplayName, AccountType

root@kitploit:~
Si nous connaissons l'emplacement de nos données dans la chaîne, nous pouvons la diviser directement en colonnes nommées.

![Division 2](https://raw.githubusercontent.com/reprise99/Sentinel-Queries/main/Diagrams/split2.png?raw=true)

Une fois nos données divisées, nous pouvons les interroger comme si elles étaient structurées dès le départ. Ainsi, si nous ajoutons un deuxième enregistrement à nos données, puis effectuons une recherche sur des correspondances spécifiques, nous trouverons ce que nous cherchons.```kql
let ExampleText = datatable(TestData:string)
[
'Name=Reprise99,UPNSuffix=testdomain.com,AadTenantId=345c1234-a833-43e4-1d34-123440a5bcdd1,AadUserId=cf6f2df6-b754-48dc-b7bc-c8339caf211,DisplayName=Test User,Type=account',
'Name=Reprise103,UPNSuffix=testdomain.com,AadTenantId=331c1234-a841-43e5-1d31-12220a5bcee1,AadUserId=cf6f2df6-b754-48dc-b7bc-c8339caf211,DisplayName=Test User 2,Type=account'
]
;
ExampleText
| extend Name = split(TestData,',')[0]
| extend DomainSuffix = split(TestData,',')[1]
| extend AzureADTenantId = split(TestData,',')[2]
| extend AzureADUserId = split(TestData,',')[3]
| extend DisplayName = split(TestData,',')[4]
| extend AccountType = split(TestData,',')[5]
| project Name, DomainSuffix, AzureADTenantId, AzureADUserId, DisplayName, AccountType
| where Name contains "Reprise99"

Nous n'obtenons qu'un seul résultat, où Name contient "Reprise99" ; notre deuxième enregistrement, où Name contient "Reprise103", n'est pas trouvé.

Split 3

Télécharger l’outil