Sigma es un estándar abierto diseñado para la creación de reglas de detección de amenazas en registros de eventos, especialmente orientado a entornos de seguridad. Es un estándar en la industria y debemos conocerlo porque nos va a permitir crear reglas de detección en base a logs de actividad. Sigma permite definir patrones de comportamiento malicioso sin depender de un sistema específico de análisis de logs, es decir, que es agnóstico del SIEM o sistema concreto. Los fabricantes de SIEM se van a adaptar para interpretar, además de su lenguaje, las reglas Sigma.
Como analistas de ciberseguridad y en especial si nos dedicamos al DFIR debemos conocer este estándar. Encontrar nuevos patrones de ataque puede llevarnos a querer compartir con el mundo nuevas detecciones. Si estas detecciones se basan en logs de los sistemas, debemos usar el estándar Sigma.
Aunque no es objetivo de esta entrada, podemos decir que Sigma es para los logs lo que Yara es para los ficheros o Snort para la creación de reglas en base a tráfico de red.
¿Por qué necesitamos estandarizar?
Como analistas DFIR es posible que lleguemos a un incidente y nos encontremos un SIEM. En muchos casos, darnos una paliza realizando clonados y triajes no es necesario cuando ya tenemos los logs ahí. Pedimos acceso al SIEM, abrimos la consola y, ¿cómo tiramos la búsqueda? Cada fabricante define su propio lenguaje de consulta. Y aunque se esfuerzan en hacerlos completos e intuitivos, conocerlos todos no es algo trivial. Por ejemplo tenemos:
- Sentinel – Kusto Query Languaje (KQL)
- Splunk – Splunk Processing Language (SPL)
- Elasticsearch – Lucene Query Syntax/DSL (Domain Specific Language)
- IBM QRadar – Advanced Query Language (AQL)
- ArcSight – ArcSight Query Language
Un ejemplo de cada fabricante
Veamos como cada fabricante define su lenguaje de consulta para una detección muy sencilla, un inicio de sesión en una máquina Windows dada.
KQL
SecurityEvent
| where EventID == 4624
| where Computer contains "NombreDelEquipo"
| project TimeGenerated, Computer, AccountName, LogonType
SPL
index=windows_logs sourcetype="WinEventLog:Security" EventCode=4624
| search ComputerName="NombreDelEquipo"
| table _time, ComputerName, Account_Name, Logon_Type
DSL
{
"query": {
"bool": {
"must": [
{ "match": { "event.code": "4624" } },
{ "match": { "host.name": "NombreDelEquipo" } }
]
}
}
}
AQL
SELECT LOGSOURCETYPENAME(logsourceid) AS LogSource,
QIDNAME(qid) AS EventName,
"HostName", "EventID", "Username", "TimeLogged"
FROM events
WHERE "EventID" = 4624 AND "HostName" LIKE 'NombreDelEquipo'
ArcSight Query Language
SELECT Name, DeviceHostName, TargetUserName, StartTime
FROM events
WHERE EventId = 4624 AND DeviceHostName CONTAINS 'NombreDelEquipo'
No es sencillo conocer cada uno de los lenguajes y todas sus particularidades. Además, enfrentamos otro problema. ¿Qué ocurre si yo creo una detección para una actividad en un lenguaje de un SIEM y comparto esta regla con otro equipo que no usa la misma tecnología SIEM? El proceso de traducción puede ser costoso y dar lugar a muchos errores.
Estandarización
Para resolver esta problemática se avanzan en esfuerzos por crear estándares de reglas de detección. Un lenguaje universal que sea entendido por todos los fabricantes y que faciliten la creación y compartición de reglas. Los ejemplos de antes ilustran la diversidad de tecnologías y lenguajes a las que puede enfrentarse un analista de seguridad. Cada fabricante realiza sus mejores esfuerzos para simplificar y hacer más completos sus lenguajes de consulta. Esto resulta en una gran variedad de lenguajes de consulta y no es trivial conocer en profundidad todos ellos. Sigma es el estándar creado para la creación de reglas y patrones de detección sobre logs de sistemas o actividad.
Reglas Sigma
Las reglas Sigma (generic signature format for SIEM systems) son un formato estándar y abierto diseñado para describir patrones de detección de amenazas en logs. El formato de las reglas Sigma es YAML. Al principio pueden resultar algo complejas y los analistas atraviesan por una curva de aprendizaje antes de poder construir condiciones de detección más complejas.
YAML es un formato ampliamente usado para definición de datos. En este caso para estructurar las diferentes secciones de las reglas YARA. YAML significa “YAML Ain’t Markup Language”, es decir, que YAML no es un lenguaje de markup. La fortaleza de YAML radica en lo intuitivo que es definir y estructurar los datos.
A continuación, se ilustra un ejemplo que sigue el mismo propósito que los descritos en la sección anterior. Pretendemos crear una regla que detecte el inicio de sesión en una máquina Windows. Para ello debe usarse el ID 4624 del evento de seguridad.
title: Inicio de sesión 4624
description: Regla para detectar inicios de sesión en una máquina específica.
status: test
author: Analista DFIR
date: 2024-12-23
logsource:
category: security
product: windows
detection:
selection:
EventID: 4624
WorkstationName: 'Nombre de maquina'
condition: selection
falsepositives:
- Administradores legítimos iniciando sesión
level: low
De primeras parece algo más complejo, ¿no? Por una lado debo decir que es algo injusto compararlo con las queries anteriores ya que en esta regla hay mucho metadato. Pero aun así, es algo más complejo. ¿Cuál es la parte positiva? Que esta regla va a valer para todos los SIEM que acepten Sigma.
En los siguientes subcapítulos se describen las diferentes partes del archivo YAML que definen la regla.
Metadata (opcional)
Una sección inicial con campos adicionales a modo de metadatos. Es decir, datos que no forman parte de la definición estricta de la regla. En el primer nivel de indentación, todo campo que no sea “logsource” ni “detection” es lo que consideramos que es un metadato.
IMPORTANTE: En el primer nivel de indentación, todo campo que no sea “logsource” ni “detection” es lo que consideramos que es un metadato
Campos posibles a usar como metadato dentro de la regla Sigma:
- Title: Título que se le asigna a la regla
- ID: UUID versión 4 que se le asigna a la regla. Sigma recomienda usar un UUID generado aleatoriamente.
- Os dejo un recurso para generar UUIDs: https://www.uuidgenerator.net/version4
- Status: Estado actual de la regla con uno de los siguientes valores posibles:
stable | test | experimental | deprecated | unsupported
- Description: Campo de texto libre usado para describir el propósito de la regla
- License: Texto libre para describir si hay alguna licencia asociada
- Author: Texto libre para indicar al autor de la regla
- Date / Modified: Cuándo se crea (date) y cuándo es la última modificación para la versión que estamos viendo (modified)
- References: Si se quiere mostrar una o varias URLs que hagan referencia a la regla y que contextualicen la información
- Tags: Etiquetas usadas normalmente para asignar valores para frameworks como MITRE o TLP.
- El ejemplo siguiente ilustra como podemos usar tags para identificar datos de framewroks como MITRE ATT&CK, MITRE CAR, TLP o CVE
tags:
# MITRE ATT&CK framework references
- attack.discovery
- attack.t1012
# MITRE Cyber Analytics Repository (CAR)
- car.2016-04-005
- car-2016-04-005
# Traffic Light Protocol
- tlp.amber
- tlp.green
# CVE
- cve.2022-27925
- FalsePositives: Campo de texto que describe si esta regla puede generar falsos positivos
- Level: indica la severidad o nivel de la alerta de entre estos posibles valores:
critical | high | medium | low | informational
- IMPORTANTE: Como norma se suele usar los valores critical y high para reglas que deben generar alerta. Y el resto de los valores para información que se debe incluir en informes y paneles de datos
En la siguiente captura se puede ver las recomendaciones ofrecidas por la documentación oficial de Sigma para la asignación de severidad a las reglas:
Detection (obligatorio)
Esto ya es el meollo de la regla. Todo lo que se incluye en la sección ficticia metadata no tiene valor para la detección, es solo información contextual que nutre a la regla de sentido. Pero en la sección detection se define la lógica de detección de la regla.
Operador AND/OR
Antes de ver como se aplican las condiciones, debemos entender como se construyen los operadores AND y OR. En YAML, dos o más variables en formato lista sería un OR, y dos o más variables en formato diccionario/objeto sería un AND. Es decir:
- Dos variables en formato lista = OR
detection:
selection:
field_name:
- this #OR
- that
- Dos variables en formato diccionario = AND
detection:
selection:
field_name1: this # AND
field_name2: that
selection + conditon
Las condiciones de la regla se definen dentro de la sección detection, en los campos selection y condition.
- selection: Define los datos. Define que se va a buscar. Se pueden tener varias selecciones con nombres diferentes.
- condition: Indica cómo se deben combinar los datos definidos en las selections para disparar la alerta.
En definitiva, en selection elegimos los datos y en condition como deben aplicarse en la regla. Veámoslo con un ejemplo:
detection:
selection:
EventID: 6416
ClassName: 'DiskDrive'
condition: selection
Como se puede observar en el ejemplo, la sección selection define una serie de datos. El ID 6416 (que identifica que se ha introducido un dispositivo externo) y el string “DiskDrive” que identifica que el dispositivo introducido sea de tipo disco de datos. Como ya se ha establecido, ambos datos están en modo diccionario. Es decir, se aplican con el operador AND (se deben cumplir ambos valores). Esta regla va a detectar que se ha añadido un nuevo disco duro al equipo.
Varios aspectos a tener en cuenta:
- Cuando la regla es más compleja, los datos se van a agrupar en varios campos selection. Estos deberán tener diferente nombre
- Si no queremos que los campos defindos en selection sean una condicion exacta sino que contenga, debemos definir la sección con el campo a buscar acompañada de «|contains». Por ejemplo:
Data|contains:
- Cuando hay varios campos selection es trabajo de la sección condition decir como aplica la logica de detección
Usando esto podemos ir a un ejemplo más complejo. Este ejemplo es la sección detection de la regla que detecta descargas sospechosas con PowerShell proporcionada en el repositorio oficial de Sigma. Podéis encontrar la regla aquí.
detection:
selection_webclient:
Data|contains: 'Net.WebClient'
selection_download:
Data|contains:
- '.DownloadFile('
- '.DownloadString('
condition: all of selection_*
Tenemos una primera sección que define que se encuentre el string «Net.WebClient» que sirve para identificar conexiones web. Una segunda sección que identifica descarga de archivos o datos. Para ello el dato del evento debe contener '.DownloadFile('
OR (es formato lista) '.DownloadString('
. Ambas secciones se unen en la condition diciendo que deben cumplirse ambas secciones para que la regla haga match.
Otros métodos para las conditions
Ya hemos visto como se crean las conditions. Pero vamos a ser un poco formales y vamos a ir a la definición de los detection methods que se incluye en la documentación oficial.
Existe según la documentación 3 formas de crear las conditions:
- Por Keyword
- Por Field Value
- Por Multiple Field Value
Por Keyword
Se define una lista de valores que se va a buscar en bruto en el evento (en qué evento lo veremos después cuando analicemos la sección logsource).
detection:
keywords:
- 'rm *bash_history'
- 'echo "" > *bash_history'
- 'truncate -s0 *bash_history'
- 'history -c'
- 'history -w'
condition: keywords
La selection con nombre keyword (puede tener este nombre u otro, pero se usa este como buena práctica) define una serie de strings en formato OR. La condicion es directamente la sección. Se van a buscar estos strings en el evento. Importante: este tipo de busquedas suele ser mucho más costosa para los SIEMs
Por Field Value
A diferencia de las búsquedas por keyword, las búsquedas por field indican en qué campo buscar. Para ello, dentro de la section, se deben definir los campos y su valor como un diccionario u objeto:
detection:
selection:
Username: "Administrator"
condition: selection
No va a buscar en todo el log, sino solo en el campo Username.
Este es el mismo ejemplo que hemos usado antes con la regla de detección de añadir un nuevo disco duro a un equipo:
detection:
selection:
EventID: 6416
ClassName: 'DiskDrive'
condition: selection
La pregunta aquí es: ¿Cómo sabemos para cada fuente y tipo de evento cuales son los campos disponibles? ¿Cómo se cual es el campo para la línea de comandos dentro del evento 4688 de seguridad de Windows?
Sigma cuenta en su repositorio oficial con documentación para cada fuente (al menos de las más usadas). Podéis encontrarlo aquí. Por ejemplo para el evento de seguridad de Windows 4688 (process creation):
- Documentación: https://github.com/SigmaHQ/sigma/blob/master/documentation/logsource-guides/windows/category/process_creation.md
Por Field List o Multiple Filed Value
Es como el método anterior solo que nos permite buscar más de un campo en un Field. Por ejemplo:
detection:
selection:
EventID:
- 4728
- 4729
- 4730
condition: selection
Importante que sean en OR. Un campo no puede tener más de un valor, y una condición AND resultaría en una regla que nunca saltaría.
Combinar varias selections
Dentro del campo condition se pueden combinar las selections:
condition: (selection_one or selection_two) and not selection_three
Esto nos permite agrupar los datos en selections y crear estructuras más complejas. En la documentación oficial podéis encontrar todas las posibilidades de agrupación de las selections en una condition. Os dejo el enlace aquí.
logsources (obligatorio)
Si en el campo detecion definimos las condiciones de detección, en la sección logsource definimos de que logs debemos tirar para esta regla. Un log se puede clasificar por tres variables:
- Category
- Product
- Service
Todos los logs que pensemos se definen rellenado estas variables. Por ejemplo el log de un Apache:
logsource:
service: apache
O el log del evento de seguridad de Windows:
logsource:
category: security
product: windows
Podéis encontrar un listado completo de logs y su sección logsource del YAML asociado en la documentación oficial aquí.
Al logsource se le puede añadir un campo de texto libre denominado «definition«. Esto ayuda a añadir anotaciones o descripciones. Por ejemplo:
logsource:
product: windows
category: ps_script
definition: Script Block Logging must be enabled
Conclusiones
Os animo a que compartáis inteligencia. Que compartáis nuevas detecciones. Y que para hacerlo sobre logs, que lo hagáis usando el estándar Sigma.
Hasta la próxima.