Migrar regras de deteção do Splunk para Microsoft Sentinel

As regras de deteção do Splunk são componentes de gestão de informações e eventos de segurança (SIEM) que se comparam às regras de análise no Microsoft Sentinel. Este artigo descreve os conceitos para identificar, comparar e migrar para Microsoft Sentinel. A melhor forma é começar com a experiência de migração SIEM, que identifica regras de análise OOTB (out-of-the-box) para traduzir automaticamente.

Se quiser migrar a implementação de Observabilidade do Splunk, saiba mais sobre como migrar do Splunk para o Azure Monitorizar Registos.

Regras de auditoria

Microsoft Sentinel utiliza a análise de machine learning para criar incidentes acionáveis e de alta fidelidade. Algumas das suas deteções do Splunk existentes podem ser redundantes no Microsoft Sentinel, por isso não as migre todas cegamente. Reveja estas considerações à medida que identifica as regras de deteção existentes.

  • Certifique-se de que seleciona casos de utilização que justificam a migração de regras, considerando a prioridade comercial e a eficiência.
  • Verifique se compreende Microsoft Sentinel tipos de regras.
  • Verifique se compreende a terminologia da regra.
  • Reveja as regras desatualizadas que não têm alertas nos últimos 6 a 12 meses e determine se ainda são relevantes.
  • Elimine alertas ou ameaças de baixo nível que ignora regularmente.
  • Confirme as origens de dados ligadas e reveja os métodos de ligação de dados. Microsoft Sentinel Analytics requer que o tipo de dados esteja presente na área de trabalho do Log Analytics antes de uma regra ser ativada. Revisite as conversações de recolha de dados para garantir a profundidade e a amplitude dos dados em todos os casos de utilização que planeia detetar. Em seguida, utilize a experiência de migração SIEM para garantir que as origens de dados são mapeadas adequadamente.

Migrar regras

Depois de identificar as deteções do Splunk a migrar, veja estas considerações sobre o processo de migração:

  • Compare a funcionalidade existente das regras de análise OOTB do Microsoft Sentinel com os seus casos de utilização atuais. Utilize a experiência de migração SIEM para ver que deteções do Splunk são convertidas automaticamente em modelos OOTB.
  • Traduzir deteções que não estão alinhadas com as regras de análise OOTB. A melhor forma de traduzir automaticamente deteções do Splunk é com a experiência de migração SIEM.
  • Descubra mais algoritmos para os seus casos de utilização ao explorar recursos da comunidade, como o Marketplace de Deteção de Ameaças Principais do SOC.
  • Traduzir manualmente as deteções se as regras incorporadas não estiverem disponíveis ou não forem traduzidas automaticamente. Crie as novas consultas KQL e reveja o mapeamento de regras.

Para obter mais informações, veja melhores práticas para migrar regras de deteção.

Passos de migração de regras

  1. Verifique se tem um sistema de teste implementado para cada regra que pretende migrar.

    1. Prepare um processo de validação para as regras migradas, incluindo scripts e cenários de teste completos.

    2. Certifique-se de que a sua equipa tem recursos úteis para testar as regras migradas.

    3. Confirme que tem as origens de dados necessárias ligadas e reveja os métodos de ligação de dados.

  2. Verifique se as deteções estão disponíveis como modelos OOTB no Microsoft Sentinel:

    • Utilize a experiência de migração SIEM para automatizar a tradução e a instalação dos modelos OOTB.

      Para obter mais informações, veja Utilizar a experiência de migração SIEM.

    • Se tiver casos de utilização não refletidos nas deteções, crie regras para a sua própria área de trabalho com modelos de regras OOTB.

      Em Microsoft Sentinel, aceda ao Hub de conteúdos.

      Filtrar Tipo de conteúdo para modelos de regras de Análise .

      Localizar e Instalar/Atualizar cada solução do Hub de conteúdos correspondente ou modelo de regra de análise autónoma.

      Para obter mais informações, consulte Detetar ameaças fora da caixa.

    • Se tiver deteções que não estão abrangidas pelas regras OOTB de Microsoft Sentinel, experimente primeiro a experiência de migração SIEM para tradução automática.

    • Se nem as regras OOTB nem a migração SIEM traduzirem completamente a deteção, crie a regra manualmente. Nestes casos, utilize os seguintes passos para criar a regra:

      1. Identifique as origens de dados que pretende utilizar na regra. Identifique as tabelas de Microsoft Sentinel que pretende consultar ao criar uma tabela de mapeamento entre origens de dados e tabelas de dados.

      2. Identifique quaisquer atributos, campos ou entidades nos seus dados que pretenda utilizar nas suas regras.

      3. Identifique os critérios e a lógica da regra. Nesta fase, considere encontrar modelos de regras como exemplos de como construir as suas consultas KQL.

        Considere filtros, regras de correlação, listas ativas, conjuntos de referência, listas de observação, anomalias de deteção, agregações, etc. Pode utilizar referências fornecidas pelo siEM legado para compreender como mapear melhor a sintaxe da consulta.

      4. Identifique a condição do acionador e a ação da regra e, em seguida, construa e reveja a consulta KQL. Ao rever a consulta, considere os recursos de orientação de otimização do KQL.

  3. Teste a regra com cada um dos seus casos de utilização relevantes. Se não fornecer os resultados esperados, reveja e edite o KQL e teste-o novamente.

  4. Quando estiver satisfeito, considere a regra migrada. Crie um manual de procedimentos para a sua ação de regra conforme necessário. Para obter mais informações, veja Automatizar a resposta a ameaças com manuais de procedimentos no Microsoft Sentinel.

Saiba mais sobre as regras de análise:

Comparar terminologia de regra

Esta tabela ajuda-o a clarificar o conceito de uma regra com base no Linguagem de Pesquisa Kusto (KQL) no Microsoft Sentinel em comparação com uma deteção do Splunk com base na Linguagem de Processamento de Pesquisa (SPL).

Splunk Microsoft Sentinel
Tipo de regra • Agendado
• Em tempo real
• Consulta agendada
• Fusão
• Microsoft Security
• Análise Comportamental do Machine Learning (ML)
Critérios Definir em SPL Definir no KQL
Condição do acionador • Número de resultados
• Número de anfitriões
• Número de origens
• Personalizado
Limiar: número de resultados da consulta
Ação • Adicionar aos alertas acionados
• Evento de Registo
• Resultados de saída a procurar
• E muito mais
• Criar alerta ou incidente
• Integra-se no Logic Apps

Mapear e comparar exemplos de regras

Utilize estes exemplos para comparar e mapear regras de Splunk para Microsoft Sentinel em vários cenários.

Comandos de pesquisa comuns

Comando SPL Descrição Operador KQL Exemplo de KQL
chart/ timechart Devolve resultados numa saída tabular para gráficos de série temporal. operador de composição … | render timechart
dedup Remove os resultados subsequentes que correspondem a um critério especificado. distinto
resumir
… | summarize by Computer, EventID
eval Calcula uma expressão. Saiba mais sobre comandos comunseval. expandir T | extend duration = endTime - startTime
fields Remove campos dos resultados da pesquisa. projeto
project-away
T | project cost=price*quantity, price
head/tail Devolve o primeiro ou último N resultados. superior T | top 5 by Name desc nulls last
lookup Adiciona valores de campo de uma origem externa. externaldata
pesquisa
Exemplo de KQL
rename Muda o nome de um campo. Utilize carateres universais para especificar vários campos. nome do projeto T | project-rename new_column_name = column_name
rex Especifica nomes de grupos com expressões regulares para extrair campos. corresponde ao regex … | where field matches regex "^addr.*"
search Filtra os resultados para resultados que correspondem à expressão de pesquisa. procurar search "X"
sort Ordena os resultados da pesquisa pelos campos especificados. ordenar T | sort by strlen(country) asc, price desc
stats Fornece estatísticas, opcionalmente agrupadas por campos. Saiba mais sobre os comandos de estatísticas comuns. resumir Exemplo de KQL
mstats Semelhante às estatísticas, utilizadas em métricas em vez de eventos. resumir Exemplo de KQL
table Especifica os campos a manter no conjunto de resultados e retém os dados em formato tabular. projeto T | project columnA, columnB
top/rare Apresenta os valores mais ou menos comuns de um campo. superior T | top 5 by Name desc nulls last
transaction Agrupa os resultados da pesquisa em transações.

Exemplo de SPL
Exemplo: row_window_session Exemplo de KQL
eventstats Gera estatísticas de resumo a partir de campos nos seus eventos e guarda essas estatísticas num novo campo.

Exemplo de SPL
Exemplos:
associar
make_list
mv-expand
Exemplo de KQL
streamstats Localize a soma cumulativa de um campo.

Exemplo de SPL:
... | streamstats sum(bytes) as bytes _ total \| timechart
row_cumsum ...\| serialize cs=row_cumsum(bytes)
anomalydetection Localize anomalias no campo especificado.

Exemplo de SPL
series_decompose_anomalies() Exemplo de KQL
where Filtra os resultados da pesquisa com eval expressões. Utilizado para comparar dois campos diferentes. em que T | where fruit=="apple"

lookup comando: exemplo de 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 
])) | ... 

stats comando: exemplo de KQL

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

mstats comando: exemplo de KQL

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

transaction comando: exemplo de SPL

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

transaction comando: exemplo de 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

Utilize row_window_session() para calcular valores de início de sessão para uma coluna num conjunto de linhas serializado.

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

eventstats comando: exemplo de SPL

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

eventstats comando: exemplo de KQL

Eis um exemplo com a join instrução :

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

Eis um exemplo com a make_list instrução :

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

anomalydetection comando: exemplo de SPL

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

anomalydetection comando: exemplo de 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)

Comandos comuns eval

Comando SPL Descrição Exemplo de SPL Comando KQL Exemplo de KQL
abs(X) Devolve o valor absoluto de X. abs(number) abs() abs(X)
case(X,"Y",…) Utiliza pares de X argumentos e Y , em que os X argumentos são expressões booleanas. Quando avaliados como TRUE, os argumentos devolvem o argumento correspondente Y . Exemplo de SPL case Exemplo de KQL
ceil(X) Limite de um número X. ceil(1.9) ceiling() ceiling(1.9)
cidrmatch("X",Y) Identifica endereços IP que pertencem a uma sub-rede específica. 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,…) Devolve o primeiro valor que não é nulo. coalesce(null(), "Returned val", null()) coalesce() coalesce(tolong("not a number"),
tolong("42"), 33) == 42
cos(X) Calcula o cosseno de X. n=cos(0) cos() cos(X)
exact(X) Avalia uma expressão X com aritmética de vírgula flutuante de precisão dupla. exact(3.14*num) todecimal() todecimal(3.14*2)
exp(X) Devolve eX. exp(3) exp() exp(3)
if(X,Y,Z) Se X for avaliado como TRUE, o resultado é o segundo argumento Y. Se X for avaliado como FALSE, o resultado é avaliado como o terceiro argumento Z. if(error==200,
"OK", "Error")
iff() Exemplo de KQL
isbool(X) Devolve TRUE se X for booleano. isbool(field) iff()
gettype
iff(gettype(X) =="bool","TRUE","FALSE")
isint(X) Devolve TRUE se X for um número inteiro. isint(field) iff()
gettype
Exemplo de KQL
isnull(X) Devolve TRUE se X for nulo. isnull(field) isnull() isnull(field)
isstr(X) Devolve TRUE se X for uma cadeia. isstr(field) iff()
gettype
Exemplo de KQL
len(X) Esta função devolve o comprimento do caráter de uma cadeia X. len(field) strlen() strlen(field)
like(X,"y") Devolve TRUE se e apenas se X for como o padrão SQLite em Y. like(field, "addr%") has
contains
startswith
corresponde ao regex
Exemplo de KQL
log(X,Y) Devolve o registo do primeiro argumento X com o segundo argumento Y como base. O valor predefinido de Y é 10. log(number,2) log
log2
log10
log(X)

log2(X)

log10(X)
lower(X) Devolve o valor em minúsculas de X. lower(username) tolower tolower(username)
ltrim(X,Y) Devolve X com os carateres no parâmetro Y cortados do lado esquerdo. A saída predefinida de Y é espaços e separadores. ltrim(" ZZZabcZZ ", " Z") trim_start() trim_start(“ ZZZabcZZ”,” ZZZ”)
match(X,Y) Devolve se X corresponder ao padrão regex Y. match(field, "^\d{1,3}.\d$") matches regex … | where field matches regex @"^\d{1,3}.\d$")
max(X,…) Devolve o valor máximo numa coluna. max(delay, mydelay) max()
arg_max()
… | summarize max(field)
md5(X) Devolve o hash MD5 de um valor Xde cadeia . md5(field) hash_md5 hash_md5("X")
min(X,…) Devolve o valor mínimo numa coluna. min(delay, mydelay) min_of()
min()
arg_min
Exemplo de KQL
mvcount(X) Devolve o número (total) de X valores. mvcount(multifield) dcount …| summarize dcount(X) by Y
mvfilter(X) Filtra um campo de valores múltiplos com base na expressão booleana X . mvfilter(match(email, "net$")) mv-apply Exemplo de KQL
mvindex(X,Y,Z) Devolve um subconjunto do argumento de valores X múltiplos de uma posição inicial (baseada em zero) Y para Z (opcional). mvindex( multifield, 2) array_slice array_slice(arr, 1, 2)
mvjoin(X,Y) Dado um campo X de valores múltiplos e um delimitador Yde cadeias, e associa os valores individuais de utilização Yde X . mvjoin(address, ";") strcat_array Exemplo de KQL
now() Devolve a hora atual, representada na hora do Unix. now() now() now()

now(-2d)
null() Não aceita argumentos e devolve NULL. null() nulo null
nullif(X,Y) Inclui dois argumentos e XY, e devolve X se os argumentos forem diferentes. Caso contrário, devolve NULL. nullif(fieldA, fieldB) iff iff(fieldA==fieldB, null, fieldA)
random() Devolve um número pseudo-aleatório entre 0 para 2147483647. random() rand() rand()
relative_ time(X,Y) Dado um tempo X de época e um especificador Yde tempo relativo , devolve o valor de tempo de época de Y aplicado a X. relative_time(now(),"-1d@d") hora unix Exemplo de KQL
replace(X,Y,Z) Devolve uma cadeia formada pela substituição da cadeia Z por cada ocorrência da cadeia de expressão Y regular na cadeia X. Devolve a data com os números de mês e dia mudados.
Por exemplo, para a 4/30/2015 entrada, o resultado é 30/4/2009:

replace(date, "^(\d{1,2})/ (\d{1,2})/", "\2/\1/")
replace() Exemplo de KQL
round(X,Y) Devolve X arredondado para o número de casas decimais especificadas por Y. A predefinição é arredondar para um número inteiro. round(3.5) round round(3.5)
rtrim(X,Y) Devolve X com os carateres de Y cortados do lado direito. Se Y não for especificado, os espaços e os separadores são cortados. rtrim(" ZZZZabcZZ ", " Z") trim_end() trim_end(@"[ Z]+",A)
searchmatch(X) Devolve TRUE se o evento corresponder à cadeia de Xpesquisa . searchmatch("foo AND bar") iff() iff(field has "X","Yes","No")
split(X,"Y") Devolve X como um campo de valores múltiplos, dividido por delimitador Y. split(address, ";") split() split(address, ";")
sqrt(X) Devolve a raiz quadrada de X. sqrt(9) sqrt() sqrt(9)
strftime(X,Y) Devolve o valor X de tempo de época composto com o formato especificado por Y. strftime(_time, "%H:%M") format_datetime() format_datetime(time,'HH:mm')
strptime(X,Y) Dado um tempo representado por uma cadeia X, devolve o valor analisado a partir do formato Y. strptime(timeStr, "%H:%M") format_datetime() Exemplo de KQL
substr(X,Y,Z) Devolve um campo X de subcadeia da posição inicial (baseada em um) Y para Z carateres (opcionais). substr("string", 1, 3) substring() substring("string", 0, 3)
time() Devolve a hora do relógio de parede com resolução de microssegundos. time() format_datetime() Exemplo de KQL
tonumber(X,Y) Converte a cadeia X de entrada num número, em Y que (opcional, o valor predefinido é 10) define a base do número para o qual converter. tonumber("0A4",16) toint() toint("123")
tostring(X,Y) Descrição Exemplo de SPL tostring() tostring(123)
typeof(X) Devolve uma representação de cadeia do tipo de campo. typeof(12) gettype() gettype(12)
urldecode(X) Devolve o URL X descodificado. Exemplo de SPL url_decode Exemplo de KQL

case(X,"Y",…) Exemplo de SPL

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

case(X,"Y",…) Exemplo de KQL

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

if(X,Y,Z) Exemplo de KQL

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

isint(X) Exemplo de KQL

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

isstr(X) Exemplo de KQL

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

like(X,"y") exemplo

… | where field has "addr"

… | where field contains "addr"

… | where field startswith "addr"

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

min(X,…) Exemplo de KQL

min_of (expr_1, expr_2 ...)

…|summarize min(expr)

…| summarize arg_min(Price,*) by Product

mvfilter(X) Exemplo de KQL

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

mvjoin(X,Y) Exemplo de KQL

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

relative time(X,Y) Exemplo de KQL

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

replace(X,Y,Z) Exemplo de KQL

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

strptime(X,Y) Exemplo de KQL

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

time() Exemplo de KQL

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

tostring(X,Y)

Devolve um valor de campo de X como uma cadeia.

  • Se o valor de X for um número, X será reformatado para um valor de cadeia.
  • Se X for um valor booleano, X é reformatado para TRUE ou FALSE.
  • Se X for um número, o segundo argumento Y é opcional e pode ser hex (convertido X num hexadecimal), commas (formatos com vírgulas X e duas casas decimais) ou duration (converte X de um formato de tempo em segundos para um formato de tempo legível: HH:MM:SS).
tostring(X,Y) Exemplo de SPL

Este exemplo devolve:

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

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

urldecode(X) Exemplo de SPL

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

Exemplo de KQL de comandos comuns stats

Comando SPL Descrição Comando KQL Exemplo de KQL
avg(X) Devolve a média dos valores do campo X. avg() avg(X)
count(X) Devolve o número de ocorrências do campo X. Para indicar um valor de campo específico a corresponder, formate X como eval(field="value"). count() summarize count()
dc(X) Devolve a contagem de valores distintos do campo X. dcount() …\| summarize countries=dcount(country) by continent
earliest(X) Devolve o valor observado cronologicamente mais cedo de X. arg_min() … \| summarize arg_min(TimeGenerated, *) by X
latest(X) Devolve o valor observado cronologicamente mais recente de X. arg_max() … \| summarize arg_max(TimeGenerated, *) by X
max(X) Devolve o valor máximo do campo X. Se os valores de X não forem numéricos, o valor máximo é encontrado por ordem alfabética. max() …\| summarize max(X)
median(X) Devolve o valor mais médio do campo X. percentil() …\| summarize percentile(X, 50)
min(X) Devolve o valor mínimo do campo X. Se os valores de X não forem numéricos, o valor mínimo é encontrado por ordem alfabética. min() …\| summarize min(X)
mode(X) Devolve o valor mais frequente do campo X. top-hitters() …\| top-hitters 1 of Y by X
perc(Y) Devolve o valor de percentil X do campo Y. Por exemplo, perc5(total) devolve o quinto valor de percentil de um campo total. percentil() …\| summarize percentile(Y, 5)
range(X) Devolve a diferença entre os valores máximo e mínimo do campo X. intervalo() range(1, 3)
stdev(X) Devolve o desvio-padrão de exemplo do campo X. desvpad stdev()
stdevp(X) Devolve o desvio-padrão da população do campo X. stdevp() stdevp()
sum(X) Devolve a soma dos valores do campo X. sum() sum(X)
sumsq(X) Devolve a soma dos quadrados dos valores do campo X.
values(X) Devolve a lista de todos os valores distintos do campo X como uma entrada com múltiplos valores. A ordem dos valores é alfabética. make_set() …\| summarize r = make_set(X)
var(X) Devolve a variância de exemplo do campo X. variância variance(X)

Passos seguintes

Neste artigo, aprendeu a mapear as regras de migração do Splunk para o Microsoft Sentinel.