Skip to content

Commit

Permalink
Merge pull request #554 from Yamato-Security/552-fix-add-check-for-in…
Browse files Browse the repository at this point in the history
…compatible-modifier

fix: add check for incompatible modifier
  • Loading branch information
YamatoSecurity authored Dec 19, 2023
2 parents 1929efd + 5a84ede commit bd1fe11
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 153 deletions.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

7 changes: 6 additions & 1 deletion tools/sigmac/logsource_mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ def is_detectable(self, obj: dict) -> bool:
"""
process_creation/registry_xxルールののSysmon/Securityイベント用変換後フィールドの妥当性チェック
"""
if self.category != "process_creation" and self.category != "registry_set" and self.category != "registry_add" and self.category != "registry_event" and self.category == "registry_delete" :
if self.category != "process_creation" and self.category != "registry_set" and self.category != "registry_add" and self.category != "registry_event" and self.category != "registry_delete" :
return True
for key in obj.keys():
if key in ["condition", "process_creation", "timeframe", "registry_set", "registry_add", "registry_event", "registry_delete"]:
Expand Down Expand Up @@ -264,6 +264,11 @@ def convert(self):
logsourceのcategory/serviceをlogsource_mapに基づき変換し、変換後の内容でdetectionブロックを更新する
"""
obj = create_obj(base_dir=None, file_name=self.sigma_path)
keys = get_terminal_keys_recursive(obj["detection"], [])
modifiers = {re.sub(r".*\|", "", k) for k in keys if "|" in k}
if modifiers and [m for m in modifiers if m not in ["all", "base64", "base64offset", "cidr", "contains", "endswith", "endswithfield", "equalsfield", "re", "startswith"]]:
LOGGER.error(f"This rule has incompatible field.{obj['detection']}. skip conversion.")
return
logsources = self.get_logsources(obj)
if not logsources:
new_obj = copy.deepcopy(obj)
Expand Down
47 changes: 33 additions & 14 deletions tools/sigmac/test_logsource_mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def test_get_logsources(self):
win_audit_map = create_category_map(create_obj(script_dir, 'windows-audit.yaml'), service2channel)
win_service_map = create_category_map(create_obj(script_dir, 'windows-services.yaml'), service2channel)
all_category_map = merge_category_map(service2channel, [sysmon_map, win_audit_map, win_service_map])
process_creation_field_map = create_field_map(create_obj(script_dir, 'windows-audit.yaml'))
process_creation_field_map = create_field_map("fieldmappings_process", create_obj(script_dir, 'windows-audit.yaml'))
lc = LogsourceConverter("", all_category_map, process_creation_field_map, [])
r = lc.get_logsources({"logsource": {"service": "sysmon"}})
self.assertEquals(r[0].service, "sysmon")
Expand All @@ -80,25 +80,44 @@ def test_get_logsources_raise_exception_if_not_supported_category(self):
win_audit_map = create_category_map(create_obj(script_dir, 'windows-audit.yaml'), service2channel)
win_service_map = create_category_map(create_obj(script_dir, 'windows-services.yaml'), service2channel)
all_category_map = merge_category_map(service2channel, [sysmon_map, win_audit_map, win_service_map])
process_creation_field_map = create_field_map(create_obj(script_dir, 'windows-audit.yaml'))
process_creation_field_map = create_field_map("fieldmappings_process", create_obj(script_dir, 'windows-audit.yaml'))
lc = LogsourceConverter("", all_category_map, process_creation_field_map, [])
with self.assertRaises(Exception):
lc.get_logsources({"logsource": {"service": "file_rename"}})

def test_logsource_validate_security_4688(self):
ls = LogSource(category="process_creation", event_id=4688, service="", channel="")
self.assertFalse(ls.is_convertible({"selection": {"Image": "a.exe"}}))
self.assertFalse(ls.is_convertible({"selection": {"ParentImage": "b.exe"}}))
self.assertTrue(ls.is_convertible({"selection": {"NewProcessName": "a.exe" }}))
self.assertTrue(ls.is_convertible({"selection": {"ParentProcessName": "b.exe" }}))
self.assertTrue(ls.is_convertible({"selection": {"NewProcessName|contains": "c.exe" }}))
self.assertTrue(ls.is_convertible({"selection": {'ParentProcessName|endswith': '\\winword.exe', 'NewProcessName|contains': '/l'}, 'condition': 'selection'}))
self.assertFalse(ls.is_detectable({"selection": {"Image": "a.exe"}}))
self.assertFalse(ls.is_detectable({"selection": {"ParentImage": "b.exe"}}))
self.assertTrue(ls.is_detectable({"selection": {"NewProcessName": "a.exe" }}))
self.assertTrue(ls.is_detectable({"selection": {"ParentProcessName": "b.exe" }}))
self.assertTrue(ls.is_detectable({"selection": {"NewProcessName|contains": "c.exe" }}))
self.assertTrue(ls.is_detectable({"selection": {'ParentProcessName|endswith': '\\winword.exe', 'NewProcessName|contains': '/l'}, 'condition': 'selection'}))

def test_logsource_validate_security_4657(self):
ls = LogSource(category="registry_set", event_id=4657, service="", channel="")
self.assertFalse(ls.is_detectable({"selection": {"Image": "a.exe"}}))
self.assertFalse(ls.is_detectable({"selection": {"Details": "foo"}}))
self.assertTrue(ls.is_detectable({"selection": {"ProcessName": "a.exe" }}))
self.assertTrue(ls.is_detectable({"selection": {"SubjectUserName": "foo" }}))
self.assertTrue(ls.is_detectable({"selection": {"NewValue|contains": "c.exe" }}))
self.assertTrue(ls.is_detectable({"selection": {'OperationType|endswith': '%%1904'}, 'condition': 'selection'}))


def test_logsource_validate_sysmon_1(self):
ls = LogSource(category="process_creation", event_id=1, service="", channel="")
self.assertFalse(ls.is_convertible({"selection": {"NewProcessName": "a.exe"}}))
self.assertFalse(ls.is_convertible({"selection": {"ParentProcessName": "b.exe"}}))
self.assertTrue(ls.is_convertible({"selection": {"Image": "a.exe" }}))
self.assertTrue(ls.is_convertible({"selection": {"ParentImage": "b.exe" }}))
self.assertTrue(ls.is_convertible({"selection": {"Image|contains": "c.exe" }}))
self.assertTrue(ls.is_convertible({'selection': {'Image|endswith': '\\winword.exe', 'CommandLine|contains': '/l'}, 'condition': 'selection'}))
self.assertFalse(ls.is_detectable({"selection": {"NewProcessName": "a.exe"}}))
self.assertFalse(ls.is_detectable({"selection": {"ParentProcessName": "b.exe"}}))
self.assertTrue(ls.is_detectable({"selection": {"Image": "a.exe" }}))
self.assertTrue(ls.is_detectable({"selection": {"ParentImage": "b.exe" }}))
self.assertTrue(ls.is_detectable({"selection": {"Image|contains": "c.exe" }}))
self.assertTrue(ls.is_detectable({'selection': {'Image|endswith': '\\winword.exe', 'CommandLine|contains': '/l'}, 'condition': 'selection'}))

def test_logsource_validate_security_12(self):
ls = LogSource(category="registry_set", event_id=12, service="", channel="")
self.assertFalse(ls.is_detectable({"selection": {"ProcessName": "a.exe"}}))
self.assertFalse(ls.is_detectable({"selection": {"NewValue": "foo"}}))
self.assertTrue(ls.is_detectable({"selection": {"Image": "a.exe" }}))
self.assertTrue(ls.is_detectable({"selection": {"Details": "foo" }}))
self.assertTrue(ls.is_detectable({"selection": {"EventType": "CreateKey" }}))
self.assertTrue(ls.is_detectable({"selection": {'TargetObject|endswith': 'software'}, 'condition': 'selection'}))

0 comments on commit bd1fe11

Please sign in to comment.