Posted by:

David Greenwood

David Greenwood, Chief of Signal

If you are reading this blog post via a 3rd party source it is very likely that many parts of it will not render correctly. Please view the post on signalscorps.com for the full interactive viewing experience.

In this post I will explain why you might want to turn Sigma Rules into STIX Objects and show an example of how it could be done.

Sigma and STIX Patterning have goals that are related, but at the end of the day have slightly different scopes. While Sigma seeks to be “for log files what Snort is for network traffic and YARA is for files”, STIX Patterning’s goal is to encompass all three fundamental security data source types - network, file, and log - and do so simultaneously, allowing you to create complex queries and analytics that span domains.

As such, I have been advocating standardising on STIX Patterns for writing detection content recently. It is not perfect, but it has proven effective especially for teams already invested in representing threat intelligence as STIX 2.1 Objects (and I would argue that detection content is threat intel).

However, unlike Sigma, there is not too much detection content available that is written in STIX Patterns.

Given the flexible licensing of Sigma Rules, I decided to backfill my STIX Pattern Detection content by converting existing Sigma Rules to STIX Objects.

STIX Indicator SDOs and Sigma Patterns

The STIX 2.1 specification supports the pattern_type Sigma for Indicator SDOs. If this is selected the entire Sigma rule (all fields) should be printed in the pattern field.

Whilst this works well when the Indicator is consumed by a machine, when creating or reading rules in Indicator Objects by analysts it’s not very user friendly.

Here’s an example, look at the content in the pattern field;

The first step that needed to be figured out was how to programmatically convert Sigma to STIX.

Converting Sigma Rules to STIX Patterns

It is possible to convert Sigma Rules to STIX 2.1 Patterns using Sigmac which has a STIX target backend and 3 STIX specific configurations;

  1. STIX Shifter
  2. Custom STIX backend
  3. STIX 2.0 backend

All the backends contain a fair amount of custom fields (denoted with the prefix x-). For more generic rules (with common fields), the STIX Custom or STIX Shifter backend generally produce similar results.

There is definitely some work to be done, that I’d like to contribute to, to get these STIX backends to fully support STIX 2.1.

Running Sigmac (and installing if need be);

git clone https://github.com/SigmaHQ/sigma
cd sigma
python3 -m venv tutorial_env
source tutorial_env/bin/activate
pipenv install
cd tools
python3 sigmac -h

I can use the Custom STIX backend to convert an existing Sigma Rule into a STIX Pattern;

python3 sigmac --target stix --config stix-custom ../rules/windows/builtin/application/win_av_relevant_match.yml

Which returns;

[(((artifact:payload_bin LIKE 'Crack' AND artifact:payload_bin LIKE 'Keygen' AND artifact:payload_bin LIKE 'anti_ransomware_service.exe' AND artifact:payload_bin LIKE 'cyber-protect-service.exe')) AND (artifact:payload_bin LIKE '.WinCred.' OR artifact:payload_bin LIKE 'ASP/Backdoor' OR artifact:payload_bin LIKE 'ASPXSpy' OR artifact:payload_bin LIKE 'Backdoor.ASP' OR artifact:payload_bin LIKE 'Backdoor.JSP' OR artifact:payload_bin LIKE 'Backdoor.PHP' OR artifact:payload_bin LIKE 'COBEACON' OR artifact:payload_bin LIKE 'Chopper' OR artifact:payload_bin LIKE 'Clearlog' OR artifact:payload_bin LIKE 'CobaltStr' OR artifact:payload_bin LIKE 'Cometer' OR artifact:payload_bin LIKE 'DumpCreds' OR artifact:payload_bin LIKE 'Filecoder' OR artifact:payload_bin LIKE 'HTool-' OR artifact:payload_bin LIKE 'Hacktool' OR artifact:payload_bin LIKE 'JSP/Backdoor' OR artifact:payload_bin LIKE 'Keylogger' OR artifact:payload_bin LIKE 'Koadic' OR artifact:payload_bin LIKE 'Korplug' OR artifact:payload_bin LIKE 'MPreter' OR artifact:payload_bin LIKE 'MeteTool' OR artifact:payload_bin LIKE 'Mimikatz' OR artifact:payload_bin LIKE 'PHP/Backdoor' OR artifact:payload_bin LIKE 'PWCrack' OR artifact:payload_bin LIKE 'Packed.Generic.347' OR artifact:payload_bin LIKE 'PlugX' OR artifact:payload_bin LIKE 'Portscan' OR artifact:payload_bin LIKE 'Pwdump' OR artifact:payload_bin LIKE 'Ransom' OR artifact:payload_bin LIKE 'Webshell' OR artifact:payload_bin LIKE 'WmiExec' OR artifact:payload_bin LIKE 'Xscan'))]

Note, the backend still needs some work as not all rules can currently be converted. For example;

python3 sigmac --target stix --config stix-shifter ../rules/application/antivirus/av_exploiting.yml
An unsupported feature is required for this Sigma rule (../rules/application/antivirus/av_exploiting.yml): can only concatenate str (not "NoneType") to str

When the rule converts to a STIX pattern, the output is only the STIX pattern. This means a lot of context from the original Sigma Rule (e.g. name, description, etc.) is lost.

Creating STIX 2.1 SDOs from Sigma Rules

As such in addition to converting the rule from Sigma to STIX, I have started adding custom fields to any Indicator SDOs with STIX patterns derived from Sigma Rules.

Below is a first pass at a way to map a Sigma Rule to pure STIX 2.1 Objects using the stix Pattern Type;

{
    "type": "extension-definition",
    "spec_version": "2.1",
    "id": "extension-definition--c8ea5ecb-f4a3-45e7-94de-9b9ba05161af",
    "created_by_ref": "identity--<FILE2STIX ID>",
    "created": "2022-01-01T00:00:00.000Z",
    "modified": "2022-01-01T00:00:00.000Z",
    "name": "Sigma Rules",
    "description": "This schema adds Sigma Rules to Indicator Objects",
    "schema": "https://github.com/SigmaHQ/sigma",
    "version": "1.0",
    "extension_types": [
        "property-extension"
    ]
}

Which used in an Indicator SDO look as follows;

  {
    "type": "indicator",
    "spec_version": "2.1",
    "id": "indicator--<GENERATED BY STIX 2 LIBRARY>",
    "created_by_ref": "identity--<IDENTITY ID OF CREATOR>",
    "created": "<SIGMA RULE DATE FIELD>",
    "modified": "<SIGMA RULE MODIFIED FIELD>",
    "indicator_types": ["unknown"],
    "name": "Sigma Rule: <SIGMA RULE TITLE>",
    "description": "<SIGMA RULE DESCRIPTION>",
    "pattern": "<ENTIRE SIGMA RULE YAML WITH JSON ESCAPES>",
    "pattern_type": "sigma",
    "valid_from": "<SIGMA RULE DATE FIELD>",
    "external_references": [
      {
        "url": "<SIGMA RULE REFERENCES FIELD[0]>"
      }
    ],
    "object_marking_refs": [
      "<SIGMA RULE TAG TLP CONVERTED TO STIX MARKING DEFINITION ID>"
    ],
    "extensions": {
      "extension-definition--6ef7b8cf-0093-4992-b131-347299e07f4c": {
        "title": "<SIGMA RULE TITLE>",
        "id": "<SIGMA RULE ID>",
        "date": "<SIGMA RULE DATE>",
        "modified": "<SIGMA RULE MODIFIED>",
        "related": ["SIGMA RULE RELATED[0]"],
        "status": "<SIGMA RULE STATUS>",
        "description": "<SIGMA RULE DESCRIPTION>",
        "author": "<SIGMA RULE AUTHOR>",
        "references": ["<SIGMA RULE REFERENCE[0]>"],
        "fields": ["<SIGMA RULE FIELDS [0]>"],
        "falsepositives": ["<SIGMA RULE FALSEPOSITIVES [0]>"],
        "level": "<SIGMA RULE LEVEL>",
        "tags": ["<SIGMA RULE TAGS [0]>"],
        "logsource": {
          "category": "<SIGMA RULE LOGSOURCE.CATEGORY>",
          "product": "<SIGMA RULE LOGSOURCE.PRODUCT>",
          "service": "<SIGMA RULE LOGSOURCE.SERVICE>",
          "definition": "<SIGMA RULE LOGSOURCE.DEFINITION>"
        },
        "detection": {
          "<CUSTOM SEARCH IDENTIFIER>": {
            "<CUSTOM KEY>": "<CUSTOM VALUE>"
          },
          "condition": "<SIGMA RULE DETECTION.CONDITION>"
        }
      }
    }
  }

As noted in Part 1, the tags field can contain pre-defined MITRE ATT&CK tags and TLP tags, in addition to free-form tags, e.g.

tags:
  - tlp.amber
  - attack.execution # tactic
  - attack.t1203 # technique
  - attack.s0677 # software
  - attack.g0018 # group

In the case of TLP, these are mapped to the default STIX 2.1 Marking Definitions as follows

  • tlp.white = marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9
  • tlp.green = marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da
  • tlp.amber = marking-definition--f88d31f6-486f-44da-b317-01333bde0b82
  • tlp.red = marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed

These are then written into the Indicator SDOs object_marking_refs property.

In the case of ATT&CK the Enterprise, Mobile and ICS Matrices are used where;

  • Tactics are matched to x-mitre-tactic STIX 2.1 Objects name property
  • Technique are matched to attack-pattern STIX 2.1 Objects external_references.external_id property
  • Software are matched to tool STIX 2.1 Objects external_references.external_id property
  • Groups are matched to intrusion-set STIX 2.1 Objects external_references.external_id property

When an ATT&CK match is identified, the Object is added to a Relationship Object with the following structure;

        {
          "type": "relationship",
          "spec_version": "2.1",
          "id": "relationship--<GENERATED BY STIX 2 LIBRARY>",
          "created_by_ref": "identity--<IDENTITY ID OF CREATOR>",
          "created": "<SIGMA RULE DATE FIELD>",
          "modified": "<SIGMA RULE DATE FIELD>",
          "relationship_type": "indicates",
          "source_ref": "indicator--<INDICATOR SDO ID>",
          "target_ref": "<MITRE ATT&CK OBJECT ID>"
        }

To avoid any data loss, all fields in the SIGMA Rule YAML are captured in the Indicator SDOs extensions property.

Here is the Extension Definition Object:

      {
        "id": "extension-definition--6ef7b8cf-0093-4992-b131-347299e07f4c",
        "type": "extension-definition",
        "spec_version": "2.1",
        "name": "SIGMA Rule definition",
        "description": "This schema adds an entire SIGMA Rule parsed into JSON fields to an Object",
        "created": "2022-01-01T00:00:00.000Z",
        "modified": "2022-01-01T00:00:00.000Z",
        "version": "1.0",
        "schema": "https://github.com/SigmaHQ/sigma/wiki/Specification",
        "extension_types": [ "property-extension" ]
      }

Let me demonstrate with an example;

testrule1.yml:

title: Test name
id: aec48417-4c2e-43d2-af43-7f4e715c5733
status: test
description: A description
author: Someone
references:
  - https://www.example.com
  - https://www.example2.com
date: 2018/09/09
modified: 2022/05/12
logsource:
  category: antivirus
detection:
  selection:
    Signature|contains:
      - 'MeteTool'
      - 'MPreter'
      - 'Meterpreter'
  condition: selection
fields:
  - FileName
  - User
falsepositives:
  - Unlikely
level: critical
tags:
  - attack.execution
  - attack.t1203
  - tlp.green
  - tag1

And modelled in STIX 2.1:

Note how the pattern field contains the entire SIGMA Rule (which JSON escapes), the object_marking_refs references the standard TLP:GREEN STIX 2.1 Object (marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da), and the two Relationship Objects linking the Indicator SDO to the two MITRE ATT&CK Tactic (x-mitre-tactic--4ca45d45-df4d-4613-8980-bac22d278fa5) and Technique (attack-pattern--be2dcee9-a7a7-4e38-afd6-21b31ecc3d63) Objects.

Whilst STIX 2.1 Indicator SDOs support the pattern_type = sigma, it is not particularly elegant to shove a whole SIGMA Rule in this field.

Creating STIX 2.1 SDOs from Sigma Rules as STIX Patterns

Therefore, I also decided to create a copy of the SIGMA Rule. Where the pattern_type is STIX, and the pattern field contains the SIGMA Rule converted into a STIX pattern by Sigmac. I then link them together using an SRO with the relationship_type derived-from.

        {
          "type": "relationship",
          "spec_version": "2.1",
          "id": "relationship--<GENERATED BY STIX 2 LIBRARY>",
          "created_by_ref": "identity--<IDENTITY ID OF CREATOR>",
          "created": "<SIGMA RULE DATE FIELD>",
          "modified": "<SIGMA RULE DATE FIELD>",
          "relationship_type": "derived-from",
          "source_ref": "indicator--<STIX PATTERN INDICATOR SDO ID>",
          "target_ref": "indicator--<SIGMA PATTERN INDICATOR SDO ID>"
        }

First I convert the Rule to a STIX Pattern:

python3 sigmac --target stix --config stix-custom testrule1.yml

Which gives the pattern;

[(x-windows:signature LIKE '%MeteTool%' OR x-windows:signature LIKE '%MPreter%' OR x-windows:signature LIKE '%Meterpreter%')]

Modelled in STIX 2.1 this looks as follows;

But no downstream detection tools support STIX 2.1…

Yes. I agree.

The main reason I am using STIX 2.1 Patterns/Objects is because they offer a scalable way to create, manage and collaborate on them using existing tooling (e.g TIPs). However, I am well aware it does not solve the operational problem of executing the rules on SIEM, EDR, XDR tools.

In my Sigma tutorial series I showed how Sigma Rules could be converted into target backend formats (e.g. Splunk Rules) using Sigmac or pySigma.

A similar tool exists for STIX which solves the same problem (and a does bit more). It is called STIX Shifter and I will show you how to use in the next post.




Discuss this post


Signals Corps Slack

Never miss an update


Sign up to receive new articles in your inbox as they published.