SIGMA Rules Introduction - Parte 01
Por Davi Chaves
Table of Contents
- SIGMA Rules - Parte 01 - Introduction
- Tipos de regras SIGMA
- Funcionamento
- Escrevendo uma SIGMA Rule
- Exemplo de SIGMA Rule real
- Conclusão
- Reference Anteriormente, as detecções no âmbito do SIEM eram isoladas em compartimentos específicos vinculados a fornecedores ou plataformas particulares. Parceiros que pretendiam compartilhar conteúdo de detecção muitas vezes enfrentavam o desafio de traduzir uma consulta de um fornecedor para outro. Essa abordagem revelou-se insustentável. Assim como YARA ou as regras do Snort, o SIGMA representa outra ferramenta voltada para o compartilhamento aberto de detecções, mas com foco no SIEM em vez de arquivos ou tráfego de rede. O SIGMA capacita defensores a compartilhar detecções (alertas, casos de uso) em uma linguagem comum.
Tipos de regras SIGMA
Existem atualmente dois tipos básicos de regras no SIGMA que podem ser expressos:
- Regras SIGMA baseadas em correspondência: amplamente suportadas e mais fáceis de escrever, essas regras são centradas na correspondência direta. Exemplo: uma regra que trás os usuários que falharam em se autenticar.
- Regras SIGMA baseadas em correspondência e correlações simples: com suporte limitado e uma complexidade um pouco maior de escrita, essas regras envolvem não apenas a correspondência, mas também correlações simples. Exemplo: uma regra que trás os usuários que falharam em se autenticar X vezes em um intervalo de tempo específico. Nesse artigo não vamos abordar esse tipo de regra.
Funcionamento
De forma simplificada, o processo de transformação de uma regra SIGMA em uma detecção real pode ser dividida em 3 partes:
- Escrita da regra SIGMA: primeiro, é necessário a criação de uma SIGMA rule.
- Backend Transformation: em seguida, algum backend, como o pySigma-backend-splunk, vai ser responsável por colocar a SIGMA rule no formato de query apropriado. 1
- Pipelines: por último, é possivel utilizar pipelines para mapear os campos genéricos escritos por outros autores de SIGMA rules para os campos específicos do seu ambiente desejado. O ponto importante aqui é entender que, dado uma mesma SIGMA rule, é possível transforma-lá em diferentes detecções de diferentes SIEMs. Nesse artigo, apenas a escrita das regras SIGMA serão abordadas.
Escrevendo uma SIGMA Rule
Vamos escrever uma regra extremamente simples que detecte execuções do binário CertUtil.exe
que contenham na CommandLine
flags como -encode
ou /encode
.
Atualmente, para termos uma regra SIGMA válida, são necessários apenas dois campos: logsource
e detection
.
logsource:
product: windows
detection:
selection:
Image|endswith: '\certutil.exe'
CommandLine|contains:
- '-encode'
- '/encode'
condition: selection
Antes de entendermos a estrutura dessa regra, é importante entender que é possível converte-lás em detecções de diferentes SIEMs com muita facilidade utilizando o sigma-cli/pySigma:
// Splunk Backend
Image="*\\certutil.exe" CommandLine IN ("*-encode*", "*/encode*")
// QRadar Backend
SELECT UTF8(payload) as search_payload from events where "Image" ILIKE '%\certutil.exe' AND ("Process CommandLine" ILIKE ENUMERATION('%-encode%','%/encode%'))
// ElasticSearch Backend
Image:*\\certutil.exe AND (CommandLine:(*\-encode* OR *\/encode*))
Atualmente, os seguintes backends são suportados pelo pySigma em 2022/04/10:
pySigma | Observation |
---|---|
pySigma-pipeline-crowdstrike | CrowdStrike Search Processing Language (SPL) |
pySigma-backend-uberAgent | uberAgent ESA Threat Detection Engine |
pySigma-backend-splunk | Splunk Search Processing Language (SPL) |
pySigma-backend-QRadar-AQL | IBM Qradar AQL |
pySigma-backend-powershell | PowerShell event log cmdlets |
pySigma-backend-opensearch (proxied by pySigma-backend-elasticsearch) | OpenSearch search query string. Only searches, no aggregations |
pySigma-backend-opensearch (proxied by pySigma-backend-elasticsearch) | OpenSearch DSL query |
pySigma-backend-opensearch | OpenSearch monitors and ElasticRule are in Elastic Common Schema |
pySigma-backend-microsoft365defender | Microsoft Defender ATP Hunting Queries |
pySigma-backend-elasticsearch | Elasticsearch DSL query |
pySigma-backend-elasticsearch | Elasticsearch query string. Only searches, no aggregations |
pySigma-backend-elasticsearch | Kibana JSON Configuration files (searches only) |
Nesse artigo, vamos utilizar como exemplo o pySigma-backend-splunk. |
Campo Logsource
O campo logsource
serve apenas como “metadado” para que os consumidores da regra SIGMA, mais a frente, possam especificar em quais dados essa regra deve ser aplicada. Por exemplo, nesse caso não faria sentido aplicar essa regra em logs de firewall ou do Linux. Portanto, o autor da regra pode escrever product: windows
como uma dica que essa regra deve ser aplicada, de preferência, em ambientes Windows. Entretanto, o consumidor dessa regra pode, muito bem, ignorar isso e aplicar em logs de firewall, por exemplo. Além disso, apenas o campo product
é obrigatório. Todos os outros podem conter qualquer coisa que o autor quiser.
logsource:
banana: apple
service: windows_audit
category: process_creation
product: windows
detection:
...
Como exemplo, o campo product: windows
poderia ser lido por um backend, ou uma pipeline, para introduzir na query de detecção um campo que restrinja à logs do Windows:
index="CoolCompanyName-windows" Image="*\\certutil.exe" CommandLine IN ("*-encode*", "*/encode*")
Indo além, o backend, ou pipeline, poderia inserir, para regras que contenham um logsource category: process_creation
e service: windows_audit
, campos que restrinjam à logs de criação de processos do Windows Audit:
index="CoolCompanyName-windows" EventCode=4688 Image="*\\certutil.exe" CommandLine IN ("*-encode*", "*/encode*")
O mais importante é entender que os campos do logsource não fazem nada “sozinhos”, são os backends e pipelines que podem, ou não, usar essas informações para melhor direcionar as buscas de detecção. Nos próximos artigos vamos ver como escrever backends e pipelines.
Campo Detection
O componente de detecção é o espaço no qual o autor estabelece os critérios de detecção. Isso envolve, no mínimo, um componente de seleção e um componente de condição.
Selection
Esse campo pode, na verdade, receber qualquer nome. Entretanto, a documentação utiliza o prefixo selection_
para descrever os critérios de detecção.
detection:
selection_banana:
Image|endswith: '\certutil.exe'
CommandLine|contains:
- '-encode'
- '/encode'
condition: selection_banana
// Query gerada (SPLUNK-SPL)
Image:*\\certutil.exe AND (CommandLine:(*\-encode* OR *\/encode*))
Condition
O campo condition
contém a lógica booleana (AND, OR, NOT) que define como cada seleção deve ser incluída na consulta final. Por exemplo, podemos criar uma outra seleção e utilizar ela como filtro.
detection:
selection_banana:
Image|endswith: '\certutil.exe'
CommandLine|contains:
- '-encode'
- '/encode'
filter_bad_banana:
ParentCommandLine|contains: 'apple'
condition: selection_banana and not filter_bad_banana
// Query gerada (SPLUNK-SPL)
(Image:*\\certutil.exe AND (CommandLine:(*\-encode* OR *\/encode*))) AND (NOT ParentCommandLine:*apple*)
Normalmente, é utilizado o prefíxo filter_
para seleções agem como um tipo de filtro.
Image, CommandLine… what are they?
Os subcomponentes do campo de seleção possuem a estrutura de field: value
. Teoricamente, o autor pode utilizar os nomes de campo que desejar, desde que alguém esteja disposto a dedicar tempo para escrever especificações para traduzir esses campos para os deles. Diante disso, é bom seguir uma certa convenção para que as regras SIGMA sejam mais facilmente utilizadas.
detection:
selection:
# Também é válido
NomeDoProcesso|endswith: '\certutil.exe'
# Também é válido
LinhaDeComandoDoProcesso|contains:
- '-encode'
- '/encode'
...
// Query gerada (SPLUNK-SPL)
NomeDoProcesso:*\\certutil.exe AND (LinhaDeComandoDoProcesso:(*\-encode* OR *\/encode*))
Modificadores
O que são esses termos endswith
, contains
e startswith
? Eles são chamados de modificadores! Sigma possui modificadores especiais para facilitar a busca de strings não delimitadas:
- *something –> endswith modifier
- something* –> startswith modifier
- something –> contains modifier Abaixo, os atuais modificadores suportados pelo SIGMA. Vale a pena lembrar que, como tudo nas regras SIGMA, os modificadores não fazem nada “sozinhos”, vai ser o backend, ou o consumidor da regra, que vai utilizar os campos das regras para construir a detecção desejada.
Modifier | Use |
---|---|
contains | the value is matched anywhere in the field (strings and regular expressions) |
startswith | The value is expected at the beginning of the field’s content (strings and regular expressions) |
endswith | The value is expected at the end of the field’s content (strings and regular expressions) |
exists | The field exists (yes/true) in the matched event or doesn’t exist (no/false) |
base64 | The value is encoded with Base64 |
base64offset | If a value might appear somewhere in a base64-encoded value the representation might change depending on the position in the overall value |
wide | transforms value to UTF16-LE encoding |
re | value is handled as regular expression by backends |
i | Regular expression ignore case modifier |
ignorecase | Regular expression ignore case modifier |
m | Regular expression multiline modifier |
multiline | Regular expression multiline modifier |
s | Regular expression dot matches all modifier |
dotall | Regular expression dot matches all modifier |
cidr | value is handled as an IPv4 CIDR by backends |
all | This modifier changes OR logic to AND |
lt | Field is less than the value |
lte | Field is less or egal than the value |
gt | Field is Greater than the value |
gte | Field is Greater or egal than the value |
expand | Modifier for expansion of placeholders in values. It replaces placeholder strings (%something%) |
Exemplo de SIGMA Rule real
Na realidade, apesar de uma regra SIGMA só precisar de dois campos (logsource
e detection
), existem muitos outros campos que servem de metadados. Por exemplo, pela documentação, o campo description
deve conter uma descrição sobre o que aquela regra SIGMA visa detectar.
title: Unusually Long PowerShell CommandLine
id: d0d28567-4b9a-45e2-8bbc-fb1b66a1f7f6
status: test
description: Detects unusually long PowerShell command lines with a length of 1000 characters or more
references:
- https://speakerdeck.com/heirhabarov/hunting-for-powershell-abuse
author: oscd.community, Natalia Shornikova
date: 2020/10/06
modified: 2023/04/14
tags:
- attack.execution
- attack.t1059.001
- detection.threat_hunting
logsource:
category: process_creation
product: windows
detection:
selection_powershell:
- Image|endswith:
- '\powershell.exe'
- '\pwsh.exe'
- OriginalFileName:
- 'PowerShell.EXE'
- 'pwsh.dll'
- Description: 'Windows Powershell'
- Product: 'PowerShell Core 6'
selection_length:
CommandLine|re: '.{1000,}'
condition: all of selection_*
falsepositives:
- Unknown
level: low
Atualmente, as especificações completas de regras SIGMA podem ser encontradas no repositório oficial: SigmaHQ/sigma-specification: Sigma rule specification (github.com)
Conclusão
Nesse artigo, foi feito uma introdução sobre como escrever regras SIGMA e uma breve explicação sobre como ocorre o processo de transformação de uma regra para uma query. Nos próximos artigos, vamos nós aprofundar em como pipelines e backends funcionam.
Reference
What Are SIGMA Rules: Beginner’s Guide - SOC Prime 2 SigmaHQ/sigma: Main Sigma Rule Repository (github.com) SigmaHQ/pySigma: Python library to parse and convert Sigma rules into queries (and whatever else you could imagine) (github.com) pySigma Documentation — pySigma documentation (sigmahq-pysigma.readthedocs.io)