Lesson 4 of 5 · 25 min read

Converting Sigma — sigma-cli, Uncoder, and What Gets Lost in Translation

A Sigma rule is only useful if it runs in your SIEM. Conversion from Sigma YAML to SIEM-native queries is the step where subtle errors introduce silent failures. This lesson covers the conversion workflow and the pitfalls to watch for.


The Conversion Workflow

Sigma Rule (.yml)


sigma-cli / Uncoder
       │ field mapping pipeline

Field names translated to SIEM-specific names

       │ syntax generation

SIEM-native query (SPL / KQL / EQL / etc.)


Deploy to SIEM → Test → Ship

sigma-cli: Command-Line Conversion

Installation

pip install sigma-cli

# Install backend plugins
pip install pySigma-backend-splunk
pip install pySigma-backend-microsoft365defender
pip install pySigma-backend-elasticsearch

# List available backends and pipelines
sigma list backends
sigma list pipelines

Basic conversion

# Convert to Splunk SPL using Sysmon field mappings
sigma convert \
  -t splunk \
  -p sysmon \
  rules/proc_creation_win_powershell_download_cradle.yml

# Convert to KQL (Microsoft Sentinel) using Windows Security Events pipeline
sigma convert \
  -t microsoft365defender \
  -p windows_audit \
  rules/proc_creation_win_powershell_download_cradle.yml

# Convert entire directory
sigma convert \
  -t elasticsearch \
  -p ecs-windows \
  rules/windows/process_creation/

Converting our PowerShell Download Cradle rule

sigma convert -t splunk -p sysmon rules/powershell-download-cradle.yml

Output (SPL):

(Image="*\\powershell.exe" (CommandLine="*New-Object*" CommandLine="*Net.WebClient*") 
OR (Image="*\\powershell.exe" (CommandLine="*Invoke-WebRequest*" OR CommandLine="*wget*" 
OR CommandLine="*curl*")) OR (Image="*\\powershell.exe" CommandLine="*Start-BitsTransfer*")) 
NOT CommandLine IN ("*WindowsUpdate*","*MicrosoftUpdate*","*download.windowsupdate.com*")

And for Microsoft 365 Defender KQL:

DeviceProcessEvents
| where FileName =~ "powershell.exe"
| where (ProcessCommandLine contains "New-Object" and ProcessCommandLine contains "Net.WebClient")
    or ProcessCommandLine has_any ("Invoke-WebRequest", "wget", "curl")
    or ProcessCommandLine contains "Start-BitsTransfer"
| where not (ProcessCommandLine has_any ("WindowsUpdate", "MicrosoftUpdate", "download.windowsupdate.com"))

What Gets Lost in Translation

Problem 1: Missing field mappings

If your Sigma rule uses a field that isn’t in the pipeline’s mapping, the converted query drops that condition:

# Sigma rule
detection:
  selection:
    Image|endswith: '\powershell.exe'
    OriginalFileName: 'PowerShell.EXE'  ← This field

If OriginalFileName isn’t in your Splunk pipeline mapping, sigma-cli silently drops it:

# Converted output (missing OriginalFileName):
Image="*\\powershell.exe"

The converted rule now only checks Image, not OriginalFileName — which means a renamed PowerShell binary would NOT be detected. The silent omission is dangerous: your rule appears to work but provides weaker coverage than intended.

Fix: Always review converted output. Look for missing conditions. Add custom field mappings to your pipeline for fields your environment uses.

Problem 2: Regex dialect differences

Sigma’s re: modifier converts to regex syntax, but regex dialects differ across systems:

detection:
  selection:
    TargetFilename|re: '.*\\AppData\\Local\\Temp\\[a-z]{8}\.exe'

In Elasticsearch Lucene: TargetFilename:/.*\\AppData\\Local\\Temp\\[a-z]{8}\.exe/ In Splunk: TargetFilename=/(.*\\AppData\\Local\\Temp\\[a-z]{8}\.exe)/ In KQL: TargetFilename matches regex @".*\\AppData\\Local\\Temp\\[a-z]{8}\.exe"

Backslash escaping differs. Test every regex-based rule after conversion.

Problem 3: Aggregation conditions

# Sigma aggregation
condition: selection | count() by ComputerName > 10

This converts differently:

SPL:

... | stats count by ComputerName | where count > 10

KQL:

... | summarize count_ = count() by ComputerName | where count_ > 10

EQL: EQL doesn’t support this directly — must be rewritten as ES|QL or a time-series query.


Uncoder.io: Web-Based Conversion

Navigate to uncoder.io, paste a Sigma rule, select the target platform, and copy the output. Uncoder supports 20+ SIEM platforms.

sigma-cli— SigmaHQ GitHub Uncoder.io— Uncoder pySigma backends— GitHub