# Output backends for sigmac # Copyright 2021 Datadog, Inc. # 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 . import re from sigma.backends.base import SingleTextQueryBackend from sigma.parser.condition import NodeSubexpression class DatadogLogsBackend(SingleTextQueryBackend): """Converts Sigma rule into Datadog log search query.""" identifier = "datadog-logs" active = True config_required = False andToken = " AND " orToken = " OR " notToken = "-" subExpression = "(%s)" listExpression = "(%s)" # List selection items are linked with a logical 'OR' per the Sigma specification: # https://github.com/SigmaHQ/sigma/wiki/Specification#lists. listSeparator = " OR " valueExpression = "%s" mapExpression = "%s:%s" nullExpression = "-%s:*" notNullExpression = "%s:*" # The escaped characters list comes from https://docs.datadoghq.com/logs/explorer/search_syntax/#escaping-of-special-characters. specialCharactersRegexp = re.compile(r'([+\-=&|>", val) ) def generateMapItemNode(self, node): key, value = node return super().generateMapItemNode(((self.wrap_key(key)), value)) def generateNULLValueNode(self, node): return super().generateNULLValueNode((self.wrap_key(node))) def generateNotNULLValueNode(self, node): return super().generateNotNULLValueNode(self.wrap_key(node)) def wrap_key(self, key): if key not in self.tags: return "@%s" % key else: return key