Compartir a través de


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 identificarlas, compararlas y migrarlas a Microsoft Sentinel. La mejor manera es empezar con la experiencia de migración de SIEM, que identifica reglas de análisis listas para usar (OOTB) a las que traducir automáticamente.

Si quiere migrar la implementación de Splunk Observability, obtenga más información sobre cómo hacer la migración de Splunk a registros de Azure Monitor.

Auditoría de las reglas

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

  • Asegúrese de seleccionar los casos de uso que justifican la migración de reglas, teniendo en cuenta la prioridad empresarial y la eficacia.
  • Asegúrese de entender los tipos de reglas de Microsoft Sentinel.
  • Asegúrese de entender la terminología de las reglas.
  • Revise las reglas obsoletas que no tengan alertas durante los últimos 6 a 12 meses y determine si siguen siendo pertinentes.
  • Elimine las amenazas o alertas de bajo nivel que omite de forma rutinaria.
  • Confirme los orígenes de datos conectados y revise los métodos de conexión de datos. El análisis de Microsoft Sentinel requiere que el tipo de datos esté presente en el área de trabajo de Log Analytics antes de habilitar una regla. Vuelva a revisar las conversaciones de recopilación de datos para garantizar la profundidad y la amplitud de los datos en todos los casos de uso que piensa detectar. A continuación, use la experiencia de migración de SIEM para asegurarse de que los orígenes de datos se hayan asignado 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 OOTB de Microsoft Sentinel con los casos de uso actuales. Use laexperiencia de migración de SIEM para ver qué detecciones de Splunk se convierten automáticamente en plantillas OOTB.
  • Traduzca las detecciones que no estén alineadas con las reglas de análisis OOTB. La mejor manera de traducir las detecciones de Splunk automáticamente es con la experiencia de migración de SIEM.
  • Descubra más algoritmos para sus casos de uso mediante la exploración de los recursos de la comunidad, como el marketplace de detección de amenazas Prime de SOC.
  • 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 los procedimientos recomendados para migrar reglas de detección.

Pasos de migración de reglas

  1. Compruebe que cuenta con un sistema de pruebas para cada regla que quiere migrar.

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

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

    3. Confirme que tiene los orígenes de datos necesarios conectados 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 de SIEM para automatizar la traducción e instalación de las plantillas OOTB.

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

    • Si tiene casos de uso no reflejados en las detecciones, cree reglas para su propia área de trabajo con plantillas de reglas OOTB.

      En Microsoft Sentinel, vaya al Centro de contenido.

      Filtre el tipo de contenido para las plantillas de regla de análisis.

      Busque e instale o actualice cada solución del Centro de contenido correspondiente o plantilla de regla de análisis independiente.

      Para más información, consulte Detección de amenazas integrada.

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

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

      1. Identifique los orígenes de datos que desea usar en la regla. Identifique las tablas de Microsoft Sentinel que quiere 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 en los datos que desea 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 reglas como ejemplos para construir las consultas de KQL.

        Considere la posibilidad de usar filtros, reglas de correlación, listas activas, conjuntos de referencias, listas de control, anomalías de detección, agregaciones, etcétera. Puede usar las referencias proporcionadas por la solución de SIEM heredada para entender 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 esto no proporciona los resultados esperados, revise y edite el código KQL y vuelva a probarlo.

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

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

Comparación de la terminología de las reglas

Esta tabla le ayuda a aclarar el concepto de una regla basada en el 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 • Programadas
• Tiempo real
• Consulta programada
• Fusión
• Seguridad de Microsoft
• Análisis de comportamiento de Machine Learning (ML)
Criterios Definición en SPL Definición en KQL
Condición desencadenadora • Número de resultados:
• Número de hosts
• Número de orígenes
• Personalizado
Umbral: número de resultados de la consulta
Acción • Adición a alertas desencadenadas
• Registro de eventos
• Resultados de salida para la búsqueda
• Y mucho más
• Crear alerta o incidente
• Integrar 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 Descripción 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. distinct
summarize
… | summarize by Computer, EventID
eval Calcula una expresión. Obtenga información sobre los comandos eval comunes. extend T | extend duration = endTime - startTime
fields Quita los campos de los resultados de la búsqueda. project
project-away
T | project cost=price*quantity, price
head/tail Devuelve los primeros o últimos N resultados. top T | top 5 by Name desc nulls last
lookup Agrega valores de campo de un origen externo. externaldata
lookup
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 mediante expresiones regulares para extraer campos. matches regex … | where field matches regex "^addr.*"
search Filtra los resultados por los resultados que coinciden con la expresión de búsqueda. search search "X"
sort Ordena los resultados de búsqueda por los campos especificados. sort T | sort by strlen(country) asc, price desc
stats Proporciona estadísticas, opcionalmente agrupadas por campos. Obtenga más información sobre los comandos de estadísticas comunes. summarize Ejemplo de KQL
mstats De forma similar a las estadísticas, se usa en métricas en lugar de eventos. summarize Ejemplo de KQL
table Especifica los campos que se deben conservar en el conjunto de resultados y conserva los datos en formato tabular. project 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 de los campos de los eventos y guarda esas estadísticas en un nuevo campo.

Ejemplo de SPL
Ejemplos:
join
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 búsqueda mediante eval expresiones. Se usa para comparar dos campos diferentes. where T | where fruit=="apple"

Comando lookup: 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 
])) | ... 

Comando stats: ejemplo de KQL

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

Comando mstats: ejemplo de KQL

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

Comando transaction: ejemplo de SPL

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

Comando transaction: 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))

Comando eventstats: ejemplo de SPL

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

Comando eventstats: ejemplo de KQL

Este es un ejemplo con la instrucción 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

Este es un ejemplo con la instrucción 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

Comando anomalydetection: ejemplo de SPL

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

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

Comando SPL Descripción 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 argumentos X y Y, donde los argumentos X son expresiones booleanas. Cuando se evalúa 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 del argumento. n=cos(0) cos() cos(X)
exact(X) Evalúa una expresión X con 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")
iif() Ejemplo de KQL
isbool(X) Devuelve TRUE si X es booleano. isbool(field) iif()
gettype
iif(gettype(X) =="bool","TRUE","FALSE")
isint(X) Devuelve TRUE si X es un entero. isint(field) iif()
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) iif()
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 similar al patrón SQLite de Y. like(field, "addr%") has
contains
startswith
matches regex
Ejemplo de KQL
log(X,Y) Devuelve el registro del primer argumento X con 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 un valor en minúscula de X. lower(username) tolower tolower(username)
ltrim(X,Y) Devuelve X con los caracteres del parámetro Y recortado desde el lado izquierdo. La salida predeterminada de Y son espacios y pestañas. ltrim(" ZZZabcZZ ", " Z") trim_start() trim_start(“ ZZZabcZZ”,” ZZZ”)
match(X,Y) Devuelve si X coincide con el patrón regex 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 de cadena X. 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 valores X. mvcount(multifield) dcount …| summarize dcount(X) by Y
mvfilter(X) Filtra un campo multivalor basado en 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 multivalor y un delimitador de cadena Y y combina los valores individuales de X mediante 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) iif iif(fieldA==fieldB, null, fieldA)
random() Devuelve un número pseudoaleatorio entre 0 a 2147483647. random() rand() rand()
relative_ time(X,Y) Dada una hora de época X y un especificador de hora relativo Y, devuelve el valor de hora de época de Y aplicado a X. relative_time(now(),"-1d@d") hora de unix Ejemplo de KQL
replace(X,Y,Z) Devuelve una cadena formada al sustituir la cadena Z por cada aparición de la cadena de expresión regular Y en la cadena X. Devuelve la fecha con los números de mes y día modificados.
Por ejemplo, para la entrada 4/30/2015, 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 redondeado 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 desde el lado derecho. Si Y no se especifica, se recortan espacios y pestañas. rtrim(" ZZZZabcZZ ", " Z") trim_end() trim_end(@"[ Z]+",A)
searchmatch(X) Devuelve TRUE si el evento coincide con la cadena de búsqueda X. searchmatch("foo AND bar") iif() iif(field has "X","Yes","No")
split(X,"Y") Devuelve X como un campo multivalor, 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 de hora de época X representado con el formato especificado por Y. strftime(_time, "%H:%M") format_datetime() format_datetime(time,'HH:mm')
strptime(X,Y) Dada una hora representada 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 de subcadena X de la posición inicial (basada en uno) Y para Z caracteres (opcionales). substr("string", 1, 3) substring() substring("string", 0, 3)
time() Devuelve el tiempo del reloj con resolución de microsegundos. time() format_datetime() Ejemplo de KQL
tonumber(X,Y) Convierte la cadena de entrada X 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

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

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

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

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

Ejemplo de KQL de if(X,Y,Z)

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

Ejemplo de KQL de isint(X)

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

Ejemplo de KQL de isstr(X)

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

Ejemplo de like(X,"y")

… | where field has "addr"

… | where field contains "addr"

… | where field startswith "addr"

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

Ejemplo de KQL de min(X,…)

min_of (expr_1, expr_2 ...)

…|summarize min(expr)

…| summarize arg_min(Price,*) by Product

Ejemplo de KQL de mvfilter(X)

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

Ejemplo de KQL de mvjoin(X,Y)

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

Ejemplo de KQL de relative time(X,Y)

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

Ejemplo de KQL de replace(X,Y,Z)

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

Ejemplo de KQL de strptime(X,Y)

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

Ejemplo de KQL de time()

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 a TRUE o FALSE.
  • Si X es un número, el segundo argumento Y es opcional y puede ser hex (convierte X en hexadecimal), commas (formatos X con comas y dos posiciones decimales), o duration (convierte X de un formato de tiempo en segundos a un formato de tiempo legible: HH:MM:SS).
Ejemplo de SPL de tostring(X,Y)

En este ejemplo se devuelve lo siguiente:

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

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

Ejemplo de SPL de urldecode(X)

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

Ejemplo de KQL de comandos stats comunes

Comando SPL Descripción 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 que debe coincidir, dé formato a 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 cronológico más reciente visto 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 a través del orden alfabético. max() …\| summarize max(X)
median(X) Devuelve el valor 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 el orden alfabético. 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 X del percentil 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áximos y mínimos del campo X. range() range(1, 3)
stdev(X) Obtiene la desviación estándar de muestra del campo X. stdev stdev()
stdevp(X) Obtiene 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. variance variance(X)

Pasos siguientes

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