Skip to content

Commit

Permalink
t
Browse files Browse the repository at this point in the history
  • Loading branch information
saltar-ua committed Feb 24, 2020
1 parent dc5a31a commit 516e61f
Showing 1 changed file with 27 additions and 61 deletions.
88 changes: 27 additions & 61 deletions tools/sigma/backends/ala.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@

import re
import xml.etree.ElementTree as xml

from ..parser.modifiers.type import SigmaRegularExpressionModifier
from .base import SingleTextQueryBackend
from .data import sysmon_schema
from .exceptions import NotSupportedError
Expand Down Expand Up @@ -46,29 +44,9 @@ class AzureLogAnalyticsBackend(SingleTextQueryBackend):
mapListsSpecialHandling = True
mapListValueExpression = "%s in %s"

_WIN_SECURITY_EVENT_MAP = {
"Image": "NewProcessName",
"ParentImage": "ParentProcessName",
"User": "SubjectUserName",
}

def __init__(self, *args, **kwargs):
"""Initialize field mappings"""
super().__init__(*args, **kwargs)
self.category = None
self.product = None
self.service = None
self.table = None
self.eventid = None
self._parser = None
self._fields = None
self._agg_var = None
self._has_logsource_event_cond = False
if not self.sysmon and not self.sigmaconfig.config:
self._field_map = self._WIN_SECURITY_EVENT_MAP
else:
self._field_map = {}
self.typedValueExpression[SigmaRegularExpressionModifier] = "matches regex \"%s\""

def id_mapping(self, src):
"""Identity mapping, source == target field name"""
Expand Down Expand Up @@ -98,8 +76,6 @@ def default_value_mapping(self, val):
val = re.sub('([".^$]|\\\\(?![*?]))', '\\\\\g<1>', val)
val = re.sub('\\*', '.*', val)
val = re.sub('\\?', '.', val)
if "\\" in val:
return "%s @\"%s\"" % (op, val)
elif type(val) == str: # value possibly only starts and/or ends with *, use prefix/postfix match
if val.endswith("*") and val.startswith("*"):
op = "contains"
Expand All @@ -112,6 +88,7 @@ def default_value_mapping(self, val):
val = self.cleanValue(val[1:])

if "\\" in val:
#val = val.replace("\\", "\\\\")
return "%s @\"%s\"" % (op, val)

return "%s \"%s\"" % (op, val)
Expand All @@ -127,26 +104,13 @@ def generate(self, sigmaparser):
self.product = None
self.service = None


detection = sigmaparser.parsedyaml.get("detection", {})
is_parent_cmd = False
if "keywords" in detection.keys():
return super().generate(sigmaparser)

if self.category == "process_creation":
self.table = "SysmonEvent"
self.eventid = "1"
elif self.service == "security":
self.table = "SecurityEvent"
elif self.service == "sysmon":
self.table = "SysmonEvent"
elif self.service == "powershell":
self.table = "Event"
else:
if self.service:
self.table = self.service.title()
elif self.product:
self.table = self.product.title()
if self.sysmon:
self.table = "Event"
self.eventid = "1"
else:
self.table = "SecurityEvent"
self.eventid = "4688"

return super().generate(sigmaparser)

Expand Down Expand Up @@ -177,10 +141,8 @@ def generateMapItemNode(self, node):
) + ")"
elif key == "EventID": # EventIDs are not reflected in condition but in table selection
if self.service == "sysmon":
self.table = "SysmonEvent"
self.eventid = value
elif self.service == "powershell":
self.table = "Event"
self.eventid = value
elif self.service == "security":
self.table = "SecurityEvent"
elif self.service == "system":
Expand Down Expand Up @@ -211,7 +173,6 @@ def generateMapItemNode(self, node):

return super().generateMapItemNode(node)


class AzureAPIBackend(AzureLogAnalyticsBackend):
"""Converts Sigma rule into Azure Log Analytics Rule."""
identifier = "ala-rule"
Expand Down Expand Up @@ -241,24 +202,29 @@ def create_rule(self, config):
tactics.append(tag.title())

rule = {
"displayName": "{} by {}".format(config.get("title"), config.get('author')),
"description": "{} {}".format(config.get("description"), "Technique: {}.".format(",".join(technics))),
"severity": config.get("level"),
"enabled": True,
"query": config.get("translation"),
"queryFrequency": "12H",
"queryPeriod": "12H",
"triggerOperator": "GreaterThan",
"triggerThreshold": 1,
"suppressionDuration": "12H",
"suppressionEnabled": False,
"tactics": tactics
}
"analytics":
[
{
"displayName": "{} by {}".format(config.get("title"), config.get('author')),
"description": "{} {}".format(config.get("description"), "Technique: {}.".format(",".join(technics))),
"severity": config.get("level"),
"enabled": True,
"query": config.get("translation"),
"queryFrequency": "12H",
"queryPeriod": "12H",
"triggerOperator": "GreaterThan",
"triggerThreshold": 1,
"suppressionDuration": "12H",
"suppressionEnabled": False,
"tactics": tactics
}
]
}
return rule

def generate(self, sigmaparser):
translation = super().generate(sigmaparser)
configs = sigmaparser.parsedyaml
configs.update({"translation": translation})
rule = self.create_rule(configs)
return rule
return rule

0 comments on commit 516e61f

Please sign in to comment.