af9f636199
Breaking change: Instead of feeding the output class with the results, they are now returned as strings (*Backend.generate()) or list (SigmaCollectionParser.generate()). Users of the library must now take care of the output to the terminal, files or wherever Sigma rules should be pushed to.
58 lines
2.0 KiB
Python
58 lines
2.0 KiB
Python
# Output backends for sigmac
|
|
# Copyright 2016-2017 Thomas Patzke
|
|
|
|
# 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/>.
|
|
|
|
import re
|
|
from .base import BaseBackend
|
|
from .mixins import QuoteCharMixin
|
|
|
|
class GrepBackend(BaseBackend, QuoteCharMixin):
|
|
"""Generates Perl compatible regular expressions and puts 'grep -P' around it"""
|
|
identifier = "grep"
|
|
active = True
|
|
|
|
reEscape = re.compile("([\\|()\[\]{}.^$])")
|
|
|
|
def generateQuery(self, parsed):
|
|
return "grep -P '^%s'" % self.generateNode(parsed.parsedSearch)
|
|
|
|
def cleanValue(self, val):
|
|
val = super().cleanValue(val)
|
|
return re.sub("\\*", ".*", val)
|
|
|
|
def generateORNode(self, node):
|
|
return "(?:%s)" % "|".join([".*" + self.generateNode(val) for val in node])
|
|
|
|
def generateANDNode(self, node):
|
|
return "".join(["(?=.*%s)" % self.generateNode(val) for val in node])
|
|
|
|
def generateNOTNode(self, node):
|
|
return "(?!.*%s)" % self.generateNode(node.item)
|
|
|
|
def generateSubexpressionNode(self, node):
|
|
return "(?:.*%s)" % 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.generateORNode(node)
|
|
|
|
def generateMapItemNode(self, node):
|
|
key, value = node
|
|
return self.generateNode(value)
|
|
|
|
def generateValueNode(self, node):
|
|
return self.cleanValue(str(node))
|