En la entrada anterior se analizó el estándar de reglas Sigma. Un lenguaje universal para crear patrones de detección de actividad maliciosa en base a logs de actividad. Este estándar con sintaxis YAML se está convirtiendo en una referencia en la industria. La mayoría de SIEMS y soluciones de seguridad ya lo aceptan como parte de su lenguaje de creación de reglas.
Con lo que se vio en la entrada anterior ya se pueden crear reglas sencillas. Reglas donde se busque un evento concreto con una determinada ocurrencia. Por ejemplo, un inicio de sesión con usuario «Administrador». Que se haya conectado un disco duro externo al equipo…
Pero Sigma se ha ido desarrollando y permite definiciones más avanzadas que sirven para construir condiciones de detección más complejas.
Sigma Specification v2.0
El 08 de agosto de 2024, en el blog de Sigma se publicó el siguiente artículo:
Since its inception, Sigma has always strived to be as user-friendly as possible while maintaining an expandable feature set. Over the years, both the vision of the project and the needs of its users have grown, necessitating the project’s evolution. This led to the creation of pySigma, a complete rewrite of the sigmac library, which introduced many new features and enhancements. Consequently, the specification had to evolve as well, resulting in the release of v2.0, an exciting milestone full of new ideas, features and enhancements.
¿Cuáles son por tanto estas nuevas mejoras? Veamos algunas.
Nuevos campos
Algunos nuevos campos se han añadido para la definición de la regla. Además de algunas modificaciones menores en los metadatos que podéis encontrar aquí, se han añadido mejoras en cómo se definen los valores que se añaden a las reglas:
- Para strings
- Para números
- Direcciones IP
- Encoding
Para strings
Hay una serie de campos y operadores nuevos que podemos usar en la definición de los valores que asignamos a los campos de las conditions. Del artículo anterior parecía que todo deben ser string aplicados en coincidencia exacta o en contains.
Por ejemplo:

A continuación se muestra operadores nuevos que podemos usar a partir de esta versión 2:
- «windash» : Para crear referencias a los caracteres que se usan para indicar en Windows parámetros a la línea de comandos. Sabemos que no siempre se indican los parámetros en una línea de comandos de windows de la misma forma.
- Por ejemplo:
ping -n 4 8.8.8.8
dir /s /p
curl --request GET --url https://api.example.com
- Disponer del operador «windash» nos permite definir ocurrencias sobre líneas de comandos donde el carácter usado para indicar los parámetros sea indiferente
- Para su aplicación solo tenemos que definir una sección con un listado de strings que se quieran identificar como parámetros de la línea de comandos
- Por ejemplo:
detection:
selection:
Image:
- 'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe'
CommandLine|windash:
- 'invoke-mimikatz'
- 'download-file'
- «re«: Permite aplicar expresiones regulares
- Se pueden aplicar sub-modifieres sobre «re». Estos son:
- «i«: Aplica la búsqueda en modo case-sensitive
- «m«: Aplica la búsqueda en multiline. Se usan los caracteres «^» / «$» para indicar inicio / fin de línea. Se usa para hacer búsquedas en multilínea forzando a indicar los inicios y fin de linea de forma específica
- «s«: Aplica la búsqueda single line. El carácter «.» hace match con todos los carácteres, incluyendo el de newline. Se usa para hacer búsquedas en varias líneas sin tener que tener las nuevas líneas en cuenta
- En el siguiente ejemplo se aplica una expresión regular para buscar dentro de la ruta de usuario, independientemente del nombre del usuario.
- Se pueden aplicar sub-modifieres sobre «re». Estos son:
detection:
selection:
TargetFilename|re:
- '^C:\\\\Users\\\\[^\\\\]+\\\\AppData\\\\Local\\\\Temp\\\\[a-zA-Z0-9_-]{8,}\.exe$'
condition: selection
Para aplicar los sub-modifiers:
detection:
selection:
LogContent|re|m:
- '^Error.*\n.*Critical'
condition: selection
También se pueden combinar:
detection:
selection:
CommandLine|re|i|m|s:
- '(?i)create.*\n.*file.*'
condition: selection
IMPORTANTE: Aquí estamos viendo los incluidos en la especificación 2.0. Todos los modificadores que se pueden usar se pueden encontrar aquí. No se vieron todos en la entrada 1, pero son importantes conocerlos y tener la referencia.
Para números
Además de los modificadores que se aplican a los strings, hay otros que se aplican a los campos que contienen valores numéricos:
- «lt«: Menor que
- «lte«: Menor o igual que
- «gt«: Mayor que
- «gte«: Mayor o igual que
El siguiente ejemplo crea una regla que busca ficheros en una ruta que sean mayores de 1 MB y menores de 10 MB.
detection:
selection:
TargetFilename:
- 'C:\\Users\\*\\AppData\\Local\\Temp\\*'
FileSize|gt: 1048576 # 1 MB en bytes
FileSize|lt: 10485760 # 10 MB en bytes
condition: selection
Direcciones IP
Para las direcciones IP se habilita un campo que permite definir rangos y buscar IPs que estén en dicho rango. Es fácil:
- «cidr«: Indica rangos CIDR y buscar ocurrencias de IPs que estén en dicho rango
detection:
selection:
SourceIp|cidr:
- '192.168.1.0/24'
- '10.0.0.0/8'
condition: selection
Encoding
- «base64«: Busca los valores que se indiquen, pero en base64. Esto se usa para detectar cuando los atacantes codifican la commandline o algunos parámetros y los indican en base64
- «base64offset«: Se usa preferiblemente este operador sobre base64. Esto es por la forma en que se codifica los caracteres ASCII y como generan offsets. Se usa el operador base64offset para evitar esta problemática
En el siguiente ejemplo se va a crear un condition sobre una fuente de datos que recoge tráfico HTTP. Muchas veces los atacantes codifican base64 sus órdenes para pasar desapercibidos. Con el modificador base64offset se busca indicios de shell para el caso en que venga codificado en base64.
detection:
selection:
fieldname|base64offset|contains:
- /bin/bash
- /bin/sh
- /bin/zsh
condition: selection
Sigma Correlations
La correlación es una nueva funcionalidad que se introduce en esta versión. El objetivo es poder unir varios logs de varias fuentes para poder crear patrones de detección más complejos.
Correlación básica
La correlación más básica es agregar varios logs del mismo tipo que han ocurrido en un rango de tiempo (inicios de sesión fallidos para un usuario en un periodo de 30 minutos). Esto se agrega en un nuevo bloque de detección formando campos nuevos (cuenta de logs agrupados). En base a este nuevo bloque se pueden crear detecciones (que un usuario haya tenido más de 10 inicios de sesión fallidos en 30 minutos). Aquí podéis encontrar el post oficial de Sigma.
Veamos este ejemplo usando Sigma.
title: Failed logon
name: failed_logon
status: test
logsource:
product: windows
service: security
detection:
selection:
EventID: 4625
condition: selection
---
title: Multiple failed logons for a single user (possible brute force attack)
status: test
correlation:
type: event_count
rules:
- failed_logon
group-by:
- TargetUserName
- TargetDomainName
timespan: 5m
condition:
gte: 10
Por resumir, arribar creamos las reglas básicas, y abajo definimos la nueva regla con la correlación en una sección que se llama «correlation«, la cual tiene unas consideraciones especiales que veremos a continuación. La separación entre las reglas básicas y la correlación se indica con «—«.
La definición de la regla básica es lo que venimos viendo hasta ahora. Lo que ya definimos en la primera entrada de esta serie. Se usa como fuente el log de seguridad de Windows. La detección consiste en el evento de inicio de sesión fallido, el 4625.
¿Cómo funciona la siguiente regla? ¿Cómo se define la correlación?
Además de poder definir una serie de datos a modo de metadatos como vimos en la primera entrada, tenemos la sección «correlation» que determina como se agrega y cuál es la lógica de detección:
- Campo «type«: Tipo de agregación que vamos a hacer. En este ejemplo estamos viendo la de agregación por cuenta de eventos, así que el type es «event_count«. Más adelante veremos el resto de tipos.
- Campo «rules«: Define qué reglas básicas se usan para la correlación. Para ello usamos el nombre definido a la regla básica en el campo «name«.
- Importante: Es posible definirla por el campo name o también por el campo id
- Campo «group-by«: Define qué campos de los eventos se van a usar para agrupar. En este ejemplo se han usado el nombre del usuario y el dominio. Contará por tanto todos los eventos de seguridad fallidos para cada par de valores únicos usuario-dominio.
- Campo «timespan«: Vale, agrupamos pero, ¿en qué rango de tiempo? El campo timespan define cuál es el rango de tiempo que se toma para hacer la agregación. En este caso 5 minutos. Usa la definición de expresiones temporales de la ISO 8601. Podéis ampliar más detalle aquí.
- Campo «condition«: finalmente la condición que levanta la alerta. Como es una regla de tipo «event_count«, solo nos queda definir cuál es el valor numérico que queremos que se cumpla para levantar la alerta. Para esta regla se ha definido mayor o igual que 10 eventos para un mismo usuario+dominio.
Otros tipos de correlación
Ya hemos visto el tipo de correlación del tipo «event_count«. Vamos a ver las otras 2:
type: value_count
- Si el event_count cuenta el número de eventos dadas unas condiciones, el value_count cuenta cuantos valores únicos hay de un determinado campo
- Con event_count podemos extraer que hay 10 inicios de sesión para el usuario X
- Con value_count podemos extraer que hay inicios de sesión fallidos de 15 usuarios distintos
- El ejemplo reflejado por Sigma muestra una regla que detecta cuando un mismo usuario enumera 4 grupos privilegiados diferentes (esto puede indicar una herramienta de enumeración estilo BloodHound)
- Primero define una regla que identifica el evento de enumeración (4799) para los 4 grupos privilegiados definidos
- En la correlación del tipo value_count agrupa por el username que hace le enumeración. Como cuenta valores diferentes, solo va a levantarse la regla cuando un mismo usuario haya enumerado los 4 grupos en un rango de 15 minutos. Como podéis ver la condition dice que sea 4 o más TargetUserName (grupo enumerado) diferentes.
- IMPORTANTE: da igual que un usuario haya enumerado el mismo grupo 4 o más veces, esto no hará saltar la regla. El tipo event_count solo cuenta cuantos valores únicos aparecen en la agrupación
- Si el event_count cuenta el número de eventos dadas unas condiciones, el value_count cuenta cuantos valores únicos hay de un determinado campo
title: High-privilege group enumeration
name: privileged_group_enumeration
status: stable
logsource:
product: windows
service: security
detection:
selection:
EventID: 4799
CallerProcessId: 0x0
TargetUserName:
- Administrators
- Remote Desktop Users
- Remote Management Users
- Distributed COM Users
condition: selection
level: informational
falsepositives:
- Administrative activity
- Directory assessment tools
---
title: Enumeration of multiple high-privilege groups by tools like BloodHound
status: stable
correlation:
type: value_count
rules:
- privileged_group_enumeration
group-by:
- SubjectUserName
timespan: 15m
condition:
gte: 4
field: TargetUserName
level: high
falsepositives:
- Administrative activity
- Directory assessment tools
type: temporal
- El tipo temporal se usa para definir varias reglas y definir una correlación que salte si estas reglas hacen match en un rango de tiempo definido.
- Si quiero levantar una regla de criticidad alta si dos reglas bajas determinadas saltan en menos de 15 minutos
- El ejemplo reflejado por Sigma muestra dos reglas definidas por su ID y una correlación que dice que levante una alerta de severidad alta si ambas reglas saltan en un margen de tiempo de 10 segundos
- Las dos reglas son:
- https://github.com/SigmaHQ/sigma/blob/ae45e83c73fa2c7bca828e359998bcf8c97e2b92/rules-emerging-threats/2023/Exploits/CVE-2023-22518/web_exploit_cve_2023_22518_confluence_auth_bypass.yml
- https://github.com/SigmaHQ/sigma/blob/ae45e83c73fa2c7bca828e359998bcf8c97e2b92/rules-emerging-threats/2023/Exploits/CVE-2023-22518/proc_creation_win_exploit_cve_2023_22518_confluence_tomcat_child_proc.yml
- Las dos reglas son:
title: CVE-2023-22518 Exploit Chain
description: Access to endpoint vulnerable to CVE-2023-22518 with suspicious process creation.
status: experimental
correlation:
type: temporal
rules:
- a902d249-9b9c-4dc4-8fd0-fbe528ef965c
- 1ddaa9a4-eb0b-4398-a9fe-7b018f9e23db
timespan: 10s
level: high
IMPORTANTE: Este es un ejemplo de regla de correlación de eventos desde diferentes fuentes. Ambas reglas identificadas por su id, tienen fuentes difernetes. Os dejo las capturas de la sección logsource de ambas reglas:
Correlar con diferentes nombres de campos
Una pregunta que nos ponemos hacer es, ¿qué pasa si agregamos dos eventos donde el nombre de usuario viene en diferentes campos con difernete nombre? O, ¿qué ocurre si quiero contar con la IP de origen en un evento y con la IP de destino en el otro evento? Para ello existe el campo «aliases» dentro de la sección «correlation«.
correlation:
type: temporal
rules:
- rule_with_src_ip
- rule_with_dest_ip
aliases:
ip:
rule_with_src_ip: src_ip
rule_with_dest_ip: dest_ip
group-by:
- ip
timespan: 5m
Con aliases se crea un campo nuevo que es «ip«. Para la regla rule_with_src_ip
, se define que el valor de ip
es el del campo src_ip
. Para la regla rule_with_dest_ip
se define que el valor de ip
es el del campo dest_ip
.
Finalmente se puede agrupar por el campo ip y definir una regla temporal en 5 minutos. Esta regla dice que salten ambas reglas para la misma IP (en un caso de origen y en otro de destino) en un margen de 5 minutos.
Conclusión
Nuevos campos y correlaciones. En el siguiente artículo veremos el filtrado. Una nueva capacidad de Sigma que simplifica el filtrado de falsos positivos en las reglas.