Files
blue-team-tools/tools/sigma/backends/logiq.py
T

62 lines
2.0 KiB
Python
Raw Normal View History

2020-02-22 20:50:30 -08:00
import re
2020-02-22 20:59:56 -08:00
from .base import SingleTextQueryBackend
2020-02-22 20:50:30 -08:00
import json
2020-02-22 20:59:56 -08:00
class LogiqBackend(SingleTextQueryBackend):
"""Converts Sigma rule into LOGIQ event rule api payload """
2020-02-22 20:50:30 -08:00
identifier = "logiq"
config_required = False
2020-02-22 20:59:56 -08:00
active = True
reEscape = re.compile('(")')
reClear = None
andToken = " && "
orToken = " || "
notToken = " !~ "
subExpression = "%s"
listExpression = "%s"
listSeparator = ", "
valueExpression = "message =~ \'%s\'"
keyExpression = "%s"
2020-04-08 23:43:46 +02:00
nullExpression = "!~ %s"
2020-02-22 20:59:56 -08:00
notNullExpression = "!%s"
mapExpression = "(%s=%s)"
mapListsSpecialHandling = True
2020-02-22 20:50:30 -08:00
reEscape = re.compile("([\\|()\[\]{}.^$+])")
def generate(self, sigmaparser):
"""Method is called for each sigma rule and receives the parsed rule (SigmaParser)"""
eventRule = dict()
eventRule["name"] = sigmaparser.parsedyaml["title"]
2020-04-08 23:43:46 +02:00
eventRule["groupName"] = sigmaparser.parsedyaml["logsource"].get("product", "")
2020-02-22 20:50:30 -08:00
eventRule["description"] = sigmaparser.parsedyaml["description"]
eventRule["condition"] = sigmaparser.parsedyaml["detection"]
eventRule["level"] = sigmaparser.parsedyaml["level"]
for parsed in sigmaparser.condparsed:
query = self.generateQuery(parsed)
before = self.generateBefore(parsed)
after = self.generateAfter(parsed)
eventRule["condition"] = ""
if before is not None:
eventRule["condition"] = before
if query is not None:
eventRule["condition"] += query
if after is not None:
eventRule["condition"] += after
2020-02-22 20:59:56 -08:00
return json.dumps(eventRule)
2020-02-22 20:50:30 -08:00
def cleanValue(self, val):
2020-04-08 23:43:46 +02:00
if val.startswith('*'):
2020-02-22 20:50:30 -08:00
val = val.replace("*","/*")
2020-02-22 20:59:56 -08:00
2020-02-22 20:50:30 -08:00
return val
def generateListNode(self, node):
if not set([type(value) for value in node]).issubset({str, int}):
raise TypeError("List values must be strings or numbers")
return self.generateORNode(node)