diff --git a/detection_rules/schemas/v7_11.py b/detection_rules/schemas/v7_11.py index 35792a0d033..7ee85c95cfa 100644 --- a/detection_rules/schemas/v7_11.py +++ b/detection_rules/schemas/v7_11.py @@ -39,16 +39,29 @@ def downgrade(cls, target_cls, document, role=None): """Remove 7.11 additions from the rule.""" # ignore when this method is inherited by subclasses if cls == ApiSchema711 and "threat" in document: - threat_field = list(document["threat"]) - for threat in threat_field: - if "technique" in threat: - threat["technique"] = [t.copy() for t in threat["technique"]] + v711_threats = document.get("threat", []) + v710_threats = [] - for technique in threat["technique"]: - technique.pop("subtechnique", None) + for threat in v711_threats: + # drop tactic without threat + if "technique" not in threat: + continue + + threat = threat.copy() + threat["technique"] = [t.copy() for t in threat["technique"]] + + # drop subtechniques + for technique in threat["technique"]: + technique.pop("subtechnique", None) + + v710_threats.append(threat) document = document.copy() - document["threat"] = threat_field + document.pop("threat") + + # only add if the array is not empty + if len(v710_threats) > 0: + document["threat"] = v710_threats # now strip any any unrecognized properties return target_cls.strip_additional_properties(document, role) diff --git a/tests/test_schemas.py b/tests/test_schemas.py index 64f0d52247e..3dbc060c0f0 100644 --- a/tests/test_schemas.py +++ b/tests/test_schemas.py @@ -53,6 +53,14 @@ def setUpClass(cls): "name": "PowerShell", "reference": "https://attack.mitre.org/techniques/T1059/001/" }] + cls.v711_kql["threat"].append({ + "framework": "MITRE ATT&CK", + "tactic": { + "id": "TA0008", + "name": "Lateral Movement", + "reference": "https://attack.mitre.org/tactics/TA0008/" + }, + }) cls.versioned_rule = Rule("test.toml", copy.deepcopy(cls.v79_kql)) cls.versioned_rule.contents["version"] = 10