pySigma 2.0.0__tar.gz → 2.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pysigma-2.0.0 → pysigma-2.0.1}/PKG-INFO +1 -1
- {pysigma-2.0.0 → pysigma-2.0.1}/pyproject.toml +1 -1
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/collection.py +1 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/conditions.py +2 -2
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/conversion/base.py +4 -2
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/filters.py +5 -2
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/modifiers.py +18 -5
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/policy/__init__.py +5 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/processing/finalization.py +1 -1
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/processing/pipeline.py +10 -5
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/processing/regex.py +2 -2
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/processing/transformations/external.py +2 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/rule/detection.py +11 -7
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/types.py +17 -9
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/validation.py +3 -0
- pysigma-2.0.0/sigma/__init__.py +0 -6
- {pysigma-2.0.0 → pysigma-2.0.1}/LICENSE +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/README.md +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/backends/test/__init__.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/backends/test/backend.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/conversion/__init__.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/conversion/deferred.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/conversion/state.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/correlations.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/data/mitre_attack.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/data/mitre_d3fend.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/exceptions.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/pipelines/base.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/pipelines/common.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/pipelines/test/__init__.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/pipelines/test/pipeline.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/plugins.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/policy/profiles.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/policy/regex_engine.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/processing/__init__.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/processing/condition_expressions.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/processing/conditions/__init__.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/processing/conditions/base.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/processing/conditions/fields.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/processing/conditions/rule.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/processing/conditions/state.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/processing/conditions/values.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/processing/postprocessing.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/processing/resolver.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/processing/templates.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/processing/tracking.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/processing/transformations/__init__.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/processing/transformations/base.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/processing/transformations/condition.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/processing/transformations/detection_item.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/processing/transformations/failure.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/processing/transformations/fields.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/processing/transformations/meta.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/processing/transformations/placeholder.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/processing/transformations/rule.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/processing/transformations/state.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/processing/transformations/values.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/py.typed +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/rule/__init__.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/rule/attributes.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/rule/base.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/rule/logsource.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/rule/rule.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/validators/base.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/validators/core/__init__.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/validators/core/condition.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/validators/core/logsources.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/validators/core/metadata.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/validators/core/modifiers.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/validators/core/tags.py +0 -0
- {pysigma-2.0.0 → pysigma-2.0.1}/sigma/validators/core/values.py +0 -0
|
@@ -248,10 +248,10 @@ class ConditionSelector(ConditionItem):
|
|
|
248
248
|
"""
|
|
249
249
|
Resolve all detection identifiers referenced by the selector.
|
|
250
250
|
"""
|
|
251
|
-
import
|
|
251
|
+
from sigma.policy import default_policy
|
|
252
252
|
|
|
253
253
|
policy = detections.policy
|
|
254
|
-
engine = (policy or
|
|
254
|
+
engine = (policy or default_policy).regex_engine
|
|
255
255
|
if self.pattern == "them":
|
|
256
256
|
r = engine.compile(".*")
|
|
257
257
|
else:
|
|
@@ -767,8 +767,10 @@ class Backend(ABC):
|
|
|
767
767
|
]
|
|
768
768
|
rule.set_conversion_result(finalized_queries)
|
|
769
769
|
rule.set_conversion_states(states)
|
|
770
|
-
|
|
771
|
-
|
|
770
|
+
if rule._output:
|
|
771
|
+
return finalized_queries
|
|
772
|
+
else:
|
|
773
|
+
return []
|
|
772
774
|
|
|
773
775
|
@abstractmethod
|
|
774
776
|
def convert_correlation_event_count_rule(
|
|
@@ -71,7 +71,7 @@ class SigmaGlobalFilter(SigmaDetections):
|
|
|
71
71
|
|
|
72
72
|
return cls(
|
|
73
73
|
detections={
|
|
74
|
-
name: SigmaDetection.from_definition(definition, source)
|
|
74
|
+
name: SigmaDetection.from_definition(definition, source, policy)
|
|
75
75
|
for name, definition in detections.items()
|
|
76
76
|
if name
|
|
77
77
|
not in (
|
|
@@ -82,6 +82,7 @@ class SigmaGlobalFilter(SigmaDetections):
|
|
|
82
82
|
rules=rules,
|
|
83
83
|
condition=condition,
|
|
84
84
|
source=source,
|
|
85
|
+
policy=policy,
|
|
85
86
|
)
|
|
86
87
|
|
|
87
88
|
def to_dict(self: Self) -> dict[str, Any]:
|
|
@@ -163,7 +164,9 @@ class SigmaFilter(SigmaRuleBase):
|
|
|
163
164
|
|
|
164
165
|
# parse detections
|
|
165
166
|
try:
|
|
166
|
-
filter_global_filter = SigmaGlobalFilter.from_dict(
|
|
167
|
+
filter_global_filter = SigmaGlobalFilter.from_dict(
|
|
168
|
+
sigma_filter["filter"], source, policy=policy
|
|
169
|
+
)
|
|
167
170
|
except KeyError:
|
|
168
171
|
filter_global_filter = EmptySigmaGlobalFilter()
|
|
169
172
|
errors.append(
|
|
@@ -40,7 +40,7 @@ from sigma.types import (
|
|
|
40
40
|
TimestampPart,
|
|
41
41
|
SigmaStringPartType,
|
|
42
42
|
)
|
|
43
|
-
from sigma.exceptions import SigmaRuleLocation, SigmaTypeError, SigmaValueError
|
|
43
|
+
from sigma.exceptions import SigmaModifiedError, SigmaRuleLocation, SigmaTypeError, SigmaValueError
|
|
44
44
|
|
|
45
45
|
if TYPE_CHECKING:
|
|
46
46
|
from .rule import SigmaDetectionItem
|
|
@@ -418,6 +418,7 @@ class SigmaWindowsDashModifier(SigmaValueModifier[SigmaString, SigmaExpansion]):
|
|
|
418
418
|
en_dash = chr(int("2013", 16))
|
|
419
419
|
em_dash = chr(int("2014", 16))
|
|
420
420
|
horizontal_bar = chr(int("2015", 16))
|
|
421
|
+
max_expanded_dashes = 3
|
|
421
422
|
|
|
422
423
|
def modify(self, val: SigmaString) -> SigmaExpansion:
|
|
423
424
|
def callback(p: Placeholder) -> Iterator[str | Placeholder]:
|
|
@@ -426,12 +427,24 @@ class SigmaWindowsDashModifier(SigmaValueModifier[SigmaString, SigmaExpansion]):
|
|
|
426
427
|
else:
|
|
427
428
|
yield p
|
|
428
429
|
|
|
430
|
+
with_placeholders = val.replace_with_placeholder(re.compile("\\B[-/]\\b"), "_windash")
|
|
431
|
+
expanded_dashes = sum(
|
|
432
|
+
1
|
|
433
|
+
for part in with_placeholders.s
|
|
434
|
+
if isinstance(part, Placeholder) and part.name == "_windash"
|
|
435
|
+
)
|
|
436
|
+
if expanded_dashes > self.max_expanded_dashes:
|
|
437
|
+
raise SigmaModifiedError(
|
|
438
|
+
"windash modifier expands at most three dash occurrences in one value; "
|
|
439
|
+
"split multiple dash expansions into separate ORed string match conditions "
|
|
440
|
+
"with one dash expanded",
|
|
441
|
+
source=self.source,
|
|
442
|
+
)
|
|
443
|
+
|
|
429
444
|
return SigmaExpansion(
|
|
430
445
|
cast(
|
|
431
446
|
list[SigmaType],
|
|
432
|
-
|
|
433
|
-
re.compile("\\B[-/]\\b"), "_windash"
|
|
434
|
-
).replace_placeholders(callback),
|
|
447
|
+
with_placeholders.replace_placeholders(callback),
|
|
435
448
|
)
|
|
436
449
|
)
|
|
437
450
|
|
|
@@ -445,7 +458,7 @@ class SigmaRegularExpressionModifier(SigmaValueModifier[SigmaString, SigmaRegula
|
|
|
445
458
|
"Regular expression modifier only applicable to unmodified values",
|
|
446
459
|
source=self.source,
|
|
447
460
|
)
|
|
448
|
-
return SigmaRegularExpression(val.original)
|
|
461
|
+
return SigmaRegularExpression(val.original, policy=self.detection_item.policy)
|
|
449
462
|
|
|
450
463
|
|
|
451
464
|
class SigmaRegularExpressionFlagModifier(
|
|
@@ -132,7 +132,7 @@ class NestedFinalizer(Finalizer):
|
|
|
132
132
|
finalizer_cls = finalizers[finalizer_type]
|
|
133
133
|
import sigma as _sigma
|
|
134
134
|
|
|
135
|
-
effective_policy = policy or _sigma.default_policy
|
|
135
|
+
effective_policy = policy or _sigma.policy.default_policy
|
|
136
136
|
if issubclass(finalizer_cls, TemplateBase):
|
|
137
137
|
finalizer["policy"] = policy
|
|
138
138
|
finalizer["restrict_template_path"] = not effective_policy.allow_external_sources
|
|
@@ -27,6 +27,7 @@ from sigma.processing.tracking import FieldMappingTracking
|
|
|
27
27
|
from sigma.processing.transformations import transformations
|
|
28
28
|
from sigma.processing.transformations.external import ExternalSourceBaseTransformation
|
|
29
29
|
from sigma.rule import SigmaDetectionItem, SigmaRule
|
|
30
|
+
from sigma.rule.base import check_alias_expansion
|
|
30
31
|
from sigma.correlations import SigmaCorrelationRule
|
|
31
32
|
from sigma.processing.transformations.base import PreprocessingTransformation, Transformation
|
|
32
33
|
from sigma.processing.postprocessing import (
|
|
@@ -353,7 +354,7 @@ class ProcessingItemBase:
|
|
|
353
354
|
}
|
|
354
355
|
import sigma as _sigma
|
|
355
356
|
|
|
356
|
-
effective_policy = policy or _sigma.default_policy
|
|
357
|
+
effective_policy = policy or _sigma.policy.default_policy
|
|
357
358
|
if issubclass(transformation_class, TemplateBase):
|
|
358
359
|
params["policy"] = policy
|
|
359
360
|
params["restrict_template_path"] = not effective_policy.allow_external_sources
|
|
@@ -810,9 +811,9 @@ class ProcessingPipeline:
|
|
|
810
811
|
Prefer the policy attached to this pipeline and fall back to the
|
|
811
812
|
global default policy only if no pipeline policy is set.
|
|
812
813
|
"""
|
|
813
|
-
import
|
|
814
|
+
from sigma.policy import default_policy
|
|
814
815
|
|
|
815
|
-
return self.policy or
|
|
816
|
+
return self.policy or default_policy
|
|
816
817
|
|
|
817
818
|
def resolve_regex_engine(self) -> "RegexEngine":
|
|
818
819
|
"""Return the effective regex engine for this pipeline."""
|
|
@@ -826,6 +827,10 @@ class ProcessingPipeline:
|
|
|
826
827
|
) -> "ProcessingPipeline":
|
|
827
828
|
"""Instantiate processing pipeline from a parsed processing item description."""
|
|
828
829
|
|
|
830
|
+
# Validate aliases once at the pipeline root so nested from_dict calls don't
|
|
831
|
+
# repeatedly traverse already checked substructures.
|
|
832
|
+
check_alias_expansion(d, SigmaConfigurationError)
|
|
833
|
+
|
|
829
834
|
custom_keys = [
|
|
830
835
|
k
|
|
831
836
|
for k in d.keys()
|
|
@@ -845,7 +850,7 @@ class ProcessingPipeline:
|
|
|
845
850
|
|
|
846
851
|
import sigma as _sigma
|
|
847
852
|
|
|
848
|
-
effective_policy = policy or _sigma.default_policy
|
|
853
|
+
effective_policy = policy or _sigma.policy.default_policy
|
|
849
854
|
|
|
850
855
|
vars = d.get("vars", dict()) # default: no variables
|
|
851
856
|
|
|
@@ -938,7 +943,7 @@ class ProcessingPipeline:
|
|
|
938
943
|
import dataclasses
|
|
939
944
|
import sigma as _sigma
|
|
940
945
|
|
|
941
|
-
effective_policy = policy or _sigma.default_policy
|
|
946
|
+
effective_policy = policy or _sigma.policy.default_policy
|
|
942
947
|
if effective_policy.vars_allowed_paths is None and source_path is not None:
|
|
943
948
|
policy = dataclasses.replace(
|
|
944
949
|
effective_policy,
|
|
@@ -24,14 +24,14 @@ class ProcessingRegularExpressionMixin:
|
|
|
24
24
|
|
|
25
25
|
def resolve_regex_engine(self) -> RegexEngine:
|
|
26
26
|
"""Return the effective regex engine for this processing context."""
|
|
27
|
-
import
|
|
27
|
+
from sigma.policy import default_policy
|
|
28
28
|
|
|
29
29
|
_pipeline = getattr(self, "_pipeline", None)
|
|
30
30
|
if _pipeline is None:
|
|
31
31
|
_policy = getattr(self, "policy", None)
|
|
32
32
|
if _policy is not None:
|
|
33
33
|
return _policy.regex_engine # type: ignore[no-any-return]
|
|
34
|
-
return
|
|
34
|
+
return default_policy.regex_engine
|
|
35
35
|
return _pipeline.resolve_regex_engine() # type: ignore[no-any-return]
|
|
36
36
|
|
|
37
37
|
def compile_regex(self, pattern: str) -> RegexPattern:
|
|
@@ -27,6 +27,7 @@ import yaml
|
|
|
27
27
|
from sigma.exceptions import SigmaConfigurationError, SigmaSecurityError, SigmaValueError
|
|
28
28
|
from sigma.policy.regex_engine import RegexPattern
|
|
29
29
|
from sigma.processing.transformations.placeholder import BasePlaceholderTransformation
|
|
30
|
+
from sigma.rule.base import check_alias_expansion
|
|
30
31
|
from sigma.types import Placeholder, SigmaString
|
|
31
32
|
from typing import TYPE_CHECKING
|
|
32
33
|
|
|
@@ -207,6 +208,7 @@ class ExternalSourceBaseTransformation(BasePlaceholderTransformation):
|
|
|
207
208
|
parsed = yaml.safe_load(data)
|
|
208
209
|
except yaml.YAMLError as e:
|
|
209
210
|
raise SigmaValueError(f"Failed to parse YAML data: {e}") from e
|
|
211
|
+
check_alias_expansion(parsed, SigmaValueError)
|
|
210
212
|
try:
|
|
211
213
|
result = jq.all(self.jq_expression, parsed)
|
|
212
214
|
except ValueError as e:
|
|
@@ -76,6 +76,7 @@ class SigmaDetectionItem(ProcessingItemTrackingMixin, ParentChainMixin):
|
|
|
76
76
|
init=False, repr=False, hash=False, compare=False
|
|
77
77
|
) # Copy of original values for conversion back to data structures (and YAML/JSON)
|
|
78
78
|
auto_modifiers: bool = dataclasses.field(default=True, compare=False, repr=False)
|
|
79
|
+
policy: "SigmaPolicy | None" = dataclasses.field(default=None, compare=False, repr=False)
|
|
79
80
|
|
|
80
81
|
def __post_init__(self: Self) -> None:
|
|
81
82
|
if not isinstance(self.value, list) or not all(
|
|
@@ -116,6 +117,7 @@ class SigmaDetectionItem(ProcessingItemTrackingMixin, ParentChainMixin):
|
|
|
116
117
|
key: str | None,
|
|
117
118
|
val: list[float | str | bool | None] | float | str | bool | None,
|
|
118
119
|
source: SigmaRuleLocation | None = None,
|
|
120
|
+
policy: "SigmaPolicy | None" = None,
|
|
119
121
|
) -> Self:
|
|
120
122
|
"""
|
|
121
123
|
Constructs SigmaDetectionItem object from a mapping between field name containing
|
|
@@ -155,16 +157,17 @@ class SigmaDetectionItem(ProcessingItemTrackingMixin, ParentChainMixin):
|
|
|
155
157
|
for v in val_list
|
|
156
158
|
]
|
|
157
159
|
|
|
158
|
-
return cls(field, modifiers, sigma_val, source=source)
|
|
160
|
+
return cls(field, modifiers, sigma_val, source=source, policy=policy)
|
|
159
161
|
|
|
160
162
|
@classmethod
|
|
161
163
|
def from_value(
|
|
162
164
|
cls: type[Self],
|
|
163
165
|
val: list[float | str | bool | None] | float | str | bool | None,
|
|
164
166
|
source: SigmaRuleLocation | None = None,
|
|
167
|
+
policy: "SigmaPolicy | None" = None,
|
|
165
168
|
) -> Self:
|
|
166
169
|
"""Convenience method for from_mapping(None, value)."""
|
|
167
|
-
return cls.from_mapping(None, val, source=source)
|
|
170
|
+
return cls.from_mapping(None, val, source=source, policy=policy)
|
|
168
171
|
|
|
169
172
|
def disable_conversion_to_plain(self: Self) -> None:
|
|
170
173
|
"""
|
|
@@ -315,19 +318,20 @@ class SigmaDetection(ParentChainMixin):
|
|
|
315
318
|
Mapping[str, Any] | list[int | float | str | bool | None] | float | str | bool | None
|
|
316
319
|
),
|
|
317
320
|
source: SigmaRuleLocation | None = None,
|
|
321
|
+
policy: "SigmaPolicy | None" = None,
|
|
318
322
|
) -> Self:
|
|
319
323
|
"""Instantiate an appropriate SigmaDetection object from a parsed Sigma detection definition."""
|
|
320
324
|
if isinstance(definition, Mapping): # key-value-definition (case 1)
|
|
321
325
|
return cls(
|
|
322
326
|
detection_items=[
|
|
323
|
-
SigmaDetectionItem.from_mapping(key, val, source)
|
|
327
|
+
SigmaDetectionItem.from_mapping(key, val, source, policy)
|
|
324
328
|
for key, val in definition.items()
|
|
325
329
|
],
|
|
326
330
|
source=source,
|
|
327
331
|
)
|
|
328
332
|
elif isinstance(definition, (str, int, float, bool, type(None))): # plain value (case 2)
|
|
329
333
|
return cls(
|
|
330
|
-
detection_items=[SigmaDetectionItem.from_value(definition, source)],
|
|
334
|
+
detection_items=[SigmaDetectionItem.from_value(definition, source, policy)],
|
|
331
335
|
source=source,
|
|
332
336
|
)
|
|
333
337
|
elif isinstance(definition, list): # list of items (case 3)
|
|
@@ -335,14 +339,14 @@ class SigmaDetection(ParentChainMixin):
|
|
|
335
339
|
{str, int, float, bool, type(None)}
|
|
336
340
|
): # list of values: create one detection item containing all values
|
|
337
341
|
return cls(
|
|
338
|
-
detection_items=[SigmaDetectionItem.from_value(definition, source)],
|
|
342
|
+
detection_items=[SigmaDetectionItem.from_value(definition, source, policy)],
|
|
339
343
|
source=source,
|
|
340
344
|
)
|
|
341
345
|
else:
|
|
342
346
|
return cls(
|
|
343
347
|
detection_items=[
|
|
344
348
|
SigmaDetection.from_definition(
|
|
345
|
-
item, source
|
|
349
|
+
item, source, policy
|
|
346
350
|
) # nested SigmaDetection in other cases
|
|
347
351
|
for item in definition
|
|
348
352
|
],
|
|
@@ -548,7 +552,7 @@ class SigmaDetections:
|
|
|
548
552
|
check_alias_expansion(detections, sigma_exceptions.SigmaDetectionError, source)
|
|
549
553
|
return cls(
|
|
550
554
|
detections={
|
|
551
|
-
name: SigmaDetection.from_definition(definition, source)
|
|
555
|
+
name: SigmaDetection.from_definition(definition, source, policy)
|
|
552
556
|
for name, definition in detections.items()
|
|
553
557
|
if name not in ("condition",)
|
|
554
558
|
},
|
|
@@ -128,6 +128,7 @@ class SigmaString(SigmaType):
|
|
|
128
128
|
s: list[
|
|
129
129
|
SigmaStringPartType
|
|
130
130
|
] # the string is represented as sequence of strings and characters with special meaning
|
|
131
|
+
max_placeholder_expansions: ClassVar[int] = 200
|
|
131
132
|
|
|
132
133
|
def __init__(self, s: str | None = None, escape: bool = True):
|
|
133
134
|
"""
|
|
@@ -544,6 +545,8 @@ class SigmaString(SigmaType):
|
|
|
544
545
|
|
|
545
546
|
The callback can return a plain string, a SpecialChars instance (for insertion of wildcards) or a Placeholder (e.g. to keep
|
|
546
547
|
the placeholder for later processing pipeline items).
|
|
548
|
+
|
|
549
|
+
The total number of expanded strings is limited to max_placeholder_expansions.
|
|
547
550
|
"""
|
|
548
551
|
if (
|
|
549
552
|
not self.contains_placeholder()
|
|
@@ -558,15 +561,20 @@ class SigmaString(SigmaType):
|
|
|
558
561
|
placeholder = s[i]
|
|
559
562
|
suffix = SigmaString()
|
|
560
563
|
suffix.s = s[i + 1 :]
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
) # iterate over all callback result values
|
|
564
|
+
results: list[SigmaString] = []
|
|
565
|
+
for replacement in callback(
|
|
566
|
+
cast(Placeholder, placeholder)
|
|
567
|
+
): # iterate over all callback result values
|
|
566
568
|
for result_suffix in suffix.replace_placeholders(
|
|
567
569
|
callback
|
|
568
|
-
) # iterate over all result values of calling this method with the SigmaString remainder
|
|
569
|
-
|
|
570
|
+
): # iterate over all result values of calling this method with the SigmaString remainder
|
|
571
|
+
results.append(prefix + replacement + result_suffix)
|
|
572
|
+
if len(results) > self.max_placeholder_expansions:
|
|
573
|
+
raise SigmaValueError(
|
|
574
|
+
"Placeholder expansion exceeds maximum of "
|
|
575
|
+
f"{self.max_placeholder_expansions} items"
|
|
576
|
+
)
|
|
577
|
+
return results
|
|
570
578
|
return [self]
|
|
571
579
|
|
|
572
580
|
def __iter__(self) -> Iterable[SigmaStringPartType]:
|
|
@@ -828,9 +836,9 @@ class SigmaRegularExpression(SigmaType):
|
|
|
828
836
|
|
|
829
837
|
def compile(self) -> None:
|
|
830
838
|
"""Verify if regular expression is valid by compiling it"""
|
|
831
|
-
import
|
|
839
|
+
from sigma.policy import default_policy
|
|
832
840
|
|
|
833
|
-
engine = (self.policy or
|
|
841
|
+
engine = (self.policy or default_policy).regex_engine
|
|
834
842
|
try:
|
|
835
843
|
flags = 0
|
|
836
844
|
for flag in self.flags:
|
|
@@ -3,6 +3,7 @@ from typing import Any, DefaultDict, Iterable, Iterator, Type
|
|
|
3
3
|
from uuid import UUID
|
|
4
4
|
from sigma.exceptions import SigmaConfigurationError, SigmaValidatorConfigurationParsingError
|
|
5
5
|
from sigma.rule import SigmaRule
|
|
6
|
+
from sigma.rule.base import check_alias_expansion
|
|
6
7
|
from sigma.validators.base import SigmaRuleValidator, SigmaValidationIssue
|
|
7
8
|
import yaml
|
|
8
9
|
|
|
@@ -56,6 +57,8 @@ class SigmaValidator:
|
|
|
56
57
|
:return: Instantiated SigmaValidator
|
|
57
58
|
:rtype: SigmaValidator
|
|
58
59
|
"""
|
|
60
|
+
check_alias_expansion(d, SigmaConfigurationError)
|
|
61
|
+
|
|
59
62
|
# Build validator class set
|
|
60
63
|
vs = set()
|
|
61
64
|
for v in d.get("validators", []):
|
pysigma-2.0.0/sigma/__init__.py
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|