Merge pull request #1408 from roysjosh/es-rule-threshold

Implement Elastic threshold detection rules
This commit is contained in:
Thomas Patzke
2021-04-06 00:50:50 +02:00
committed by GitHub
+20 -2
View File
@@ -25,7 +25,7 @@ from distutils.util import strtobool
import sigma
import yaml
from sigma.parser.modifiers.type import SigmaRegularExpressionModifier, SigmaTypeModifier
from sigma.parser.condition import ConditionOR, ConditionAND, NodeSubexpression
from sigma.parser.condition import ConditionOR, ConditionAND, NodeSubexpression, SigmaAggregationParser
from sigma.config.mapping import ConditionalFieldMapping
from .base import BaseBackend, SingleTextQueryBackend
@@ -1220,6 +1220,8 @@ class ElasticSearchRuleBackend(ElasticsearchQuerystringBackend):
super().__init__(*args, **kwargs)
self.tactics = self._load_mitre_file("tactics")
self.techniques = self._load_mitre_file("techniques")
self.rule_type = "query"
self.rule_threshold = {}
def _load_mitre_file(self, mitre_type):
try:
@@ -1246,6 +1248,20 @@ class ElasticSearchRuleBackend(ElasticsearchQuerystringBackend):
rule = self.create_rule(configs, index)
return rule
def generateAggregation(self, agg):
if agg.aggfunc == SigmaAggregationParser.AGGFUNC_COUNT:
if agg.cond_op not in [">", ">="]:
raise NotImplementedError("Threshold rules can only handle > and >= operators")
if agg.aggfield:
raise NotImplementedError("Threshold rules cannot COUNT(DISTINCT %s)" % agg.aggfield)
self.rule_type = "threshold"
self.rule_threshold = {
"field": agg.groupfield if agg.groupfield else [],
"value": int(agg.condition) if agg.cond_op == ">=" else int(agg.condition) + 1
}
return ""
raise NotImplementedError("Aggregation %s is not implemented for this backend" % agg.aggfunc_notrans)
def create_threat_description(self, tactics_list, techniques_list):
threat_list = list()
for tactic in tactics_list:
@@ -1351,10 +1367,12 @@ class ElasticSearchRuleBackend(ElasticsearchQuerystringBackend):
"severity": configs.get("level", "medium"),
"tags": new_tags,
"to": "now",
"type": "query",
"type": self.rule_type,
"threat": threat,
"version": 1
}
if self.rule_type == "threshold":
rule.update({"threshold": self.rule_threshold})
if references:
rule.update({"references": references})
return json.dumps(rule)