├── README.md
├── SA-Mitigation-Endpoint
├── bin
│ └── mitigate_proc.py
├── default
│ ├── commands.conf
│ ├── inputs.conf
│ ├── savedsearches.conf
│ └── transforms.conf
├── logs
│ └── proc_mitigator.log
├── lookups
│ ├── proc_queue_template.csv
│ ├── proc_queue_template.csv.default
│ ├── process_queue.csv
│ └── process_queue.csv.default
└── metadata
│ ├── default.meta
│ └── default.meta.SplunkESSuite
├── SA-Mitigation
├── .DS_Store
├── README.md
├── bin
│ ├── README.md
│ ├── mitigator_endpoint.py
│ └── mitigator_network.py
├── default
│ ├── app.conf
│ ├── commands.conf
│ ├── correlationsearches.conf
│ ├── data
│ │ └── ui
│ │ │ ├── nav
│ │ │ └── default.xml
│ │ │ └── views
│ │ │ ├── mitigation_center.xml
│ │ │ └── mitigation_tracker.xml
│ ├── indexes.conf
│ ├── inputs.conf
│ ├── pan.conf
│ ├── savedsearches.conf
│ ├── searchbnf.conf
│ └── transforms.conf
├── local
│ └── app.conf
├── logs
│ └── mitigator.log
├── lookups
│ ├── mitigation.csv.default
│ ├── mitigation_endpoint.csv
│ ├── mitigation_endpoint.csv.default
│ ├── mitigation_network.csv
│ └── mitigation_network.csv.default
└── metadata
│ ├── default.meta
│ └── default.meta.SplunkESSuite
├── images
├── SA-Mitigation-Endpoint-arch.png
└── SA-Mitigation_search_arch.png
├── prezo
├── Auto Mitigation - Endpoint Example.mp4
└── confPrezo.pptx
└── setup.xml.txt
/README.md:
--------------------------------------------------------------------------------
1 | Splunk Mitigation Framework
2 | ===========================
3 |
4 | ## TODOs
5 | * setup.xml
6 | * documentation
7 | * error handling for the endpoint component
8 |
9 | ## Presentation Content
10 | [Slides](prezo/confPrezo.pptx)
11 |
12 | [Demo Video](https://www.youtube.com/watch?v=C4UIGNuoRdg)
13 |
14 | ## Installation
15 | Primariy package is the SA-Mitigation which contains a setup function with instructions on what to configure to get the framework setup.
16 |
17 | ### SA-Mitigation (Search Head Component)
18 | Contains all the search logic and the custom commands to take action.
19 |
20 | #### Search Architecture
21 | 
22 |
23 | #### Installation Instructions
24 | coming soon...
25 |
26 | ### SA--Mitigator-Endpoint (Endpoint Component)
27 |
28 | #### Endpoing component architecture
29 | 
30 |
31 | #### Installation Instructions
32 | comin soon...
33 |
34 |
--------------------------------------------------------------------------------
/SA-Mitigation-Endpoint/bin/mitigate_proc.py:
--------------------------------------------------------------------------------
1 | import logging
2 | import logging.handlers
3 | import subprocess
4 |
5 | import splunk.Intersplunk as si
6 | from splunk.appserver.mrsparkle.lib.util import make_splunkhome_path
7 |
8 | ## Setup the logger
9 | def setup_logger():
10 | """
11 | Sets up a logger for the ProcMitigator.
12 | """
13 |
14 | logger = logging.getLogger('proc_mitigator')
15 | # Prevent the log messages from being duplicated in the python.log
16 | # Authorization Failed
17 | logger.propagate = False
18 | logger.setLevel(logging.DEBUG)
19 |
20 | file_handler = logging.handlers.RotatingFileHandler(
21 | make_splunkhome_path(['etc', 'apps', 'SA-Mitigation-Endpoint',
22 | 'logs','proc_mitigator.log']))
23 |
24 | formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
25 | file_handler.setFormatter(formatter)
26 |
27 | logger.addHandler(file_handler)
28 |
29 | return logger
30 |
31 | logger = setup_logger()
32 |
33 | class ProcMitigator(object):
34 | """
35 | Process Mitigator Class
36 | Used to Mitigate, kill, processes found in the Process Mitigation
37 | Queue (proc_mitigation_queue).
38 | """
39 |
40 | ## Mitigate PID Command dictionary
41 | _proc_cmds = {
42 | "kill_pid": {
43 | 'win': ['taskkill', '/F', '/PID'],
44 | 'nix': ['kill', '-9']
45 | },
46 | "kill_proc_name": {
47 | 'win': ['taskkill', '/F' ,'/IM'],
48 | 'nix': ['killall', '-9'],
49 | },
50 | "list_procs": {
51 | 'win': ['tasklist', '/V', '/FO', 'CSV'],
52 | 'nix': ['ps', '-A', '-o', 'pid']
53 | }
54 | }
55 |
56 | def __init__(self, platform):
57 | """
58 | ProcMitigator Constructor
59 | Used to initialize the Process Mitigator
60 | @param platform: The O/S platform of the system running the mitigator
61 | app. This MUST be one of [win, nix].
62 | """
63 | self._setPlatform(platform)
64 | if self._platform is not None:
65 | logger.info("ProcMitigator established for platform: " +
66 | self._platform)
67 |
68 | def _setPlatform(self, platform):
69 | """
70 | Private method: _setPlatform
71 | Used to initialize the _platform field.
72 | @param platform: The O/S platform of the system running the mitigator
73 | app. This MUST be one of [win, nix].
74 | """
75 | if platform in ['win', 'nix']:
76 | self._platform = platform
77 | else:
78 | logger.error("Unknown Platform Used! - Specified Platform: " +
79 | str(self._platform))
80 | self._platform = None
81 |
82 | def getPlatform(self):
83 | """
84 | Public Method: getPlatform
85 | @return: self._platform
86 | """
87 | return self._platform
88 |
89 | def _generateWinProcListing(self):
90 | """
91 | Private Method: _generateWinProcList
92 | @return: A List of processes currently running on the system. Assumes
93 | the O/S platform is windows.
94 | """
95 | p = subprocess.Popen(self._proc_cmds['list_procs']['win'],
96 | stdout=subprocess.PIPE)
97 | out, err = p.communicate()
98 |
99 | proc_list = []
100 | out = out.split('\n')
101 | header = out[0]
102 | header = header[1:-1].split('","')
103 | out = out[1:]
104 | if not out[-1]:
105 | out = out[:-1]
106 | for line in out:
107 | attribs = line[1:-1].split('","')
108 | temp = {}
109 | for i in range(len(attribs)):
110 | temp[header[i]] = attribs[i]
111 | proc_list.append(temp)
112 | logger.info("Windows Process Listing Generated!")
113 | return proc_list
114 |
115 |
116 | def _generateNixProcListing(self):
117 | """
118 | Private Method: _generateNixProcListing
119 | @return: A list of processes currently running on the system. Assumes
120 | the O/S platform is Nix based.
121 | """
122 | p = subprocess.Popen(self._proc_cmds['list_procs']['nix'],
123 | stdout=subprocess.PIPE)
124 | out, err = p.communicate()
125 |
126 | proc_list = []
127 | out = out.split('\n')
128 | header = out[0].strip()
129 | out = out[1:]
130 | if not out[-1]:
131 | out = out[:-1]
132 | for line in out:
133 | line = line.strip()
134 | proc_list.append({header: line})
135 | logger.info("Nix Process Listing Generated!")
136 | return proc_list
137 |
138 |
139 | def locateProcess(self, proc_name=None, pid=None):
140 | """
141 | Public Method: locateProcess
142 | @return: True if proc_name or pid were found in the process
143 | listing, False otherwise.
144 | """
145 | located = False
146 | if self.getPlatform() == 'win':
147 | proc_list = self._generateWinProcListing()
148 | for proc in proc_list:
149 | if proc_name == proc['Image Name']:
150 | located = True
151 | break
152 | elif pid == proc['PID']:
153 | located = True
154 | break
155 | elif self.getPlatform() == 'nix':
156 | proc_list = self._generateNixProcListing()
157 | for proc in proc_list:
158 | if pid == proc['PID']:
159 | located = True
160 | break
161 |
162 | return located
163 |
164 | def killProcByID(self, the_pid):
165 | """
166 | Public Method: killProcByID
167 | Used to issue a kill pid command to the system to for
168 | the_pid.
169 |
170 | @param the_pid: The PID of the process to be killed.
171 | @return [out, err] from the process communication.
172 | """
173 | out = None
174 | err = None
175 | if self.locateProcess(pid=the_pid):
176 | p = subprocess.Popen(self._proc_cmds['kill_pid'][self.getPlatform()] + [str(the_pid)],
177 | stdout=subprocess.PIPE)
178 | out, err = p.communicate()
179 | else:
180 | logger.error("PID: " + str(the_pid) + " not found running on " +
181 | "the system!")
182 | return [out,err]
183 |
184 | def killProcByName(self, the_proc_name):
185 | """
186 | Public Method: killProcByName
187 | Used to issue a kill process command to the system for
188 | the_proc_name
189 |
190 | @param the_proc_name: The Process Name of the process to be killed.
191 | @return [out, err] from the process communication.
192 | """
193 | out = None
194 | err = None
195 | if self.locateProcess(proc_name=the_proc_name):
196 | p = subprocess.Popen(self._proc_cmds['kill_proc_name'][self.getPlatform()] + [str(the_proc_name)],
197 | stdout=subprocess.PIPE)
198 | out, err = p.communicate()
199 | else:
200 | logger.error("Process Name: " + str(the_proc_name) + " not found " +
201 | " running on the system!")
202 |
203 | return [out,err]
204 |
205 | if __name__ == '__main__':
206 | try:
207 | results = si.readResults()
208 | keywords, options = si.getKeywordsAndOptions()
209 |
210 | for entry in results:
211 | ## PID
212 | if "pid" in entry:
213 | pid = entry["pid"]
214 | else:
215 | pid = options.get('pid', None)
216 |
217 | ## Process Name
218 | if 'proc_name' in entry:
219 | proc_name = entry['proc_name']
220 | else:
221 | proc_name = options.get('proc_name', None)
222 |
223 | ## Platform
224 | if 'platform' in entry:
225 | platform = entry['platform']
226 | else:
227 | platform = options.get('platform', None)
228 |
229 | mitigator = ProcMitigator(str(platform))
230 |
231 | if pid is not None:
232 | logger.info(str(mitigator.killProcByID(str(pid))))
233 | elif proc_name is not None:
234 | logger.info(str(mitigator.killProcByName(str(proc_name))))
235 |
236 | except Exception as e:
237 | logger.error("There was an issue establishing arguments for the " +
238 | "mitigateProc search command!")
239 | logger.exception(str(e))
240 |
--------------------------------------------------------------------------------
/SA-Mitigation-Endpoint/default/commands.conf:
--------------------------------------------------------------------------------
1 | ############## ##############
2 | # Version 0.09.11.2014 #
3 | # DO NOT EDIT THIS FILE! #
4 | # Please make all changes to files in $SPLUNK_HOME/etc/apps/SA-Mitigation/local#
5 | # To make changes, copy the section/stanza you want to change into ../local #
6 | # and edit there. #
7 | # #
8 | # Configuration for external search commands #
9 | # #
10 | ############## ##############
11 |
12 | [mitigateproc]
13 | filename = mitigate_proc.py
14 | supports_rawargs = true
--------------------------------------------------------------------------------
/SA-Mitigation-Endpoint/default/inputs.conf:
--------------------------------------------------------------------------------
1 | [monitor://$SPLUNK_HOME/etc/apps/SA-Mitigation-Endpoint/logs/proc_mitigator.log]
2 | sourcetype=mitigation
3 | index = mitigation
4 |
--------------------------------------------------------------------------------
/SA-Mitigation-Endpoint/default/savedsearches.conf:
--------------------------------------------------------------------------------
1 | #######################
2 | ## Mitigation Searches
3 | #######################
4 |
5 | #Enable this search if deplaying to Nix enviroment and disable the windows one below
6 | #[queue_manager_nix]
7 | #action.email.sendresults = 0
8 | #cron_schedule = */5 * * * *
9 | #disabled = False
10 | #dispatch.latest_time = +0s
11 | #enableSched = 1
12 | #is_visible = false
13 | #search = | inputlookup process_queue | head 1 | mitigateproc platform=nix | append [|inputlookup process_queue | join type=left pid [|inputlookup process_queue | head 1| eval temp=pid] | eval rm=if(pid==temp,1,0)] | where rm != 1 | fields time,pid | outputlookup process_queue
14 |
15 | #Enable this search if deploying in Win enviroment and disable the Nix one above
16 | [queue_manager_win]
17 | action.email.sendresults = 0
18 | cron_schedule = */5 * * * *
19 | disabled = False
20 | dispatch.latest_time = +0s
21 | enableSched = 1
22 | is_visible = false
23 | search = | inputlookup process_queue | head 1 | mitigateproc platform=win | append [|inputlookup process_queue | join type=left pid [|inputlookup process_queue | head 1| eval temp=pid] | eval rm=if(pid==temp,1,0)] | where rm != 1 | fields time,pid | outputlookup process_queue
24 |
--------------------------------------------------------------------------------
/SA-Mitigation-Endpoint/default/transforms.conf:
--------------------------------------------------------------------------------
1 | [process_queue]
2 | filename = process_queue.csv
3 | case_sensitive_match = false
4 |
5 | [proc_queue_template]
6 | filename = proc_queue_template.csv
7 | case_sensitive_match = false
--------------------------------------------------------------------------------
/SA-Mitigation-Endpoint/logs/proc_mitigator.log:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/josehelps/Splunk-Mitigation-Framework/e973cdb9656a7d1abcef4b2b2e3c9b12b3710e39/SA-Mitigation-Endpoint/logs/proc_mitigator.log
--------------------------------------------------------------------------------
/SA-Mitigation-Endpoint/lookups/proc_queue_template.csv:
--------------------------------------------------------------------------------
1 | pid,time
2 | DNF,DNF
--------------------------------------------------------------------------------
/SA-Mitigation-Endpoint/lookups/proc_queue_template.csv.default:
--------------------------------------------------------------------------------
1 | pid,time
2 |
--------------------------------------------------------------------------------
/SA-Mitigation-Endpoint/lookups/process_queue.csv:
--------------------------------------------------------------------------------
1 | pid,time
2 |
--------------------------------------------------------------------------------
/SA-Mitigation-Endpoint/lookups/process_queue.csv.default:
--------------------------------------------------------------------------------
1 | time,pid
--------------------------------------------------------------------------------
/SA-Mitigation-Endpoint/metadata/default.meta:
--------------------------------------------------------------------------------
1 |
2 | # Application-level permissions
3 |
4 | []
5 | access = read : [ * ], write : [ admin, power ]
6 |
7 | ### EVENT TYPES
8 |
9 | [eventtypes]
10 | export = system
11 |
12 |
13 | ### PROPS
14 |
15 | [props]
16 | export = system
17 |
18 |
19 | ### TRANSFORMS
20 |
21 | [transforms]
22 | export = system
23 |
24 |
25 | ### LOOKUPS
26 |
27 | [lookups]
28 | export = system
29 |
30 |
31 | ### VIEWSTATES: even normal users should be able to create shared viewstates
32 |
33 | [viewstates]
34 | access = read : [ * ], write : [ * ]
35 | export = system
36 |
--------------------------------------------------------------------------------
/SA-Mitigation-Endpoint/metadata/default.meta.SplunkESSuite:
--------------------------------------------------------------------------------
1 |
2 | ## SplunkEnterpriseSecuritySuite Application-level permissions
3 | [event_renderers]
4 | export = none
5 |
6 | ## per SOLNPCI-297 renaming 'ess_correlation_search_edit' -> 'correlation_search_edit'
7 | ## and setting exportation to local
8 | [views/correlation_search_edit]
9 | export = none
10 |
11 | ## The following export=none allows for general suppression definitions:
12 | ## 'ess_notable_supppression_new' -> 'notable_suppression_new'
13 | [views/notable_suppression_new]
14 | export = none
15 |
16 | ## Don't export the workflow actions since other apps will not have the notable editor and we don't
17 | ## want to redirect the users to an inaccessible view.
18 | ## Furthermore, we don't want to list the workflow actions twice if the customer has both ES and PCI
19 | [workflow_actions]
20 | export = none
21 |
22 | # Import the Domain Addons for ES. Note that these DA's will import the Supporting Addons.
23 | []
24 | import = DA-ESS-AccessProtection,DA-ESS-EndpointProtection,DA-ESS-IdentityManagement,DA-ESS-NetworkProtection
25 | ## shared Application-level permissions
26 | []
27 | access = read : [ * ], write : [ admin ]
28 | export = system
29 |
30 | [savedsearches]
31 | owner = admin
32 |
33 | [governance]
34 | access = read : [ * ], write : [ * ]
35 |
36 | ## Postprocess
37 | [postprocess]
38 | access = read : [ * ], write : [ * ]
39 |
40 |
41 | ## Exclude export of custom alert actions
42 | [alert_actions/email]
43 | export = none
44 |
--------------------------------------------------------------------------------
/SA-Mitigation/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/josehelps/Splunk-Mitigation-Framework/e973cdb9656a7d1abcef4b2b2e3c9b12b3710e39/SA-Mitigation/.DS_Store
--------------------------------------------------------------------------------
/SA-Mitigation/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/josehelps/Splunk-Mitigation-Framework/e973cdb9656a7d1abcef4b2b2e3c9b12b3710e39/SA-Mitigation/README.md
--------------------------------------------------------------------------------
/SA-Mitigation/bin/README.md:
--------------------------------------------------------------------------------
1 | Attack Mitigation Scripts
2 | =========================
3 |
4 | ### mitigator\_endpoint.py
5 | * Requires: Authentication for remote Splunk Agents instances under credential manager of ES under Realm `LWF`.
6 |
7 | This script makes a custom rest call to populate the `process_queue.csv` lookup in the remote splunk instances telling it what to block.
8 |
9 | ### mitigator\_network.py
10 | * Requires: Authentication for the remote Palo Alto firewalls under credential manager in ES with Realm `PAN`.
11 |
12 | This script is a modification of the pan block which uses credential manager, adds IPs to a designated group in a Palo Alto.
13 |
14 |
15 |
--------------------------------------------------------------------------------
/SA-Mitigation/bin/mitigator_endpoint.py:
--------------------------------------------------------------------------------
1 | import urllib
2 | import urllib2
3 | import json
4 | import time
5 | import logging
6 | import logging.handlers
7 |
8 | import splunk.Intersplunk as si
9 | import splunk.rest
10 | from splunk.appserver.mrsparkle.lib.util import make_splunkhome_path
11 |
12 | def setup_logger():
13 | """
14 | Sets up a logger for the Mitigator search command to track issued
15 | mitigation tasks.
16 | """
17 | logger = logging.getLogger('mitigator')
18 | # Prevent the log messgaes from being duplicated in the python.log
19 | # AuthorizationFailed
20 | logger.propagate = False
21 | logger.setLevel(logging.DEBUG)
22 |
23 | file_handler = logging.handlers.RotatingFileHandler(
24 | make_splunkhome_path(['etc', 'apps', 'SA-Mitigation', 'logs',
25 | 'mitigator.log']),
26 | maxBytes=25000000, backupCount=5)
27 | formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
28 | file_handler.setFormatter(formatter)
29 |
30 | logger.addHandler(file_handler)
31 |
32 | return logger
33 |
34 | logger = setup_logger()
35 |
36 | class Mitigator(object):
37 | """
38 | Mitigator Class
39 | This class is used for issuing mitigation tasks to remote forwarders
40 | containing the SA-LWF_Mitigater Splunk App.
41 | """
42 |
43 | ## Forwarder Management Port
44 | _MGMT_PORT = ':8089'
45 |
46 | ## REST Endpoint for issuing Splunk Searches
47 | _SEARCH_ENDPOINT = '/servicesNS/nobody/search/search/jobs/export'
48 |
49 | ## REST Endpoint for authentication. Used to obtain a session key
50 | _AUTH_ENDPOINT = '/servicesNS/nobody/search/auth/login'
51 |
52 | def __init__(self, system, localSessionKey):
53 | """
54 | Mitigator Constructor
55 | The constructor will attempt to obtain a session key for the remote
56 | instance. If this fails the Mitigator will be unable to issue a
57 | mitigation task to the remote forwarder.
58 | @param system: The system (hostname or ip) in which the mitigation task
59 | is being issued to.
60 | @param uname: Username for the remote Splunk instance
61 | @param passwd: Password for the remote Splunk instance
62 | """
63 | self.queueSearch = ("| inputlookup proc_queue_template " +
64 | "| eval pid={0} | eval time={1} | fields time, " +
65 | "pid | outputlookup append=T max=1 process_queue")
66 | self._setHost(system)
67 | self._time = str(int(time.time()))
68 | self._setLocalSessionKey(localSessionKey)
69 | self.sessionKey = self._requestSessionKey()
70 |
71 | logger.info("Mitigator Established for System: " + self._host)
72 |
73 |
74 | def _setLocalSessionKey(self, local_session_key):
75 | """
76 | Private Method: _setLocalSessionKey
77 | Used to set the local session key for the Splunk instance where
78 | SA-Mitigation resides.
79 | """
80 | self._localSessionKey = str(local_session_key)
81 |
82 | def _setHost(self, the_system):
83 | """
84 | Private Method: _setHost
85 | Method used to initialize the _host field.
86 |
87 | @param the_system: The system (hostname or ip) in which the mitigation task
88 | is being issued to.
89 | """
90 | self._host = 'https://' + str(the_system) + self._MGMT_PORT
91 |
92 | def _getLWFCreds(self):
93 | """
94 | """
95 | uname = None
96 | passwd = None
97 | response, content = splunk.rest.simpleRequest('storage/passwords',
98 | getargs={'output_mode': 'json','count': '0'},
99 | raiseAllErrors=True,
100 | sessionKey=self._localSessionKey)
101 |
102 | if response['status'] == "200":
103 | content = json.loads(content)
104 | for entry in content['entry']:
105 | if entry['content']['realm'] == "LWF":
106 | uname = entry['content']['username']
107 | passwd = entry['content']['clear_password']
108 | break
109 |
110 | #logger.info("Username: " + str(uname) + " Password: " + str(passwd))
111 | logger.info("Loggin in as Username: " + str(uname) + " From LWF Realm in cred manager")
112 | else:
113 | logger.error("Received something other than an HTTP 200 response " +
114 | "when attempting to acquire the LWF creds from the " +
115 | " cred manager.")
116 | return uname, passwd
117 |
118 | def _requestSessionKey(self):
119 | """
120 | Private Method: _requestSessionKey
121 | Method used to request a session key from the remote splunk
122 | instance.
123 |
124 | @return String representation of the session key for the remote splunk
125 | instance.
126 | """
127 | try:
128 | uname, passwd = self._getLWFCreds()
129 | url = self._host + self._AUTH_ENDPOINT
130 | request = urllib2.Request(url,
131 | data = urllib.urlencode({'username': uname, 'password': passwd,
132 | 'output_mode': 'json'}))
133 | content = urllib2.urlopen(request).read()
134 | content = json.loads(content)
135 | return 'Splunk ' + content['sessionKey']
136 | except Exception as e:
137 | logger.error("There was an issue requesting the session key for " +
138 | " host: " + self._host)
139 | logger.exception(str(e))
140 |
141 |
142 | def getSessionKey(self):
143 | """
144 | Public Method: getSessionKey
145 | @return The session key requested from the remote splunk instance.
146 | """
147 | return self.sessionKey
148 |
149 | def sendMitigatePIDTask(self, pid):
150 | """
151 | Public Method: sendMitigatePIDTask
152 | Used to issue PID mitigation tasks to the remote splunk instance.
153 |
154 | @param pid: The PID that is to be mitigated by the remote Splunk
155 | instance
156 | """
157 | try:
158 | url = self._host + self._SEARCH_ENDPOINT
159 | request = urllib2.Request(url,
160 | data = urllib.urlencode({'search': self.queueSearch.format(str(pid), self._time),
161 | 'output_mode': 'json'}),
162 | headers = {'Authorization': self.getSessionKey()})
163 |
164 | content = urllib2.urlopen(request)
165 | logger.info("Mitigate PID task sent to host: " + self._host +
166 | " for PID: " + str(pid) + ", at Time: " + self._time)
167 | except Exception as e:
168 | logger.error("There was an issue sending a PID Mitigation Task " +
169 | "for host: " + self._host + ", time: " + self._time +
170 | ", PID: " + str(pid))
171 | logger.exception(str(e))
172 |
173 | if __name__ == '__main__':
174 |
175 | try:
176 | results, dummyresults, settings = si.getOrganizedResults()
177 | keywords, options = si.getKeywordsAndOptions()
178 |
179 | for entry in results:
180 | ## System info
181 | if "system" in entry:
182 | system = entry["system"]
183 | else:
184 | system = options.get('system', None)
185 |
186 | ## PID Info
187 | if "pid" in entry:
188 | pid = entry["pid"]
189 | else:
190 | pid = options.get('pid', None)
191 |
192 | mit = Mitigator(system, settings['sessionKey'])
193 | mit.sendMitigatePIDTask(pid)
194 | print 'sent PID ' + pid + ' to be mitigated at ' + system
195 |
196 | except Exception as e:
197 | logger.error("There was an issue establishing arguments for the " +
198 | "mitigator search command!")
199 | logger.exception(str(e))
200 |
--------------------------------------------------------------------------------
/SA-Mitigation/bin/mitigator_network.py:
--------------------------------------------------------------------------------
1 | ##########################################
2 | # This is a modifed version of the panChange.py script from the Palo Alto App
3 | # This script is meant to be use with Splunk Enterprise Security.
4 | # Author: jose@splunk.com
5 | # Description: This is a modifed version of the panChange.py script from the Palo Alto App
6 | # This script is meant to be use with Splunk Enterprise Security.
7 | # Udpates:
8 | # * crendetials now stored encrypted using credential manager with ES
9 | # * configuration file moved to default/pan.conf
10 | ##########################################
11 | # Original Documentation Below
12 | ###########################################
13 | # Version 0.1
14 | # Extremely Experimental
15 | # author: monzy@splunk.com
16 | # About this script:
17 | # Given an IP address, adds or removes the IP from an address group
18 | # The script assumes that you have firewall policy setup that blocks
19 | # traffic for a given group, e.g. a badActors group.
20 | # It is important to recognize that this script does NOT modify a firewall rule.
21 | # It only adds/removes address objects.
22 | # So if a rule operates on an Address Group, this scripts add/remove will impact
23 | # that rule/policy.
24 | ############################################
25 | # How to Use this script
26 | # in the example below, we are blocking all ip's returned by the search
27 | # example1: index=pan_logs 1.1.1.1 | stats dc(dst_ip) by dst_ip | panblock action="add" group="badboys"
28 | # Adds the IP 1.1.1.1
29 | # example2: index=pan_logs wine | stats dc(dst_hostname) by dst_hostname | panblock action="rem" group="badboys" device="sales-fw"
30 | # Removes all dst_hostnames returned by the search from the sales firewall from the badboys group
31 | ###########################################
32 | # Known issues:
33 | # Very limited error checking
34 | # Errors may not reported in the Splunk UI
35 | # Changes do not get implemented on Panorama (i am happy to work with someone to add this feature)
36 | ###########################################
37 | # DEFAULTS
38 | ACTION = 'add'
39 | # This is a default actor.
40 | ACTOR = '1.1.1.1'
41 | # if you DO want to go through a proxy, e.g., HTTP_PROXY={squid:'2.2.2.2'}
42 | HTTP_PROXY = {}
43 |
44 | #########################################################
45 | # Do NOT modify anything below this line unless you are
46 | # certain of the ramifications of the changes
47 | #########################################################
48 |
49 | import splunk.Intersplunk # so you can interact with Splunk
50 | import splunk.entity as entity # for splunk config info
51 | import urllib2 # make http requests to PAN firewall
52 | import sys # for system params and sys.exit()
53 | import re # regular expressions checks in PAN messages
54 | import splunk.mining.dcutils as dcu
55 | import ConfigParser # to parse out the pa.conf file
56 | from splunk.appserver.mrsparkle.lib.util import make_splunkhome_path # to grab the default splunk path
57 | import splunk.rest
58 | import json
59 |
60 | logger = dcu.getLogger()
61 | # set path of config
62 | panconf = make_splunkhome_path(["etc","apps","SA-Mitigation","default","pan.conf"])
63 | # read config file
64 | config = ConfigParser.RawConfigParser()
65 | config.read(panconf)
66 |
67 | #Assign PA IP
68 | PAN = config.get('PAN','IP')
69 |
70 | #Assign BADACTORS group name
71 | BADACTORS = config.get('PAN','GROUP')
72 |
73 | ## Major props to Ledion. copying his function, verbatim and then adding comments and traceback and logging
74 | ## http://blogs.splunk.com/2011/03/15/storing-encrypted-credentials/
75 | ## access the credentials in /servicesNS/nobody//admin/passwords
76 |
77 | def getCredentials(sessionKey):
78 | '''Given a splunk sesionKey returns a clear text user name and password from a splunk password container'''
79 | USERNAME =''
80 | PASSWORD =''
81 | #make a rest call to get passwords from credential manager
82 | response,content = splunk.rest.simpleRequest('storage/passwords', sessionKey=sessionKey, getargs={'output_mode':'json'}, postargs=None, method='GET', raiseAllErrors=False, proxyMode=False, rawResult=False, timeout=None, jsonargs=None)
83 | #format output as json
84 | content = json.loads(content)
85 |
86 | #look for the realm of PAN and resturn the credentials
87 | for items in content['entry']:
88 | if items['content']['realm'] == 'PAN':
89 | USERNAME = item['content']['username']
90 | PASSWORD = item['content']['clear_password']
91 | return USERNAME,PASSWORD
92 | ## Major props to Ledion. copying his function, verbatim and then adding comments and traceback and logging
93 |
94 | def createOpener():
95 | '''Create a generic opener for http. This is particularly helpful when there is a proxy server in line'''
96 | # Thanks to: http://www.decalage.info/en/python/urllib2noproxy
97 | proxy_handler = urllib2.ProxyHandler(HTTP_PROXY)
98 | opener = urllib2.build_opener(proxy_handler)
99 | urllib2.install_opener(opener)
100 | return opener
101 |
102 | def getKey(PAN, PANUSER, PANPASS):
103 | ''' Logs into the PAN firewall and obtains a PAN session key'''
104 | # create an opener object
105 | opener = createOpener()
106 | try:
107 | # the url for the PAN
108 | panReq = urllib2.Request('https://'+PAN+'/api/?type=keygen&user='+PANUSER+'&password='+PANPASS)
109 | # make the request
110 | req = opener.open(panReq)
111 | except:
112 | sys.exit(-1)
113 | # the result of the URL request
114 | result = req.read()
115 | # get the status of the result
116 | try:
117 | sm = re.search(r"success",result).group(0)
118 | if sm == 'success' :
119 | status = 'success'
120 | except:
121 | sys.exit(-1)
122 | # parse the key from the result
123 | key = result.split("")[0].split("")[1]
124 | return key
125 |
126 | def checkAddr(address):
127 | '''Check if an address is a FQDN or IP with some netmask. Return the appropriate uri for PAN api'''
128 | # element is everything after the element= field in the PAN api
129 | # re pattern for IP address
130 | ippat = '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'
131 | # re pattern for fully qualified domain name (could be stricter)
132 | fqdnpat = '\w+[.-]'
133 | # is element an IP address
134 | if re.match(ippat, address) != None :
135 | ipuri = ''+address+'/32'
136 | return ipuri
137 | if re.match(fqdnpat, address) != None :
138 | fqdnuri = ''+address+''
139 | return fqdnuri
140 |
141 | def panorama():
142 | ''' Interact with PANorama'''
143 | #Set dynamic address object (with LinkID) at Panorama level, commit
144 | #https://pm-panorama/api/?type=config&action=set&xpath=/config/devices/entry[@name='localhost.localdomain']/device-group/entry[@name='splunktastic']/address/entry[@name='test-add']&element=test1&key=LUFRPT14MW5xOEo1R09KVlBZNnpnemh0VHRBOWl6TGM9bXcwM3JHUGVhRlNiY0dCR0srNERUQT09
145 | #https://pm-panorama/api/?type=commit&action=all&cmd=splunktastic&key=LUFRPT14MW5xOEo1R09KVlBZNnpnemh0VHRBOWl6TGM9bXcwM3JHUGVhRlNiY0dCR0srNERUQT09
146 | #Map IPs to correct UserID
147 | #https://pm-panorama/api/?type=user-id&action=set&cmd=1.0update&key=LUFRPT14MW5xOEo1R09KVlBZNnpnemh0VHRBOWl6TGM9bXcwM3JHUGVhRlNiY0dCR0srNERUQT09&target=0006C107916
148 | return 0
149 |
150 | def addActor(PAN, key, VSYS, ACTOR, BADACTORS):
151 | '''Creates an address object then add the object to an Address group'''
152 | # create an opener object
153 | opener = createOpener()
154 | # create the address object
155 | panReq = urllib2.Request('https://'+PAN+'//api/?type=config&action=set&key='+key+'&xpath=/config/devices/entry/vsys/entry[@name='+"'"+VSYS+"'"+']/address/entry[@name='+"'"+ACTOR+"'"+']&element='+checkAddr(ACTOR))
156 | req = opener.open(panReq)
157 | # add the address object to the BADACTORS group
158 | panReq = urllib2.Request('https://'+PAN+'//api/?type=config&action=set&key='+key+'&xpath=/config/devices/entry/vsys/entry[@name='+"'"+VSYS+"'"+']/address-group/entry[@name='+"'"+BADACTORS+"'"+']&element='+ACTOR+'')
159 | req = opener.open(panReq)
160 | return 0
161 |
162 | def remActor(PAN, key, VSYS, ACTOR, BADACTORS):
163 | '''Remove an address object from the address-group then remove the addres object '''
164 | # create an opener object
165 | opener = createOpener()
166 | # first we remove him from the badactors group
167 | #panReq = urllib2.Request('https://'+PAN+'/api/?type=config&action=delete&key='+key+'&xpath=/config/devices/entry/vsys/entry[@name='+"'"+VSYS+"'"+']/address-group/entry[@name='+"'"+BADACTORS+"'"+']&element='+ACTOR+'')
168 | #req = opener.open(panReq)
169 | # then we remove him all together
170 | #panReq = urllib2.Request('https://'+PAN+'/api/?type=config&action=delete&key='+key+'&xpath=/config/devices/entry/vsys/entry[@name='+"'"+VSYS+"'"+']/address/entry[@name='+"'"+ACTOR+"'"+']')
171 | #req = opener.open(panReq)
172 | panReq = urllib2.Request('https://'+PAN+'/api/?type=config&action=delete&key='+key+'&xpath=/config/devices/entry/vsys/entry[@name='+"'"+VSYS+"'"+']/address-group/entry[@name='+"'"+BADACTORS+"'"+']/member[text()='+"'"+ACTOR+"'"+']')
173 | req = opener.open(panReq)
174 | panReq = urllib2.Request('https://'+PAN+'/api/?type=config&action=delete&key='+key+'&xpath=/config/devices/entry/vsys/entry[@name='+"'"+VSYS+"'"+']/address/entry[@name='+"'"+ACTOR+"'"+']')
175 | req = opener.open(panReq)
176 | return 0
177 |
178 | def commitConfig(PAN, key):
179 | '''Save the changes made to the address objects'''
180 | # create an opener object
181 | opener = createOpener()
182 | panReq = urllib2.Request('https://'+PAN+'//api/?type=commit&cmd=&key='+key)
183 | req = opener.open(panReq)
184 | return 0
185 |
186 | def block(result):
187 | key = getKey(PAN, PANUSER, PANPASS)
188 | if ACTION == 'add':
189 | addActor(PAN, key, VSYS, str(result[result.keys()[0]]), BADACTORS)
190 | elif ACTION == 'rem':
191 | remActor(PAN, key, VSYS, str(result[result.keys()[0]]), BADACTORS)
192 | else:
193 | return ['bad action', key]
194 | return ["action submitted", key]
195 |
196 | args, kwargs = splunk.Intersplunk.getKeywordsAndOptions()
197 | #parse the kwargs for ACTION, VSYS, PAN
198 | if kwargs.has_key('action'):
199 | ACTION = kwargs['action']
200 | if kwargs.has_key('device'):
201 | PAN = kwargs['device']
202 | if kwargs.has_key('vsys'):
203 | VSYS = kwargs['vsys']
204 | if kwargs.has_key('group'):
205 | BADACTORS = kwargs['group']
206 |
207 | # an empty dictionary. it will be used to hold system values
208 | settings = dict()
209 | # results contains the data from the search results and settings contains the sessionKey that we can use to talk to splunk
210 | results,unused,settings = splunk.Intersplunk.getOrganizedResults()
211 | # get the sessionKey
212 | sessionKey = settings['sessionKey']
213 | # get the user and password using the sessionKey
214 | PANUSER, PANPASS = getCredentials(sessionKey)
215 |
216 | try:
217 | for result in results:
218 | if (result.has_key('src_ip')\
219 | or result.has_key('dst_ip') \
220 | or result.has_key('ip') \
221 | or result.has_key('hostname') \
222 | or result.has_key('dst_hostname') \
223 | or result.has_key('dest_host') \
224 | or result.has_key('domain') \
225 | or result.has_key('clientip') ):
226 | blockresult = block(result)
227 | result["status"] = blockresult[0]
228 | key = blockresult[1]
229 | # for test purposes
230 | elif (len(result) == 2) and result.has_key('test'):
231 | result["status"] = ["this is the sessionKey. not printing the password :p " + sessionKey]
232 | else:
233 | result["status"] = 'empty or invalid field vlue'
234 |
235 | #after all the addresses have been processed, commit the config
236 | commitConfig(PAN, key)
237 | except Exception, e:
238 | import traceback
239 | stack = traceback.format_exc()
240 | if isgetinfo:
241 | splunk.Intersplunk.parseError(str(e))
242 |
243 | results = splunk.Intersplunk.generateErrorResults(str(e))
244 | logger.warn(stack)
245 |
246 | # output results
247 | splunk.Intersplunk.outputResults(results)
248 |
--------------------------------------------------------------------------------
/SA-Mitigation/default/app.conf:
--------------------------------------------------------------------------------
1 | #
2 | # Splunk app configuration file
3 | #
4 |
5 | [install]
6 | is_configured = 0
7 |
8 | [ui]
9 | is_visible = 0
10 | label = SA-Mitigation
11 |
12 | [launcher]
13 | author = Jose Hernandez, Monzy Merza, Brian Luger
14 | description = Fight attacks in ES framework
15 | version = 1.0
16 |
17 | [credential:LWF:admin:]
18 | password = $1$+/Ox7ASEXpT2WsM=
19 |
20 | [credential:PAN:panservice:]
21 | password = $1$pvDs6R3GQ/c=
22 |
--------------------------------------------------------------------------------
/SA-Mitigation/default/commands.conf:
--------------------------------------------------------------------------------
1 | ############################
2 | # Version 0.09.11.2014
3 | # DO NOT EDIT THIS FILE!
4 | # Please make all changes to files in $SPLUNK_HOME/etc/apps/SA-Mitigation/local
5 | # To make changes, copy the section/stanza you want to change into ../local and edit there.
6 | # Configuration for external search commands
7 | ############################
8 |
9 | [blockendpoint]
10 | filename = mitigator_endpoint.py
11 | supports_rawargs = true
12 | passauth = true
13 |
14 | [blocknetwork]
15 | filename = mitigator_network.py
16 | supports_rawargs = true
17 | passauth = true
18 |
--------------------------------------------------------------------------------
/SA-Mitigation/default/correlationsearches.conf:
--------------------------------------------------------------------------------
1 | [Network - Mitigation High Confidence IDS - Rule]
2 | default_status = 2
3 | description = A high confidence IDS alert to $src$ example for the Mitigation framework
4 | rule_description = Notable that triggers mitigation on a high confidence IDS alert to $src$
5 | rule_name = High Confidence IDS
6 | rule_title = Mitigation - High Confidence IDS Alert on $src$
7 | search = {}
8 | security_domain = network
9 | severity = critical
10 |
11 |
12 | [Endpoint - Mitigation High Confidence Registry - Rule]
13 | default_status = 2
14 | description = Mitigation on a registry key under currentversion/run with created from a application with .vbs as a file extension with pid $pid$ on $host$
15 | rule_description = Notable that triggers mitigation on a registry key under currentversion/run with created from a application with .vbs as a file extension with pid $pid$ on $host$
16 | rule_name = High Confidence Registry
17 | rule_title = Mitigation - High Confidence Registry Alert with pid $pid$ on $host$
18 | search = {}
19 | security_domain = endpoint
20 | severity = critical
21 |
--------------------------------------------------------------------------------
/SA-Mitigation/default/data/ui/nav/default.xml:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/SA-Mitigation/default/data/ui/views/mitigation_center.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/SA-Mitigation/default/data/ui/views/mitigation_tracker.xml:
--------------------------------------------------------------------------------
1 |
208 |
--------------------------------------------------------------------------------
/SA-Mitigation/default/indexes.conf:
--------------------------------------------------------------------------------
1 | [mitigation]
2 | homePath = $SPLUNK_DB/mitigationdb/db
3 | coldPath = $SPLUNK_DB/mitigationdb/colddb
4 | thawedPath = $SPLUNK_DB/mitigationdb/thaweddb
5 | tstatsHomePath = volume:_splunk_summaries/mitigationdb/datamodel_summary
6 | maxMemMB = 20
7 | maxConcurrentOptimizes = 6
8 | maxHotIdleSecs = 86400
9 | maxHotBuckets = 10
10 | maxDataSize = auto_high_volume
11 |
12 | [mitigation_summary]
13 | homePath = $SPLUNK_DB/mitigation_summarydb/db
14 | coldPath = $SPLUNK_DB/mitigation_summarydb/colddb
15 | thawedPath = $SPLUNK_DB/mitigation_summarydb/thaweddb
16 |
--------------------------------------------------------------------------------
/SA-Mitigation/default/inputs.conf:
--------------------------------------------------------------------------------
1 | [monitor://$SPLUNK_HOME/etc/apps/SA-Mitigation/logs/mitigator.log]
2 | sourcetype=mitigation
3 | index = mitigation
4 |
--------------------------------------------------------------------------------
/SA-Mitigation/default/pan.conf:
--------------------------------------------------------------------------------
1 | #sets configuration parameters for Palo Alto
2 | # Currently does not support multiple vsys and or groing through proxies
3 |
4 | [PAN] # please do not change this might break things
5 | IP = '192.168.4.100' # ip address of palo alto
6 | GROUP = 'badActors' # name of group to drop blocked ips in
7 |
8 |
--------------------------------------------------------------------------------
/SA-Mitigation/default/savedsearches.conf:
--------------------------------------------------------------------------------
1 | [Network - Mitigation High Confidence IDS - Rule]
2 | action.email.reportServerEnabled = 0
3 | action.keyindicator.invert = 0
4 | action.summary_index = 1
5 | action.summary_index._name = notable
6 | action.summary_index.ttl = 1p
7 | alert.suppress = 1
8 | alert.suppress.fields = src
9 | alert.suppress.period = 86300
10 | alert.track = 0
11 | counttype = number of events
12 | cron_schedule = */1 * * * *
13 | dispatch.earliest_time = -24h
14 | dispatch.latest_time = +0s
15 | enableSched = 1
16 | quantity = 0
17 | realtime_schedule = 0
18 | relation = greater than
19 | search = | tstats `summariesonly` count from datamodel=Intrusion_Detection where earliest=-24h@h latest=+0s (IDS_Attacks.severity=critical OR IDS_Attacks.severity=high IDS_Attacks.src!=0.0.0.0 IDS_Attacks.src!="00:*") by IDS_Attacks.src,IDS_Attacks.dest,sourcetype,host| rename IDS_Attacks.src AS src | regex src="^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$" | rename IDS_Attacks.dest AS dest | rename sourcetype as orig_sourcetype | rename host as orig_host | table orig_sourcetype,orig_host,dest,src,count | sort - count
20 |
21 | [Endpoint - Mitigation High Confidence Registry - Rule]
22 | action.email.reportServerEnabled = 0
23 | action.keyindicator.invert = 0
24 | action.summary_index = 1
25 | action.summary_index._name = notable
26 | action.summary_index.ttl = 1p
27 | alert.suppress = 1
28 | alert.suppress.fields = host,pid,process_name
29 | alert.suppress.period = 86300
30 | alert.track = 0
31 | counttype = number of events
32 | cron_schedule = */1 * * * *
33 | dispatch.earliest_time = -48h
34 | dispatch.latest_time = +0s
35 | enableSched = 1
36 | quantity = 0
37 | realtime_schedule = 0
38 | relation = greater than
39 | search = sourcetype="winregistry" key_path="*\\windows\\currentversion\\run*" data="*.vbs" | rename sourcetype as orig_sourcetype | rename host as orig_host | table orig_sourcetype,orig_host,dest,status,pid,process_image,key_path,data
40 |
41 | [Master Mitigation - Network]
42 | cron_schedule = */1 * * * *
43 | description = Search that find all network items to mitigation and puts the block in place. Also keeps track of what is being mitigated in mitigation_network lookup
44 | dispatch.earliest_time = -1h
45 | dispatch.latest_time = now
46 | display.events.fields = ["host","source","sourcetype","tag","src_country","src","dest","Notable_Events_Meta.rule_id"]
47 | display.general.type = statistics
48 | display.visualizations.show = 0
49 | enableSched = 1
50 | search = index=notable source="Network - Mitigation*" | eval id=splunk_server."@@".index."@@".md5(_time._raw) | rename dest as system | table id,orig_sourcetype,orig_host,src,system | collect index=mitigation addtime=true marker="type=network,status=submitted,action=block" | blocknetwork action=block device=10.0.0.1 vsys=vsys1 group=BADACTORS
51 | #old search
52 | #search = index=notable source="Network - Mitigation*" | eval status="submitted" | eval action="block" | eval type="network" | rename Notable_Events_Meta.rule_id as id| table id,orig_sourcetype,orig_host,src,dest,action,status,pid,type | collect index=mitigation_summary addtime=true | blocknetwork action=block device=10.0.0.1 vsys=vsys1 group=BADACTORS
53 |
54 | [Master Mitigation - Endpoint]
55 | cron_schedule = */1 * * * *
56 | description = Search that find all network items to mitigation and puts the block in place. Also keeps track of what is being mitigated in mitigation_network lookup
57 | dispatch.earliest_time = -1h
58 | dispatch.latest_time = now
59 | display.events.fields = ["host","source","sourcetype","tag","src_country","src","dest","Notable_Events_Meta.rule_id", "pid"]
60 | display.general.type = statistics
61 | display.visualizations.show = 0
62 | enableSched = 1
63 | search = index=notable source="Endpoint - Mitigation*" | eval id=splunk_server."@@".index."@@".md5(_time._raw) | rename dest as system | table id,orig_sourcetype,orig_host,src,system,pid,process_image,key_path,data | collect index=mitigation_summary addtime=true marker="type=endpoint,status=submitted,action=block" | blockendpoint pid=pid system=system
64 | #old search we were using
65 | #search = index=notable source="Endpoint - Mitigation*" | eval status="submitted" | eval action="block" | eval type="endpoint" | rename Notable_Events_Meta.rule_id as id| rename dest as system | blockendpoint pid=pid system=system | table id,orig_sourcetype,orig_host,src,dest,action,status,pid,process_image,key_path,type,data | collect index=mitigation addtime=true
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/SA-Mitigation/default/searchbnf.conf:
--------------------------------------------------------------------------------
1 | ##################
2 | # mitigator
3 | ##################
4 | [blockendpoint-command]
5 | syntax = blockendpoint (pid=)* (system=)*
6 | shortdesc = Kills a process on a remote machine
7 | description = Must specify a hostname and PID
8 | usage = public
9 | example1 = blockendpoint pid=1234 system=10.0.0.1
10 | comment1 = blocks process 1234 on remote host 10.0.0.1
11 | related = blocknetwork
12 | tags = mitigate block endpoint
13 |
14 | [blocknetwork-command]
15 | syntax = blocknetwork (action=)* (device=)* (vsys=)* (group=)*
16 | shortdesc = Sends an IP address to Palo Alto to be placed under a block group.
17 | description = Must specify the device IP (device), the vsys (vsys), the action (action), and finally which block group to put the IP address in (group).
18 | usage = public
19 | example1 = blocknetwork action=block device=10.0.0.1 vsys=vsys1 group=BADACTORS
20 | comment1 = blocks any IP address passed to this command by placing them in group BADACTORs. Group needs to be configured in the Palo Alto FW as blocking.
21 | related = blockendpoint, panblock
22 | tags = mitigate block network
23 |
24 |
--------------------------------------------------------------------------------
/SA-Mitigation/default/transforms.conf:
--------------------------------------------------------------------------------
1 | [mitigation_network]
2 | filename = mitigation_network.csv
3 | case_sensitive_match = false
4 |
--------------------------------------------------------------------------------
/SA-Mitigation/local/app.conf:
--------------------------------------------------------------------------------
1 | [credential:LWF:admin:]
2 | password = $1$+/Ox7ASEXpT2WsM=
3 |
--------------------------------------------------------------------------------
/SA-Mitigation/lookups/mitigation.csv.default:
--------------------------------------------------------------------------------
1 | #Intentionally left empty make modular input of this to calculate the other 2 mitigation_*.csv lookups
2 | #id = ID of notable event
3 | #ioc = indicator which will be mitigated this lookup table is then broken up per indicator (ip/runkeys/etc.)
4 | #status = failed or successful - if it was mitigated or not
5 | id,ioc,status
6 |
--------------------------------------------------------------------------------
/SA-Mitigation/lookups/mitigation_endpoint.csv:
--------------------------------------------------------------------------------
1 | #id = ID of notable event
2 | #regkey = registry key to mitigate on
3 | #status = failed or successful - if it was mitigated or not
4 | id,regkey,status
5 |
--------------------------------------------------------------------------------
/SA-Mitigation/lookups/mitigation_endpoint.csv.default:
--------------------------------------------------------------------------------
1 | #id = ID of notable event
2 | #regkey = registry key to mitigate on
3 | #status = failed or successful - if it was mitigated or not
4 | id,regkey,status
5 |
--------------------------------------------------------------------------------
/SA-Mitigation/lookups/mitigation_network.csv:
--------------------------------------------------------------------------------
1 | id,src,status,time
2 | "maquina.local@@notable@@4bc9cf3558ca18f9536f524097b6f09a","96.44.226.43",submitted,1410322200
3 | "maquina.local@@notable@@aea852f8a38071662f64456f06bf8e50","95.106.229.220",submitted,1410322200
4 | "maquina.local@@notable@@3a81fd1d3d0ac6d8583f3a75496597b5","90.86.109.191",submitted,1410322200
5 | "maquina.local@@notable@@ce87540c1a6e514ad1b1960e102d2a40","90.77.58.235",submitted,1410322200
6 | "maquina.local@@notable@@52f363c4316b9b1b3dd326b82c331ca1","69.74.142.131",submitted,1410322200
7 | "maquina.local@@notable@@5df20e3752d491dd9558271426e20d4f","67.228.139.118",submitted,1410322200
8 | "maquina.local@@notable@@4fed7066699f6834d91f02de6bf0feeb","59.60.235.251",submitted,1410322200
9 | "maquina.local@@notable@@a81206481c6a61592e36132b0665f49b","57.206.75.55",submitted,1410322200
10 | "maquina.local@@notable@@dc8891bde3d7cc162551e70b7e8934fb","55.155.183.174",submitted,1410322200
11 | "maquina.local@@notable@@7db2a3a4abf99e469aa945a21f6cd48b","47.149.190.108",submitted,1410322200
12 | "maquina.local@@notable@@865538efb5a32cb5ba49e7d36a2e5b72","47.107.105.110",submitted,1410322200
13 | "maquina.local@@notable@@b249b906d2680a5f1154bb9746b6915b","44.236.254.45",submitted,1410322200
14 | "maquina.local@@notable@@20a5b10e16c2bae423566804eb1974f3","43.155.21.76",submitted,1410322200
15 | "maquina.local@@notable@@e6060e0f44d8735ae10751365b07b828","255.86.116.223",submitted,1410322200
16 | "maquina.local@@notable@@99bac8e98d322f7a82b6aace0048b44a","247.220.184.112",submitted,1410322200
17 | "maquina.local@@notable@@f0455bc6dac3016e1735d6ef993a65a6","234.220.221.111",submitted,1410322200
18 | "maquina.local@@notable@@5ae444ce643f5fffdae2cee6523aaff3","233.205.111.93",submitted,1410322200
19 | "maquina.local@@notable@@44e54ce5d5719d012b61b7febae9947d","225.212.85.229",submitted,1410322200
20 | "maquina.local@@notable@@7ae8aed528ab0fdce53678bb9a5485ca","218.108.43.117",submitted,1410322200
21 | "maquina.local@@notable@@793a6eb6da6b78810dcc2c1bf4acfb46","213.185.100.178",submitted,1410322200
22 | "maquina.local@@notable@@d43f42c9bcb585495a7fb786dbb9aa38","211.247.75.203",submitted,1410322200
23 | "maquina.local@@notable@@a51f83fb993ba81e5ca8575c217f6744","211.169.204.162",submitted,1410322200
24 | "maquina.local@@notable@@bf0d79d0751d5d920982a207b4d44dff","207.122.211.168",submitted,1410322200
25 | "maquina.local@@notable@@c8cd7f5235625cfa48f27ff6c02e1b25","205.187.245.187",submitted,1410322200
26 | "maquina.local@@notable@@25a36a8ec97047892f080584cc4f10f3","202.87.243.241",submitted,1410322200
27 | "maquina.local@@notable@@b64e5132dc1dc7efb3c7cf20c1562790","202.79.207.134",submitted,1410322200
28 | "maquina.local@@notable@@d3ec185f57c276452f46bc402a95a6a6","192.168.96.67",submitted,1410322200
29 | "maquina.local@@notable@@599d36d655bdc06ae357c37787efde44","192.168.31.247",submitted,1410322200
30 | "maquina.local@@notable@@01ec916d6d796758b95c5f377407c844","189.207.214.112",submitted,1410322200
31 | "maquina.local@@notable@@7bb02bd88e566b0cd5e62bcf189962d4","184.101.203.90",submitted,1410322200
32 | "maquina.local@@notable@@4adec38f97fdee8d9ca95b6217f0578f","17.241.150.106",submitted,1410322200
33 | "maquina.local@@notable@@ad14bb69f58a4d0dc95812ab6f954f0e","17.18.19.6",submitted,1410322200
34 | "maquina.local@@notable@@9a2d33c128eed894928d254f48e0c38d","17.18.19.5",submitted,1410322200
35 | "maquina.local@@notable@@c6205e27d0e8a52cdd4124bbae80caab","17.18.19.21",submitted,1410322200
36 | "maquina.local@@notable@@6f3ea972da6a7b5cdfa7172b3952e04c","17.18.19.20",submitted,1410322200
37 | "maquina.local@@notable@@2704e828dddbabe8ce5ae5ef56187de2","168.162.223.148",submitted,1410322200
38 | "maquina.local@@notable@@e5a91dc4e40aa6291ada4c7a9123b57e","160.221.80.74",submitted,1410322200
39 | "maquina.local@@notable@@8e7560b43eb2fa00826d91850e07e9a1","158.138.219.125",submitted,1410322200
40 | "maquina.local@@notable@@2b842eab14e5f1c82fbfdde9194cb55c","148.167.77.93",submitted,1410322200
41 | "maquina.local@@notable@@4cf62f7e930d69cc3d7e540cbb8a713f","129.17.73.122",submitted,1410322200
42 | "maquina.local@@notable@@a96afb11132b62bc0e0d9067c7edb8e7","124.254.205.166",submitted,1410322200
43 | "maquina.local@@notable@@25cdb06d0f297afe472c7bd4eef44861","123.111.73.166",submitted,1410322200
44 | "maquina.local@@notable@@fec28328e6798918ccb62c3aef170c50","123.111.153.227",submitted,1410322200
45 | "maquina.local@@notable@@1b9325add9b3ce67e87805508d2b57e9","117.178.100.5",submitted,1410322200
46 | "maquina.local@@notable@@0e7cfe2ddf2fd3fd24942afe535436e1","111.77.83.117",submitted,1410322200
47 | "maquina.local@@notable@@05e712835e9d72351541b779ae7224a2","101.118.78.175",submitted,1410322200
48 |
--------------------------------------------------------------------------------
/SA-Mitigation/lookups/mitigation_network.csv.default:
--------------------------------------------------------------------------------
1 | #id = ID of notable event
2 | #ip = network ip to block traffic from
3 | #status = failed or successful - if it was mitigated or not
4 | #time = time it was mitigated
5 | id,ip,status,time
6 |
--------------------------------------------------------------------------------
/SA-Mitigation/metadata/default.meta:
--------------------------------------------------------------------------------
1 |
2 | # Application-level permissions
3 |
4 | []
5 | access = read : [ * ], write : [ admin, power ]
6 |
7 | ### EVENT TYPES
8 |
9 | [eventtypes]
10 | export = system
11 |
12 |
13 | ### PROPS
14 |
15 | [props]
16 | export = system
17 |
18 |
19 | ### TRANSFORMS
20 |
21 | [transforms]
22 | export = system
23 |
24 |
25 | ### LOOKUPS
26 |
27 | [lookups]
28 | export = system
29 |
30 |
31 | ### VIEWSTATES: even normal users should be able to create shared viewstates
32 |
33 | [viewstates]
34 | access = read : [ * ], write : [ * ]
35 | export = system
36 |
--------------------------------------------------------------------------------
/SA-Mitigation/metadata/default.meta.SplunkESSuite:
--------------------------------------------------------------------------------
1 |
2 | ## SplunkEnterpriseSecuritySuite Application-level permissions
3 | [event_renderers]
4 | export = none
5 |
6 | ## per SOLNPCI-297 renaming 'ess_correlation_search_edit' -> 'correlation_search_edit'
7 | ## and setting exportation to local
8 | [views/correlation_search_edit]
9 | export = none
10 |
11 | ## The following export=none allows for general suppression definitions:
12 | ## 'ess_notable_supppression_new' -> 'notable_suppression_new'
13 | [views/notable_suppression_new]
14 | export = none
15 |
16 | ## Don't export the workflow actions since other apps will not have the notable editor and we don't
17 | ## want to redirect the users to an inaccessible view.
18 | ## Furthermore, we don't want to list the workflow actions twice if the customer has both ES and PCI
19 | [workflow_actions]
20 | export = none
21 |
22 | # Import the Domain Addons for ES. Note that these DA's will import the Supporting Addons.
23 | []
24 | import = DA-ESS-AccessProtection,DA-ESS-EndpointProtection,DA-ESS-IdentityManagement,DA-ESS-NetworkProtection,SA-Mitigator
25 | ## shared Application-level permissions
26 | []
27 | access = read : [ * ], write : [ admin ]
28 | export = system
29 |
30 | [savedsearches]
31 | owner = admin
32 |
33 | [governance]
34 | access = read : [ * ], write : [ * ]
35 |
36 | ## Postprocess
37 | [postprocess]
38 | access = read : [ * ], write : [ * ]
39 |
40 |
41 | ## Exclude export of custom alert actions
42 | [alert_actions/email]
43 | export = none
44 |
--------------------------------------------------------------------------------
/images/SA-Mitigation-Endpoint-arch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/josehelps/Splunk-Mitigation-Framework/e973cdb9656a7d1abcef4b2b2e3c9b12b3710e39/images/SA-Mitigation-Endpoint-arch.png
--------------------------------------------------------------------------------
/images/SA-Mitigation_search_arch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/josehelps/Splunk-Mitigation-Framework/e973cdb9656a7d1abcef4b2b2e3c9b12b3710e39/images/SA-Mitigation_search_arch.png
--------------------------------------------------------------------------------
/prezo/Auto Mitigation - Endpoint Example.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/josehelps/Splunk-Mitigation-Framework/e973cdb9656a7d1abcef4b2b2e3c9b12b3710e39/prezo/Auto Mitigation - Endpoint Example.mp4
--------------------------------------------------------------------------------
/prezo/confPrezo.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/josehelps/Splunk-Mitigation-Framework/e973cdb9656a7d1abcef4b2b2e3c9b12b3710e39/prezo/confPrezo.pptx
--------------------------------------------------------------------------------
/setup.xml.txt:
--------------------------------------------------------------------------------
1 |
2 | remind user to setup index under role
3 | remind user to configure searches
4 | include SA-Mitigation as part of ES pieces
5 | remind user to make sure host can resolve when sending command
6 | recreate the dashboard views in ES
7 |
--------------------------------------------------------------------------------