Merge pull request #1 from simrankaursoin/master

Fix NOT bug
This commit is contained in:
Simran Kaur Soin 2020-07-23 09:50:18 -04:00 committed by GitHub
commit a03d1b091e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 27 deletions

View File

@ -154,10 +154,12 @@ class BaseBackend:
pass
return query
def generateNode(self, node):
def generateNode(self, node, currently_within_NOT_node=False):
if type(node) == sigma.parser.condition.ConditionAND:
return self.applyOverrides(self.generateANDNode(node))
elif type(node) == sigma.parser.condition.ConditionOR:
if currently_within_NOT_node:
return self.applyOverrides(self.generateANDNode(node))
return self.applyOverrides(self.generateORNode(node))
elif type(node) == sigma.parser.condition.ConditionNOT:
return self.applyOverrides(self.generateNOTNode(node))
@ -246,8 +248,8 @@ class SingleTextQueryBackend(RulenameCommentMixin, BaseBackend, QuoteCharMixin):
sort_condition_lists = False # Sort condition items for AND and OR conditions
def generateANDNode(self, node):
generated = [ self.generateNode(val) for val in node ]
def generateANDNode(self, node, currently_within_NOT_node=False):
generated = [ self.generateNode(val, currently_within_NOT_node) for val in node ]
filtered = [ g for g in generated if g is not None ]
if filtered:
if self.sort_condition_lists:
@ -256,8 +258,8 @@ class SingleTextQueryBackend(RulenameCommentMixin, BaseBackend, QuoteCharMixin):
else:
return None
def generateORNode(self, node):
generated = [ self.generateNode(val) for val in node ]
def generateORNode(self, node, currently_within_NOT_node):
generated = [ self.generateNode(val, currently_within_NOT_node) for val in node ]
filtered = [ g for g in generated if g is not None ]
if filtered:
if self.sort_condition_lists:
@ -266,33 +268,34 @@ class SingleTextQueryBackend(RulenameCommentMixin, BaseBackend, QuoteCharMixin):
else:
return None
def generateNOTNode(self, node):
generated = self.generateNode(node.item)
def generateNOTNode(self, node, currently_within_NOT_node):
currently_within_NOT_node = True
generated = self.generateNode(node.item, currently_within_NOT_node)
if generated is not None:
return self.notToken + generated
return generated
else:
return None
def generateSubexpressionNode(self, node):
generated = self.generateNode(node.items)
def generateSubexpressionNode(self, node, currently_within_NOT_node):
generated = self.generateNode(node.items, currently_within_NOT_node)
if generated:
return self.subExpression % generated
else:
return None
def generateListNode(self, node):
def generateListNode(self, node, currently_within_NOT_node):
if not set([type(value) for value in node]).issubset({str, int}):
raise TypeError("List values must be strings or numbers")
return self.listExpression % (self.listSeparator.join([self.generateNode(value) for value in node]))
def generateMapItemNode(self, node):
def generateMapItemNode(self, node, currently_within_NOT_node):
fieldname, value = node
transformed_fieldname = self.fieldNameMapping(fieldname, value)
if self.mapListsSpecialHandling == False and type(value) in (str, int, list) or self.mapListsSpecialHandling == True and type(value) in (str, int):
return self.mapExpression % (transformed_fieldname, self.generateNode(value))
elif type(value) == list:
return self.generateMapItemListNode(transformed_fieldname, value)
return self.generateMapItemListNode(transformed_fieldname, value, currently_within_NOT_node)
elif isinstance(value, SigmaTypeModifier):
return self.generateMapItemTypedNode(transformed_fieldname, value)
elif value is None:
@ -300,7 +303,7 @@ class SingleTextQueryBackend(RulenameCommentMixin, BaseBackend, QuoteCharMixin):
else:
raise TypeError("Backend does not support map values of type " + str(type(value)))
def generateMapItemListNode(self, fieldname, value):
def generateMapItemListNode(self, fieldname, value, currently_within_NOT_node):
return self.mapListValueExpression % (fieldname, self.generateNode(value))
def generateMapItemTypedNode(self, fieldname, value):

View File

@ -58,10 +58,14 @@ class QRadarBackend(SingleTextQueryBackend):
"""Remove quotes in text"""
return value.replace("\'","\\\'")
def generateNode(self, node):
def generateNode(self, node, currently_within_NOT_node=False):
if type(node) == sigma.parser.condition.ConditionAND:
if currently_within_NOT_node:
return self.generateORNode(node)
return self.generateANDNode(node)
elif type(node) == sigma.parser.condition.ConditionOR:
if currently_within_NOT_node:
return self.generateANDNode(node)
return self.generateORNode(node)
elif type(node) == sigma.parser.condition.ConditionNOT:
return self.generateNOTNode(node)

View File

@ -26,15 +26,24 @@ class STIXBackend(SingleTextQueryBackend):
def cleanValue(self, value):
return value
def generateMapItemListNode(self, key, value):
def generateMapItemListNode(self, key, value, currently_within_NOT_node):
items_list = list()
for item in value:
if type(item) == str and "*" in item:
item = item.replace("*", "%")
items_list.append('%s LIKE %s' % (self.cleanKey(key), self.generateValueNode(item)))
if currently_within_NOT_node:
items_list.append('%s NOT LIKE %s' % (self.cleanKey(key), self.generateValueNode(item)))
else:
items_list.append('%s LIKE %s' % (self.cleanKey(key), self.generateValueNode(item)))
else:
items_list.append('%s = %s' % (self.cleanKey(key), self.generateValueNode(item)))
return '('+" OR ".join(items_list)+')'
if currently_within_NOT_node:
items_list.append('%s != %s' % (self.cleanKey(key), self.generateValueNode(item)))
else:
items_list.append('%s = %s' % (self.cleanKey(key), self.generateValueNode(item)))
if currently_within_NOT_node:
return '(' + " AND ".join(items_list) + ')'
else:
return '('+" OR ".join(items_list)+')'
def generateMapItemTypedNode(self, key, value):
if type(value) == SigmaRegularExpressionModifier:
@ -48,18 +57,20 @@ class STIXBackend(SingleTextQueryBackend):
else:
raise NotImplementedError("Type modifier '{}' is not supported by backend".format(value.identifier))
def generateMapItemNode(self, node):
def generateMapItemNode(self, node, currently_within_NOT_node):
key, value = node
if ":" not in key:
key = "%s:%s" % (self.sigmaSTIXObjectName, str(key).lower())
if self.mapListsSpecialHandling == False and type(value) in (str, int, list) or self.mapListsSpecialHandling == True and type(value) in (str, int):
if type(value) == str and "*" in value:
value = value.replace("*", "%")
if currently_within_NOT_node:
return "%s NOT LIKE %s" % (self.cleanKey(key), self.generateValueNode(value))
return "%s LIKE %s" % (self.cleanKey(key), self.generateValueNode(value))
elif type(value) in (str, int):
return self.mapExpression % (self.cleanKey(key), self.generateValueNode(value))
elif type(value) == list:
return self.generateMapItemListNode(key, value)
return self.generateMapItemListNode(key, value, currently_within_NOT_node)
elif isinstance(value, SigmaTypeModifier):
return self.generateMapItemTypedNode(key, value)
else:
@ -68,17 +79,21 @@ class STIXBackend(SingleTextQueryBackend):
def generateValueNode(self, node):
return self.valueExpression % (self.cleanValue(str(node)))
def generateNode(self, node):
def generateNode(self, node, currently_within_NOT_node=False):
if type(node) == sigma.parser.condition.ConditionAND:
return self.generateANDNode(node)
if currently_within_NOT_node:
return self.generateORNode(node, currently_within_NOT_node)
return self.generateANDNode(node, currently_within_NOT_node)
elif type(node) == sigma.parser.condition.ConditionOR:
return self.generateORNode(node)
if currently_within_NOT_node:
return self.generateANDNode(node, currently_within_NOT_node)
return self.generateORNode(node, currently_within_NOT_node)
elif type(node) == sigma.parser.condition.ConditionNOT:
return self.generateNOTNode(node)
return self.generateNOTNode(node, currently_within_NOT_node)
elif type(node) == sigma.parser.condition.NodeSubexpression:
return self.generateSubexpressionNode(node)
return self.generateSubexpressionNode(node, currently_within_NOT_node)
elif type(node) == tuple:
return self.generateMapItemNode(node)
return self.generateMapItemNode(node, currently_within_NOT_node)
else:
raise TypeError("Node type %s was not expected in Sigma parse tree" % (str(type(node))))