diff --git a/README.md b/README.md
index 1215ea0c9..6271514d6 100644
--- a/README.md
+++ b/README.md
@@ -214,6 +214,7 @@ tools/sigmac -t splunk -c ~/my-splunk-mapping.yml -c tools/config/generic/window
* [Devo](https://devo.com)
* [LogRhythm](https://logrhythm.com/)
* [Datadog Logs](https://docs.datadoghq.com/logs/explorer/search_syntax/)
+* [FortiSIEM](https://docs.fortinet.com)
Current work-in-progress
* [Splunk Data Models](https://docs.splunk.com/Documentation/Splunk/7.1.0/Knowledge/Aboutdatamodels)
diff --git a/tools/sigma/backends/base.py b/tools/sigma/backends/base.py
index ceb56f8f8..c12face60 100644
--- a/tools/sigma/backends/base.py
+++ b/tools/sigma/backends/base.py
@@ -228,6 +228,13 @@ class BaseBackend:
def generateAfter(self, parsed):
return ""
+ def initialize(self):
+ """
+ Is called before the first file was processed with generate(). The right place if this backend is not intended to
+ look isolated at each rule, but generates an output which incorporates multiple rules, e.g. dashboards.
+ """
+ pass
+
def finalize(self):
"""
Is called after the last file was processed with generate(). The right place if this backend is not intended to
diff --git a/tools/sigma/backends/fortisiem.py b/tools/sigma/backends/fortisiem.py
index ee4a45f4e..f7b65d798 100644
--- a/tools/sigma/backends/fortisiem.py
+++ b/tools/sigma/backends/fortisiem.py
@@ -81,6 +81,12 @@ class FortisemBackend(RulenameCommentMixin, BaseBackend, QuoteCharMixin):
self.setRuleType(backend_options)
self.loadCSVfiles()
self.loadMitreAttackMatrixFile(backend_options);
+
+ def initialize(self):
+ return ""
+
+ def finalize(self):
+ return ""
# It's used to check whether the format of yml file is right.
def ymlValidator(self, node,regdicts={}):
@@ -634,9 +640,9 @@ class FortisemBackend(RulenameCommentMixin, BaseBackend, QuoteCharMixin):
result = None
if technique_str is not None:
- result = ("") % (rulename, ruleId, sub_function_str, technique_str)
+ result = ("") % (rulename, ruleId, sub_function_str, technique_str)
else:
- result = ("") % (rulename, ruleId, sub_function_str)
+ result = ("") % (rulename, ruleId, sub_function_str)
return result,ruleId,technique_str
diff --git a/tools/sigma/sigmac.py b/tools/sigma/sigmac.py
index d1f1bc3aa..055cbbd67 100755
--- a/tools/sigma/sigmac.py
+++ b/tools/sigma/sigmac.py
@@ -303,6 +303,10 @@ def main():
error = 0
output_array = []
+ result = backend.initialize()
+ if result:
+ print(result, file=out)
+
for sigmafile in get_inputs(cmdargs.inputs, cmdargs.recurse):
logger.debug("* Processing Sigma input %s" % (sigmafile))
success = True