diff --git a/.github/workflows/sigma-validation.yml b/.github/workflows/sigma-validation.yml new file mode 100644 index 000000000..b7e8be086 --- /dev/null +++ b/.github/workflows/sigma-validation.yml @@ -0,0 +1,25 @@ +name: Validate Sigma rules + +on: + push: + branches: + - "*" + pull_request: + branches: + - master + +jobs: + validate-sigma-rules: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Set up Python 3.10 + uses: actions/setup-python@v3 + with: + python-version: "3.10" + - name: Install dependencies + run: pip install check-jsonschema + - name: Validate Sigma rules + run: tests/validate-sigma-schema/validate.sh diff --git a/rules-emerging-threats/2021/Malware/Pingback/proc_creation_win_malware_pingback_backdoor.yml b/rules-emerging-threats/2021/Malware/Pingback/proc_creation_win_malware_pingback_backdoor.yml index 172309163..f928d1f1c 100644 --- a/rules-emerging-threats/2021/Malware/Pingback/proc_creation_win_malware_pingback_backdoor.yml +++ b/rules-emerging-threats/2021/Malware/Pingback/proc_creation_win_malware_pingback_backdoor.yml @@ -3,7 +3,7 @@ id: b2400ffb-7680-47c0-b08a-098a7de7e7a9 related: - id: 35a7dc42-bc6f-46e0-9f83-81f8e56c8d4b # DLL Load type: similar - - id: 2bd63d53-84d4-4210-80ff-bf0658f1bf789 # File Indicators + - id: 2bd63d53-84d4-4210-80ff-bf0658f1bf78 # File Indicators type: similar status: test description: Detects the use of Pingback backdoor that creates ICMP tunnel for C2 as described in the trustwave report diff --git a/rules/windows/file/file_event/file_event_win_winrm_awl_bypass.yml b/rules/windows/file/file_event/file_event_win_winrm_awl_bypass.yml index c6180f208..a6d2cf763 100644 --- a/rules/windows/file/file_event/file_event_win_winrm_awl_bypass.yml +++ b/rules/windows/file/file_event/file_event_win_winrm_awl_bypass.yml @@ -1,7 +1,7 @@ title: AWL Bypass with Winrm.vbs and Malicious WsmPty.xsl/WsmTxt.xsl - File id: d353dac0-1b41-46c2-820c-d7d2561fc6ed related: - - id: 074e0ded-6ced-4ebd-8b4d-53f55908119 + - id: 074e0ded-6ced-4ebd-8b4d-53f55908119d type: derived status: test description: Detects execution of attacker-controlled WsmPty.xsl or WsmTxt.xsl via winrm.vbs and copied cscript.exe (can be renamed) diff --git a/tests/validate-sigma-schema/sigma-schema.json b/tests/validate-sigma-schema/sigma-schema.json new file mode 100644 index 000000000..aab23dd89 --- /dev/null +++ b/tests/validate-sigma-schema/sigma-schema.json @@ -0,0 +1,227 @@ +{ + "title": "Sigma rule specification V1.0.4 (2023/06/29)", + "type": "object", + "required": ["title", "logsource", "detection"], + "properties": { + "title": { + "type": "string", + "maxLength": 256, + "description": "A brief title for the rule that should contain what the rules is supposed to detect" + }, + "id": { + "type": "string", + "description": "A globally unique identifier for the Sigma rule. This is recommended to be a UUID v4, but not mandatory.", + "format": "uuid" + }, + "related": { + "type": "array", + "description": "A list of related Sigma rules to keep track of the relationships between detections. This can be used to indicate that a rule is derived from another rule, or that a rule has been obsoleted by another rule.", + "items": { + "type": "object", + "required": ["id", "type"], + "properties": { + "id": { + "type": "string", + "description": "A globally unique identifier for the Sigma rule. This is recommended to be a UUID v4, but not mandatory.", + "format": "uuid" + }, + "type": { + "type": "string", + "oneOf": [ + { + "const": "derived", + "description": "The rule was derived from the referred rule or rules, which may remain active" + }, + { + "const": "obsoletes", + "description": "The rule obsoletes the referred rule or rules, which aren't used anymore" + }, + { + "const": "merged", + "description": "The rule was merged from the referred rules. The rules may be still existing and in use" + }, + { + "const": "renamed", + "description": "The rule had previously the referred identifier or identifiers but was renamed for whatever reason, e.g. from a private naming scheme to UUIDs, to resolve collisions etc. It's not expected that a rule with this id exists anymore" + }, + { + "const": "similar", + "description": "TUse to relate similar rules to each other (e.g. same detection content applied to different log sources, rule that is a modified version of another rule with a different level)" + } + ] + } + } + } + }, + "status": { + "type": "string", + "oneOf": [ + { + "const": "stable", + "description": "The rule didn't produce any obvious false positives in multiple environments over a long period of time" + }, + { + "const": "test", + "description": "The rule doesn't show any obvious false positives on a limited set of test systems" + }, + { + "const": "experimental", + "description": "A new rule that hasn't been tested outside of lab environments and could lead to many false positives" + }, + { + "const": "deprecated", + "description": "The rule is to replace or cover another one. The link between both rules is made via the `related` field" + }, + { + "const": "unsupported", + "description": "The rule can not be used in its current state (special correlation log, home-made fields...etc.)" + } + ] + }, + "description": { + "type": "string", + "description": "A short description of the rule and the malicious activity that can be detected", + "maxLength": 65535 + }, + "license": { + "type": "string", + "description": "License of the rule according the SPDX ID specification (https://spdx.dev/ids/)" + }, + "author": { + "type": "string", + "description": "Creator of the rule. (can be a name, nickname, twitter handle, etc.)" + }, + "references": { + "type": "array", + "description": "References to the source that the rule was derived from. These could be blog articles, technical papers, presentations or even tweets", + "items": { + "type": "string" + } + }, + "date": { + "type": "string", + "description": "Creation date of the rule. Use the format YYYY/MM/DD", + "pattern": "^\\d{4}/(0[1-9]|1[012])/(0[1-9]|[12][0-9]|3[01])$" + }, + "modified": { + "type": "string", + "description": "Last modification date of the rule. Use the format YYYY/MM/DD", + "pattern": "^\\d{4}/(0[1-9]|1[012])/(0[1-9]|[12][0-9]|3[01])$" + }, + "logsource": { + "type": "object", + "description": "The log source that the rule is supposed to detect malicious activity in.", + "items": { + "type": "string" + } + }, + "detection": { + "type": "object", + "required": ["condition"], + "description": "A set of search-identifiers that represent properties of searches on log data", + "additionalProperties": { + "anyOf": [ + { + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + }, + { + "type": "object", + "items": { + "type": "string" + } + } + ] + } + }, + { + "type": "object", + "items": { + "type": "string" + } + } + ] + }, + "properties": { + "condition": { + "anyOf": [ + { + "type": "string", + "description": "A search condition that is applied to the log data. The following format must be used: fieldname : value" + }, + { + "type": "array", + "items": { + "type": "string", + "minLength": 2 + } + } + ], + "description": "A set of search-identifiers that represent properties of searches on log data" + } + } + }, + "fields": { + "type": "array", + "description": "A list of log fields that could be interesting in further analysis of the event and should be displayed to the analyst", + "items": { + "type": "string" + } + }, + "falsepositives": { + "description": "A list of known false positives that may occur", + "anyOf": [ + { + "type": "string", + "minLength": 2 + }, + { + "type": "array", + "items": { + "type": "string", + "minLength": 2 + } + } + ] + }, + "level": { + "type": "string", + "description": "The criticality of a triggered rule", + "oneOf": [ + { + "const": "informational", + "description": "Rule is intended for enrichment of events, e.g. by tagging them. No case or alerting should be triggered by such rules because it is expected that a huge amount of events will match these rules" + }, + { + "const": "low", + "description": "Notable event but rarely an incident. Low rated events can be relevant in high numbers or combination with others. Immediate reaction shouldn't be necessary, but a regular review is recommended" + }, + { + "const": "medium", + "description": "Relevant event that should be reviewed manually on a more frequent basis" + }, + { + "const": "high", + "description": "Relevant event that should trigger an internal alert and requires a prompt review" + }, + { + "const": "critical", + "description": "Highly relevant event that indicates an incident. Critical events should be reviewed immediately. It is used only for cases in which probability borders certainty" + } + ] + }, + "tags": { + "type": "array", + "items": { + "type": "string", + "pattern": "^[a-z0-9_.-]+$" + } + } + } +} diff --git a/tests/validate-sigma-schema/validate.sh b/tests/validate-sigma-schema/validate.sh new file mode 100755 index 000000000..fc12c024b --- /dev/null +++ b/tests/validate-sigma-schema/validate.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +# Check if the check-jsonschema tool is installed +if ! command -v check-jsonschema &> /dev/null +then + echo "check-jsonschema could not be found" + echo "Please install it from PyPI using:" + echo "pip install check-jsonschema" + exit +fi + +# Validate all the Sigma rules in the current directory +echo "Validating Sigma rules against sigma-schema.json" +check-jsonschema --schemafile tests/validate-sigma-schema/sigma-schema.json $(find ./rules ./rules-compliance ./rules-dfir ./rules-emerging-threats ./rules-placeholder ./rules-threat-hunting -type f -name "*.yml")