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 SigmaCollection object.

Parameters:

inputs – List of strings and pathlib.Path objects that reference files or

directories that should be loaded. :param collect_errors: parse or verification errors are collected in SigmaRuleBase objects instead of raising them immediately. Defaults to False. :param on_beforeload: Optional function that is called for each path to a Sigma rule before the parsing and construction of the SigmaCollection object is done. The path returned by this function is used as input. A rule path is skipped if None is returned. :param on_load: Optional function that is called after the SigmaCollection was constructed from the path. The path and the SigmaCollection object are passed to this function and it is expected to return a SigmaCollection object that is merged in the collection of the ruleset or None if the generated collection should be skipped. :param recursion_pattern: Pattern used to recurse into directories, defaults to **/*.yml.

Returns:

SigmaCollection of 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:

  1. a mapping between field/value pairs that all should appear in matched events.

  2. a plain value

  3. 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

SigmaRelatedType

class sigma.rule.attributes.SigmaRelatedType(*values)

SigmaRelatedItem

class sigma.rule.attributes.SigmaRelatedItem(id: uuid.UUID, type: sigma.rule.attributes.SigmaRelatedType)
classmethod from_dict(value: dict[str, str]) SigmaRelatedItem

Returns Related item from dict with fields.

SigmaRelated

class sigma.rule.attributes.SigmaRelated(related: list[sigma.rule.attributes.SigmaRelatedItem])
classmethod from_dict(val: list[dict[str, str]]) SigmaRelated

Returns Related object from dict with fields.

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:

SigmaString

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.