Share via


Migrer des règles de détection Splunk vers Microsoft Sentinel

Cet article décrit comment identifier, comparer et migrer vos règles de détection Splunk vers des règles intégrées Microsoft Sentinel.

Si vous souhaitez migrer votre déploiement Observabilité Splunk, découvrez comment migrer de Splunk vers des journaux Azure Monitor.

Identifier et migrer des règles

Microsoft Sentinel utilise l’analytique Machine Learning pour créer des incidents de haute fidélité actionnables. Certaines de vos détections existantes peuvent être redondantes dans Microsoft Sentinel. Par conséquent, ne migrez pas aveuglément toutes vos règles de détection et d’analyse. Passez en revue ces considérations quand vous identifiez vos règles de détection existantes.

  • Veillez à sélectionner les cas d’usage qui justifient la migration des règles, en tenant compte des priorités et de l’efficacité de l’entreprise.
  • Vérifiez que vous comprenez les types de règles Microsoft Sentinel.
  • Vérifiez que vous comprenez la terminologie des règles.
  • Examinez toutes les règles qui n’ont pas déclenché d’alertes au cours des 6 à 12 derniers mois et déterminez si elles sont toujours pertinentes.
  • Éliminez les menaces ou les alertes de bas niveau que vous ignorez régulièrement.
  • Utilisez les fonctionnalités existantes et vérifiez si les règles d’analytique intégrées de Microsoft Sentinel peuvent traiter vos cas d’usage actuels. Étant donné que Microsoft Sentinel utilise l’analytique Machine Learning pour produire des incidents haute fidélité et actionnables, il est probable que certaines de vos détections existantes ne soient plus nécessaires.
  • Vérifiez que vous avez connecté toutes les sources de données requises et passez en revue vos méthodes de connexion de données. Revenez sur les conversations de collecte de données pour vous assurer de la profondeur et de l’étendue des données dans vos cas d’usage.
  • Testez les fonctionnalités de l’expérience de migration SIEM pour déterminer si la traduction automatisée convient.
  • Explorez les ressources de la communauté telles que la Place de marché de détection des menaces SOC Prime pour vérifier si vos règles sont disponibles.
  • Déterminez si un convertisseur de requête en ligne tel que Uncoder.io peut fonctionner pour vos règles.
  • Si les règles ne sont pas disponibles ou ne peuvent pas être converties, elles doivent être créées manuellement à l’aide d’une requête KQL. Examinez le mappage des règles pour créer de nouvelles requêtes.

En savoir plus sur les meilleures pratiques relatives à la migration des règles de détection.

Pour migrer vos règles d’analytique vers Microsoft Sentinel, procédez comme suit :

  1. Vérifiez que vous avez mis en place un système de test pour chaque règle que vous souhaitez migrer.

    1. Préparez un processus de validation pour vos règles migrées, y compris des scénarios et des scripts de test complets.

    2. Assurez-vous que votre équipe dispose des ressources utiles pour tester vos règles migrées.

    3. Confirmez que vous avez connecté toutes les sources de données requises, et révisez vos méthodes de connexion de données.

  2. Vérifiez si vos détections sont disponibles comme modèles intégrés dans Microsoft Sentinel :

    • Utilisez l’expérience de migration SIEM pour automatiser la traduction et la migration.

      Pour plus d’informations, consultez Utiliser l’expérience de migration SIEM.

    • Si les règles intégrées sont suffisantes, utilisez les modèles de règles intégrées pour créer des règles pour votre propre espace de travail.

      Dans Microsoft Sentinel, accédez à l’onglet Configuration > Analytique > Modèles de règles, puis créez et mettez à jour chacune des règles d’analytique pertinentes.

      Pour plus d’informations, consultez Détection des menaces prête à l’emploi.

    • Si certaines de vos détections ne sont pas couvertes par les règles intégrées de Microsoft Sentinel, essayez un convertisseur de requêtes en ligne, par exemple Uncoder.io ou SPL2KQL, pour convertir vos requêtes en KQL.

      Identifiez la condition du déclencheur et l’action de la règle, puis créez et passez en revue votre requête KQL.

    • Si ni les règles intégrées ni un convertisseur de règles en ligne ne suffisent, vous devrez créer la règle manuellement. Dans ce cas, procédez comme suit pour commencer à créer votre règle :

      1. Identifiez les sources de données que vous souhaitez utiliser dans votre règle. Vous devez créer une table de correspondance entre les sources de données et les tables de données de Microsoft Sentinel pour identifier les tables que vous souhaitez interroger.

      2. Identifiez tous les attributs, champs ou entités de vos données que vous souhaitez utiliser dans vos règles.

      3. Identifiez les critères et la logique de vos règles. À ce stade, vous pouvez utiliser des modèles de règle comme exemples pour construire vos requêtes KQL.

        Pensez aux filtres, aux règles de corrélation, aux listes actives, aux ensembles de référence, aux listes de surveillance, aux anomalies de détection, aux agrégations, etc. Vous pouvez utiliser les références fournies par votre SIEM héritée pour comprendre comment mapper au mieux la syntaxe de vos requêtes.

      4. Identifiez la condition du déclencheur et l’action de la règle, puis créez et passez en revue votre requête KQL. Lorsque vous examinez votre requête, tenez compte des aides relatives à l’optimisation de KQL.

  3. Testez la règle avec chacun de vos cas d’usage pertinents. Si elle ne fournit pas les résultats attendus, vous pouvez revoir la requête KQL et la tester à nouveau.

  4. Lorsque vous êtes satisfait, vous pouvez considérer que la règle a été migrée. Créez un playbook pour votre action de règle le cas échéant. Pour plus d’informations, consultez Automatisation de la réponse aux menaces avec des playbooks dans Microsoft Sentinel.

En savoir plus sur les règles d’analytique :

Comparer la terminologie des règles

Ce tableau vous aide à clarifier le concept d’une règle dans Microsoft Sentinel par rapport à Splunk.

Splunk Microsoft Sentinel
Type de règle • Planifiée
• Temps réel
• Requête planifiée
• Fusion
• Sécurité Microsoft
• Analytique comportementale du Machine Learning
Critères Définir dans SPL Définir dans KQL
Condition de déclencheur • Nombre de résultats
• Nombre d’hôtes
• Nombre de sources
• Personnalisé
Seuil : le nombre de résultats de la requête
Action • Ajouter aux alertes déclenchées
• Journaliser les événements
• Afficher les résultats à rechercher
• Et plus
• Créer une alerte ou un incident
• S’intègre à Logic Apps

Mapper et comparer des exemples de règles

Utilisez ces exemples pour comparer et mapper des règles de Splunk à Microsoft Sentinel dans différents scénarios.

Commandes de recherche courantes

Commande SPL Description Opérateur KQL Exemple KQL
chart/ timechart Retourne des résultats dans une sortie tabulaire pour le graphique de série chronologique. render, opérateur … | render timechart
dedup Supprime les résultats suivants qui correspondent à un critère spécifié. distinct
summarize
… | summarize by Computer, EventID
eval Calcule une expression. Découvrez les commandes d’évaluation courantes. extend T | extend duration = endTime - startTime
fields Supprime les champs des résultats de la recherche. project
project-away
T | project cost=price*quantity, price
head/tail Retourne les N premiers ou derniers résultats. top T | top 5 by Name desc nulls last
lookup Ajoute des valeurs de champ à partir d’une source externe. externaldata
lookup
Exemple KQL
rename Renomme un champ. Utiliser des caractères génériques pour spécifier plusieurs champs. project-rename T | project-rename new_column_name = column_name
rex Spécifie des noms de groupe en utilisant des expressions régulières pour extraire des champs. matches regex … | where field matches regex "^addr.*"
search Filtre les résultats correspondant à l’expression de recherche. search search "X"
sort Trie les résultats de la recherche selon les champs spécifiés. sort T | sort by strlen(country) asc, price desc
stats Fournit des statistiques, éventuellement regroupées par champs. En savoir plus sur les commandes statistiques courantes. summarize Exemple KQL
mstats Comme pour les statistiques, utilisées sur des métriques à la place des événements. summarize Exemple KQL
table Spécifie les champs à conserver dans le jeu de résultats et conserve les données au format tabulaire. project T | project columnA, columnB
top/rare Affiche les valeurs les plus ou les moins courantes d’un champ. top T | top 5 by Name desc nulls last
transaction Regroupe les résultats de recherche dans les transactions.

Exemple SPL
Exemple : row_window_session Exemple KQL
eventstats Génère des statistiques récapitulatives à partir de champs de vos événements et enregistre ces statistiques dans un nouveau champ.

Exemple SPL
Exemples :
join
make_list
mv-expand
Exemple KQL
streamstats Rechercher la somme cumulée d’un champ.

Exemple SPL :
... | streamstats sum(bytes) as bytes _ total \| timechart
row_cumsum ...\| serialize cs=row_cumsum(bytes)
anomalydetection Rechercher des anomalies dans le champ spécifié.

Exemple SPL
series_decompose_anomalies() Exemple KQL
where Filtre les résultats de recherche en utilisant des expressions eval. Utilisé pour comparer deux champs différents. where T | where fruit=="apple"

Commande de recherche : exemple KQL

Users 
| where UserID in ((externaldata (UserID:string) [
@"https://storageaccount.blob.core.windows.net/storagecontainer/users.txt" 
h@"?...SAS..." // Secret token to access the blob 
])) | ... 

Commande de statistique : exemple KQL

Sales 
| summarize NumTransactions=count(), 
Total=sum(UnitPrice * NumUnits) by Fruit, 
StartOfMonth=startofmonth(SellDateTime) 

Commande mstats : exemple KQL

T | summarize count() by price_range=bin(price, 10.0) 

commande de transaction : exemple SPL

sourcetype=MyLogTable type=Event
| transaction ActivityId startswith="Start" endswith="Stop"
| Rename timestamp as StartTime
| Table City, ActivityId, StartTime, Duration

commande de transaction : exemple KQL

let Events = MyLogTable | where type=="Event";
Events
| where Name == "Start"
| project Name, City, ActivityId, StartTime=timestamp
| join (Events
| where Name == "Stop"
| project StopTime=timestamp, ActivityId)
on ActivityId
| project City, ActivityId, StartTime, 
Duration = StopTime – StartTime

Utilisez row_window_session() pour calculer les valeurs de début de session d’une colonne dans un ensemble de lignes sérialisées.

...| extend SessionStarted = row_window_session(
Timestamp, 1h, 5m, ID != prev(ID))

Commande evenstats : exemple SPL

… | bin span=1m _time
|stats count AS count_i by _time, category
| eventstats sum(count_i) as count_total by _time

Commande evenstats : exemple KQL

Voici un exemple avec l’instruction join :

let binSize = 1h;
let detail = SecurityEvent 
| summarize detail_count = count() by EventID,
tbin = bin(TimeGenerated, binSize);
let summary = SecurityEvent
| summarize sum_count = count() by 
tbin = bin(TimeGenerated, binSize);
detail 
| join kind=leftouter (summary) on tbin 
| project-away tbin1

Voici un exemple avec l’instruction make_list :

let binSize = 1m;
SecurityEvent
| where TimeGenerated >= ago(24h)
| summarize TotalEvents = count() by EventID, 
groupBin =bin(TimeGenerated, binSize)
|summarize make_list(EventID), make_list(TotalEvents), 
sum(TotalEvents) by groupBin
| mvexpand list_EventID, list_TotalEvents

Commande anomalydetection : exemple SPL

sourcetype=nasdaq earliest=-10y
| anomalydetection Close _ Price

Commande anomalydetection : exemple KQL

let LookBackPeriod= 7d;
let disableAccountLogon=SignIn
| where ResultType == "50057"
| where ResultDescription has "account is disabled";
disableAccountLogon
| make-series Trend=count() default=0 on TimeGenerated 
in range(startofday(ago(LookBackPeriod)), now(), 1d)
| extend (RSquare,Slope,Variance,RVariance,Interception,
LineFit)=series_fit_line(Trend)
| extend (anomalies,score) = 
series_decompose_anomalies(Trend)

Commandes d’évaluation courantes

Commande SPL Description Exemple SPL Commande KQL Exemple KQL
abs(X) Retourne la valeur absolue de X. abs(number) abs() abs(X)
case(X,"Y",…) Prend des paires d’arguments X et Y, où les arguments X sont des expressions booléennes. Quand ils sont évalués à TRUE, les arguments retournent l’argument Y correspondant. Exemple SPL case Exemple KQL
ceil(X) Arrondi vers le haut d’un nombre X. ceil(1.9) ceiling() ceiling(1.9)
cidrmatch("X",Y) Identifie les adresses IP qui appartiennent à un sous-réseau particulier. cidrmatch
("123.132.32.0/25",ip)
ipv4_is_match()
ipv6_is_match()
ipv4_is_match('192.168.1.1', '192.168.1.255')
== false
coalesce(X,…) Retourne la première valeur qui n’est pas Null. coalesce(null(), "Returned val", null()) coalesce() coalesce(tolong("not a number"),
tolong("42"), 33) == 42
cos(X) Calcule le cosinus de X. n=cos(0) cos() cos(X)
exact(X) Évalue une expression X en utilisant une arithmétique à virgule flottante double précision. exact(3.14*num) todecimal() todecimal(3.14*2)
exp(X) Retourne eX. exp(3) exp() exp(3)
if(X,Y,Z) Si X est évalué à TRUE, le résultat est le deuxième argument Y. Si X est évalué à FALSE, le résultat est le troisième argument Z. if(error==200,
"OK", "Error")
iif() Exemple KQL
isbool(X) Retourne TRUE si X est booléen. isbool(field) iif()
gettype
iif(gettype(X) =="bool","TRUE","FALSE")
isint(X) Retourne TRUE si X est un entier. isint(field) iif()
gettype
Exemple KQL
isnull(X) Retourne TRUE si X est Null. isnull(field) isnull() isnull(field)
isstr(X) Retourne TRUE si X est une chaîne. isstr(field) iif()
gettype
Exemple KQL
len(X) Cette fonction retourne la longueur en caractères d’une chaîne X. len(field) strlen() strlen(field)
like(X,"y") Retourne TRUE si et seulement si X est similaire au modèle SQLite dans Y. like(field, "addr%") has
contains
startswith
matches regex
Exemple KQL
log(X,Y) Retourne le logarithme du premier argument X en utilisant le deuxième argument Y comme base. La valeur par défaut de Y est 10. log(number,2) log
log2
log10
log(X)

log2(X)

log10(X)
lower(X) Retourne la valeur en minuscule de X. lower(username) tolower tolower(username)
ltrim(X,Y) Retourne X avec les caractères du paramètre Y supprimés à partir du côté gauche. La sortie par défaut de Y est constituée d’espaces et de tabulations. ltrim(" ZZZabcZZ ", " Z") trim_start() trim_start(“ ZZZabcZZ”,” ZZZ”)
match(X,Y) Retourne si X correspond au modèle d’expression régulière Y. match(field, "^\d{1,3}.\d$") matches regex … | where field matches regex @"^\d{1,3}.\d$")
max(X,…) Renvoie la valeur maximale d’une colonne. max(delay, mydelay) max()
arg_max()
… | summarize max(field)
md5(X) Retourne le hachage MD5 d’une valeur de chaîne X. md5(field) hash_md5 hash_md5("X")
min(X,…) Renvoie la valeur minimale d’une colonne. min(delay, mydelay) min_of()
min()
arg_min
Exemple KQL
mvcount(X) Retourne le nombre (total) de valeurs X. mvcount(multifield) dcount …| summarize dcount(X) by Y
mvfilter(X) Filtre un champ à valeurs multiples en fonction de l’expression booléenne X. mvfilter(match(email, "net$")) mv-apply Exemple KQL
mvindex(X,Y,Z) Retourne un sous-ensemble de l’argument à valeurs multiples X à partir d’une position de début (commençant à zéro) Y jusqu’à Z (facultatif). mvindex( multifield, 2) array_slice array_slice(arr, 1, 2)
mvjoin(X,Y) Pour un champ X à valeurs multiples et un délimiteur de chaîne Y, joint les valeurs individuelles de X en utilisant Y. mvjoin(address, ";") strcat_array Exemple KQL
now() Retourne l’heure actuelle, représentée en date/heure Unix. now() now() now()

now(-2d)
null() N’accepte pas d’arguments et retourne NULL. null() null null
nullif(X,Y) Inclut deux arguments X et Y, et retourne X si les arguments sont différents. Sinon, retourne NULL. nullif(fieldA, fieldB) iif iif(fieldA==fieldB, null, fieldA)
random() Retourne un nombre pseudo-aléatoire entre 0 et 2147483647. random() rand() rand()
relative_ time(X,Y) Étant donné une heure Epoch X et un spécificateur d’heure relative Y, retourne la valeur de l’heure Epoch de Y appliquée à X. relative_time(now(),"-1d@d") unix time Exemple KQL
replace(X,Y,Z) Retourne une chaîne formée en remplaçant la chaîne Z pour chaque d’une chaîne d’expression régulière Y dans la chaîne X. Retourne la date avec les numéros de mois et de jour permutés.
Par exemple, pour l’entrée 4/30/2015, la sortie est 30/4/2009 :

replace(date, "^(\d{1,2})/ (\d{1,2})/", "\2/\1/")
replace() Exemple KQL
round(X,Y) Retourne X arrondi au nombre de décimales spécifié par Y. Le comportement par défaut est d’arrondir à un entier. round(3.5) round round(3.5)
rtrim(X,Y) Retourne X avec les caractères de Y supprimés à partir du côté droit. Si Y n’est pas spécifié, les espaces et les tabulations sont supprimés. rtrim(" ZZZZabcZZ ", " Z") trim_end() trim_end(@"[ Z]+",A)
searchmatch(X) Retourne TRUE si l’événement correspond à la chaîne de recherche X. searchmatch("foo AND bar") iif() iif(field has "X","Yes","No")
split(X,"Y") Retourne X en tant que champ à valeurs multiples, séparées par le délimiteur Y. split(address, ";") split() split(address, ";")
sqrt(X) Retourne la racine carrée du nombre X. sqrt(9) sqrt() sqrt(9)
strftime(X,Y) Retourne la valeur de l’heure Epoch X rendue en utilisant le format spécifié par Y. strftime(_time, "%H:%M") format_datetime() format_datetime(time,'HH:mm')
strptime(X,Y) Étant donné une heure représentée par une chaîne X, retourne la valeur analysée d’après le format Y. strptime(timeStr, "%H:%M") format_datetime() Exemple KQL
substr(X,Y,Z) Retourne un champ de sous-chaîne X à partir de la position de début (commençant à 1) Y pour Z caractères (facultatif). substr("string", 1, 3) substring() substring("string", 0, 3)
time() Retourne le temps écoulé avec une résolution en microsecondes. time() format_datetime() Exemple KQL
tonumber(X,Y) Convertit la chaîne d’entrée X en un nombre, où Y (facultatif, valeur par défaut étant 10) définit la base du nombre vers lequel convertir. tonumber("0A4",16) toint() toint("123")
tostring(X,Y) Description Exemple SPL tostring() tostring(123)
typeof(X) Retourne une représentation sous forme de chaîne du type du champ. typeof(12) gettype() gettype(12)
urldecode(X) Retourne l’URL X décodée. Exemple SPL url_decode Exemple KQL

case(X,"Y",…) - Exemple SPL

case(error == 404, "Not found",
error == 500,"Internal Server Error",
error == 200, "OK")

case(X,"Y",…) - Exemple KQL

T
| extend Message = case(error == 404, "Not found", 
error == 500,"Internal Server Error", "OK") 

if(X,Y,Z)- Exemple KQL

iif(floor(Timestamp, 1d)==floor(now(), 1d), 
"today", "anotherday")

isint(X) - Exemple KQL

iif(gettype(X) =="long","TRUE","FALSE")

isstr(X) - Exemple KQL

iif(gettype(X) =="string","TRUE","FALSE")

like(X,"y") - Exemple

… | where field has "addr"

… | where field contains "addr"

… | where field startswith "addr"

… | where field matches regex "^addr.*"

min(X,…) - Exemple KQL

min_of (expr_1, expr_2 ...)

…|summarize min(expr)

…| summarize arg_min(Price,*) by Product

mvfilter(X) - Exemple KQL

T | mv-apply Metric to typeof(real) on 
(
 top 2 by Metric desc
)

mvjoin(X,Y) - Exemple KQL

strcat_array(dynamic([1, 2, 3]), "->")

relative time(X,Y) - Exemple KQL

let toUnixTime = (dt:datetime)
{
(dt - datetime(1970-01-01))/1s 
};

replace(X,Y,Z) - Exemple KQL

replace( @'^(\d{1,2})/(\d{1,2})/', @'\2/\1/',date)

strptime(X,Y) - Exemple KQL

format_datetime(datetime('2017-08-16 11:25:10'),
'HH:mm')

time() - Exemple KQL

format_datetime(datetime(2015-12-14 02:03:04),
'h:m:s')

tostring(X,Y)

Retourne une valeur de champ de X sous forme de chaîne.

  • Si la valeur de X est un nombre, X est remise en forme en valeur de chaîne.
  • Si X est une valeur booléenne, X est remis en forme en TRUE ou FALSE.
  • Si X est un nombre, le deuxième argument Y est facultatif et peut être hex (convertit X en hexadécimal), commas (met en forme X avec des virgules et deux décimales) ou duration (convertit X d’un format d’heure en secondes en un format d’heure lisible : HH:MM:SS).
tostring(X,Y) - Exemple SPL

Cet exemple retourne :

foo=615 and foo2=00:10:15:

… | eval foo=615 | eval foo2 = tostring(
foo, "duration")

urldecode(X) - Exemple SPL

urldecode("http%3A%2F%2Fwww.splunk.com%2Fdownload%3Fr%3Dheader")

Exemples KQL de commandes de statistiques courantes

Commande SPL Description Commande KQL Exemple KQL
avg(X) Retourne la moyenne des valeurs du champ X. avg() avg(X)
count(X) Retourne le nombre d’occurrences du champ X. Pour indiquer une valeur de champ spécifique à mettre en correspondance, mettez en forme X en eval(field="value"). count() summarize count()
dc(X) Retourne le nombre de valeurs distinctes du champ X. dcount() …\| summarize countries=dcount(country) by continent
earliest(X) Retourne la valeur chronologiquement la plus ancienne de X. arg_min() … \| summarize arg_min(TimeGenerated, *) by X
latest(X) Retourne la valeur chronologiquement la plus récente de X. arg_max() … \| summarize arg_max(TimeGenerated, *) by X
max(X) Retourne la valeur maximale du champ X. Si les valeurs de X sont non numériques, la valeur maximale est déterminée d’après l’ordre alphabétique. max() …\| summarize max(X)
median(X) Retourne la valeur la plus proche de la moyenne du champ X. percentile() …\| summarize percentile(X, 50)
min(X) Retourne la valeur minimale du champ X. Si les valeurs de X sont non numériques, la valeur minimale est déterminée d’après l’ordre alphabétique. min() …\| summarize min(X)
mode(X) Retourne la valeur la plus fréquente du champ X. top-hitters() …\| top-hitters 1 of Y by X
perc(Y) Retourne la valeur du centile X du champ Y. Par exemple, perc5(total) retourne la cinquième valeur de centile d’un champ total. percentile() …\| summarize percentile(Y, 5)
range(X) Retourne la différence entre la valeur maximale et la valeur minimale du champ X. range() range(1, 3)
stdev(X) Retourne l’écart type de l’échantillon du champ X. stdev stdev()
stdevp(X) Retourne l’écart type de la population du champ X. stdevp() stdevp()
sum(X) Retourne la somme des valeurs du champ X. sum() sum(X)
sumsq(X) Retourne la somme des carrés des valeurs du champ X.
values(X) Retourne la liste de toutes les valeurs distinctes du champ X sous la forme d’une entrée à valeurs multiples. L’ordre des valeurs est alphabétique. make_set() …\| summarize r = make_set(X)
var(X) Retourne la variance de l’échantillon du champ X. variance variance(X)

Étapes suivantes

Dans cet article, vous avez appris à mapper vos règles de migration de Splunk vers Microsoft Sentinel.