From 1f707cb37caa91d5203d55831e19cf0bc8caefce Mon Sep 17 00:00:00 2001 From: juju4 Date: Sun, 9 Dec 2018 17:55:51 -0500 Subject: [PATCH] Adding Sumologic backend --- tools/config/sumologic.yml | 68 +++++++++++++++++++++++++++++++ tools/setup.py | 1 + tools/sigma/backends/sumologic.py | 63 ++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100644 tools/config/sumologic.yml create mode 100644 tools/sigma/backends/sumologic.py diff --git a/tools/config/sumologic.yml b/tools/config/sumologic.yml new file mode 100644 index 000000000..833b387cc --- /dev/null +++ b/tools/config/sumologic.yml @@ -0,0 +1,68 @@ +# 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, EventChannel, EventID +logsources: + linux: + product: linux + index: + - _index=LINUX + linux-sshd: + product: linux + service: sshd + index: + - _index=LINUX + linux-auth: + product: linux + service: auth + index: + - _index=LINUX + linux-clamav: + product: linux + service: clamav + index: + - _index=LINUX + windows: + product: windows + index: + - _index=WINDOWS + windows-sysmon: + product: windows + service: sysmon + conditions: + EventChannel: Microsoft-Windows-Sysmon + index: + - _index=WINDOWS + windows-security: + product: windows + service: security + conditions: + EventChannel: Security + index: + - _index=WINDOWS + windows-powershell: + product: windows + service: powershell + conditions: + EventChannel: Microsoft-Windows-Powershell + index: + - _index=WINDOWS + windows-system: + product: windows + service: system + conditions: + EventChannel: System + index: + - _index=WINDOWS + apache: + product: apache + service: apache + index: + - _index=WEBSERVER + firewall: + product: firewall + index: + - _index=FIREWALL +# if no index, search in all indexes +defaultindex: +# all mappings depends either on FER or on query parsing +fieldmappings: diff --git a/tools/setup.py b/tools/setup.py index 281e82cb8..c8dbc0689 100644 --- a/tools/setup.py +++ b/tools/setup.py @@ -54,6 +54,7 @@ setup( 'config/spark.yml', 'config/netwitness.yml', 'config/splunk-windows-all.yml', + 'config/sumologic.yml', ])], scripts=[ 'sigmac', diff --git a/tools/sigma/backends/sumologic.py b/tools/sigma/backends/sumologic.py new file mode 100644 index 000000000..4b430fd57 --- /dev/null +++ b/tools/sigma/backends/sumologic.py @@ -0,0 +1,63 @@ +# Output backends for sigmac +# Copyright 2016-2018 Thomas Patzke, Florian Roth, juju4 + +# 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 +import sigma +from .base import SingleTextQueryBackend + +# Sumo specifics +# https://help.sumologic.com/05Search/Search-Query-Language +# want _index or _sourceCategory for performance +# try to get most string match on first line for performance +# further sorting can be done with extra parsing +# No regex match, must use 'parse regex' https://help.sumologic.com/05Search/Search-Query-Language/01-Parse-Operators/02-Parse-Variable-Patterns-Using-Regex +# For some strings like Windows ProcessCmdline or LogonProcess, it might be good to force case lower and upper as Windows is inconsistent in logs + +class SumoLogicBackend(SingleTextQueryBackend): + """Converts Sigma rule into SumoLogic query""" + identifier = "sumologic" + active = True + + reEscape = re.compile('("|\\\\(?![*?]))') + reClear = None + andToken = " AND " + orToken = " OR " + notToken = "!" + subExpression = "(%s)" + listExpression = "(%s)" + listSeparator = ", " + valueExpression = "\"%s\"" + nullExpression = "isEmpty(%s)" + notNullExpression = "!isEmpty(%s)" + mapExpression = "%s=%s" + mapListsSpecialHandling = True + mapListValueExpression = "%s IN %s" + + def generateAggregation(self, agg): + if agg == None: + return "" + if agg.aggfunc == sigma.parser.condition.SigmaAggregationParser.AGGFUNC_NEAR: + raise NotImplementedError("The 'near' aggregation operator is not yet implemented for this backend") + if agg.groupfield == None: + #return " | %s(%s) | when _count %s %s" % (agg.aggfunc_notrans, agg.aggfield or "", agg.cond_op, agg.condition) + return " | %s(%s) as val | when val %s %s" % (agg.aggfunc_notrans, agg.aggfield or "", agg.cond_op, agg.condition) + else: + return " | %s(%s) as val by %s | when val %s %s" % (agg.aggfunc_notrans, agg.aggfield or "", agg.groupfield or "", agg.cond_op, agg.condition) + +# TimeFrame condition / within timeframe +# condition | timeslice 5m | count_distinct(f1) as val by f2 | where val > 5 +# Near condition => how near... like timeframe? +