SIGMA Rules Introduction - Parte 01

Por Davi Chaves

Table of Contents

  1. SIGMA Rules - Parte 01 - Introduction
  2. Tipos de regras SIGMA
  3. Funcionamento
  4. Escrevendo uma SIGMA Rule
    1. Campo Logsource
    2. Campo Detection
      1. Selection
      2. Condition
      3. Image, CommandLine… what are they?
      4. Modificadores
  5. Exemplo de SIGMA Rule real
  6. Conclusão
  7. 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:

  1. 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.
  2. 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:

  1. Escrita da regra SIGMA: primeiro, é necessário a criação de uma SIGMA rule.
  2. 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
  3. 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)


  1. Na realidade, o backend é aplicado após as transformações (pipelines). ↩︎

  2. Esse artigo foi pesadamente inspirado nesse blog post do Adam Swan. ↩︎