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 (usually, the interactive graphs). Please view the post on dogesec.com for the full interactive viewing experience.

tl;dr

In this post I walk you through the database queries we use to compare Sigma Rules releases. We use these to identify the detail of what has changed before we push any updates internally.

Overview

As I’ve mentioned numerous times before, our intelligence team considers the authoring of detection rules a key deliverable of any research.

We write all our rules in Sigma so that they can be easily translated into other detection languages see SIEM Rules.

In writing our own rules, we take inspiration from other sources, including the core public Sigma ruleset here.

The Sigma team regularly publish updated releases with new rules and enhancements to the existing ruleset. Kudos to the Sigma team for their detailed changelog with each release.

However, to really understand the changes, we like to delve into each updated release more deeply alongside the changelog. In this post I will show you how we did this for the most recent release (r2024-11-10), should this also be useful for your workflows.

Follow along

In this post I am going to provide ArangoDB queries you can use to analyse and filter Sigma Rules data (represented as STIX objects).

If you would like to follow along, and keep a searchable copy of Sigma STIX objects locally, you can import the data using stix2arango.

Once you’ve installed stix2arango, you can run the following command to import all versions of Sigma that are available at the time of writing (r2023-08-24 - r2024-11-10)

python3 utilities/arango_cti_processor/insert_archive_sigma_rules.py \
    --database blog_demo \
    --ignore_embedded_relationships True

Sigma Rule releases over time

FOR doc IN mitre_cwe_vertex_collection
  FILTER doc._stix2arango_note != "automatically imported on collection creation"
  COLLECT note = doc._stix2arango_note WITH COUNT INTO count
  LET release = SUBSTRING(note, 1) // Remove "v" prefix
  SORT TO_NUMBER(SPLIT(release, ".")[0]) ASC, TO_NUMBER(SPLIT(release, ".")[1]) ASC
  RETURN { release: release, count: count }

Count of Sigma Rules by release

Since v2023-08-24 (released about 1.25 years ago), there are 469 more rules in the latest version v2024-11-10.

Changes between version v2024-11-10 and v2024-09-02

LET version1Docs = (
  FOR doc IN sigma_rules_vertex_collection
  FILTER doc._stix2arango_note == "v2024-11-10"
  AND doc.type == "indicator"
  RETURN { id: doc.id, modified: doc.modified }
)

LET version2Docs = (
  FOR doc IN sigma_rules_vertex_collection
  FILTER doc._stix2arango_note == "v2024-09-02"
  AND doc.type == "indicator"
  RETURN { id: doc.id, modified: doc.modified }
)

LET version1IDs = (FOR v IN version1Docs RETURN v.id)
LET version2IDs = (FOR v IN version2Docs RETURN v.id)

LET added = (
  FOR v1 IN version1Docs
  FILTER v1.id NOT IN version2IDs
  RETURN v1
)

LET removed = (
  FOR v2 IN version2Docs
  FILTER v2.id NOT IN version1IDs
  RETURN v2
)

LET unchanged = (
  FOR v2 IN version2Docs
  FILTER v2.id IN version1IDs
  LET v1 = FIRST(FOR v1Doc IN version1Docs FILTER v1Doc.id == v2.id RETURN v1Doc)
  FILTER v1.modified == v2.modified // Same ID and modified time
  RETURN v2
)

LET modified = (
  FOR v2 IN version2Docs
  FILTER v2.id IN version1IDs
  LET v1 = FIRST(FOR v1Doc IN version1Docs FILTER v1Doc.id == v2.id RETURN v1Doc)
  FILTER v1.modified != v2.modified // Same ID but different modified time
  RETURN v2
)

RETURN {
  added: LENGTH(added),
  removed: LENGTH(removed),
  unchanged: LENGTH(unchanged),
  modified: LENGTH(modified)
}

Sigma Rules changes in version v2024-11-10 vs v2024-09-02

Most of the rules remain unchanged (3183), 17 were added, and 38 modified. Let’s take a closer look at those added and modified…

New objects in v2024-11-10 compared to v2024-09-02

This query returns all the new objects in v2024-11-10;

LET groupings = (
  FOR doc IN sigma_rules_vertex_collection
  FILTER doc._stix2arango_note == "v2024-11-10"
  AND doc.type == "grouping"
  RETURN { name: doc.name, object_refs: doc.object_refs }
)

LET version1Docs = (
  FOR doc IN sigma_rules_vertex_collection
  FILTER doc._stix2arango_note == "v2024-11-10"
  AND doc.type == "indicator"
  RETURN { id: doc.id, name: doc.name, description: doc.description, created: doc.created, modified: doc.modified }
)

LET version2IDs = (
  FOR doc IN sigma_rules_vertex_collection
  FILTER doc._stix2arango_note == "v2024-09-02"
  AND doc.type == "indicator"
  RETURN doc.id
)

LET newItems = (
  FOR v1 IN version1Docs
  FILTER v1.id NOT IN version2IDs
  LET grouping_name = FIRST(
    FOR grouping IN groupings
    FILTER v1.id IN grouping.object_refs
    RETURN grouping.name
  )
  RETURN MERGE(v1, { state: "added", grouping_name })
)

RETURN (
  FOR item IN newItems
  SORT item.name ASC
  RETURN {
    id: item.id,
    name: item.name,
    grouping: item.grouping_name
  }
)
name grouping
.RDP File Created by Outlook Process rules/windows/file/file_event
Access To Browser Credential Files By Uncommon Applications - Security rules-threat-hunting/windows/builtin/security
Command Executed Via Run Dialog Box - Registry rules-threat-hunting/windows/registry/registry_set
ETW Logging/Processing Option Disabled On IIS Server rules/windows/builtin/iis-configuration
Group Policy Abuse for Privilege Addition rules/windows/builtin/security
HTTP Logging Disabled On IIS Server rules/windows/builtin/iis-configuration
Network Connection Initiated To BTunnels Domains rules/windows/network_connection
New Module Module Added To IIS Server rules/windows/builtin/iis-configuration
Potential Python DLL SideLoading rules/windows/image_load
Potentially Suspicious Command Executed Via Run Dialog Box - Registry rules/windows/registry/registry_set
PowerShell Web Access Feature Enabled Via DISM rules/windows/process_creation
PowerShell Web Access Installation - PsScript rules/windows/powershell/powershell_script
Previously Installed IIS Module Was Removed rules/windows/builtin/iis-configuration
Process Deletion of Its Own Executable rules/windows/file/file_delete
Remote Access Tool - MeshAgent Command Execution via MeshCentral rules/windows/process_creation
Scheduled Task Deletion rules-threat-hunting/windows/builtin/security
Startup/Logon Script Added to Group Policy Object rules/windows/builtin/security

Note: for easier reading, I’ve removed the ID of the rules returned by the search from the table above.

Modified objects in v2024-11-10 compared to v2024-09-02

This query returns all the modified objects in v2024-11-10;

LET groupings = (
  FOR doc IN sigma_rules_vertex_collection
  FILTER doc._stix2arango_note == "v2024-11-10"
  AND doc.type == "grouping"
  RETURN { name: doc.name, object_refs: doc.object_refs }
)

LET version1Docs = (
  FOR doc IN sigma_rules_vertex_collection
  FILTER doc._stix2arango_note == "v2024-11-10"
  AND doc.type == "indicator"
  RETURN { id: doc.id, modified: doc.modified, created: doc.created, name: doc.name, description: doc.description }
)

LET version2Docs = (
  FOR doc IN sigma_rules_vertex_collection
  FILTER doc._stix2arango_note == "v2024-09-02"
  AND doc.type == "indicator"
  RETURN { id: doc.id, modified: doc.modified, created: doc.created, name: doc.name, description: doc.description }
)

LET version1IDs = (FOR v IN version1Docs RETURN v.id)

LET modified = (
  FOR v2 IN version2Docs
  FILTER v2.id IN version1IDs
  LET v1 = FIRST(FOR v1Doc IN version1Docs FILTER v1Doc.id == v2.id RETURN v1Doc)
  FILTER v1.modified != v2.modified // Same ID but different modified time
  LET grouping_name = FIRST(
    FOR grouping IN groupings
    FILTER v2.id IN grouping.object_refs
    RETURN grouping.name
  )
  RETURN MERGE(v2, { state: "modified", grouping_name })
)

RETURN (
  FOR item IN modified
  SORT item.name ASC
  RETURN {
    id: item.id,
    name: item.name,
    grouping: item.grouping_name
  }
)
name grouping
Alternate PowerShell Hosts Pipe rules/windows/pipe_created
Antivirus Exploitation Framework Detection rules/category/antivirus
Antivirus Hacktool Detection rules/category/antivirus
Antivirus Password Dumper Detection rules/category/antivirus
Antivirus Ransomware Detection rules/category/antivirus
Antivirus Relevant File Paths Alerts rules/category/antivirus
Antivirus Web Shell Detection rules/category/antivirus
BITS Transfer Job Download From File Sharing Domains rules/windows/builtin/bits_client
CodeIntegrity - Unmet Signing Level Requirements By File Under Validation rules/windows/builtin/code_integrity
COM Object Hijacking Via Modification Of Default System CLSID Default Value rules/windows/registry/registry_set
Disable Windows Defender Functionalities Via Registry Keys rules/windows/registry/registry_set
DNS Query To Remote Access Software Domain From Non-Browser App rules/windows/dns_query
HackTool - Certipy Execution rules/windows/process_creation
Linux HackTool Execution rules/linux/process_creation
Linux Network Service Scanning Tools Execution rules/linux/process_creation
Local System Accounts Discovery - Linux rules/linux/process_creation
LSASS Process Memory Dump Files rules/windows/file/file_event
Network Communication Initiated To File Sharing Domains From Process Located In Suspicious Folder rules/windows/network_connection
New Connection Initiated To Potential Dead Drop Resolver Domain rules/windows/network_connection
Persistence and Execution at Scale via GPO Scheduled Task rules/windows/builtin/security
Potential CommandLine Obfuscation Using Unicode Characters rules-threat-hunting/windows/process_creation
Potential CommandLine Obfuscation Using Unicode Characters From Suspicious Image rules/windows/process_creation
Potential Python Reverse Shell rules/linux/process_creation
Potentially Suspicious File Download From File Sharing Domain Via PowerShell.EXE rules/windows/process_creation
Powershell Exfiltration Over SMTP rules-threat-hunting/windows/powershell/powershell_script
Process Terminated Via Taskkill rules-threat-hunting/windows/process_creation
Python Spawning Pretty TTY rules/linux/process_creation
RDP File Creation From Suspicious Application rules/windows/file/file_event
Renamed Powershell Under Powershell Channel rules/windows/powershell/powershell_classic
Suspicious File Download From File Sharing Domain Via Curl.EXE rules/windows/process_creation
Suspicious File Download From File Sharing Domain Via Wget.EXE rules/windows/process_creation
Suspicious File Download From File Sharing Websites - File Stream rules/windows/create_stream_hash
Suspicious Non PowerShell WSMAN COM Provider rules/windows/powershell/powershell_classic
Suspicious Office Token Search Via CLI rules/windows/process_creation
Suspicious Schtasks From Env Var Folder rules/windows/process_creation
Suspicious Windows Service Tampering rules/windows/process_creation
UNC2452 Process Creation Patterns rules-emerging-threats/2020/TA/SolarWinds-Supply-Chain
Unusual File Download From File Sharing Websites - File Stream rules/windows/create_stream_hash

Note: for easier reading, I’ve removed the ID of the rules returned by the search from the table above.

Looking more deeply at modified objects in v2024-11-10

I can also programmatically compare the changes to specific rules between versions using the IDs of the objects. This is what we use to analyse the updated objects before updating our rulesets.

Here I analyse the updates to indicator--61e988d6-6bb4-5dc4-8e0e-2cc900ca9d62 (Alternate PowerShell Hosts Pipe) between versions;

LET specificId = "indicator--61e988d6-6bb4-5dc4-8e0e-2cc900ca9d62"

LET version1Doc = (
  FOR doc IN sigma_rules_vertex_collection
  FILTER doc._stix2arango_note == "v2024-11-10"
  AND doc.type == "indicator"
  AND doc.id == specificId
  RETURN doc
)[0]

LET version2Doc = (
  FOR doc IN sigma_rules_vertex_collection
  FILTER doc._stix2arango_note == "v2024-09-02"
  AND doc.type == "indicator"
  AND doc.id == specificId
  RETURN doc
)[0]

LET changes = (
  FOR key IN ATTRIBUTES(version1Doc)
  FILTER !STARTS_WITH(key, "_") // Exclude keys starting with "_"
  AND version1Doc[key] != version2Doc[key]
  RETURN { field: key, old_value: version2Doc[key], new_value: version1Doc[key] }
)

RETURN {
  id: specificId,
  name: version1Doc.name,
  grouping: FIRST(
    FOR grouping IN sigma_rules_vertex_collection
    FILTER grouping._stix2arango_note == "v2024-11-10"
    AND grouping.type == "grouping"
    AND specificId IN grouping.object_refs
    RETURN grouping.name
  ),
  changes
}
[
  {
    "id": "indicator--61e988d6-6bb4-5dc4-8e0e-2cc900ca9d62",
    "name": "Alternate PowerShell Hosts Pipe",
    "grouping": "rules/windows/pipe_created",
    "changes": [
      {
        "field": "pattern",
        "old_value": "{'title': 'Alternate PowerShell Hosts Pipe', 'id': '58cb02d5-78ce-4692-b3e1-dce850aae41a', 'related': [{'id': 'ac7102b4-9e1e-4802-9b4f-17c5524c015c', 'type': 'derived'}], 'status': 'test', 'description': 'Detects alternate PowerShell hosts potentially bypassing detections looking for powershell.exe', 'references': ['https://threathunterplaybook.com/hunts/windows/190610-PwshAlternateHosts/notebook.html', 'https://threathunterplaybook.com/hunts/windows/190410-LocalPwshExecution/notebook.html'], 'author': 'Roberto Rodriguez @Cyb3rWard0g, Tim Shelton', 'date': datetime.date(2019, 9, 12), 'modified': datetime.date(2023, 10, 18), 'tags': ['attack.execution', 'attack.t1059.001'], 'logsource': {'product': 'windows', 'category': 'pipe_created', 'definition': 'Note that you have to configure logging for Named Pipe Events in Sysmon config (Event ID 17 and Event ID 18). The basic configuration is in popular sysmon configuration (https://github.com/SwiftOnSecurity/sysmon-config), but it is worth verifying. You can also use other repo, e.g. https://github.com/Neo23x0/sysmon-config, https://github.com/olafhartong/sysmon-modular. How to test detection? You can check powershell script from this site https://svch0st.medium.com/guide-to-named-pipes-and-hunting-for-cobalt-strike-pipes-dc46b2c5f575'}, 'detection': {'selection': {'PipeName|startswith': '\\\\PSHost'}, 'filter_main_generic': {'Image|contains': [':\\\\Program Files\\\\PowerShell\\\\7-preview\\\\pwsh.exe', ':\\\\Program Files\\\\PowerShell\\\\7\\\\pwsh.exe', ':\\\\Windows\\\\system32\\\\dsac.exe', ':\\\\Windows\\\\system32\\\\inetsrv\\\\w3wp.exe', ':\\\\Windows\\\\System32\\\\sdiagnhost.exe', ':\\\\Windows\\\\system32\\\\ServerManager.exe', ':\\\\Windows\\\\system32\\\\wbem\\\\wmiprvse.exe', ':\\\\Windows\\\\System32\\\\WindowsPowerShell\\\\v1.0\\\\powershell_ise.exe', ':\\\\Windows\\\\System32\\\\WindowsPowerShell\\\\v1.0\\\\powershell.exe', ':\\\\Windows\\\\System32\\\\wsmprovhost.exe', ':\\\\Windows\\\\SysWOW64\\\\WindowsPowerShell\\\\v1.0\\\\powershell_ise.exe', ':\\\\Windows\\\\SysWOW64\\\\WindowsPowerShell\\\\v1.0\\\\powershell.exe']}, 'filter_main_sqlserver': {'Image|contains|all': [':\\\\Program Files', '\\\\Microsoft SQL Server\\\\'], 'Image|endswith': '\\\\Tools\\\\Binn\\\\SQLPS.exe'}, 'filter_optional_citrix': {'Image|contains': ':\\\\Program Files\\\\Citrix\\\\'}, 'filter_optional_exchange': {'Image|contains': ':\\\\Program Files\\\\Microsoft\\\\Exchange Server\\\\'}, 'filter_main_null': {'Image': None}, 'condition': 'selection and not 1 of filter_main_* and not 1 of filter_optional_*'}, 'falsepositives': ['Programs using PowerShell directly without invocation of a dedicated interpreter.'], 'level': 'medium'}",
        "new_value": "{'title': 'Alternate PowerShell Hosts Pipe', 'id': '58cb02d5-78ce-4692-b3e1-dce850aae41a', 'related': [{'id': 'ac7102b4-9e1e-4802-9b4f-17c5524c015c', 'type': 'derived'}], 'status': 'test', 'description': 'Detects alternate PowerShell hosts potentially bypassing detections looking for powershell.exe', 'references': ['https://threathunterplaybook.com/hunts/windows/190610-PwshAlternateHosts/notebook.html', 'https://threathunterplaybook.com/hunts/windows/190410-LocalPwshExecution/notebook.html'], 'author': 'Roberto Rodriguez @Cyb3rWard0g, Tim Shelton', 'date': datetime.date(2019, 9, 12), 'modified': datetime.date(2024, 10, 7), 'tags': ['attack.execution', 'attack.t1059.001'], 'logsource': {'product': 'windows', 'category': 'pipe_created', 'definition': 'Note that you have to configure logging for Named Pipe Events in Sysmon config (Event ID 17 and Event ID 18). The basic configuration is in popular sysmon configuration (https://github.com/SwiftOnSecurity/sysmon-config), but it is worth verifying. You can also use other repo, e.g. https://github.com/Neo23x0/sysmon-config, https://github.com/olafhartong/sysmon-modular. How to test detection? You can check powershell script from this site https://svch0st.medium.com/guide-to-named-pipes-and-hunting-for-cobalt-strike-pipes-dc46b2c5f575'}, 'detection': {'selection': {'PipeName|startswith': '\\\\PSHost'}, 'filter_main_generic': {'Image|contains': [':\\\\Program Files\\\\PowerShell\\\\7-preview\\\\pwsh.exe', ':\\\\Program Files\\\\PowerShell\\\\7\\\\pwsh.exe', ':\\\\Windows\\\\system32\\\\dsac.exe', ':\\\\Windows\\\\system32\\\\inetsrv\\\\w3wp.exe', ':\\\\Windows\\\\System32\\\\sdiagnhost.exe', ':\\\\Windows\\\\system32\\\\ServerManager.exe', ':\\\\Windows\\\\system32\\\\wbem\\\\wmiprvse.exe', ':\\\\Windows\\\\System32\\\\WindowsPowerShell\\\\v1.0\\\\powershell_ise.exe', ':\\\\Windows\\\\System32\\\\WindowsPowerShell\\\\v1.0\\\\powershell.exe', ':\\\\Windows\\\\System32\\\\wsmprovhost.exe', ':\\\\Windows\\\\SysWOW64\\\\WindowsPowerShell\\\\v1.0\\\\powershell_ise.exe', ':\\\\Windows\\\\SysWOW64\\\\WindowsPowerShell\\\\v1.0\\\\powershell.exe']}, 'filter_optional_sqlserver': {'Image|startswith': ['C:\\\\Program Files (x86)\\\\', 'C:\\\\Program Files\\\\'], 'Image|contains': '\\\\Microsoft SQL Server\\\\', 'Image|endswith': '\\\\Tools\\\\Binn\\\\SQLPS.exe'}, 'filter_optional_azure_connected_machine_agent': {'Image|startswith': 'C:\\\\Program Files\\\\AzureConnectedMachineAgent\\\\GCArcService', 'Image|endswith': '\\\\GC\\\\gc_worker.exe'}, 'filter_optional_citrix': {'Image|startswith': 'C:\\\\Program Files\\\\Citrix\\\\'}, 'filter_optional_exchange': {'Image|startswith': 'C:\\\\Program Files\\\\Microsoft\\\\Exchange Server\\\\'}, 'filter_main_null': {'Image': None}, 'condition': 'selection and not 1 of filter_main_* and not 1 of filter_optional_*'}, 'falsepositives': ['Programs using PowerShell directly without invocation of a dedicated interpreter.'], 'level': 'medium'}"
      },
      {
        "field": "modified",
        "old_value": "2023-10-18T00:00:00.000Z",
        "new_value": "2024-10-07T00:00:00.000Z"
      }
    ]
  }
]

Here, the big change is an update to the detection;

'detection': {'selection': {'PipeName|startswith': '\\\\PSHost'}, 'filter_main_generic': {'Image|contains': [':\\\\Program Files\\\\PowerShell\\\\7-preview\\\\pwsh.exe', ':\\\\Program Files\\\\PowerShell\\\\7\\\\pwsh.exe', ':\\\\Windows\\\\system32\\\\dsac.exe', ':\\\\Windows\\\\system32\\\\inetsrv\\\\w3wp.exe', ':\\\\Windows\\\\System32\\\\sdiagnhost.exe', ':\\\\Windows\\\\system32\\\\ServerManager.exe', ':\\\\Windows\\\\system32\\\\wbem\\\\wmiprvse.exe', ':\\\\Windows\\\\System32\\\\WindowsPowerShell\\\\v1.0\\\\powershell_ise.exe', ':\\\\Windows\\\\System32\\\\WindowsPowerShell\\\\v1.0\\\\powershell.exe', ':\\\\Windows\\\\System32\\\\wsmprovhost.exe', ':\\\\Windows\\\\SysWOW64\\\\WindowsPowerShell\\\\v1.0\\\\powershell_ise.exe', ':\\\\Windows\\\\SysWOW64\\\\WindowsPowerShell\\\\v1.0\\\\powershell.exe']}, 'filter_optional_sqlserver': {'Image|startswith': ['C:\\\\Program Files (x86)\\\\', 'C:\\\\Program Files\\\\'], 'Image|contains': '\\\\Microsoft SQL Server\\\\', 'Image|endswith': '\\\\Tools\\\\Binn\\\\SQLPS.exe'}, 'filter_optional_azure_connected_machine_agent': {'Image|startswith': 'C:\\\\Program Files\\\\AzureConnectedMachineAgent\\\\GCArcService', 'Image|endswith': '\\\\GC\\\\gc_worker.exe'}, 'filter_optional_citrix': {'Image|startswith': 'C:\\\\Program Files\\\\Citrix\\\\'}, 'filter_optional_exchange': {'Image|startswith': 'C:\\\\Program Files\\\\Microsoft\\\\Exchange Server\\\\'}
'detection': {'selection': {'PipeName|startswith': '\\\\PSHost'}, 'filter_main_generic': {'Image|contains': [':\\\\Program Files\\\\PowerShell\\\\7-preview\\\\pwsh.exe', ':\\\\Program Files\\\\PowerShell\\\\7\\\\pwsh.exe', ':\\\\Windows\\\\system32\\\\dsac.exe', ':\\\\Windows\\\\system32\\\\inetsrv\\\\w3wp.exe', ':\\\\Windows\\\\System32\\\\sdiagnhost.exe', ':\\\\Windows\\\\system32\\\\ServerManager.exe', ':\\\\Windows\\\\system32\\\\wbem\\\\wmiprvse.exe', ':\\\\Windows\\\\System32\\\\WindowsPowerShell\\\\v1.0\\\\powershell_ise.exe', ':\\\\Windows\\\\System32\\\\WindowsPowerShell\\\\v1.0\\\\powershell.exe', ':\\\\Windows\\\\System32\\\\wsmprovhost.exe', ':\\\\Windows\\\\SysWOW64\\\\WindowsPowerShell\\\\v1.0\\\\powershell_ise.exe', ':\\\\Windows\\\\SysWOW64\\\\WindowsPowerShell\\\\v1.0\\\\powershell.exe']}

SIEM Rules

Your detection engineering AI assistant. Turn cyber threat intelligence research into highly-tuned detection rules.

SIEM Rules. Your detection engineering database.

Discuss this post

Head on over to the DOGESEC community to discuss this post.

DOGESEC community

Posted by:

David Greenwood

David Greenwood, Do Only Good Everyday



Never miss an update


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

Your subscription could not be saved. Please try again.
Your subscription has been successful.