-
Notifications
You must be signed in to change notification settings - Fork 21
/
sigma2splunkalert
executable file
·142 lines (111 loc) · 4.57 KB
/
sigma2splunkalert
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/usr/bin/env python3
# A Sigma to Splunk Alter Converter
# Copyright 2019 Patrick Bareiss (@patrick_bareiss)
import sys
import argparse
import os
import yaml
import subprocess
from subprocess import DEVNULL
from jinja2 import Environment, FileSystemLoader
from classes.UseCase import UseCase
from classes.DetectionRuleConverter import DetectionRuleConverter
def main(argv):
# parse input variables
parser = argparse.ArgumentParser(
description='Convert Sigma rules to Splunk Alerts savedsearches.conf configuration.')
parser.add_argument('rules', action='store', metavar='N', nargs='+',
help='folder or file containing the Sigma rules')
parser.add_argument('--config', '-c', action='store', dest='config',
help='Sigma2SplunkAlert configuration file')
parser.add_argument('--sigma-config', '-sc', action='store', dest='sigma_config',
help='Sigma configuration with field name and index name mapping')
parser.add_argument('--template', '-t', action='store', dest='template',
help='file containing the savedsearches.conf template')
cmdargs = parser.parse_args()
# cmdargs Sigma2SplunkAlert configuration
if cmdargs.config:
converter_config_path = cmdargs.config
else:
converter_config_path = 'config/config.yml'
# cmdargs Sigma Configuration
if cmdargs.sigma_config:
sigma_config_path = cmdargs.sigma_config
else:
sigma_config_path = 'sigma_config/splunk-all.yml'
# cmdargs template Configuration
if cmdargs.template:
template_path = cmdargs.template
# Splunk Search Converter
# variables
input_path_list = cmdargs.rules
detection_rules = []
# Load Sigma2SplunkAlert Configuration
sigma2splunkalertconfig = openSigma2SplunkConfiguration(converter_config_path)
# Iterate through N input folders
for input_path in input_path_list:
files = loadSigmaRules(input_path)
for file in files:
# Load Sigma Rule
sigma_rule = openSigmaDetectionRule(file)
# Convert Sigma Rule to Splunk Search
splunk_search = DetectionRuleConverter.convertSigmaRule(sigma_config_path, file)
if splunk_search == "Converter Failure":
continue
# Perform Splunk Search transformations
if "search_transformations" in sigma2splunkalertconfig:
splunk_search = DetectionRuleConverter.performSearchTransformation(
sigma2splunkalertconfig["search_transformations"], splunk_search, sigma_rule)
# Alert with Summary index
splunk_search = DetectionRuleConverter.addToSummaryIndex(
splunk_search, sigma2splunkalertconfig, sigma_rule)
# Create Detection Rule
detection_rule = UseCase(sigma_rule, sigma2splunkalertconfig, splunk_search)
detection_rules.append(detection_rule)
# Use Jinja2 Templating for create configuration
if cmdargs.template:
file_loader = FileSystemLoader(os.path.dirname(template_path))
else:
file_loader = FileSystemLoader('templates')
env = Environment(loader=file_loader)
env.trim_blocks = True
env.lstrip_blocks = True
env.rstrip_blocks = True
if cmdargs.template:
template = env.get_template(os.path.basename(template_path))
else:
template = env.get_template('template')
output = template.render(uc_list=detection_rules)
print(output)
def openSigma2SplunkConfiguration(converter_config_path):
# Load Sigma2SplunkAlert configuration
with open(converter_config_path, 'r') as stream:
try:
converter_config = yaml.safe_load(stream)
except yaml.YAMLError as exc:
print(exc)
print("Failure to read the Sigma2SplunkAlert configuration")
sys.exit(1)
return converter_config
def openSigmaDetectionRule(rule_path):
# Load Sigma detection rule
with open(rule_path, 'r') as stream:
try:
sigma_uc = list(yaml.safe_load_all(stream))[0]
except yaml.YAMLError as exc:
print(exc)
sys.exit(1)
return sigma_uc
def loadSigmaRules(path):
files = []
if os.path.isfile(path):
files.append(path)
else:
# r=root, d=directories, f = files
for r, d, f in os.walk(path):
for file in f:
if '.yml' in file:
files.append(os.path.join(r, file))
return files
if __name__ == "__main__":
main(sys.argv)