From c6a2bdc45f74189d794f26ec05f6540ac16fb71b Mon Sep 17 00:00:00 2001 From: eric-forte-elastic Date: Wed, 13 Aug 2025 13:05:45 -0400 Subject: [PATCH 1/9] Fix rule and mitigate py toml --- detection_rules/rule_formatter.py | 2 ++ ...e_escalation_printspooler_service_suspicious_file.toml | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/detection_rules/rule_formatter.py b/detection_rules/rule_formatter.py index 0702bdf8a89..3ef8b8aefec 100644 --- a/detection_rules/rule_formatter.py +++ b/detection_rules/rule_formatter.py @@ -151,6 +151,8 @@ def dump_str(self, v: str | NonformattedField) -> str: return "\n".join([TRIPLE_SQ] + [self._old_dump_str(line)[1:-1] for line in lines] + [TRIPLE_SQ]) if raw: return f"'{lines[0]:s}'" + if "\\\\x" in v: + return f'"{v!s}"' return self._old_dump_str(v) def _dump_flat_list(self, v: Iterable[Any]) -> str: diff --git a/rules/windows/privilege_escalation_printspooler_service_suspicious_file.toml b/rules/windows/privilege_escalation_printspooler_service_suspicious_file.toml index 5fd974a8857..27eec149754 100644 --- a/rules/windows/privilege_escalation_printspooler_service_suspicious_file.toml +++ b/rules/windows/privilege_escalation_printspooler_service_suspicious_file.toml @@ -2,7 +2,7 @@ creation_date = "2020/08/14" integration = ["endpoint", "windows", "m365_defender", "sentinel_one_cloud_funnel"] maturity = "production" -updated_date = "2025/03/20" +updated_date = "2025/08/13" [rule] author = ["Elastic"] @@ -106,14 +106,14 @@ value = "?:\\\\Windows\\\\Sys?????\\\\PrintConfig.dll" negate = true [rule.filters.query.wildcard."file.path"] case_insensitive = true -value = "?:\\Windows\\Sys?????\\u005lrs.dll" +value = "?:\\Windows\\Sys?????\\x5lrs.dll" [[rule.filters]] [rule.filters.meta] negate = true [rule.filters.query.wildcard."file.path"] case_insensitive = true -value = "?:\\Windows\\system32\\spool\\DRIVERS\\u0064\\\\*.dll" +value = "?:\\Windows\\system32\\spool\\DRIVERS\\x64\\*.dll" [[rule.filters]] [rule.filters.meta] @@ -127,7 +127,7 @@ value = "?:\\\\Windows\\\\system32\\\\spool\\\\DRIVERS\\\\W32X86\\\\*.dll" negate = true [rule.filters.query.wildcard."file.path"] case_insensitive = true -value = "?:\\Windows\\system32\\spool\\PRTPROCS\\u0064\\\\*.dll" +value = "?:\\Windows\\system32\\spool\\PRTPROCS\\x64\\*.dll" [[rule.filters]] [rule.filters.meta] From c19c8e3eed6bcdb667cbcafdb425552564b6fb06 Mon Sep 17 00:00:00 2001 From: eric-forte-elastic Date: Wed, 13 Aug 2025 13:11:37 -0400 Subject: [PATCH 2/9] Bump patch version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d16e7dd7346..08c32aa9b86 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "detection_rules" -version = "1.3.23" +version = "1.3.24" description = "Detection Rules is the home for rules used by Elastic Security. This repository is used for the development, maintenance, testing, validation, and release of rules for Elastic Security’s Detection Engine." readme = "README.md" requires-python = ">=3.12" From 2ced0dc55f3b0409b2dbdd0b767ae1a306978f47 Mon Sep 17 00:00:00 2001 From: eric-forte-elastic Date: Wed, 13 Aug 2025 15:27:39 -0400 Subject: [PATCH 3/9] Add reference to issue --- detection_rules/rule_formatter.py | 1 + 1 file changed, 1 insertion(+) diff --git a/detection_rules/rule_formatter.py b/detection_rules/rule_formatter.py index 3ef8b8aefec..f547969f089 100644 --- a/detection_rules/rule_formatter.py +++ b/detection_rules/rule_formatter.py @@ -151,6 +151,7 @@ def dump_str(self, v: str | NonformattedField) -> str: return "\n".join([TRIPLE_SQ] + [self._old_dump_str(line)[1:-1] for line in lines] + [TRIPLE_SQ]) if raw: return f"'{lines[0]:s}'" + # In the toml library there is a magic replace for \\\\x -> u00 that we wish to avoid until #4979 is resolved if "\\\\x" in v: return f'"{v!s}"' return self._old_dump_str(v) From 1965007243bff92b10820719ef6a2e38ae4e43c5 Mon Sep 17 00:00:00 2001 From: eric-forte-elastic Date: Mon, 18 Aug 2025 12:41:34 -0400 Subject: [PATCH 4/9] Add unit test for path issues --- detection_rules/etc/test_toml.json | 8 ++++++++ tests/test_toml_formatter.py | 10 +++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/detection_rules/etc/test_toml.json b/detection_rules/etc/test_toml.json index c17376cbe80..081222bbb20 100644 --- a/detection_rules/etc/test_toml.json +++ b/detection_rules/etc/test_toml.json @@ -48,6 +48,14 @@ ] } }, + { + "metadata": { + "field": "value" + }, + "rule": { + "path": "?:\\\\Windows\\\\Sys?????\\\\x5lrs.dll" + } + }, { "metadata": { "field": "value" diff --git a/tests/test_toml_formatter.py b/tests/test_toml_formatter.py index dea5e850eff..22e07ef7ad8 100644 --- a/tests/test_toml_formatter.py +++ b/tests/test_toml_formatter.py @@ -71,4 +71,12 @@ def test_formatter_rule(self): def test_formatter_deep(self): """Test that the data remains unchanged from formatting.""" - self.compare_test_data(self.test_data[1:]) + self.compare_test_data(self.test_data[2:]) + + def test_formatter_paths(self): + """Test that paths are handled as expected in with toml lib.""" + with self.assertRaisesRegex( + AssertionError, + r'\+ {"metadata": {"field": "value"}, "rule": {"path": "\?:\\\\Windows\\\\Sys\?\?\?\?\?\\\\x5lrs\.dll"}}', + ): + self.compare_test_data([self.test_data[1]]) From 5dab22913e1f7c9801f0d8e959e01fa92174463e Mon Sep 17 00:00:00 2001 From: eric-forte-elastic Date: Mon, 18 Aug 2025 13:32:16 -0400 Subject: [PATCH 5/9] Update comment --- tests/test_toml_formatter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_toml_formatter.py b/tests/test_toml_formatter.py index 22e07ef7ad8..0923e206067 100644 --- a/tests/test_toml_formatter.py +++ b/tests/test_toml_formatter.py @@ -74,7 +74,7 @@ def test_formatter_deep(self): self.compare_test_data(self.test_data[2:]) def test_formatter_paths(self): - """Test that paths are handled as expected in with toml lib.""" + """Test that paths are handled as expected with toml lib.""" with self.assertRaisesRegex( AssertionError, r'\+ {"metadata": {"field": "value"}, "rule": {"path": "\?:\\\\Windows\\\\Sys\?\?\?\?\?\\\\x5lrs\.dll"}}', From d69acdd53e4b1237be108d3dd8c38b0ed8d2d98a Mon Sep 17 00:00:00 2001 From: eric-forte-elastic Date: Mon, 18 Aug 2025 14:44:05 -0400 Subject: [PATCH 6/9] Certain strings were not properly escaped --- detection_rules/rule_formatter.py | 5 +++-- tests/test_toml_formatter.py | 10 +--------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/detection_rules/rule_formatter.py b/detection_rules/rule_formatter.py index f547969f089..7974ce7ed08 100644 --- a/detection_rules/rule_formatter.py +++ b/detection_rules/rule_formatter.py @@ -152,8 +152,9 @@ def dump_str(self, v: str | NonformattedField) -> str: if raw: return f"'{lines[0]:s}'" # In the toml library there is a magic replace for \\\\x -> u00 that we wish to avoid until #4979 is resolved - if "\\\\x" in v: - return f'"{v!s}"' + # Also addresses an issue where backslashes in certain strings are not properly escaped in self._old_dump_str(v) + if "\\" in v: + return f'"{repr(v)[1:-1]}"' return self._old_dump_str(v) def _dump_flat_list(self, v: Iterable[Any]) -> str: diff --git a/tests/test_toml_formatter.py b/tests/test_toml_formatter.py index 0923e206067..dea5e850eff 100644 --- a/tests/test_toml_formatter.py +++ b/tests/test_toml_formatter.py @@ -71,12 +71,4 @@ def test_formatter_rule(self): def test_formatter_deep(self): """Test that the data remains unchanged from formatting.""" - self.compare_test_data(self.test_data[2:]) - - def test_formatter_paths(self): - """Test that paths are handled as expected with toml lib.""" - with self.assertRaisesRegex( - AssertionError, - r'\+ {"metadata": {"field": "value"}, "rule": {"path": "\?:\\\\Windows\\\\Sys\?\?\?\?\?\\\\x5lrs\.dll"}}', - ): - self.compare_test_data([self.test_data[1]]) + self.compare_test_data(self.test_data[1:]) From e6d22d9b9cc25801ba9ac04b79b5724b087b748b Mon Sep 17 00:00:00 2001 From: eric-forte-elastic Date: Mon, 18 Aug 2025 15:20:30 -0400 Subject: [PATCH 7/9] Updated to use json instead of repr --- detection_rules/rule_formatter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detection_rules/rule_formatter.py b/detection_rules/rule_formatter.py index 7974ce7ed08..bd505ad212c 100644 --- a/detection_rules/rule_formatter.py +++ b/detection_rules/rule_formatter.py @@ -154,7 +154,7 @@ def dump_str(self, v: str | NonformattedField) -> str: # In the toml library there is a magic replace for \\\\x -> u00 that we wish to avoid until #4979 is resolved # Also addresses an issue where backslashes in certain strings are not properly escaped in self._old_dump_str(v) if "\\" in v: - return f'"{repr(v)[1:-1]}"' + return json.dumps(v) return self._old_dump_str(v) def _dump_flat_list(self, v: Iterable[Any]) -> str: From f1501ca74590e17fb208324a53039335ce8887e8 Mon Sep 17 00:00:00 2001 From: eric-forte-elastic Date: Mon, 18 Aug 2025 15:37:51 -0400 Subject: [PATCH 8/9] replace _old_dump_str with json.dumps --- detection_rules/rule_formatter.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/detection_rules/rule_formatter.py b/detection_rules/rule_formatter.py index bd505ad212c..46469f24daf 100644 --- a/detection_rules/rule_formatter.py +++ b/detection_rules/rule_formatter.py @@ -123,7 +123,6 @@ class RuleTomlEncoder(toml.TomlEncoder): # type: ignore[reportMissingTypeArgume def __init__(self, *args: Any, **kwargs: Any) -> None: """Create the encoder but override some default functions.""" super().__init__(*args, **kwargs) # type: ignore[reportUnknownMemberType] - self._old_dump_str = toml.TomlEncoder().dump_funcs[str] self._old_dump_list = toml.TomlEncoder().dump_funcs[list] self.dump_funcs[str] = self.dump_str self.dump_funcs[str] = self.dump_str @@ -148,14 +147,12 @@ def dump_str(self, v: str | NonformattedField) -> str: if multiline: if raw: return "".join([TRIPLE_DQ, *initial_newline, *lines, TRIPLE_DQ]) - return "\n".join([TRIPLE_SQ] + [self._old_dump_str(line)[1:-1] for line in lines] + [TRIPLE_SQ]) + return "\n".join([TRIPLE_SQ] + [json.dumps(line)[1:-1] for line in lines] + [TRIPLE_SQ]) if raw: return f"'{lines[0]:s}'" # In the toml library there is a magic replace for \\\\x -> u00 that we wish to avoid until #4979 is resolved # Also addresses an issue where backslashes in certain strings are not properly escaped in self._old_dump_str(v) - if "\\" in v: - return json.dumps(v) - return self._old_dump_str(v) + return json.dumps(v) def _dump_flat_list(self, v: Iterable[Any]) -> str: """A slightly tweaked version of original dump_list, removing trailing commas.""" From 84da63c972089d68b292d0e5acb1336038fd3e21 Mon Sep 17 00:00:00 2001 From: eric-forte-elastic Date: Mon, 18 Aug 2025 16:54:02 -0400 Subject: [PATCH 9/9] Bump Version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 08c32aa9b86..8303f0fcbd4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "detection_rules" -version = "1.3.24" +version = "1.3.25" description = "Detection Rules is the home for rules used by Elastic Security. This repository is used for the development, maintenance, testing, validation, and release of rules for Elastic Security’s Detection Engine." readme = "README.md" requires-python = ">=3.12"