From e053841c512c056cdc6e06cf68b097fead69b72b Mon Sep 17 00:00:00 2001 From: frack113 <62423083+frack113@users.noreply.github.com> Date: Sun, 28 Jan 2024 10:49:03 +0100 Subject: [PATCH] =?UTF-8?q?style:=20=F0=9F=92=84=20Run=20black?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/local_pysigma_dd_conversion.py | 2 +- sigma/backends/datadog/__init__.py | 2 +- sigma/backends/datadog/datadog.py | 107 ++++++++++++------------- sigma/pipelines/datadog/__init__.py | 2 +- sigma/pipelines/datadog/datadog.py | 2 + tests/test_pipelines_datadog.py | 6 +- 6 files changed, 63 insertions(+), 58 deletions(-) diff --git a/scripts/local_pysigma_dd_conversion.py b/scripts/local_pysigma_dd_conversion.py index 3b34786..2022c2a 100644 --- a/scripts/local_pysigma_dd_conversion.py +++ b/scripts/local_pysigma_dd_conversion.py @@ -10,7 +10,7 @@ # Add the path to the rule that should be converted to the following list: sigma_rules_to_convert = [ r"/Users/{your.username}/sigma/sigma/rules/{path/to/rule/to/be/converted}", - r"/Users/{your.username}/sigma/sigma/rules/cloud/azure/azure_blocked_account_attempt.yml", # example rule path + r"/Users/{your.username}/sigma/sigma/rules/cloud/azure/azure_blocked_account_attempt.yml", # example rule path ] sigma_rule_collection = SigmaCollection.load_ruleset(sigma_rules_to_convert) diff --git a/sigma/backends/datadog/__init__.py b/sigma/backends/datadog/__init__.py index 0b5ec2b..35d9dc1 100644 --- a/sigma/backends/datadog/__init__.py +++ b/sigma/backends/datadog/__init__.py @@ -1 +1 @@ -from .datadog import DatadogBackend \ No newline at end of file +from .datadog import DatadogBackend diff --git a/sigma/backends/datadog/datadog.py b/sigma/backends/datadog/datadog.py index 1b281af..bcb8c15 100644 --- a/sigma/backends/datadog/datadog.py +++ b/sigma/backends/datadog/datadog.py @@ -35,9 +35,9 @@ class DatadogBackend(TextQueryBackend): ConditionAND, ConditionOR, ) - group_expression: ClassVar[ - str - ] = "({expr})" # Expression for precedence override grouping as format string with {expr} placeholder + group_expression: ClassVar[str] = ( + "({expr})" # Expression for precedence override grouping as format string with {expr} placeholder + ) parenthesize: bool = True # Generated query tokens @@ -45,46 +45,46 @@ class DatadogBackend(TextQueryBackend): or_token: ClassVar[str] = "OR" and_token: ClassVar[str] = "AND" not_token: ClassVar[str] = "NOT" - eq_token: ClassVar[ - str - ] = ":" # Token inserted between field and value (without separator) + eq_token: ClassVar[str] = ( + ":" # Token inserted between field and value (without separator) + ) # String Output Fields Quoting # field_quote : ClassVar[str] = "'" # Character used to quote field characters if field_quote_pattern matches (or not, depending on field_quote_pattern_negation). No field name quoting is done if not set. field_quote_pattern: ClassVar[Pattern] = re.compile( "^\\w+$" ) # Quote field names if this pattern (doesn't) matches, depending on field_quote_pattern_negation. Field name is always quoted if pattern is not set. - field_quote_pattern_negation: ClassVar[ - bool - ] = True # Negate field_quote_pattern result. Field name is quoted if pattern doesn't matches if set to True (default). + field_quote_pattern_negation: ClassVar[bool] = ( + True # Negate field_quote_pattern result. Field name is quoted if pattern doesn't matches if set to True (default). + ) ### Escaping - field_escape: ClassVar[ - str - ] = "\\" # Character to escape particular parts defined in field_escape_pattern. - field_escape_quote: ClassVar[ - bool - ] = True # Escape quote string defined in field_quote + field_escape: ClassVar[str] = ( + "\\" # Character to escape particular parts defined in field_escape_pattern. + ) + field_escape_quote: ClassVar[bool] = ( + True # Escape quote string defined in field_quote + ) field_escape_pattern: ClassVar[Pattern] = re.compile( "[\\s*]" ) # All matches of this pattern are prepended with the string contained in field_escape. ## Values - escape_char: ClassVar[ - str - ] = "\\" # Escaping character for special characters inside string + escape_char: ClassVar[str] = ( + "\\" # Escaping character for special characters inside string + ) wildcard_multi: ClassVar[str] = "*" # Character used as multi-character wildcard wildcard_single: ClassVar[str] = "*" # Character used as single-character wildcard - add_escaped: ClassVar[ - str - ] = ' + - = && || ! ( ) { } [ ] < > ^ “ ” ~ * ? : " ' # Characters quoted in addition to wildcards and string quote - bool_values: ClassVar[ - Dict[bool, str] - ] = { # Values to which boolean values are mapped. - True: "true", - False: "false", - } + add_escaped: ClassVar[str] = ( + ' + - = && || ! ( ) { } [ ] < > ^ “ ” ~ * ? : " ' # Characters quoted in addition to wildcards and string quote + ) + bool_values: ClassVar[Dict[bool, str]] = ( + { # Values to which boolean values are mapped. + True: "true", + False: "false", + } + ) # String matching operators. if none is appropriate eq_token is used. startswith_expression: ClassVar[str] = "{field}:{value}*" @@ -93,9 +93,9 @@ class DatadogBackend(TextQueryBackend): icontains_token: ClassVar[str] = "{field}:*{value}*" # Numeric comparison operators - compare_op_expression: ClassVar[ - str - ] = "{field}:{operator}{value}" # Compare operation query as format string with placeholders {field}, {operator} and {value} + compare_op_expression: ClassVar[str] = ( + "{field}:{operator}{value}" # Compare operation query as format string with placeholders {field}, {operator} and {value} + ) # Mapping between CompareOperators elements and strings used as replacement for {operator} in compare_op_expression compare_operators: ClassVar[Dict[SigmaCompareExpression.CompareOperators, str]] = { SigmaCompareExpression.CompareOperators.GT: ">", @@ -105,39 +105,39 @@ class DatadogBackend(TextQueryBackend): } # Expression for comparing two event fields - field_equals_field_expression: ClassVar[ - Optional[str] - ] = None # Field comparison expression with the placeholders {field1} and {field2} corresponding to left field and right value side of Sigma detection item + field_equals_field_expression: ClassVar[Optional[str]] = ( + None # Field comparison expression with the placeholders {field1} and {field2} corresponding to left field and right value side of Sigma detection item + ) field_equals_field_escaping_quoting: Tuple[bool, bool] = ( True, True, ) # If regular field-escaping/quoting is applied to field1 and field2. A custom escaping/quoting can be implemented in the convert_condition_field_eq_field_escape_and_quote method. # Field existence condition expressions. - field_exists_expression: ClassVar[ - str - ] = "({field})" # Expression for field existence as format string with {field} placeholder for field name - field_not_exists_expression: ClassVar[ - str - ] = "NOT ({field})" # Expression for field non-existence as format string with {field} placeholder for field name. If not set, field_exists_expression is negated with boolean NOT. + field_exists_expression: ClassVar[str] = ( + "({field})" # Expression for field existence as format string with {field} placeholder for field name + ) + field_not_exists_expression: ClassVar[str] = ( + "NOT ({field})" # Expression for field non-existence as format string with {field} placeholder for field name. If not set, field_exists_expression is negated with boolean NOT. + ) # Field value in list, e.g. "field in (value list)" or "field contains all (value list)" # Convert OR as in-expression convert_and_as_in: ClassVar[bool] = False # Convert AND as in-expression - field_in_list_expression: ClassVar[ - str - ] = "{field}{op}({list})" # Expression for field in list of values as format string with placeholders {field}, {op} and {list} + field_in_list_expression: ClassVar[str] = ( + "{field}{op}({list})" # Expression for field in list of values as format string with placeholders {field}, {op} and {list} + ) # and_in_operator : ClassVar[str] = "contains-all" # Operator used to convert AND into in-expressions. Must be set if convert_and_as_in is set list_separator: ClassVar[str] = " OR " # List element separator # Value not bound to a field - unbound_value_str_expression: ClassVar[ - str - ] = '"{value}"' # Expression for string value not bound to a field as format string with placeholder {value} - unbound_value_num_expression: ClassVar[ - str - ] = "{value}" # Expression for number value not bound to a field as format string with placeholder {value} + unbound_value_str_expression: ClassVar[str] = ( + '"{value}"' # Expression for string value not bound to a field as format string with placeholder {value} + ) + unbound_value_num_expression: ClassVar[str] = ( + "{value}" # Expression for number value not bound to a field as format string with placeholder {value} + ) def convert_condition_field_eq_val_re( self, cond: SigmaRegularExpression, state: Any @@ -200,9 +200,11 @@ def finalize_query_siem_rule( "cases": [ { "name": "", - "status": str(rule.level.name).lower() - if rule.level is not None - else "low", + "status": ( + str(rule.level.name).lower() + if rule.level is not None + else "low" + ), "condition": "a > 0", "notifications": [], } @@ -217,7 +219,6 @@ def finalize_query_siem_rule( "message": f"Sigma Rule ID: \n {str(rule.id)} \n " f"False Positives: \n {self.concat_false_positive_as_string(rule.falsepositives)} \n " f"Description: \n {str(rule.description)} \n " - f"Author: \n {str(rule.author) if rule.author is not None else []} \n ", "tags": ["source:sigmahq"] + [f"{tag.namespace}:{tag.name}" for tag in rule.tags], @@ -227,5 +228,3 @@ def finalize_query_siem_rule( def finalize_output_siem_rule(self, queries: List[Dict]) -> List[Dict]: return list(queries) - - diff --git a/sigma/pipelines/datadog/__init__.py b/sigma/pipelines/datadog/__init__.py index 6bfccef..0dbdbc2 100644 --- a/sigma/pipelines/datadog/__init__.py +++ b/sigma/pipelines/datadog/__init__.py @@ -1 +1 @@ -from .datadog import datadog_pipeline \ No newline at end of file +from .datadog import datadog_pipeline diff --git a/sigma/pipelines/datadog/datadog.py b/sigma/pipelines/datadog/datadog.py index ab2a7e0..84bb959 100644 --- a/sigma/pipelines/datadog/datadog.py +++ b/sigma/pipelines/datadog/datadog.py @@ -14,6 +14,8 @@ from sigma.rule import SigmaRule import sigma + + class AggregateRuleProcessingCondition(RuleProcessingCondition): def match( self, pipeline: "sigma.processing.pipeline.ProcessingPipeline", rule: SigmaRule diff --git a/tests/test_pipelines_datadog.py b/tests/test_pipelines_datadog.py index 2ce034d..b3d66fd 100644 --- a/tests/test_pipelines_datadog.py +++ b/tests/test_pipelines_datadog.py @@ -1,11 +1,15 @@ # pylint: disable=too-many-lines import pytest from sigma.collection import SigmaCollection -from sigma.exceptions import SigmaTransformationError, SigmaFeatureNotSupportedByBackendError +from sigma.exceptions import ( + SigmaTransformationError, + SigmaFeatureNotSupportedByBackendError, +) from sigma.backends.datadog import DatadogBackend + def test_aws_field_transformations(): assert ( DatadogBackend().convert(