|9 min read|Yvann Lièvre

Converting Sigma Rules to Splunk (SPL): A Practical Guide

How to convert Sigma rules into SPL queries with pySigma, handle CIM field mapping, avoid rules that match nothing, and maintain the pipeline at scale.

SigmaSplunkSIEMDetection
Converting Sigma Rules to Splunk (SPL): A Practical Guide

You have a solid library of Sigma rules, a Splunk SIEM in production, and yet nothing fires. The problem is almost never the rule, it's the conversion. Splunk doesn't read Sigma natively, and a sloppy conversion produces SPL queries that look for fields that don't exist in your index. Here's how to do it properly.

What Sigma is, and why Splunk can't read it

Sigma is a generic detection rule format, written in YAML. The idea: describe a detection once, independently of the SIEM, then compile it to the target query language, SPL for Splunk, KQL for Sentinel, Lucene/EQL for Elastic, AQL for QRadar.

A Sigma rule looks like this:

title: PowerShell EncodedCommand
logsource:
    category: process_creation
    product: windows
detection:
    selection:
        Image|endswith: '\powershell.exe'
        CommandLine|contains:
            - '-enc'
            - '-EncodedCommand'
    condition: selection

It's readable, portable, and version-controllable in Git. But Splunk doesn't know what to do with it: its engine expects SPL. So you have to compile the Sigma rule into an executable SPL query. That's the job of pySigma.

Converting with pySigma and the Splunk backend

pySigma is the reference library (it replaces the older sigmac). Conversion to Splunk relies on two components:

  • pysigma-backend-splunk, the SplunkBackend, which emits SPL syntax.
  • A processing pipeline, here splunk_windows, which maps Sigma fields onto Splunk's CIM (Common Information Model) schema.

Install and convert from the command line:

pip install sigma-cli pysigma-backend-splunk
 
sigma convert -t splunk -p splunk_windows rule.yml

The -t splunk flag selects the backend, -p splunk_windows applies the pipeline. Without the pipeline you get a query that is syntactically valid but semantically wrong, we'll get to that right away, because it's the number-one trap.

The real problem: field mapping

This is where 90% of conversions fail silently. A Sigma rule speaks in abstract Sigma fields: Image, CommandLine, ParentImage. Those names don't exist as-is in Splunk. Your data is indexed against a schema (often the CIM, the Endpoint.Processes data model) where the fields are called Processes.process_path, Processes.process, Processes.parent_process.

Without a pipeline, sigma convert produces a query that literally looks for a field named Image:

Image="*\\powershell.exe" CommandLine IN ("*-enc*", "*-EncodedCommand*")

If your Sysmon data is CIM-normalized, there is no field called Image in the index. The query runs, raises no error, and returns zero results. You think you're covered; you're not. That's the trap of "raw" converted rules: they're green in your catalog and blind in production.

The splunk_windows pipeline resolves this mapping. It translates Image to the real field name, adds the logsource constraint (the correct sourcetype / data model), and handles CIM quirks. The query then becomes usable against your actual data.

A complete example: before and after

Take the PowerShell -EncodedCommand rule from above.

Sigma (source, portable):

detection:
    selection:
        Image|endswith: '\powershell.exe'
        CommandLine|contains:
            - '-enc'
            - '-EncodedCommand'
    condition: selection

Generated SPL (target, executable):

Image="*\\powershell.exe" CommandLine IN ("*-enc*", "*-EncodedCommand*")

Note the mechanics: endswith becomes a wildcard *\powershell.exe, the contains list becomes an IN (...) with wildcards on both sides. With the CIM pipeline, Image and CommandLine are replaced by their indexed equivalents (Processes.process_path, Processes.process) and the query is prefixed with the appropriate tstats / datamodel call. Without the pipeline, you keep raw Image and CommandLine, correct syntax, null result.

Common traps that break conversion

Even with the right backend and pipeline, several things derail pySigma:

  • Non-standard Sigma tags, a field outside the specification (an in-house extension, a custom.field) that the pipeline doesn't know will not be mapped, or will break parsing. Stick to the official Sigma taxonomy.
  • correlation rules, Sigma correlation rules (aggregation, temporal) are not supported by every backend. Check coverage before relying on them, or the conversion fails or emits partial SPL.
  • Backticks and special characters, a backtick inside a value can break the generated SPL query. Watch out too for characters that carry meaning in SPL.
  • Windows backslash escaping, Windows paths (\Device\, C:\Windows\) require double escaping. A single mis-escaped backslash and the wildcard matches nothing. It's a classic source of "green but dead" rules.

The common thread across these traps: they don't necessarily raise an error. They produce a rule that appears to work. So you have to test each converted rule against real data or test logs, not just check that it compiles.

Maintaining this at scale

Converting one rule by hand is fine. Converting 3,000 (and re-converting them every time the Sigma repository updates) is not. The public Sigma corpus evolves constantly, pySigma backends change, and so does your indexing schema.

At scale, you have to treat conversion as code:

  • A versioned pipeline: the Sigma source, the mapping pipeline, and the generated SPL all live in Git.
  • Automated re-conversion on every upstream update, not a one-off manual export.
  • A test suite that replays each rule against known logs to catch field-mapping regressions before production.

Without this, your catalog silently drifts from reality: some rules stay in Sigma format, never compiled; others point at a CIM field that was renamed six months ago.

If you don't want to maintain this pipeline yourself, the ThreatClaw rule feed publishes signed Sigma and YARA rules, delivered already converted for Splunk (SPL/CIM), Sentinel, Elastic, and QRadar. You get load-ready SPL, re-tested on every update, instead of re-running pySigma across thousands of files.

FAQ

Does pySigma support all Splunk fields?

No, and that's the key nuance. pySigma emits correct SPL, but field mapping depends entirely on the pipeline you choose. The splunk_windows pipeline covers CIM for common Windows logs (process creation, network, authentication). A Sigma field with no equivalent in the pipeline won't be mapped, you then have to extend the pipeline or add a custom mapping. No backend "guesses" your indexing schema for you.

Do you need Splunk Enterprise Security (ES)?

Not to run a converted SPL query, a base Splunk is enough to execute the search. However, the CIM pipeline assumes your data is normalized against the CIM data models, which is exactly the territory of ES and the Common Information Model app. Without CIM normalization, adapt the pipeline to your own field names, or your rules will look for fields that aren't there.

Can you convert to several SIEMs from the same Sigma source?

Yes, that's the whole point of Sigma. The same YAML rule compiles to SPL (Splunk), KQL (Sentinel), Lucene/EQL (Elastic), or AQL (QRadar) simply by switching the pySigma backend and pipeline. Field mapping remains target-specific, though: a rule validated for Splunk CIM must be re-tested against each other SIEM's schema.

Related articles