Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/socprime/sigma into pr-1049
Browse files Browse the repository at this point in the history
  • Loading branch information
thomaspatzke committed Oct 23, 2020
2 parents e7462be + 383823f commit 9dc8064
Show file tree
Hide file tree
Showing 10 changed files with 704 additions and 165 deletions.
185 changes: 185 additions & 0 deletions tools/config/sumologic-cse.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
title: SumoLogic
order: 20
backends:
- sumologic-cse
- sumologic-cse-rule
# Sumulogic mapping depends on customer configuration. Adapt to your context!
# typically rule on _sourceCategory, _index or Field Extraction Rules (FER)
# supposing existing FER for service, metdata_vendor, EventID
logsources:
unix:
product: unix
index: UNIX
linux:
product: linux
index: Linux
linux-sshd:
product: linux
service: sshd
index: Linux
linux-auth:
product: linux
service: auth
index: Linux
linux-clamav:
product: linux
service: clamav
index: Linux
windows:
product: windows
index: Windows
conditions:
metdata_vendor: Microsoft
windows-sysmon:
product: windows
service: sysmon
conditions:
metdata_vendor: Microsoft
index: Windows
windows-security:
product: windows
service: security
conditions:
metdata_vendor: Microsoft
index: Security
windows-powershell:
product: windows
service: powershell
conditions:
metdata_vendor: Microsoft
index: Powershell
windows-system:
product: windows
service: system
conditions:
metdata_vendor: Microsoft
index: Windows
windows-dhcp:
product: windows
service: dhcp
conditions:
metdata_vendor: Microsoft
index: Windows
microsoft:
product: gsuite
index: gsuite
apache:
product: apache
service: apache
index: Apache
apache2:
product: apache
index: Apache
nginx:
product: nginx
index: Nginx
cisco:
product: cisco
index: Cisco
webserver:
category: webserver
index: WEBSERVER
firewall:
category: firewall
index: FIREWALL
firewall2:
product: firewall
index: FIREWALL
network-dns:
category: dns
index: DNS
network-dns2:
product: dns
index: DNS
proxy:
category: proxy
index: PROXY
vpn:
product: vpn
index: network
antivirus:
product: antivirus
index: ANTIVIRUS
azure:
product: azure
index: Azure
conditions:
metdata_vendor: Microsoft
azuread:
product: azuread
index: Azure AD
conditions:
metdata_vendor: Microsoft
zeek:
product: zeek
index: zeek
application-sql:
product: sql
index: DATABASE
application-python:
product: python
index: APPLICATIONS
application-django:
product: django
index: Django
application-rails:
product: rails
index: RAILS
application-spring:
product: spring
index: SPRING
# if no index, search in all indexes

fieldmappings:
EventID: metadata_deviceEventId
event_id: metadata_deviceEventId
Image: baseImage
event_data.Image: baseImage
TargetImage: changeTarget
EventType: changeType
CommandLine: commandLine
Commandline: commandLine
process.args: commandLine
event_data.CommandLine: commandLine
Description: description

DestinationHostname: dstDevice_hostname
DestinationIp: dstDevice_ip
dst_ip: dstDevice_ip
dst_mac: dstDevice_mac
DestinationPort: dstPort
dst_port: dstPort

FileName: file_basename
Imphash: file_hash_imphash
hash: file_hash_imphash
file_hash: file_hash_imphash
# :file_hash_md5
# :file_hash_sha1
# :file_hash_sha256

Path: file_path
path: file_path

LogonType: logonType
ModuleType: moduleType
ObjectType: objectType

ParentImage: parentBaseImage
event_data.ParentImage: parentBaseImage
ParentCommandLine: parentCommandLine
ParentProcessName: parentPid

SourceHostname: srcDevice_hostname
SourceIp: srcDevice_ip
src_ip: srcDevice_ip
src_mac: srcDevice_mac
SourcePort: srcPort
src_port: srcPort
User: user_username
User-Agent: http_userAgent
Protocol: http_url_protocol

destination.domain: http_url_rootDomain
domain: http_url_rootDomain

9 changes: 9 additions & 0 deletions tools/config/sysmon.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
title: Sysmon
order: 20
backends:
- sysmon
fieldmappings:
event_id: EventID
event_data.ParentImage: ParentImage
event_data.CommandLine: CommandLine
event_data.Image: Image
105 changes: 69 additions & 36 deletions tools/sigma/backends/ala.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,62 +110,95 @@ def default_value_mapping(self, val):
if isinstance(val, str):
if "*" in val[1:-1]: # value contains * inside string - use regex match
op = "matches regex"
val = re.sub('\\*', '.*', val)
val = re.sub('(\\\\\*|\*)', '.*', val)
if "\\" in val:
return "%s \"(?i)%s\"" % (op, val)
return "%s \"(?i)%s\"" % (op, val)
val = "@'(?i)%s'" % (val)
else:
val = "'(?i)%s'" % (val)
return "%s %s" % (op, self.cleanValue(val))
elif val.startswith("*") or val.endswith("*"):
op = "contains"
if val.startswith("*") and val.endswith("*"):
op = "contains"
elif val.startswith("*"):
op = "endswith"
elif val.endswith("*"):
op = "startswith"
val = re.sub('([".^$]|(?![*?]))', '\g<1>', val)
val = re.sub('\\*', '', val)
val = re.sub('(\\\\\*|\*)', '.*', val)
val = re.sub('\\?', '.', val)
# if "\\" in val:
# return "%s @\"%s\"" % (op, val)
return "%s \"%s\"" % (op, val)
# elif "\\" in val:
# return "%s @\"%s\"" % (op, val)
return "%s \"%s\"" % (op, val)

def generate(self, sigmaparser):
self.table = None
self.category = sigmaparser.parsedyaml['logsource'].setdefault('category', None)
self.product = sigmaparser.parsedyaml['logsource'].setdefault('product', None)
self.service = sigmaparser.parsedyaml['logsource'].setdefault('service', None)

detection = sigmaparser.parsedyaml.get("detection", {})
if "keywords" in detection.keys():
return super().generate(sigmaparser)

if self.category == "process_creation":
self.table = "SecurityEvent"
if "\\" in val:
return "%s @'%s'" % (op, self.cleanValue(val))
return "%s '%s'" % (op, self.cleanValue(val))
elif "\\" in val:
return "%s @'%s'" % (op, self.cleanValue(val))
return "%s \"%s\"" % (op, self.cleanValue(val))

def getTable(self, sigmaparser):
if self.category == "process_creation" and len(set(sigmaparser.values.keys()) - {"Image", "ParentImage",
"CommandLine"}) == 0:
self.table = "SecurityEvent | where EventID == 4688 "
self.eventid = "4688"
elif self.category == "process_creation":
self.table = "SysmonEvent"
self.eventid = "1"
elif self.service == "security":
elif self.service and self.service.lower() == "security":
self.table = "SecurityEvent"
elif self.service == "sysmon":
elif self.service and self.service.lower() == "sysmon":
self.table = "SysmonEvent"
elif self.service == "powershell":
elif self.service and self.service.lower() == "powershell":
self.table = "Event"
elif self.service == "office365":
elif self.service and self.service.lower() == "office365":
self.table = "OfficeActivity"
elif self.service == "azuread":
elif self.service and self.service.lower() == "azuread":
self.table = "AuditLogs"
elif self.service == "azureactivity":
elif self.service and self.service.lower() == "azureactivity":
self.table = "AzureActivity"
else:
if self.service:
if "-" in self.service:
self.table = "-".join([item.title() for item in self.service.split("-")])
self.table = "-".join([item.capitalize() for item in self.service.split("-")])
elif "_" in self.service:
self.table = "_".join([item.title() for item in self.service.split("_")])
self.table = "_".join([item.capitalize() for item in self.service.split("_")])
else:
self.table = self.service.title()
if self.service.islower() or self.service.isupper():
self.table = self.service.capitalize()
else:
self.table = self.service
elif self.product:
if "-" in self.product:
self.table = "-".join([item.title() for item in self.product.split("-")])
self.table = "-".join([item.capitalize() for item in self.product.split("-")])
elif "_" in self.product:
self.table = "_".join([item.title() for item in self.product.split("_")])
self.table = "_".join([item.capitalize() for item in self.product.split("_")])
else:
if self.product.islower() or self.product.isupper():
self.table = self.product.capitalize()
else:
self.table = self.product
elif self.category:
if "-" in self.category:
self.table = "-".join([item.capitalize() for item in self.category.split("-")])
elif "_" in self.category:
self.table = "_".join([item.capitalize() for item in self.category.split("_")])
else:
self.table = self.product.title()
if self.category.islower() or self.category.isupper():
self.table = self.category.capitalize()
else:
self.table = self.category

def generate(self, sigmaparser):
try:
self.category = sigmaparser.parsedyaml['logsource'].setdefault('category', None)
self.product = sigmaparser.parsedyaml['logsource'].setdefault('product', None)
self.service = sigmaparser.parsedyaml['logsource'].setdefault('service', None)
except KeyError:
self.category = None
self.product = None
self.service = None
detection = sigmaparser.parsedyaml.get("detection", {})
if "keywords" in detection.keys():
return super().generate(sigmaparser)
if self.table is None:
self.getTable(sigmaparser)

return super().generate(sigmaparser)

Expand Down
7 changes: 3 additions & 4 deletions tools/sigma/backends/carbonblack.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ def containsWildcard(self, value):


class CarbonBlackQueryBackend(CarbonBlackWildcardHandlingMixin, SingleTextQueryBackend):
"""Converts Sigma rule into CarbonBlack query string. Only searches, no aggregations."""

"""Converts Sigma rule into CarbonBlack query string. Only searches, no aggregations. Contributed by SOC Prime. https://socprime.com"""
identifier = "carbonblack"
active = True

Expand Down Expand Up @@ -133,13 +132,13 @@ def cleanValue(self, val):

def cleanIPRange(self, value):
new_value = value
if type(new_value) is str and value.find('*'):
if isinstance(new_value, str) and value.find('*'):
sub = value.count('.')
if value[-2:] == '.*':
value = value[:-2]
min_ip = value + '.0' * (4 - sub)
new_value = min_ip + '/' + str(8 * (4 - sub))
elif type(new_value) is list:
elif isinstance(new_value, list):
for index, vl in enumerate(new_value):
new_value[index] = self.cleanIPRange(vl)

Expand Down
12 changes: 6 additions & 6 deletions tools/sigma/backends/humio.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from .mixins import MultiRuleOutputMixin

class HumioBackend(SingleTextQueryBackend):
"""Converts Sigma rule into Humio query."""
"""Converts Sigma rule into Humio query. Contributed by SOC Prime. https://socprime.com"""
identifier = "humio"
active = True

Expand Down Expand Up @@ -117,23 +117,23 @@ def generateMapItemListNode(self, key, value):
# return (" | " + " | ".join([self.regexExpression % (key, self.cleanValue(item)) for item in value]) + " | ")
if not set([type(val) for val in value]).issubset({str, int}):
raise TypeError("List values must be strings or numbers")
return (" or ".join(['%s=%s' % (key, self.generateValueNode(item)) for item in value]))
return " or ".join(['%s=%s' % (key, self.generateValueNode(item)) for item in value])

def generateAggregation(self, agg):
if agg == None:
if agg is None:
return ""
if agg.aggfunc == SigmaAggregationParser.AGGFUNC_NEAR:
raise NotImplementedError("The 'near' aggregation operator is not yet implemented for this backend")
if agg.groupfield == None:
if agg.groupfield is None:
if agg.aggfunc_notrans == 'count':
if agg.aggfield == None :
if agg.aggfield is None :
return " | val := count() | val %s %s" % (agg.cond_op, agg.condition)
else:
agg.aggfunc_notrans = 'dc'
return " | count(field=%s, distinct=true, as=val) | val %s %s" % (agg.aggfield or "", agg.cond_op, agg.condition)
else:
if agg.aggfunc_notrans == 'count':
if agg.aggfield == None :
if agg.aggfield is None :
return " | val := count(field=%s) | val %s %s" % (agg.groupfield or "", agg.cond_op, agg.condition)
else:
agg.aggfunc_notrans = 'dc'
Expand Down
Loading

0 comments on commit 9dc8064

Please sign in to comment.