Sigma Rules¶
This documentation page describes the parsing of Sigma rules and working with Sigma objects resulting from parsed rules.
Parsing¶
Programatic Construction¶
Rule Collections¶
- class sigma.collection.SigmaCollection(init_rules: dataclasses.InitVar[list[sigma.rule.rule.SigmaRule | sigma.correlations.SigmaCorrelationRule | sigma.filters.SigmaFilter]], errors: list[~sigma.exceptions.SigmaError] = <factory>, collect_filters: dataclasses.InitVar[bool] = False, resolve_references: dataclasses.InitVar[bool] = True, rules: list[~sigma.rule.rule.SigmaRule | ~sigma.correlations.SigmaCorrelationRule] = <factory>, filters: list[~sigma.filters.SigmaFilter] = <factory>)¶
Collection of Sigma rules
- apply_filters(filters: list[SigmaFilter]) None¶
Apply filters on each rule and replace the rule with the filtered rule
- classmethod from_dicts(rules: list[dict[str, str | int | float | bool | None | dict[str, str | int | float | bool | None | NestedDict]]], collect_errors: bool = False, source: SigmaRuleLocation | None = None, collect_filters: bool = False, resolve_references: bool = True) Self¶
Generate a rule collection from list of dicts containing parsed YAML content.
If the collect_errors parameters is set, exceptions are not raised while parsing but collected in the errors property individually for each Sigma rule and the whole SigmaCollection.
If collect_filters is set, filters are only collected in the collection but not yet applied to the rules.
- classmethod from_yaml(yaml_str: bytes | str | IO[Any], collect_errors: bool = False, source: SigmaRuleLocation | None = None, collect_filters: bool = False, resolve_references: bool = True) Self¶
Generate a rule collection from a string containing one or multiple YAML documents.
If the collect_errors parameters is set, exceptions are not raised while parsing but collected in the errors property individually for each Sigma rule and the whole SigmaCollection.
If collect_filters is set, filters are only collected in the collection but not yet applied to the rules.
- get_output_rules() Iterable[SigmaRuleBase]¶
Returns an iterator across all rules where the output property is set to true
- get_unreferenced_rules() Iterable[SigmaRuleBase]¶
Returns an iterator across all rules that are not referenced by any other rule
- classmethod load_ruleset(inputs: list[str | Path], collect_errors: bool = False, on_beforeload: Callable[[Path], Path | None] | None = None, on_load: Callable[[Path, SigmaCollection], SigmaCollection | None] | None = None, recursion_pattern: str = '**/*.yml', resolve_references: bool = True) Self¶
Load a ruleset from a list of files or directories and construct a
SigmaCollectionobject.- Parameters:
inputs – List of strings and
pathlib.Pathobjects that reference files or
directories that should be loaded. :param collect_errors: parse or verification errors are collected in
SigmaRuleBaseobjects instead of raising them immediately. Defaults toFalse. :param on_beforeload: Optional function that is called for each path to a Sigma rule before the parsing and construction of theSigmaCollectionobject is done. The path returned by this function is used as input. A rule path is skipped ifNoneis returned. :param on_load: Optional function that is called after theSigmaCollectionwas constructed from the path. The path and the SigmaCollection object are passed to this function and it is expected to return aSigmaCollectionobject that is merged in the collection of the ruleset orNoneif the generated collection should be skipped. :param recursion_pattern: Pattern used to recurse into directories, defaults to**/*.yml.- Returns:
SigmaCollectionof all sigma rules contained in given paths.
- classmethod merge(collections: Iterable[SigmaCollection], resolve_references: bool = True) Self¶
Merge multiple SigmaCollection objects into one and return it.
- classmethod resolve_paths(inputs: list[str | Path], recursion_pattern: str = '**/*.yml') Iterable[Path]¶
Resolve list of paths inputs that can contain files as well as directories into a flat list of files matching resursion_pattern.
- resolve_rule_references() None¶
Resolve rule references in correlation rules to the actual rule objects and sort the rules by reference order (rules that are referenced by other rules come first).
This must be called before referencing rules are converted into queries to make references available.
Rule Object Model¶
SigmaRule¶
- class sigma.rule.rule.SigmaRule(title: str = '', id: UUID | None = None, name: str | None = None, taxonomy: str = 'sigma', related: SigmaRelated | None = None, status: SigmaStatus | None = None, description: str | None = None, license: str | None = None, references: list[str] = <factory>, tags: list[SigmaRuleTag] = <factory>, author: str | None = None, date: dt.date | None = None, modified: dt.date | None = None, fields: list[str] = <factory>, falsepositives: list[str] = <factory>, level: SigmaLevel | None = None, scope: list[str] | None = None, errors: list[sigma_exceptions.SigmaError] = <factory>, source: SigmaRuleLocation | None = None, custom_attributes: dict[str, Any] = <factory>, logsource: SigmaLogSource = <factory>, detection: SigmaDetections = <factory>)¶
A single Sigma rule.
- classmethod from_dict(rule: dict[str, Any], collect_errors: bool = False, source: SigmaRuleLocation | None = None) Self¶
Convert Sigma rule parsed in dict structure into SigmaRule object.
if collect_errors is set to False exceptions are collected in the errors property of the resulting SigmaRule object. Else the first recognized error is raised as exception.
- classmethod from_yaml(rule: str, collect_errors: bool = False) Self¶
Convert YAML input string with single document into SigmaRule object.
- to_dict() dict[str, Any]¶
Convert rule object into dict.
SigmaRuleBase¶
- class sigma.rule.base.SigmaRuleBase(title: 'str' = '', id: 'UUID | None' = None, name: 'str | None' = None, taxonomy: 'str' = 'sigma', related: 'SigmaRelated | None' = None, status: 'SigmaStatus | None' = None, description: 'str | None' = None, license: 'str | None' = None, references: 'list[str]' = <factory>, tags: 'list[SigmaRuleTag]' = <factory>, author: 'str | None' = None, date: 'dt.date | None' = None, modified: 'dt.date | None' = None, fields: 'list[str]' = <factory>, falsepositives: 'list[str]' = <factory>, level: 'SigmaLevel | None' = None, scope: 'list[str] | None' = None, errors: 'list[sigma_exceptions.SigmaError]' = <factory>, source: 'SigmaRuleLocation | None' = None, custom_attributes: 'dict[str, Any]' = <factory>)¶
- add_backreference(rule: SigmaRuleBase) None¶
Add backreference to another rule.
- disable_output() None¶
Disable output of rule.
- abstractmethod classmethod from_dict(rule: dict[str, Any], collect_errors: bool = False) Self¶
Convert dict input into SigmaRule object.
- classmethod from_dict_common_params(rule: dict[str, Any], collect_errors: bool = False, source: SigmaRuleLocation | None = None) tuple[dict[str, Any], list[SigmaError]]¶
Convert Sigma rule base parsed in dict structure into kwargs dict that can be passed to the class instantiation of an object derived from the SigmaRuleBase class and the errors list. This is intended to be called only by to_dict() methods for processing the general parameters defined in the base class.
if collect_errors is set to False exceptions are collected in the errors property of the resulting SigmaRule object. Else the first recognized error is raised as exception.
- classmethod from_yaml(rule: str, collect_errors: bool = False) Self¶
Convert YAML input string with single document into SigmaRule object.
- get_conversion_result() list[Any]¶
Get conversion result.
- get_conversion_states() list[ConversionState]¶
Get conversion state.
- referenced_by(rule: SigmaRuleBase) bool¶
Check if rule is referenced by another rule.
- set_conversion_result(result: list[Any]) None¶
Set conversion result.
- set_conversion_states(state: list[ConversionState]) None¶
Set conversion state.
- to_dict() dict[str, Any]¶
Convert rule object into dict.
SigmaYAMLLoader¶
- class sigma.rule.base.SigmaYAMLLoader(stream)¶
Custom YAML loader implementing additional functionality for Sigma.
SigmaLogSource¶
- class sigma.rule.logsource.SigmaLogSource(category: str | None = None, product: str | None = None, service: str | None = None, definition: str | None = None, source: sigma.exceptions.SigmaRuleLocation | None = None, custom_attributes: dict[str, Any] | None = None)¶
- classmethod from_dict(logsource: dict[str, str], source: SigmaRuleLocation | None = None) SigmaLogSource¶
Returns SigmaLogSource object from dict with fields.
EmptyLogSource¶
- class sigma.rule.logsource.EmptyLogSource(category: str | None = None, product: str | None = None, service: str | None = None, definition: str | None = None, source: SigmaRuleLocation | None = None, custom_attributes: dict[str, Any] | None = None)¶
Log sources can’t be empty, but this class is used to represent an empty log source as dummy for error handling purposes.
SigmaDetections¶
- class sigma.rule.detection.SigmaDetections(detections: dict[str, SigmaDetection], condition: list[str], source: SigmaRuleLocation | None = None)¶
Sigma detection section including named detections and condition.
EmptySigmaDetections¶
- class sigma.rule.detection.EmptySigmaDetections(detections: dict[str, ~sigma.rule.detection.SigmaDetection] = <factory>, condition: list[str] = <factory>, source: ~sigma.exceptions.SigmaRuleLocation | None = None)¶
Empty Sigma detection that is used as a placeholder for error handling purposes.
SigmaDetection¶
- class sigma.rule.detection.SigmaDetection(detection_items: list[SigmaDetectionItem | SigmaDetection], source: SigmaRuleLocation | None = None, item_linking: type[ConditionAND | ConditionOR] | None = None)¶
A detection is a set of atomic event definitions represented by SigmaDetectionItem instances. SigmaDetectionItems of a SigmaDetection are OR-linked.
A detection can be defined by:
a mapping between field/value pairs that all should appear in matched events.
a plain value
a list of plain values or mappings defined and matched as in 1 where at least one of the items should appear in matched events.
- add_applied_processing_item(processing_item: ProcessingItemBase | None) None¶
Propagate processing item to all contained detection items.
- classmethod from_definition(definition: Mapping[str, Any] | list[int | float | str | bool | None] | float | str | bool | None, source: SigmaRuleLocation | None = None) Self¶
Instantiate an appropriate SigmaDetection object from a parsed Sigma detection definition.
- postprocess(detections: SigmaDetections, parent: SigmaDetection | SigmaDetectionItem | ConditionItem | None = None, source: SigmaRuleLocation | None = None) ConditionItem | ConditionFieldEqualsValueExpression | ConditionValueExpression | None¶
Convert detection item into condition tree element
- to_plain() dict[str, Any] | list[Any] | str | int | float | bool | None¶
Returns a dictionary or list representation of the detection.
SigmaDetectionItem¶
- class sigma.rule.detection.SigmaDetectionItem(field: str | None, modifiers: list[type[~sigma.modifiers.SigmaModifier[~typing.Any, ~typing.Any]]], value: list[~sigma.types.SigmaType], value_linking: type[~sigma.conditions.ConditionAND | ~sigma.conditions.ConditionOR] = <class 'sigma.conditions.ConditionOR'>, source: ~sigma.exceptions.SigmaRuleLocation | None = None, auto_modifiers: bool = True)¶
Single Sigma detection definition
A detection consists of: * an optional field name * a list of value modifiers that can also be empty * the mandatory value or a list of values (internally it’s always a list of values)
By default all values are OR-linked but the ‘all’ modifier can be used to override this behavior.
If the auto_modifiers parameter is set to False, modifiers are not automatically applied to the values. This shouldn’t normally be used, but only in test scenarios.
- apply_modifiers() None¶
Applies modifiers to detection and values
- disable_conversion_to_plain() None¶
Mark detection item as not convertible to plain data type. This is required in cases where the value and original value get out of sync, e.g. because transformation are applied and conversion with to_plain() would yield an outdated state.
- classmethod from_mapping(key: str | None, val: list[float | str | bool | None] | float | str | bool | None, source: SigmaRuleLocation | None = None) Self¶
Constructs SigmaDetectionItem object from a mapping between field name containing modifiers and a value. This also supports keys containing only value modifiers which results in a keyword detection.
The value accepts plain values as well as lists of values and resolves them into the value list always contained in a SigmaDetectionItem instance.
- classmethod from_value(val: list[float | str | bool | None] | float | str | bool | None, source: SigmaRuleLocation | None = None) Self¶
Convenience method for from_mapping(None, value).
- is_keyword() bool¶
Returns True if detection item is a keyword detection without field reference.
- postprocess(detections: SigmaDetections, parent: SigmaDetection | SigmaDetectionItem | ConditionItem | None = None, source: SigmaRuleLocation | None = None) ConditionItem | ConditionAND | ConditionOR | ConditionFieldEqualsValueExpression | ConditionValueExpression | None¶
Minimal default postprocessing implementation for classes which don’t bring their own postprocess method. Just sets the parent and source property.
- to_plain() dict[str, Any] | list[Any] | str | int | float | bool | None¶
Convert detection item into plain Python type, that can be:
a plain value if it is a single plain keyword value.
a list of values if it is a list of keyword values
a dict in all other cases (detection item bound to field or keyword with modifiers)
- value_linking¶
alias of
ConditionOR
SigmaRuleTag¶
- class sigma.rule.attributes.SigmaRuleTag(namespace: str, name: str, source: sigma.exceptions.SigmaRuleLocation | None = None)¶
- classmethod from_str(tag: str, source: SigmaRuleLocation | None = None) SigmaRuleTag¶
Build SigmaRuleTag class from plain text tag string.
SigmaLevel¶
- class sigma.rule.attributes.SigmaLevel(*values)¶
SigmaStatus¶
- class sigma.rule.attributes.SigmaStatus(*values)¶
EnumLowercaseStringMixin¶
- class sigma.rule.attributes.EnumLowercaseStringMixin¶
Sigma Data Types¶
SigmaString¶
- class sigma.types.SigmaString(s: str | None = None, escape: bool = True)¶
Strings in Sigma detection values containing wildcards.
- contains_placeholder(include: list[str] | None = None, exclude: list[str] | None = None) bool¶
Check if string contains placeholders and if any placeholder name is
contained on the include list (if there is one)
not contained on the include list (if there is one)
It is sufficient that one placeholder matches these conditions. The purpose of this method is to determine if there are placeholders for further processing.
- contains_special() bool¶
Check if string contains special characters.
- convert(escape_char: str | None = '\\', wildcard_multi: str | None = '*', wildcard_single: str | None = '?', add_escaped: str = '', filter_chars: str = '') str¶
Convert SigmaString into a query string or pattern. The following parameters allow to change the behavior:
escape_char: the character used to escape special characters. By default these are only the wildcard characters.
wildcard_multi and wildcard_single: strings that should be output as wildcards for multiple and single characters.
add_escaped: characters which are escaped in addition to the wildcards
filter_chars: characters that are filtered out.
Setting one of the wildcard or multiple parameters to None indicates that this feature is not supported. Appearance of these characters in a string will raise a SigmaValueError.
- endswith(val: str | SpecialChars | Placeholder) bool¶
Check if string ends with a given string or special character.
- insert_placeholders() SigmaString¶
Replace %something% placeholders with Placeholder stub objects that can be later handled by the processing pipeline. This implements the expand modifier.
- replace_placeholders(callback: Callable[[Placeholder], Iterator[str | SpecialChars | Placeholder | SigmaString]]) list[SigmaString]¶
Iterate over all placeholders and call the callback for each one. The callback is called with the placeholder instance as argument and yields replacement values (plain strings or SpecialChars instances). Each yielded replacement value is concatenated to the SigmaString prefix before the placeholder and the method is called recursively with the suffix after the placeholder. All placeholder replacements are combined with all returned SigmaString suffixes. Therefore, the callback could be called multiple times with the same placeholder instance and should return the same results to ensure a consistent result.
The callback can return a plain string, a SpecialChars instance (for insertion of wildcards) or a Placeholder (e.g. to keep the placeholder for later processing pipeline items).
- replace_with_placeholder(regex: Pattern[str], placeholder_name: str) SigmaString¶
Replace all occurrences of string part matching regular expression with placeholder.
- Parameters:
regex (Pattern) – regular expression that should be matched.
placeholder_name (str) – name of placeholder that should be inserted.
- Returns:
Returns a string with the replacement placeholders.
- Return type:
- startswith(val: str | SpecialChars | Placeholder) bool¶
Check if string starts with a given string or special character.
- to_plain(regex: bool = False) str¶
Generate string representation of SigmaString with or without regex escaping.
- to_plain_regex() str¶
Return plain string representation of SigmaString with reduced escaping.
- to_regex(custom_escaped: str = '') SigmaRegularExpression¶
Convert SigmaString into a regular expression.
SigmaNumber¶
- class sigma.types.SigmaNumber(init_number: dataclasses.InitVar[Any])¶
Numeric value type
SigmaBool¶
- class sigma.types.SigmaBool(boolean: bool)¶
Boolean value type
SigmaNull¶
- class sigma.types.SigmaNull(dummy: Any | None = None)¶
Empty/none/null value
SigmaRegularExpression¶
- class sigma.types.SigmaRegularExpression(regexp_init: dataclasses.InitVar[typing.Union[sigma.types.SigmaString, str]], flags: set[~sigma.types.SigmaRegularExpressionFlag] = <factory>)¶
Regular expression type
- compile() None¶
Verify if regular expression is valid by compiling it
- escape(escaped: list[str] = (), escape_char: str = '\\', escape_escape_char: bool = True, flag_prefix: bool = True) str¶
Escape strings from escaped tuple as well as escape_char itself (can be disabled with escape_escape_char) with escape_char. Prepends a (?…) expression with set flags (i, m and s) if flag_prefix is set.
- insert_placeholders() SigmaRegularExpression¶
Replace %something% placeholders with Placeholder stub objects that can be later handled by the processing pipeline. This implements the expand modifier.
- replace_placeholders(callback: Callable[[Placeholder], Iterator[str | SpecialChars | Placeholder | SigmaString]]) list[SigmaRegularExpression]¶
Replace all occurrences of string part matching regular expression with placeholder.
- to_plain() str¶
Return plain Python value (str, int etc.) from SigmaType instance for usage in conversion of Sigma rules back to dicts. Uses the first annotated member as return value.
SigmaCIDRExpression¶
- class sigma.types.SigmaCIDRExpression(cidr: str, source: SigmaRuleLocation | None = None)¶
CIDR IP address range expression type
- expand(wildcard: str = '*') list[str]¶
Convert CIDR range into a list of wildcard patterns or plain CIDR notation. The following parameters allow to change the behavior:
wildcard: string that should be output as wildcard. Usually not required because this is passed to SigmaString that generates a wildcard pecial character from ‘*’ that is converted into possible individual wildcard characters.
Setting wildcard to None indicates that this feature is not need and the query language handles CIDR notation properly.
SigmaCompareExpression¶
- class sigma.types.SigmaCompareExpression(number: SigmaNumber, op: CompareOperators, source: SigmaRuleLocation | None = None)¶
Type for numeric comparison.
- class CompareOperators(*values)¶
SigmaQueryExpression¶
- class sigma.types.SigmaQueryExpression(expr: str, id: str)¶
Special purpose type for passing a query part (e.g. list lookups in placeholders) directly into the generated query. The query string may contain a {field} placeholder, which is replaced with the field name contained in the detection item containing the query expression. This is done by the finalize method.
Because this is very specific to the target language, it has to be used in late stages of the conversion process by backend-specific processing pipelines or the backend itself.