Migración de reglas de detección de Splunk a Microsoft Sentinel

Las reglas de detección de Splunk son componentes de administración de eventos e información de seguridad (SIEM) que se comparan con las reglas de análisis de Microsoft Sentinel. En este artículo se describen los conceptos para identificarlos, compararlos y migrarlos a Microsoft Sentinel. La mejor manera es empezar con la experiencia de migración SIEM, que identifica las reglas de análisis integradas (OOTB) a las que se va a traducir automáticamente.

Si desea migrar la implementación de Splunk Observability, obtenga más información sobre cómo migrar de Splunk a Azure Monitor Logs.

Reglas de auditoría

Microsoft Sentinel usa análisis de aprendizaje automático para crear incidentes de alta fidelidad y accionables. Algunas de las detecciones de Splunk existentes pueden ser redundantes en Microsoft Sentinel, por lo que no las migre a ciegas. Revise estas consideraciones a medida que identifique las reglas de detección existentes.

  • Asegúrese de seleccionar casos de uso que justifiquen la migración de reglas, teniendo en cuenta la prioridad empresarial y la eficacia.
  • Compruebe que comprende los tipos de regla de Microsoft Sentinel.
  • Compruebe que comprende la terminología de la regla.
  • Revise las reglas obsoletas que no tienen alertas durante los últimos 6-12 meses y determine si siguen siendo pertinentes.
  • Elimine las amenazas o alertas de bajo nivel que se omiten de forma rutinaria.
  • Confirme los orígenes de datos conectados y revise los métodos de conexión de datos. Microsoft Sentinel Analytics requieren que el tipo de datos esté presente en el área de trabajo de Log Analytics antes de habilitar una regla. Vuelva a consultar las conversaciones de recopilación de datos para garantizar la profundidad y amplitud de los datos en los casos de uso que tiene previsto detectar. A continuación, use la experiencia de migración siem para asegurarse de que los orígenes de datos se asignan correctamente.

Migración de reglas

Después de identificar las detecciones de Splunk que se van a migrar, revise estas consideraciones para el proceso de migración:

  • Compare la funcionalidad existente de las reglas de análisis de OOTB de Microsoft Sentinel con los casos de uso actuales. Use la experiencia de migración siem para ver qué detecciones de Splunk se convierten automáticamente en plantillas OOTB.
  • Convierta las detecciones que no se alineen con las reglas de análisis de OOTB. La mejor manera de traducir las detecciones de Splunk automáticamente es con la experiencia de migración siem.
  • Descubra más algoritmos para los casos de uso mediante la exploración de recursos de la comunidad, como soc Prime Threat Detection Marketplace.
  • Traduzca manualmente las detecciones si las reglas integradas no están disponibles o no se traducen automáticamente. Cree las nuevas consultas de KQL y revise la asignación de reglas.

Para obtener más información, consulte procedimientos recomendados para migrar reglas de detección.

Pasos de migración de reglas

  1. Compruebe que tiene un sistema de pruebas en su lugar para cada regla que quiera migrar.

    1. Prepare un proceso de validación para las reglas migradas, incluidos los escenarios de prueba completos y los scripts.

    2. Asegúrese de que el equipo tiene recursos útiles para probar las reglas migradas.

    3. Confirme que tiene conectados los orígenes de datos necesarios y revise los métodos de conexión de datos.

  2. Compruebe si las detecciones están disponibles como plantillas OOTB en Microsoft Sentinel:

    • Use la experiencia de migración siem para automatizar la traducción y la instalación de las plantillas de OOTB.

      Para obtener más información, consulte Uso de la experiencia de migración siem.

    • Si tiene casos de uso que no se reflejan en las detecciones, cree reglas para su propio área de trabajo con plantillas de regla OOTB.

      En Microsoft Sentinel, vaya al centro de contenido.

      Filtrar tipo de contenido para las plantillas de regla de Analytics .

      Busque e instale o actualice cada solución de Content Hub correspondiente o plantilla de regla de análisis independiente.

      Para obtener más información, consulte Detección de amenazas de fábrica.

    • Si tiene detecciones que no están cubiertas por las reglas OOTB de Microsoft Sentinel, pruebe primero la experiencia de migración SIEM para la traducción automática.

    • Si ni las reglas OOTB ni la migración SIEM traducen completamente la detección, cree la regla manualmente. En tales casos, siga estos pasos para crear la regla:

      1. Identifique los orígenes de datos que desea usar en la regla. Identifique las tablas Microsoft Sentinel que desea consultar mediante la creación de una tabla de asignación entre orígenes de datos y tablas de datos.

      2. Identifique los atributos, campos o entidades de los datos que quiera usar en las reglas.

      3. Identifique los criterios y la lógica de la regla. En esta fase, considere la posibilidad de buscar plantillas de regla como ejemplos para construir las consultas de KQL.

        Considere los filtros, las reglas de correlación, las listas activas, los conjuntos de referencia, las listas de seguimiento, las anomalías de detección, las agregaciones, etc. Puede usar las referencias proporcionadas por el SIEM heredado para comprender cómo asignar mejor la sintaxis de consulta.

      4. Identifique la condición del desencadenador y la acción de regla y, a continuación, construya y revise la consulta KQL. Al revisar la consulta, considere la posibilidad de usar los recursos de guía de optimización de KQL.

  3. Pruebe la regla con cada uno de los casos de uso pertinentes. Si no proporciona los resultados esperados, revise y edite el KQL y pruébelo de nuevo.

  4. Cuando esté satisfecho, tenga en cuenta la regla migrada. Cree un cuaderno de estrategias para la acción de regla según sea necesario. Para obtener más información, consulte Automatización de la respuesta a amenazas con cuadernos de estrategias en Microsoft Sentinel.

Más información sobre las reglas de análisis:

Comparación de la terminología de reglas

Esta tabla le ayuda a aclarar el concepto de una regla basada en Lenguaje de consulta Kusto (KQL) en Microsoft Sentinel en comparación con una detección de Splunk basada en el lenguaje de procesamiento de búsqueda (SPL).

Splunk Microsoft Sentinel
Tipo de regla • Programado
• En tiempo real
• Consulta programada
• Fusión
• Seguridad de Microsoft
• Análisis de comportamiento de Machine Learning (ML)
Criterios Definir en SPL Definir en KQL
Condición del desencadenador • Número de resultados
• Número de hosts
• Número de orígenes
• Personalizado
Umbral: número de resultados de consulta
Action • Agregar a alertas desencadenadas
• Evento de registro
• Resultados de salida para buscar
• Y más
• Crear alerta o incidente
• Se integra con Logic Apps

Asignación y comparación de ejemplos de reglas

Use estos ejemplos para comparar y asignar reglas de Splunk a Microsoft Sentinel en varios escenarios.

Comandos de búsqueda comunes

Comando SPL Description Operador KQL Ejemplo de KQL
chart/ timechart Devuelve resultados en una salida tabular para el gráfico de series temporales. operador render … | render timechart
dedup Quita los resultados posteriores que coinciden con un criterio especificado. distinto
resumir
… | summarize by Computer, EventID
eval Calcula una expresión. Obtenga información sobre los comandos comuneseval. ampliar T | extend duration = endTime - startTime
fields Quita los campos de los resultados de la búsqueda. proyecto
proyecto de distancia
T | project cost=price*quantity, price
head/tail Devuelve el primer o último N resultados. top T | top 5 by Name desc nulls last
lookup Agrega valores de campo de un origen externo. externaldata
búsqueda
Ejemplo de KQL
rename Cambia el nombre de un campo. Use caracteres comodín para especificar varios campos. project-rename T | project-rename new_column_name = column_name
rex Especifica los nombres de grupo que usan expresiones regulares para extraer campos. coincide con regex … | where field matches regex "^addr.*"
search Filtra los resultados a los resultados que coinciden con la expresión de búsqueda. buscar search "X"
sort Ordena los resultados de la búsqueda por los campos especificados. sort T | sort by strlen(country) asc, price desc
stats Proporciona estadísticas, agrupadas opcionalmente por campos. Obtenga más información sobre los comandos de estadísticas comunes. resumir Ejemplo de KQL
mstats Similar a las estadísticas, que se usan en métricas en lugar de eventos. resumir Ejemplo de KQL
table Especifica qué campos se conservarán en el conjunto de resultados y conservará los datos en formato tabular. proyecto T | project columnA, columnB
top/rare Muestra los valores más o menos comunes de un campo. top T | top 5 by Name desc nulls last
transaction Agrupa los resultados de búsqueda en transacciones.

Ejemplo de SPL
Ejemplo: row_window_session Ejemplo de KQL
eventstats Genera estadísticas de resumen a partir de los campos de los eventos y guarda esas estadísticas en un nuevo campo.

Ejemplo de SPL
Ejemplos:
unirse
make_list
mv-expand
Ejemplo de KQL
streamstats Busque la suma acumulativa de un campo.

Ejemplo de SPL:
... | streamstats sum(bytes) as bytes _ total \| timechart
row_cumsum ...\| serialize cs=row_cumsum(bytes)
anomalydetection Busque anomalías en el campo especificado.

Ejemplo de SPL
series_decompose_anomalies() Ejemplo de KQL
where Filtra los resultados de la búsqueda mediante eval expresiones. Se usa para comparar dos campos diferentes. Dónde T | where fruit=="apple"

lookup command: ejemplo 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 command: ejemplo de KQL

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

mstats command: ejemplo de KQL

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

transaction command: ejemplo de SPL

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

transaction command: ejemplo 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

Use row_window_session() para calcular los valores de inicio de sesión de una columna de un conjunto de filas serializado.

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

eventstats command: ejemplo de SPL

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

eventstats command: ejemplo de KQL

Este es un ejemplo con la join instrucción :

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

Este es un ejemplo con la make_list instrucción :

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 command: ejemplo de SPL

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

anomalydetection command: ejemplo 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 comunes eval

Comando SPL Description Ejemplo de SPL Comando KQL Ejemplo de KQL
abs(X) Devuelve el valor absoluto de X. abs(number) abs() abs(X)
case(X,"Y",…) Toma pares de X argumentos y Y , donde los X argumentos son expresiones booleanas. Cuando se evalúan como TRUE, los argumentos devuelven el argumento correspondiente Y . Ejemplo de SPL case Ejemplo de KQL
ceil(X) Techo de un número X. ceil(1.9) ceiling() ceiling(1.9)
cidrmatch("X",Y) Identifica las direcciones IP que pertenecen a una subred determinada. 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,…) Devuelve el primer valor que no es NULL. coalesce(null(), "Returned val", null()) coalesce() coalesce(tolong("not a number"),
tolong("42"), 33) == 42
cos(X) Calcula el coseno de X. n=cos(0) cos() cos(X)
exact(X) Evalúa una expresión X mediante aritmética de punto flotante de precisión doble. exact(3.14*num) todecimal() todecimal(3.14*2)
exp(X) Devuelve eX. exp(3) exp() exp(3)
if(X,Y,Z) Si X se evalúa como TRUE, el resultado es el segundo argumento Y. Si X se evalúa como FALSE, el resultado se evalúa como el tercer argumento Z. if(error==200,
"OK", "Error")
iff() Ejemplo de KQL
isbool(X) Devuelve TRUE si X es booleano. isbool(field) iff()
gettype
iff(gettype(X) =="bool","TRUE","FALSE")
isint(X) Devuelve TRUE si X es un entero. isint(field) iff()
gettype
Ejemplo de KQL
isnull(X) Devuelve TRUE si X es null. isnull(field) isnull() isnull(field)
isstr(X) Devuelve TRUE si X es una cadena. isstr(field) iff()
gettype
Ejemplo de KQL
len(X) Esta función devuelve la longitud de caracteres de una cadena X. len(field) strlen() strlen(field)
like(X,"y") Devuelve TRUE si y solo si X es como el patrón SQLite en Y. like(field, "addr%") has
contains
startswith
coincide con regex
Ejemplo de KQL
log(X,Y) Devuelve el registro del primer argumento X utilizando el segundo argumento Y como base. El valor predeterminado de Y es 10. log(number,2) log
log2
log10
log(X)

log2(X)

log10(X)
lower(X) Devuelve el valor en minúsculas de X. lower(username) tolower tolower(username)
ltrim(X,Y) Devuelve X con los caracteres del parámetro Y recortados desde el lado izquierdo. La salida predeterminada de Y es espacios y pestañas. ltrim(" ZZZabcZZ ", " Z") trim_start() trim_start(“ ZZZabcZZ”,” ZZZ”)
match(X,Y) Devuelve si X coincide con el patrón de expresión regular Y. match(field, "^\d{1,3}.\d$") matches regex … | where field matches regex @"^\d{1,3}.\d$")
max(X,…) Devuelve el valor máximo de una columna. max(delay, mydelay) max()
arg_max()
… | summarize max(field)
md5(X) Devuelve el hash MD5 de un valor Xde cadena . md5(field) hash_md5 hash_md5("X")
min(X,…) Devuelve el valor mínimo de una columna. min(delay, mydelay) min_of()
min()
arg_min
Ejemplo de KQL
mvcount(X) Devuelve el número (total) de X valores. mvcount(multifield) dcount …| summarize dcount(X) by Y
mvfilter(X) Filtra un campo de varios valores en función de la expresión booleana X . mvfilter(match(email, "net$")) mv-apply Ejemplo de KQL
mvindex(X,Y,Z) Devuelve un subconjunto del argumento multivalor X de una posición inicial (basada en cero) Y a Z (opcional). mvindex( multifield, 2) array_slice array_slice(arr, 1, 2)
mvjoin(X,Y) Dado un campo X de varios valores y un delimitador Yde cadena , y combina los valores individuales de X usar Y. mvjoin(address, ";") strcat_array Ejemplo de KQL
now() Devuelve la hora actual, representada en tiempo unix. now() now() now()

now(-2d)
null() No acepta argumentos y devuelve NULL. null() null null
nullif(X,Y) Incluye dos argumentos, X y Y, y devuelve X si los argumentos son diferentes. De lo contrario, devuelve NULL. nullif(fieldA, fieldB) iff iff(fieldA==fieldB, null, fieldA)
random() Devuelve un número pseudoalea aleatorio entre 0 a 2147483647. random() rand() rand()
relative_ time(X,Y) Dada una hora X de época y un especificador Yde tiempo relativo , devuelve el valor de hora de época de Y aplicado a X. relative_time(now(),"-1d@d") hora unix Ejemplo de KQL
replace(X,Y,Z) Devuelve una cadena formada sustituyendo la cadena Z por cada aparición de una cadena Y de expresión regular en la cadena X. Devuelve la fecha con los números de mes y día cambiados.
Por ejemplo, para la 4/30/2015 entrada, la salida es 30/4/2009:

replace(date, "^(\d{1,2})/ (\d{1,2})/", "\2/\1/")
replace() Ejemplo de KQL
round(X,Y) Devuelve X redondear al número de posiciones decimales especificadas por Y. El valor predeterminado es redondear a un entero. round(3.5) round round(3.5)
rtrim(X,Y) Devuelve X con los caracteres de Y recortados del lado derecho. Si Y no se especifica, se recortan los espacios y las pestañas. rtrim(" ZZZZabcZZ ", " Z") trim_end() trim_end(@"[ Z]+",A)
searchmatch(X) Devuelve TRUE si el evento coincide con la cadena Xde búsqueda . searchmatch("foo AND bar") iff() iff(field has "X","Yes","No")
split(X,"Y") Devuelve X como un campo con varios valores, dividido por delimitador Y. split(address, ";") split() split(address, ";")
sqrt(X) Devuelve la raíz cuadrada de X. sqrt(9) sqrt() sqrt(9)
strftime(X,Y) Devuelve el valor X de tiempo de época representado con el formato especificado por Y. strftime(_time, "%H:%M") format_datetime() format_datetime(time,'HH:mm')
strptime(X,Y) Dado un tiempo representado por una cadena X, devuelve el valor analizado a partir del formato Y. strptime(timeStr, "%H:%M") format_datetime() Ejemplo de KQL
substr(X,Y,Z) Devuelve un campo X de subcadena desde la posición inicial (basado en uno) Y para Z los caracteres (opcionales). substr("string", 1, 3) substring() substring("string", 0, 3)
time() Devuelve la hora del reloj de pared con resolución de microsegundos. time() format_datetime() Ejemplo de KQL
tonumber(X,Y) Convierte la cadena X de entrada en un número, donde Y (opcional, el valor predeterminado es 10) define la base del número al que se va a convertir. tonumber("0A4",16) toint() toint("123")
tostring(X,Y) Descripción Ejemplo de SPL tostring() tostring(123)
typeof(X) Devuelve una representación de cadena del tipo de campo. typeof(12) gettype() gettype(12)
urldecode(X) Devuelve la dirección URL X descodificada. Ejemplo de SPL url_decode Ejemplo de KQL

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

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

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

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

if(X,Y,Z) Ejemplo de KQL

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

isint(X) Ejemplo de KQL

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

isstr(X) Ejemplo de KQL

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

like(X,"y") ejemplo

… | where field has "addr"

… | where field contains "addr"

… | where field startswith "addr"

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

min(X,…) Ejemplo de KQL

min_of (expr_1, expr_2 ...)

…|summarize min(expr)

…| summarize arg_min(Price,*) by Product

mvfilter(X) Ejemplo de KQL

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

mvjoin(X,Y) Ejemplo de KQL

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

relative time(X,Y) Ejemplo de KQL

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

replace(X,Y,Z) Ejemplo de KQL

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

strptime(X,Y) Ejemplo de KQL

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

time() Ejemplo de KQL

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

tostring(X,Y)

Devuelve un valor de campo de X como una cadena.

  • Si el valor de X es un número, X se vuelve a formatear en un valor de cadena.
  • Si X es un valor booleano, X se vuelve a formatear en TRUE o FALSE.
  • Si X es un número, el segundo argumento Y es opcional y puede ser hex (se convierte X en hexadecimal), commas (formatos con comas X y dos posiciones decimales) o duration (convierte X de un formato de tiempo en segundos a un formato de hora legible: HH:MM:SS).
tostring(X,Y) Ejemplo de SPL

Este ejemplo devuelve:

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

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

urldecode(X) Ejemplo de SPL

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

Ejemplo de KQL de comandos comunes stats

Comando SPL Description Comando KQL Ejemplo de KQL
avg(X) Devuelve el promedio de los valores del campo X. avg() avg(X)
count(X) Devuelve el número de repeticiones del campo X. Para indicar un valor de campo específico para que coincida, formatee X como eval(field="value"). count() summarize count()
dc(X) Devuelve el recuento de valores distintos del campo X. dcount() …\| summarize countries=dcount(country) by continent
earliest(X) Devuelve el valor cronológico más antiguo visto de X. arg_min() … \| summarize arg_min(TimeGenerated, *) by X
latest(X) Devuelve el valor visto cronológicamente más reciente de X. arg_max() … \| summarize arg_max(TimeGenerated, *) by X
max(X) Devuelve el valor máximo del campo X. Si los valores de X no son numéricos, el valor máximo se encuentra mediante el orden alfabético. max() …\| summarize max(X)
median(X) Devuelve el valor más medio del campo X. percentile() …\| summarize percentile(X, 50)
min(X) Devuelve el valor mínimo del campo X. Si los valores de X no son numéricos, el valor mínimo se encuentra mediante ordenación alfabética. min() …\| summarize min(X)
mode(X) Devuelve el valor más frecuente del campo X. top-hitters() …\| top-hitters 1 of Y by X
perc(Y) Devuelve el valor del percentil X del campo Y. Por ejemplo, perc5(total) devuelve el quinto valor de percentil de un campo total. percentile() …\| summarize percentile(Y, 5)
range(X) Devuelve la diferencia entre los valores máximo y mínimo del campo X. range() range(1, 3)
stdev(X) Devuelve la desviación estándar de ejemplo del campo X. stdev stdev()
stdevp(X) Devuelve la desviación estándar de población del campo X. stdevp() stdevp()
sum(X) Devuelve la suma de los valores del campo X. sum() sum(X)
sumsq(X) Devuelve la suma de los cuadrados de los valores del campo X.
values(X) Devuelve la lista de todos los valores distintos del campo X como una entrada de varios valores. El orden de los valores es alfabético. make_set() …\| summarize r = make_set(X)
var(X) Devuelve la varianza de muestra del campo X. varianza variance(X)

Pasos siguientes

En este artículo, ha aprendido a asignar las reglas de migración de Splunk a Microsoft Sentinel.