diff --git a/sigma/processing/conditions/__init__.py b/sigma/processing/conditions/__init__.py index fa021cea..0c260667 100644 --- a/sigma/processing/conditions/__init__.py +++ b/sigma/processing/conditions/__init__.py @@ -28,6 +28,7 @@ ContainsWildcardCondition, IsNullCondition, MatchStringCondition, + MatchValueCondition, ) @@ -44,6 +45,7 @@ } detection_item_conditions: Dict[str, DetectionItemProcessingCondition] = { "match_string": MatchStringCondition, + "match_value": MatchValueCondition, "contains_wildcard": ContainsWildcardCondition, "is_null": IsNullCondition, "processing_item_applied": DetectionItemProcessingItemAppliedCondition, diff --git a/sigma/processing/conditions/values.py b/sigma/processing/conditions/values.py index fa829711..0dc0404c 100644 --- a/sigma/processing/conditions/values.py +++ b/sigma/processing/conditions/values.py @@ -1,4 +1,5 @@ from dataclasses import dataclass +from typing import Union import sigma from sigma.processing.conditions.base import ( @@ -41,6 +42,18 @@ def match_value(self, value: SigmaType) -> bool: return result +@dataclass +class MatchValueCondition(ValueProcessingCondition): + """ + Exact match of a value with an arbitrary Sigma type. + """ + + value: Union[str, int, float, bool] + + def match_value(self, value: SigmaType) -> bool: + return value == self.value + + class ContainsWildcardCondition(ValueProcessingCondition): """ Evaluates to True if the value contains a wildcard character. diff --git a/sigma/types.py b/sigma/types.py index 230fb556..8573917d 100644 --- a/sigma/types.py +++ b/sigma/types.py @@ -648,6 +648,12 @@ def __str__(self): def __bool__(self): return self.boolean + def __eq__(self, other: Union["SigmaBool", bool]) -> bool: + if isinstance(other, bool): + return self.boolean == other + else: + return self.boolean == other.boolean + class SigmaRegularExpressionFlag(Enum): IGNORECASE = auto() diff --git a/tests/test_processing_conditions.py b/tests/test_processing_conditions.py index caa95748..00853ea7 100644 --- a/tests/test_processing_conditions.py +++ b/tests/test_processing_conditions.py @@ -2,7 +2,8 @@ from typing import cast from sigma.collection import SigmaCollection from sigma.correlations import SigmaCorrelationRule -from sigma.types import SigmaNull, SigmaNumber, SigmaString +from sigma.processing.conditions.values import MatchValueCondition +from sigma.types import SigmaBool, SigmaNull, SigmaNumber, SigmaString from sigma import processing from sigma.exceptions import ( SigmaConfigurationError, @@ -420,11 +421,47 @@ def test_match_string_condition_error_mode(): MatchStringCondition(pattern="x", cond="test") -def test_match_string_condition_error_mode(): +def test_match_string_condition_error_pattern(): with pytest.raises(SigmaRegularExpressionError, match="is invalid"): MatchStringCondition(pattern="*", cond="any") +def test_match_value_condition_str(): + assert MatchValueCondition(value="test", cond="any").match( + SigmaDetectionItem("field", [], [SigmaString("test")]) + ) + + +def test_match_value_condition_str_nomatch(): + assert not MatchValueCondition(value="test", cond="any").match( + SigmaDetectionItem("field", [], [SigmaString("other")]) + ) + + +def test_match_value_condition_number(): + assert MatchValueCondition(value=123, cond="any").match( + SigmaDetectionItem("field", [], [SigmaNumber(123)]) + ) + + +def test_match_value_condition_number_nomatch(): + assert not MatchValueCondition(value=123, cond="any").match( + SigmaDetectionItem("field", [], [SigmaNumber(124)]) + ) + + +def test_match_value_condition_bool(): + assert MatchValueCondition(value=True, cond="any").match( + SigmaDetectionItem("field", [], [SigmaBool(True)]) + ) + + +def test_match_value_condition_bool_nomatch(): + assert not MatchValueCondition(value=True, cond="any").match( + SigmaDetectionItem("field", [], [SigmaBool(False)]) + ) + + def test_contains_wildcard_condition_match(): assert ContainsWildcardCondition(cond="any").match( SigmaDetectionItem("field", [], [SigmaString("*")])