sigma.schema module¶
Sigma rule schema is the core functionality of this package. The rule schema allows
you to generically read and write Sigma rules in Python. Rules can be loaded from
a dictionary or directly from a YAML file. You can also reproduce compliant Sigma
rules from in-memory representations with the Rule.to_sigma()
method. This
can be used to load, modify and save sigma rules without conversion if needed.
Sigma rule detection conditions can also be parsed using the pyparsing
package
into a python-native format, which is normally used in conjunction with a serializer.
from sigma.schema import Rule
rule = Rule.from_yaml("path/to/rule.yml")
# Retrieve common properties
print(rule.title)
print(rule.detection.condition)
print(rule.tags)
print(rule.author)
# Retrieve a parsed expression representing the full detection condition
print(rule.detection.expression)
- class sigma.schema.BaseCorrelation(*, action: Literal['correlation'], name: str, rule: Union[str, List[str]], type: sigma.schema.CorrelationType, timespan: sigma.schema.ConstrainedStrValue, level: sigma.schema.RuleLevel, **extra_data: Any)¶
Bases:
pydantic.main.BaseModel
- action: Literal['correlation']¶
A correlation action
- group_by: Optional[Union[str, List[str]]]¶
Optional field to group results by
- level: sigma.schema.RuleLevel¶
A rule level to apply to the correlation of all rules
- name: str¶
Name of this correlation
- rule: Union[str, List[str]]¶
List of rule titles or correlation names also specified in the same file.
- timespan: str¶
A timespan used for correlating events (e.g. 5m, 3d or 30s)
- type: sigma.schema.CorrelationType¶
Type of correlation to be used
- class sigma.schema.Correlation(data: Union[sigma.schema.CountCorrelation, sigma.schema.TemporalCorrelation], rules: List[Union[sigma.schema.Rule, sigma.schema.Correlation]])¶
Bases:
object
An object representing a collection of rules bound by a correlation
- class sigma.schema.CorrelationGreaterThan(*, gt: int)¶
Bases:
sigma.schema.CorrelationSimpleCondition
- gt: int¶
- class sigma.schema.CorrelationGreaterThanEqual(*, gte: int)¶
Bases:
sigma.schema.CorrelationSimpleCondition
- gte: int¶
- class sigma.schema.CorrelationLessThan(*, lt: int)¶
Bases:
sigma.schema.CorrelationSimpleCondition
- lt: int¶
- class sigma.schema.CorrelationLessThanEqual(*, lte: int)¶
Bases:
sigma.schema.CorrelationSimpleCondition
- lte: int¶
- class sigma.schema.CorrelationRange(*, range: sigma.schema.ConstrainedStrValue)¶
Bases:
pydantic.main.BaseModel
- property maximum: int¶
- property minimum: int¶
- range: str¶
- class sigma.schema.CorrelationType(value)¶
Bases:
str
,enum.Enum
An enumeration.
- EVENT_COUNT = 'event_count'¶
- TEMPORAL = 'temporal'¶
- VALUE_COUNT = 'value_count'¶
- class sigma.schema.CountCorrelation(*, action: typing.Literal['correlation'], name: str, rule: typing.Union[str, typing.List[str]], type: typing.Union[typing.Literal[<CorrelationType.EVENT_COUNT: 'event_count'>], typing.Literal[<CorrelationType.VALUE_COUNT: 'value_count'>]], timespan: sigma.schema.ConstrainedStrValue, level: sigma.schema.RuleLevel, condition: typing.Union[sigma.schema.CorrelationLessThan, sigma.schema.CorrelationLessThanEqual, sigma.schema.CorrelationGreaterThan, sigma.schema.CorrelationGreaterThanEqual, sigma.schema.CorrelationRange], **extra_data: typing.Any)¶
Bases:
sigma.schema.BaseCorrelation
- condition: Union[sigma.schema.CorrelationLessThan, sigma.schema.CorrelationLessThanEqual, sigma.schema.CorrelationGreaterThan, sigma.schema.CorrelationGreaterThanEqual, sigma.schema.CorrelationRange]¶
- type: Union[Literal[<CorrelationType.EVENT_COUNT: 'event_count'>], Literal[<CorrelationType.VALUE_COUNT: 'value_count'>]]¶
Type of correlation to be used
- class sigma.schema.IncludeSchema(*, action: Literal['include'], filename: pydantic.types.FilePath)¶
Bases:
pydantic.main.BaseModel
Defines a YAML document which includes an outside rule or correlation
- action: Literal['include']¶
- filename: pydantic.types.FilePath¶
- load() sigma.schema.Rule ¶
Load the specified included file
- class sigma.schema.LowercaseString¶
Bases:
str
- class sigma.schema.Rule(*, title: sigma.schema.ConstrainedStrValue, id: uuid.UUID = None, related: List[sigma.schema.RuleRelation] = None, status: sigma.schema.RuleStatus = None, description: sigma.schema.ConstrainedStrValue = None, author: str = None, license: str = None, references: List[str] = None, logsource: sigma.schema.RuleLogSource, detection: sigma.schema.RuleDetection, fields: List[str] = None, falsepositives: List[Union[None, str]] = None, level: sigma.schema.RuleLevel = None, tags: List[sigma.schema.RuleTag] = None, date: Optional[Union[sigma.schema.SimpleDate, str]] = None, modified: Optional[Union[sigma.schema.SimpleDate, str]] = None, **extra_data: Any)¶
Bases:
pydantic.main.BaseModel
Sigma Rule Specification
- class Config¶
Bases:
object
- extra = 'allow'¶
- schema_extra = {'examples': [{'title': 'Windows Credential Editor', 'id': '7aa7009a-28b9-4344-8c1f-159489a390df', 'description': 'Detects the use of Windows Credential Editor (WCE)', 'status': 'experimental', 'author': 'Florian Roth', 'references': ['https://www.ampliasecurity.com/research/windows-credentials-editor/'], 'date': '2019/12/31', 'modified': '2021/07/15', 'tags': ['attack.credential_access', 'attack.t1003.001', 'attack.s0005'], 'logsource': {'category': 'process_creation', 'product': 'windows'}, 'detection': {'selection1': {'Imphash': ['a53a02b997935fd8eedcb5f7abab9b9f', 'e96a73c7bf33a464c510ede582318bf2']}, 'selection2': {'CommandLine|endswith': '.exe -S', 'ParentImage|endswith': '\\services.exe'}, 'filter': {'Image|endswith': '\\clussvc.exe'}, 'condition': '( selection1 or selection2 ) and not filter'}, 'falsepositives': ['Another service that uses a single -s command line switch'], 'level': 'critical'}]}¶
- author: Optional[str]¶
Creator of the rule
- date: Optional[Union[sigma.schema.SimpleDate, str]]¶
The date the rule was created. This should be YYYY-MM-DD or YYYY/MM/DD. If the field is not formatted in this way, it will be saved as a simple string.
- description: Optional[str]¶
A short description of the rule and the malicious activity that can be detected (max. 65,535 characters).
- detection: sigma.schema.RuleDetection¶
A set of search-identifiers that represent searches on log data.
- falsepositives: Optional[List[Union[None, str]]]¶
A list of known false positives that may occur.
- fields: Optional[List[str]]¶
A list of log fields that could be interesting in further analysis of the event and should be displayed to the analyst.
- classmethod from_sigma(definition: Dict[str, Any]) sigma.schema.Rule ¶
Alias for parse_obj to be more expressive
- classmethod from_yaml(path: Union[str, pathlib.Path]) sigma.schema.Rule ¶
Load a rule from a YAML file
- id: Optional[uuid.UUID]¶
Sigma rules should be identified by a globally unique identifier in the id attribute.
- level: Optional[sigma.schema.RuleLevel]¶
The level field contains one of five string values. It describes the criticality of a triggered rule.
- license: Optional[str]¶
SPDX License Name
- logsource: sigma.schema.RuleLogSource¶
This section describes the log data on which the detection is meant to be applied to. It describes the log source, the platform, the application and the type that is required in detection.
- modified: Optional[Union[sigma.schema.SimpleDate, str]]¶
The date the rule was last modified. This should be YYYY-MM-DD or YYYY/MM/DD. If the field is not formatted in this way, it will be saved as a simple string.
- classmethod parse_obj(obj: Any) sigma.schema.Rule ¶
- references: Optional[List[str]]¶
References to the source that the rule was derived from. These could be blog articles, technical papers, presentations or even tweets.
List of rule IDs and associated relationships to this rule.
- status: Optional[sigma.schema.RuleStatus]¶
Declares the status of the rule.
- tags: Optional[List[sigma.schema.RuleTag]]¶
A Sigma rule can be categorised with tags.
- title: str¶
A brief title for the rule that should contain what the rules is supposed to detect (max. 256 characters).
- to_sigma() Dict[str, Any] ¶
Convert this rule back into a JSON-serializable dictionary representing the sigma rule. This dictionary can safely be converted to JSON or YAML and written back to disk as a valid Sigma rule.
- class sigma.schema.RuleDetection(*args, timeframe: sigma.schema.ConstrainedStrValue = None, condition: Union[List[str], str], **kwargs)¶
Bases:
pydantic.main.BaseModel
Defines the detection criteria for this rule including the timeframe, condition specification and any number of detection field lists/keywords grouped by arbitrary names.
- class Config¶
Bases:
object
- extra = 'allow'¶
- schema_extra = {'examples': [{'timeframe': '5m', 'condition': '(selection1 or selection2) and not filter', 'selection1': {'Imphash': ['a53a02b997935fd8eedcb5f7abab9b9f', 'e96a73c7bf33a464c510ede582318bf2']}, 'selection2': {'CommandLine|endswith': '.exe -S', 'ParentImage|endswith': '\\services.exe'}, 'filter': {'Image|endswith': '\\clussvc.exe'}}]}¶
- GRAMMAR_PARSER: ClassVar[Any] = Forward: 'or' term¶
- condition: Union[List[str], str]¶
- property expression: sigma.grammar.Expression¶
- get_expression(identifier: str) sigma.grammar.Expression ¶
Construct an expression from the specified identifier. If the requested identifier does not exist, a MissingIdentifier exception is raised.
- lookup_expression(pattern: str) Generator[str, None, None] ¶
Lookup identifier expressions by a glob pattern
- parse_grammar() sigma.grammar.Expression ¶
Parse the condition and evaluate fields to produce a single search expression.
- post_init(rule: sigma.schema.Rule)¶
- property rule: sigma.schema.Rule¶
- timeframe: Optional[str]¶
- transform(rule: Rule, transforms: sigma.transform.Transformation)¶
Transform all expressions with the given transformations
- update_expression(expression: sigma.grammar.Expression)¶
- classmethod validate_detection(v)¶
Validate the schema for the
- class sigma.schema.RuleDetectionFields¶
Bases:
Dict
[str
,Any
]Defines the detection criteria by AND-separated field matching.
- build_expression() sigma.grammar.Expression ¶
Build the logical AND expression for these keywords
- class sigma.schema.RuleDetectionList(iterable=(), /)¶
Bases:
List
[Union
[str
,sigma.schema.RuleDetectionFields
]]Defines the detection criteria by OR-separated keyword strings.
- build_expression() sigma.grammar.Expression ¶
Build the logical OR expression for these keywords
- class sigma.schema.RuleLevel(value)¶
Bases:
sigma.schema.LowercaseString
,enum.Enum
The level field contains one of five string values. It describes the criticality of a triggered rule. While low and medium level events have an informative character, events with high and critical level should lead to immediate reviews by security analysts.
- CRITICAL = 'critical'¶
Highly relevant event that indicates an incident. Critical events should be reviewed immediately.
- HIGH = 'high'¶
Relevant event that should trigger an internal alert and requires a prompt review.
- INFORMATIONAL = 'informational'¶
Rule is intended for enrichment of events, e.g. by tagging them. No case or alerting should be triggered by such rules because it is expected that a huge amount of events will match these rules.
- LOW = 'low'¶
Notable event but rarely an incident. Low rated events can be relevant in high numbers or combination with others. Immediate reaction shouldn’t be necessary, but a regular review is recommended.
- MEDIUM = 'medium'¶
Relevant event that should be reviewed manually on a more frequent basis.
- to_severity() int ¶
Convert the rule level to an integer severity level in the range 0-100
- class sigma.schema.RuleLicense¶
Bases:
str
License of the rule according the SPDX ID specification.
- class sigma.schema.RuleLogSource(*, category: str = None, product: str = None, service: str = None, definition: str = None, **extra_data: Any)¶
Bases:
pydantic.main.BaseModel
Defines the source of log entries for a sigma rule
- category: Optional[str]¶
- definition: Optional[str]¶
- product: Optional[str]¶
- service: Optional[str]¶
- class sigma.schema.RuleRelation(*, id: uuid.UUID, type: sigma.schema.RuleRelationType)¶
Bases:
pydantic.main.BaseModel
Defines detections/queries for this rule
- class Config¶
Bases:
object
- schema_extra = {'examples': [{'id': '7aa7009a-28b9-4344-8c1f-159489a390df', 'type': 'derived'}]}¶
- id: uuid.UUID¶
- class sigma.schema.RuleRelationType(value)¶
Bases:
sigma.schema.LowercaseString
,enum.Enum
Type of rule relationship
- DERIVED = 'derived'¶
Rule was derived from the referred rule or rules, which may remain active.
- MERGED = 'merged'¶
Rule was merged from the referred rules. The rules may be still existing and in use.
- OBSOLETES = 'obsoletes'¶
Rule obsoletes the referred rule or rules, which aren’t used anymore.
- RENAMED = 'renamed'¶
The rule had previously the referred identifier or identifiers but was renamed for any other reason, e.g. from a private naming scheme to UUIDs, to resolve collisions etc. It’s not expected that a rule with this id exists anymore.
- class sigma.schema.RuleStatus(value)¶
Bases:
sigma.schema.LowercaseString
,enum.Enum
Indicates the development status for a sigma rule
- DEPRECATED = 'deprecated'¶
the rule is replace or cover by another one. The link is made by the related field.
- EXPERIMENTAL = 'experimental'¶
an experimental rule that could lead to false results or be noisy, but could also identify interesting events.
- STABLE = 'stable'¶
the rule is considered as stable and may be used in production systems or dashboards.
- TEST = 'test'¶
an almost stable rule that possibly could require some fine tuning.
- TESTING = 'testing'¶
an almost stable rule that possibly could require some fine tuning.
- UNSUPPORTED = 'unsupported'¶
the rule can not be use in its current state (special correlation log, home-made fields)
- class sigma.schema.RuleTag¶
Bases:
str
A Sigma rule can be categorised with tags. Tags should generally follow this syntax:
Character set: lower-case letters, underscores and hyphens
no spaces
Tags are namespaced, the dot is used as separator. e.g. attack.t1234 refers to technique 1234 in the namespace attack; Namespaces may also be nested
Keep tags short, e.g. numeric identifiers instead of long sentences
If applicable, use predefined tags. Feel free to send pull request or issues with proposals for new tags
Predefined tags: https://github.com/SigmaHQ/sigma/wiki/Tags
- property name: str¶
The name is everything after the first period in the tag. If there are no periods, then the name is an empty string.
- property namespace: Optional[str]¶
The namespace is everything prior to the first period in the tag
- classmethod validate(v)¶
- class sigma.schema.Sigma¶
Bases:
object
This class is never instantiated but provides an object-oriented interface to loading sigma documents as a whole, which could include collections of rules bound by correlations and/or an include document which imports other rules from disk.
- classmethod load(path: Union[str, os.PathLike]) Union[sigma.schema.Rule, sigma.schema.Correlation, List[Union[sigma.schema.Rule, sigma.schema.Correlation]]] ¶
Load Sigma rules or correlations from the given path. The return value of this function is either a singular sigma rule or a correlation object which represents a list of rules bound by a correlation.
- class sigma.schema.SimpleDate¶
Bases:
datetime.date
Simple date class which has a custom parser to handle either YYYY/MM/DD or YYYY-MM-DD
- class sigma.schema.TemporalCorrelation(*, action: typing.Literal['correlation'], name: str, rule: typing.Union[str, typing.List[str]], type: typing.Literal[<CorrelationType.TEMPORAL: 'temporal'>], timespan: sigma.schema.ConstrainedStrValue, level: sigma.schema.RuleLevel, **extra_data: typing.Any)¶
Bases:
sigma.schema.BaseCorrelation
- type: Literal[<CorrelationType.TEMPORAL: 'temporal'>]¶
Type of correlation to be used