Merge pull request #950 from barvhaim/master
STIX Backend bug-fix and mapping updates
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
title: STIX for Linux Logs
|
||||
backends:
|
||||
- stix
|
||||
order: 40
|
||||
logsources:
|
||||
linux:
|
||||
product: linux
|
||||
fieldmappings:
|
||||
type:
|
||||
- x-event:action
|
||||
keywords:
|
||||
- x-sigma:keywords
|
||||
a0:
|
||||
- process:command_line
|
||||
a1:
|
||||
- process:command_line
|
||||
name:
|
||||
- file:name
|
||||
a3:
|
||||
- process:command_line
|
||||
key:
|
||||
- x-sigma:keywords
|
||||
exe:
|
||||
- file:name
|
||||
a2:
|
||||
- process:command_line
|
||||
SYSCALL:
|
||||
- x-event:action
|
||||
pam_message:
|
||||
- x-event:action
|
||||
pam_user:
|
||||
- user-account:user_id
|
||||
pam_rhost:
|
||||
- x-host:name
|
||||
USER:
|
||||
- user-account:user_id
|
||||
@@ -21,8 +21,6 @@ fieldmappings:
|
||||
- user-account:x_security_id
|
||||
CallTrace:
|
||||
- x-windows:calltrace
|
||||
ChangedAttributes:
|
||||
- x-windows:changedattributes
|
||||
ClientIP:
|
||||
- ipv4-addr:value
|
||||
- ipv6-addr:value
|
||||
@@ -84,7 +82,7 @@ fieldmappings:
|
||||
Image:
|
||||
- process:image_ref.name
|
||||
ImageLoadedTempPath:
|
||||
- process:image_ref.x_temp_path
|
||||
- process:extensions.'windows-service-ext'.service_dll_refs[*].x_temp_path
|
||||
ImageName:
|
||||
- process:image_ref.name
|
||||
ImagePath:
|
||||
@@ -101,9 +99,9 @@ fieldmappings:
|
||||
IntegrityLevel:
|
||||
- x-windows:integritylevel
|
||||
LoadedImage:
|
||||
- process:image_ref.name
|
||||
- process:extensions.'windows-service-ext'.service_dll_refs[*].name
|
||||
LoadedImageName:
|
||||
- process:image_ref.name
|
||||
- process:extensions.'windows-service-ext'.service_dll_refs[*].name
|
||||
LogonType:
|
||||
- x-windows:logontype
|
||||
MD5Hash:
|
||||
@@ -116,8 +114,6 @@ fieldmappings:
|
||||
- x-windows:objectname
|
||||
ObjectType:
|
||||
- x-windows:objecttype
|
||||
PSEncodedCommand:
|
||||
- x-windows:psencodedcommand
|
||||
ParentCommandLine:
|
||||
- process:parent_ref.command_line
|
||||
ParentImage:
|
||||
@@ -152,30 +148,23 @@ fieldmappings:
|
||||
- x-windows:queryresults
|
||||
QueryStatus:
|
||||
- x-windows:querystatus
|
||||
Realm:
|
||||
- x-windows:realm
|
||||
RecordNumber:
|
||||
- x-windows:recordnumber
|
||||
RegistryKey:
|
||||
- windows-registry-key:key
|
||||
RegistryValueData:
|
||||
- windows-registry-key:values[*].data
|
||||
RegistryValueName:
|
||||
- windows-registry-key:values[*].name
|
||||
RunLevel:
|
||||
- x-windows:runlevel
|
||||
SAMAccountName:
|
||||
- x-windows:samaccountname
|
||||
- user-account:account_login
|
||||
- user-account:display_name
|
||||
SHA1Hash:
|
||||
- file:hashes.SHA-1
|
||||
SHA256Hash:
|
||||
- file:hashes.SHA-256
|
||||
Scope:
|
||||
- x-windows:scope
|
||||
ServiceFileName:
|
||||
- process:extensions.windows-service-ext.service_dll_refs[*].name
|
||||
- process:extensions.'windows-service-ext'.service_dll_refs[*].name
|
||||
ServiceName:
|
||||
- process:extensions.windows-service-ext.service_name
|
||||
- process:extensions.'windows-service-ext'.service_name
|
||||
ShareName:
|
||||
- x-windows:sharename
|
||||
SharePath:
|
||||
@@ -233,12 +222,6 @@ fieldmappings:
|
||||
- user-account:user_id
|
||||
UserDomain:
|
||||
- user-account:x_domain
|
||||
UserPrincipalName:
|
||||
- x-windows:userprincipalname
|
||||
UserRight:
|
||||
- x-windows:userright
|
||||
UserWorkstations:
|
||||
- x-windows:userworkstations
|
||||
event-id:
|
||||
- x-event:id
|
||||
eventId:
|
||||
@@ -248,9 +231,9 @@ fieldmappings:
|
||||
event_data.Image:
|
||||
- process:image_ref.name
|
||||
event_data.ImageLoaded:
|
||||
- process:image_ref.name
|
||||
- process:extensions.'windows-service-ext'.service_dll_refs[*].name
|
||||
ImageLoaded:
|
||||
- process:image_ref.name
|
||||
- process:extensions.'windows-service-ext'.service_dll_refs[*].name
|
||||
event_data.ImagePath:
|
||||
- process:image_ref.name
|
||||
event_data.ParentCommandLine:
|
||||
@@ -262,7 +245,7 @@ fieldmappings:
|
||||
event_data.PipeName:
|
||||
- x-windows:pipename
|
||||
event_data.ServiceFileName:
|
||||
- process:extensions.windows-service-ext.service_dll_refs[*].name
|
||||
- process:extensions.'windows-service-ext'.service_dll_refs[*].name
|
||||
event_data.ShareName:
|
||||
- x-windows:sharename
|
||||
event_data.Signature:
|
||||
|
||||
+42
-1
@@ -91,4 +91,45 @@ fieldmappings:
|
||||
username:
|
||||
- user-account:user_id
|
||||
utf8_payload:
|
||||
- artifact:payload_bin
|
||||
- artifact:payload_bin
|
||||
|
||||
# Web mapping
|
||||
c-uri:
|
||||
- url:value
|
||||
keywords:
|
||||
- x-sigma:keywords
|
||||
cs-method:
|
||||
- http-request-ext:request_method
|
||||
sc-status:
|
||||
- x-web:status_code
|
||||
clientip:
|
||||
- ipv4-addr:value
|
||||
- ipv6-addr:value
|
||||
- network-traffic:src_ref.value
|
||||
|
||||
# Cloud mapping
|
||||
eventSource:
|
||||
- x-host:name
|
||||
eventName:
|
||||
- x-event:action
|
||||
requestParameters.attribute:
|
||||
- x-cloud:request_parameters
|
||||
responseElements.publiclyAccessible:
|
||||
- x-cloud:publicly_accessible
|
||||
errorMessage:
|
||||
- x-error:message
|
||||
errorCode:
|
||||
- x-error:code
|
||||
responseElements:
|
||||
- x-cloud:response_elements
|
||||
requestParameters.userData:
|
||||
- x-cloud:request_parameters
|
||||
userIdentity.type:
|
||||
- user-account:account_login
|
||||
eventType:
|
||||
- x-event:action
|
||||
userIdentity.arn:
|
||||
- user-account:account_login
|
||||
- user-account:display_name
|
||||
responseElements.pendingModifiedValues.masterUserPassword:
|
||||
- user-account:credential
|
||||
|
||||
@@ -14,6 +14,7 @@ class STIXBackend(SingleTextQueryBackend):
|
||||
subExpression = "(%s)"
|
||||
valueExpression = "\'%s\'"
|
||||
mapExpression = "%s = %s"
|
||||
notMapExpression = "%s != %s"
|
||||
mapListsSpecialHandling = True
|
||||
sigmaSTIXObjectName = "x-sigma"
|
||||
|
||||
@@ -26,15 +27,76 @@ class STIXBackend(SingleTextQueryBackend):
|
||||
def cleanValue(self, value):
|
||||
return value
|
||||
|
||||
def generateMapItemListNode(self, key, value):
|
||||
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:
|
||||
filtered = sorted(filtered)
|
||||
return self.andToken.join(filtered)
|
||||
else:
|
||||
return None
|
||||
|
||||
def generateORNode(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:
|
||||
filtered = sorted(filtered)
|
||||
return self.orToken.join(filtered)
|
||||
else:
|
||||
return None
|
||||
|
||||
def generateNOTNode(self, node, currently_within_NOT_node=False):
|
||||
currently_within_NOT_node = not(currently_within_NOT_node)
|
||||
generated = self.generateNode(node.item, currently_within_NOT_node)
|
||||
if generated is not None:
|
||||
return generated
|
||||
else:
|
||||
return None
|
||||
|
||||
def generateSubexpressionNode(self, node, currently_within_NOT_node=False):
|
||||
generated = self.generateNode(node.items, currently_within_NOT_node)
|
||||
if generated:
|
||||
return self.subExpression % generated
|
||||
else:
|
||||
return None
|
||||
|
||||
def generateMapItemNode(self, node, currently_within_NOT_node=False):
|
||||
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):
|
||||
if currently_within_NOT_node:
|
||||
return self.notMapExpression % (transformed_fieldname, self.generateNode(value))
|
||||
return self.mapExpression % (transformed_fieldname, self.generateNode(value))
|
||||
elif type(value) == list:
|
||||
return self.generateMapItemListNode(transformed_fieldname, value, currently_within_NOT_node)
|
||||
elif isinstance(value, SigmaTypeModifier):
|
||||
return self.generateMapItemTypedNode(transformed_fieldname, value)
|
||||
elif value is None:
|
||||
return self.nullExpression % (transformed_fieldname, )
|
||||
else:
|
||||
raise TypeError("Backend does not support map values of type " + str(type(value)))
|
||||
|
||||
def generateMapItemListNode(self, key, value, currently_within_NOT_node=False):
|
||||
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 +110,22 @@ 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=False):
|
||||
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):
|
||||
if currently_within_NOT_node:
|
||||
return self.notMapExpression % (self.cleanKey(key), self.generateValueNode(value))
|
||||
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 +134,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))))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user