diff --git a/sigma/pipelines/panther/crowdstrike_panther_pipeline.py b/sigma/pipelines/panther/crowdstrike_panther_pipeline.py index b7b8087..a25f5a0 100644 --- a/sigma/pipelines/panther/crowdstrike_panther_pipeline.py +++ b/sigma/pipelines/panther/crowdstrike_panther_pipeline.py @@ -8,6 +8,7 @@ from sigma.processing.pipeline import ProcessingItem, ProcessingPipeline, QueryPostprocessingItem from sigma.processing.transformations import ( AddConditionTransformation, + AddFieldnamePrefixTransformation, ChangeLogsourceTransformation, DropDetectionItemTransformation, FieldMappingTransformation, @@ -220,16 +221,35 @@ def crowdstrike_panther_pipeline(): ProcessingItem( transformation=FieldMappingTransformation( { - "sha256": "event.SHA256HashData", - "sha1": "event.SHA1HashData", - "ParentImage": "event.ParentBaseFileName", - "Image": "event.ImageFileName", - "CommandLine": "event.CommandLine", - "md5": "event.MD5HashData", - "TargetFileName": "event.TargetFileName", + "sha256": "SHA256HashData", + "sha1": "SHA1HashData", + "ParentImage": "ParentBaseFileName", + "Image": "ImageFileName", + "md5": "MD5HashData", } ), ), + ProcessingItem( + transformation=AddFieldnamePrefixTransformation(prefix="event."), + field_name_conditions=[ + IncludeFieldCondition( + fields=[ + "CommandLine", + "DomainName", + "ImageFileName", + "IP4Records", + "MD5HashData", + "ParentBaseFileName", + "Protocol", + "RemoteAddressIP4", + "RemotePort", + "SHA1HashData", + "SHA256HashData", + "TargetFilename", + ] + ), + ], + ), ProcessingItem( transformation=DropDetectionItemTransformation(), field_name_conditions=[IncludeFieldCondition(fields=["DestinationHostname"])], diff --git a/tests/test_crowdstrike_panther_pipeline.py b/tests/test_crowdstrike_panther_pipeline.py index 4a6deba..68e1fe1 100644 --- a/tests/test_crowdstrike_panther_pipeline.py +++ b/tests/test_crowdstrike_panther_pipeline.py @@ -33,6 +33,7 @@ def test_basic(mock_click): DestinationIp: 127.0.0.1 Initiated: "true" ParentImage: C:\\Program Files\\Microsoft Monitoring Agent\\Agent\\MonitoringHost.exe + TargetFilename|endswith: '.plist' condition: sel """ ) @@ -75,9 +76,14 @@ def test_basic(mock_click): }, { "Condition": "Equals", - "KeyPath": "ParentBaseFileName", + "KeyPath": "event.ParentBaseFileName", "Value": "MonitoringHost.exe", }, + { + "Condition": "EndsWith", + "KeyPath": "event.TargetFilename", + "Value": ".plist", + }, ] } ], @@ -85,3 +91,51 @@ def test_basic(mock_click): ) assert backend.convert(rule) == expected + + +@mock.patch("sigma.pipelines.panther.sdyaml_transformation.click") +def test_python_fields_mapping(mock_click): + mock_click.get_current_context.return_value = mock.MagicMock( + params={"pipeline": "crowdstrike_panther"} + ) + resolver = ProcessingPipelineResolver({"crowdstrike_panther": crowdstrike_panther_pipeline()}) + pipeline = resolver.resolve_pipeline("crowdstrike_panther") + backend = PantherBackend(pipeline) + + rule_id = uuid.uuid4() + rule = SigmaCollection.from_yaml( + f""" + title: Test Title + id: {rule_id} + description: description + logsource: + category: process_creation + product: windows + detection: + sel: + ParentImage: C:\\Program Files\\Microsoft Monitoring Agent\\Agent\\MonitoringHost.exe + TargetFilename|endswith: '.plist' + sha1: da39a3ee5e6b4b0d3255bfef95601890afd80709 + condition: sel + """ + ) + + expected = """def rule(event): + if all( + [ + event.deep_get("event_platform", default="") == "Windows", + event.deep_get("event_simpleName", default="") + in ["ProcessRollup2", "SyntheticProcessRollup2"], + event.deep_get("event", "ParentBaseFileName", default="") == "MonitoringHost.exe", + event.deep_get("event", "TargetFilename", default="").endswith(".plist"), + event.deep_get("event", "SHA1HashData", default="") + == "da39a3ee5e6b4b0d3255bfef95601890afd80709", + ] + ): + return True + return False +""" + + result = backend.convert(rule, output_format="python") + + assert result["Detection"][0] == expected