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

85 lines
2.6 KiB
Python
Raw Normal View History

2017-02-13 23:14:40 +01:00
# Output backends for sigmac
2018-07-24 00:01:16 +02:00
# Copyright 2016-2018 Thomas Patzke
2017-12-07 21:55:43 +01:00
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2017-02-13 23:14:40 +01:00
2018-07-20 23:30:32 +02:00
from .base import BaseBackend
2017-02-13 23:14:40 +01:00
### Backends for development purposes
2017-05-26 23:42:49 +02:00
2017-03-06 22:47:30 +01:00
class FieldnameListBackend(BaseBackend):
"""List all fieldnames from given Sigma rules for creation of a field mapping configuration."""
identifier = "fieldlist"
active = True
2019-04-22 23:40:21 +02:00
config_required = False
2017-02-22 22:47:12 +01:00
2018-03-21 23:58:23 +01:00
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields = set()
def generateQuery(self, parsed):
2018-03-21 23:58:23 +01:00
fields = list(flatten(self.generateNode(parsed.parsedSearch)))
if parsed.parsedAgg:
fields += self.generateAggregation(parsed.parsedAgg)
self.fields.update(fields)
2017-03-06 22:47:30 +01:00
def generateANDNode(self, node):
return [self.generateNode(val) for val in node]
def generateORNode(self, node):
return self.generateANDNode(node)
def generateNOTNode(self, node):
return self.generateNode(node.item)
def generateSubexpressionNode(self, node):
return self.generateNode(node.items)
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.generateNode(value) for value in node]
def generateMapItemNode(self, node):
key, value = node
2017-03-24 00:48:32 +01:00
return [key]
2017-03-06 22:47:30 +01:00
def generateValueNode(self, node):
return []
2018-03-21 23:58:23 +01:00
def generateNULLValueNode(self, node):
return [node.item]
def generateNotNULLValueNode(self, node):
return [node.item]
def generateAggregation(self, agg):
fields = list()
if agg.groupfield is not None:
fields.append(agg.groupfield)
if agg.aggfield is not None:
fields.append(agg.aggfield)
return fields
def finalize(self):
2018-08-02 22:41:32 +02:00
return "\n".join(sorted(self.fields))
2018-03-21 23:58:23 +01:00
2017-03-06 22:47:30 +01:00
# Helpers
def flatten(l):
for i in l:
if type(i) == list:
yield from flatten(i)
else:
yield i