Home Comunidade Eventos YouTube Networks Desafios // produtos Academy News CTI | CVE Contato

01 - Conversão de Sigma para Linguagens Nativas (SPL, KQL)

video explicativo
Video explicativoEspaco reservado para o video desta anotação — adicione video: https://youtu.be/... no frontmatter da nota.

Conversão de Sigma para Linguagens Nativas (SPL, KQL)

Nota de abertura da pasta de Pipeline de Detecção do capítulo 18, sobre Detection Engineering e Automação.
Explica a conversão de regras Sigma para consultas nativas como SPL, KQL e Lucene com pySigma e sigmac, incluindo limitações e pipeline de conversão.
Dialoga com o repositório Sigma HQ da pasta de DaC, com o deploy automatizado desta pasta e com a nota de consultas e linguagens do capítulo 9.

1. Contexto e Posicionamento na Biblioteca

A biblioteca já apresentou o formato Sigma na nota de consultas e linguagens do capítulo 9 como a linguagem comum de detecção, e esta nota trata da engenharia que transforma esse formato comum em consultas nativas de cada plataforma. A conversão é o coração de um pipeline de detecção multiplataforma: o engenheiro escreve e revisa a lógica uma vez, em Sigma, e a pipeline produz as variações para Splunk, Microsoft Sentinel, Elastic e qualquer outro motor com backend disponível, eliminando a duplicação que fazia a mesma regra ser mantida à mão em vários dialetos.

A nota cobre as duas gerações de ferramentas de conversão, o sigmac clássico do projeto Sigma e o pySigma atual, explica o papel das processing pipelines no mapeamento de campos, demonstra uma conversão completa de uma regra até as consultas em KQL e SPL e examina com honestidade os limites da tradução automática. O leitor que operar o pipeline completo deste capítulo usará esta nota como a etapa de build descrita pela nota de testes da pasta de DaC.

2. Formato Sigma e o Papel das Processing Pipelines

Uma regra Sigma expressa a lógica de detecção com seleções, valores e modificadores, sem mencionar dialeto ou nomes de campo específicos de produto, e essa neutralidade é a razão de existir do formato. O que conecta a lógica neutra ao ambiente concreto é a processing pipeline, um conjunto de transformações que converte o logsource da regra nos nomes de índice, categoria e campo da plataforma alvo. A pipeline é onde mora o conhecimento local: nomes de campos customizados, índices padrão da organização e diferenças de schema entre versões do agente são declarados nas pipelines, não nas regras.

A distinção entre regra e pipeline é o que mantém o catálogo portátil de verdade. Regras que tentam embutir nomes de campo proprietários deixam de ser portáveis, e pipelines que tentam corrigir lógica de detecção se tornam código espaguete de transformações. A disciplina prática é simples: a regra descreve comportamento em campos canônicos, a pipeline traduz campos canônicos para campos reais do ambiente, e qualquer regra que precise de transformação especializada recebe sua própria pipeline dedicada declarada nos metadados.

O exemplo abaixo mostra o mapeamento típico de uma processing pipeline para o ambiente de destino, declarando as transformações de categoria e campo que a conversão aplica. Esse arquivo vive no repositório junto às regras, versionado com o mesmo rigor.

# pipeline do ambiente: splunk corporativo
name: pipeline_splunk_corp
priority: 50
transformations:
  - id: campo_canonico_imagem
    type: set_state
    state:
      field_process_image: Image
    rule_conditions:
      - type: logsource
        category: process_creation
  - id: filtro_indices_windows
    type: index_condition
    index: "wineventlog_*"
    rule_conditions:
      - type: logsource
        category: process_creation
        product: windows
  - id: renomeia_campo_customizado
    type: field_name_mapping
    mapping:
      ScriptBlockText: "EventCode=4104 | Message"
    rule_conditions:
      - type: logsource
        service: powershell

3. sigmac e pySigma, Duas Gerações de Conversão

A primeira geração de conversão foi o sigmac, script em Python do projeto Sigma original, que converte uma regra por vez para o dialeto alvo com backends para dezenas de plataformas e usa pipelines em formato de configuração simples. O sigmac ancora o ecossistema há anos e ainda aparece em muitos ambientes, mas seu desenvolvimento foi congelado com o fim da estrutura original do projeto, e novos recursos de linguagem tendem a não chegar nele.

O pySigma é a geração atual, uma biblioteca em Python que substitui o sigmac e centraliza o pipeline de conversão em objetos tipados: a regra é um objeto SigmaRule validado por schema, as transformações são objetos com condições tipadas e os backends são pacotes instaláveis por plataforma, como o backend splunk e o backend kusto. O CLI sigma-cli empacota a biblioteca para uso em linha de comando, e a arquitetura de biblioteca é o que permite integrar a conversão em scripts de CI com verificação de erros estruturada, em vez de parsear saída de texto. A tabela abaixo compara as duas gerações nos critérios que importam para operação.

Critério sigmac pySigma
Estado de manutenção Congelado, correções pontuais Ativo, com releases e plugins de backend
Modelo de extensão Backends acoplados ao projeto Pacotes instaláveis independentes
Pipelines Configuração simples em YAML Objetos tipados com condições e estados
Erros de conversão Mensagens de texto, difícil automação Exceções estruturadas com contexto da regra
Uso típico Linha de comando ad hoc Scripts de CI e integração programática

A recomendação prática para um catálogo novo é começar direto em pySigma com sigma-cli, mantendo o sigmac apenas para catálogos legados e para backends que ainda não tenham equivalente. A conversão dos dois para o mesmo arquivo de regra costuma divergir em detalhes de escape e operadores, e padronizar a ferramenta evita que o mesmo YAML produza duas consultas diferentes conforme quem rodou o comando.

4. Conversão para KQL, SPL, Lucene e Elastic ECS

Os backends de pySigma traduzem a lógica Sigma para o dialeto alvo respeitando a sintaxe e, quando possível, o vocabulário de campo da plataforma. O backend kusto produz KQL para Microsoft Sentinel e Defender, o backend splunk produz SPL com índices e campos da convenção do Splunk, e backends para Lucene atendem Elasticsearch e OpenSearch, com a variante ECS usando o mapeamento de campos do Elastic Common Schema. As processing pipelines declaradas nos metadados da regra, no campo pipeline ou no argumento de linha de comando, são aplicadas antes da tradução, e o resultado muda radicalmente conforme a pipeline usada.

A escolha do backend e da pipeline determina três características da consulta gerada: os nomes de campo, pois KQL da Sentinel usa o vocabulário de tabelas do Log Analytics enquanto Lucene ECS usa os campos padronizados do ECS; os operadores, porque cada dialeto traduz modificadores Sigma como contains e re de modo diferente; e a estrutura de agregação, quando a regra usa condição de agregação como count by. O engenheiro responsável pela pipeline conhece essas diferenças e valida a consulta gerada contra o ambiente, pois a conversão correta em sintaxe não garante consulta correta em semântica de execução.

O comando de conversão em lote processa o diretório de regras e reporta sucessos e falhas por arquivo, e o modo estrito de pySigma, que falha na primeira condição não tratada, é a configuração recomendada para CI, pois impede que regras parcialmente convertidas entrem no catálogo compilado em silêncio.

5. Exemplo Completo: Regra Sigma Vira KQL e SPL

O exemplo abaixo percorre o caso concreto de uma regra Sigma de process_creation que detecta a ferramenta de administração remota usada fora do contexto legítimo, padrão comum em movimento lateral. A regra é escrita em campos canônicos e a conversão é executada com pipelines declaradas para os dois ambientes alvo.

title: Acesso Remoto com Pai Incomum
id: 5f3b2a41-9c8d-4e7a-b1d2-6f0e5c4b3a21
status: stable
description: Detecta execução de ferramentas de administração remota
  iniciadas por processo pai incomum, padrão de movimento lateral.
references:
  - https://attack.mitre.org/techniques/T1021/
author: equipe de detection engineering
date: 2025/02/14
tags:
  - attack.lateral_movement
  - attack.t1021
logsource:
  category: process_creation
  product: windows
detection:
  selection_tools:
    Image|endswith:
      - '\mstsc.exe'
      - '\psexec.exe'
  selection_parent_legit:
    ParentImage|endswith:
      - '\explorer.exe'
      - '\rdpclip.exe'
  condition: selection_tools and not selection_parent_legit
falsepositives:
  - Ferramentas de suporte iniciadas por consoles próprios
level: medium

A conversão para KQL com backend kusto e pipeline da Sentinel produz a consulta abaixo, com o vocabulário da tabela DeviceProcessEvents do Log Analytics e os operadores nativos do dialeto.

DeviceProcessEvents
| where FileName in~ ("mstsc.exe", "psexec.exe")
| where InitiatingProcessFileName !~ ("explorer.exe", "rdpclip.exe")
| project TimeGenerated, DeviceName, AccountName, FileName,
    ProcessCommandLine, InitiatingProcessFileName

A mesma regra convertida para SPL com backend splunk e pipeline da convenção Splunk produz a consulta abaixo, com índice de processos, campos do vocabulário Splunk e a mesma semântica de seleção e exclusão.

index=main sourcetype=XmlWinEventLog:Microsoft-Windows-Sysmon/Operational
  (process_name=mstsc.exe OR process_name=psexec.exe)
  parent_process_name!=explorer.exe parent_process_name!=rdpclip.exe
| table _time, Computer, user, process_name, process,
  parent_process_name

A comparação dos resultados mostra o valor e o custo da abordagem: o engenheiro manteve uma única lógica fonte, e as duas consultas nativas saíram corretas e idiomáticas, mas cada uma assumiu a pipeline correspondente com os nomes de campo do ambiente. Sem pipeline, o backend usaria os nomes canônicos e as consultas retornariam vazio em produção, que é exatamente a classe de falha silenciosa que a pipeline e o teste de integração existem para prevenir.

6. Limitações da Conversão e Onde a Tradução Quebra

A conversão automática tem limites estruturais que o engenheiro precisa conhecer para não confiar cegamente na saída. A primeira família de limites vem das funções específicas de cada dialeto: lógica que usa funções de estatística avançada, correlação entre eventos com streaming de estado, funções de decisão como coalesce e condicionais internas da consulta não têm representação no modelo Sigma, e a regra precisa ser escrita nativamente ou fragmentada em várias regras Sigma mais simples. A segunda família vem dos campos customizados: ambientes com renomeação de campos por coletor, campos de enriquecimento adicionados no pipeline de ingestão e tags internas exigem pipelines dedicadas, e a ausência delas produz consultas sintaticamente corretas e semanticamente vazias.

A terceira família é a das diferenças de semântica de operadores, a mais traiçoeira de todas. O modificador contains de Sigma vira operadores diferentes em cada dialeto, com comportamento de maiúsculas e minúsculas variando por plataforma, e diferenças entre correspondência em qualquer parte do valor e correspondência de token inteiro mudam o conjunto de resultados. Regras com regex sofrem ainda mais, porque o motor de expressão regular muda entre plataformas, e o conselho operacional é que regras complexas em regex merecem revisão manual da consulta nativa gerada, com teste contra eventos reais do ambiente.

  • Agregações complexas: contagem com janela e agrupamento é traduzível, mas agregações estatísticas avançadas, como desvio padrão por entidade, ficam fora do modelo e exigem regra nativa.
  • Correlação multi-evento: regras que correlacionam eventos distintos com estado compartilhado são nativas por definição, e o papel do Sigma se reduz à documentação da lógica.
  • Campos dependentes de enriquecimento: campos criados em tempo de busca ou de ingestão exigem pipeline que declare a dependência, e a validação de cobertura da fonte precede a aprovação da regra.
  • Diferenças de case sensitivity: o mesmo modificador produz correspondência sensível ou insensível conforme o backend, e a regra crítica deve fixar a semântica com teste, não com esperança.
  • Escape e caracteres especiais: valores com espaços, aspas e barras são escapados de modo diferente por dialeto, e a camada de teste é quem pega o erro de escape que o olho humano lê como correto.

7. Erros Comuns e Pontos de Atenção

  • Rodar a conversão sem pipeline do ambiente: a consulta sai com campos canônicos, roda sem erro e retorna vazio para sempre, e a ausência de disparo é descoberta meses depois por acaso. Pipeline por ambiente e teste de integração são pares inseparáveis.
  • Misturar pipelines de ambientes distintos na mesma execução: o resultado híbrido com campos de dois schemas é pior que a consulta vazia, porque dispara no lugar errado. Uma execução por ambiente alvo, com saída segregada por pasta.
  • Tratar a consulta gerada como imutável: edições diretas no artefato compilado derivam produção da fonte Sigma e morrem na próxima execução da pipeline. Ajuste especializado vira pipeline nova ou regra nativa declarada.
  • Converter catálogo legado em massa sem triagem: milhares de regras legadas com campos inventados produzem milhares de conversões inválidas, e a migração em massa precisa começar por inventário e deduplicação, não pelo comando de conversão.
  • Ignorar o relatório de condições não tratadas: pySigma sinaliza regras cujas condições a pipeline não cobre, e rodar em modo permissivo para terminar a tarefa rápido empurra o defeito para produção com selo de compilado.

8. Integração com o Restante da Biblioteca

O estágio de build descrito na nota de testes da pasta de DaC executa a conversão desta nota como um dos portões da pipeline, e a nota de deploy automatizado desta pasta publica os artefatos compilados por ambiente com verificação pós-deploy. A nota de simulação de alertas complementa a conversão com a prova de fogo: a consulta gerada é exercitada contra dados injetados reais, confirmando que a cadeia regra, pipeline, backend e plataforma produz o alerta esperado.

No restante da biblioteca, a nota de consultas e linguagens do capítulo 9 introduz os dialetos aqui gerados, e o capítulo 8 de hunting por TTPs fornece o repertório comportamental que vira regras Sigma. O controle AUT.3 do framework CTH consagra a automação de detecção que esta nota operacionaliza, e o controle DAT.4 sobre ingestão de logs define os schemas reais que as processing pipelines mapeiam, lembrando que conversão sem telemetria correta detecta nada.