mirror of
https://github.com/splunk/security_content
synced 2026-06-08 17:32:49 +00:00
Merge branch 'TR-2219_AzureAD_Password_Srapying' of github.com:splunk/security_content into TR-2219_AzureAD_Password_Srapying
This commit is contained in:
Binary file not shown.
@@ -192,15 +192,15 @@ def test_baseline_search(splunk_host, splunk_port, splunk_password, search, pass
|
||||
# search = search.replace('\\','\\\\')
|
||||
|
||||
if search.startswith('|'):
|
||||
search = search
|
||||
updated_search = search
|
||||
else:
|
||||
search = 'search ' + search
|
||||
updated_search = 'search ' + search
|
||||
|
||||
kwargs = {"exec_mode": "blocking",
|
||||
"dispatch.earliest_time": earliest_time,
|
||||
"dispatch.latest_time": latest_time}
|
||||
|
||||
splunk_search = search + ' ' + pass_condition
|
||||
splunk_search = updated_search + ' ' + pass_condition
|
||||
|
||||
try:
|
||||
job = service.jobs.create(splunk_search, **kwargs)
|
||||
@@ -233,15 +233,15 @@ def test_detection_search(splunk_host:str, splunk_port:int, splunk_password:str,
|
||||
attempts_remaining -= 1
|
||||
|
||||
if search.startswith('|'):
|
||||
search = search
|
||||
updated_search = search
|
||||
else:
|
||||
search = 'search ' + search
|
||||
updated_search = 'search ' + search
|
||||
|
||||
kwargs = {"exec_mode": "blocking",
|
||||
"dispatch.earliest_time": "-1d",
|
||||
"dispatch.latest_time": "now"}
|
||||
|
||||
splunk_search = search + ' ' + pass_condition
|
||||
splunk_search = updated_search + ' ' + pass_condition
|
||||
test_results = dict()
|
||||
|
||||
#These will always be present. By default, we will say that the
|
||||
@@ -317,6 +317,12 @@ def test_detection_search(splunk_host:str, splunk_port:int, splunk_password:str,
|
||||
|
||||
def delete_attack_data(splunk_host:str, splunk_password:str, splunk_port:int, wait_on_delete:Union[dict,None], search_string:str, detection_filename:str, indices:list[str]=[DEFAULT_DATA_INDEX], host:str=DEFAULT_EVENT_HOST)->bool:
|
||||
|
||||
if wait_on_delete:
|
||||
print(wait_on_delete['message'])
|
||||
print("FILENAME : [%s]"%(detection_filename))
|
||||
print("SEARCH :\n%s"%(search_string))
|
||||
_ = input("****************Press ENTER to Complete Test and DELETE data****************\n\n\n")
|
||||
|
||||
try:
|
||||
service = client.connect(
|
||||
host=splunk_host,
|
||||
@@ -329,21 +335,11 @@ def delete_attack_data(splunk_host:str, splunk_password:str, splunk_port:int, wa
|
||||
|
||||
raise(Exception("Unable to connect to Splunk instance: " + str(e)))
|
||||
|
||||
#splunk_search = 'search index=test* | delete'
|
||||
if wait_on_delete:
|
||||
print(wait_on_delete['message'])
|
||||
print("FILENAME : [%s]"%(detection_filename))
|
||||
print("SEARCH :\n%s"%(search_string))
|
||||
_ = input("****************Press ENTER to Complete Test and DELETE data****************\n\n\n")
|
||||
|
||||
data_exists = True
|
||||
|
||||
|
||||
#print(f"Deleting data for {detection_filename}: {indices}")
|
||||
for index in indices:
|
||||
while (get_number_of_indexed_events(splunk_host, splunk_port, splunk_password, index=index, event_host=host) != 0) :
|
||||
splunk_search = f'search index="{index}" host="{host}" | delete'
|
||||
|
||||
kwargs = {
|
||||
"exec_mode": "blocking",
|
||||
"dispatch.earliest_time": "-1d",
|
||||
@@ -353,34 +349,9 @@ def delete_attack_data(splunk_host:str, splunk_password:str, splunk_port:int, wa
|
||||
job = service.jobs.create(splunk_search, **kwargs)
|
||||
reader = results.ResultsReader(job)
|
||||
|
||||
|
||||
'''
|
||||
error_in_results = False
|
||||
for result in reader:
|
||||
if hasattr(result,"message") and hasattr(result,"type") and ("You have insufficient privileges to delete events" in result.message or result.type == "FATAL"):
|
||||
print("Delete is not enabled for admin: [%s] - enabling delete and trying to delete again..."%(result.message), file=sys.stderr)
|
||||
if already_enabled_delete is True:
|
||||
print("We already enabled delete, but the setting did not take effect.")
|
||||
raise(Exception("Enabling delete command failed to take effect"))
|
||||
if enable_delete_for_admin(splunk_host, splunk_port,splunk_password) != True:
|
||||
raise(Exception("Failure enabling delete for admin. We cannot continue"))
|
||||
# We enabled delete, so now we will try to delete again
|
||||
already_enabled_delete = True
|
||||
break
|
||||
else:
|
||||
#This is not one of the error messages, do nothing
|
||||
pass
|
||||
'''
|
||||
#No need to issue Delete command again, we will now break out of the loop
|
||||
#if error_in_results is False:
|
||||
# data_exists = False
|
||||
|
||||
#Otherwise, we will loop again
|
||||
|
||||
except Exception as e:
|
||||
print(f"Trouble deleting data from a run.... we will try again: {str(e)}")
|
||||
time.sleep(5)
|
||||
#raise(Exception("Unable to delete data from a run: " + str(e)))
|
||||
raise(Exception(f"Trouble deleting data using the search {splunk_search}: {str(e)}"))
|
||||
|
||||
|
||||
return True
|
||||
|
||||
@@ -122,7 +122,7 @@ def test_detection(splunk_ip:str, splunk_port:int, container_name:str, splunk_pa
|
||||
test_index = service.indexes[data_upload_index]
|
||||
|
||||
with open(target_file, 'rb') as target:
|
||||
test_index.submit(target.read(), sourcetype=attack_data['sourcetype'], source=attack_data['source'])
|
||||
test_index.submit(target.read(), sourcetype=attack_data['sourcetype'], source=attack_data['source'], host=splunk_sdk.DEFAULT_EVENT_HOST)
|
||||
|
||||
except http.client.HTTPException as e:
|
||||
raise(Exception(f"Failed to submit detection file {target_file} to Splunk Server: {str(e)}"))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: Office Product Writing cab or inf
|
||||
id: f48cd1d4-125a-11ec-a447-acde48001122
|
||||
version: 1
|
||||
date: '2021-09-10'
|
||||
version: 2
|
||||
date: '2022-07-07'
|
||||
author: Michael Haag, Splunk
|
||||
type: TTP
|
||||
datamodel:
|
||||
@@ -10,16 +10,21 @@ description: The following analytic identifies behavior related to CVE-2021-4044
|
||||
Whereas the malicious document will load ActiveX and download the remote payload
|
||||
(.inf, .cab). During triage, review parallel processes and further activity on endpoint
|
||||
to identify additional patterns. Retrieve the file modifications and analyze further.
|
||||
search: '| tstats `security_content_summariesonly` count FROM datamodel=Endpoint.Processes
|
||||
where Processes.process_name IN ("winword.exe","excel.exe","powerpnt.exe","mspub.exe","visio.exe","wordpad.exe","wordview.exe")
|
||||
by _time span=1h Processes.process_id Processes.process_name Processes.process Processes.dest
|
||||
| `drop_dm_object_name(Processes)` | join process_guid, _time [| tstats `security_content_summariesonly`
|
||||
count min(_time) as firstTime max(_time) as lastTime FROM datamodel=Endpoint.Filesystem
|
||||
where Filesystem.file_name IN ("*.inf","*.cab") by _time span=1h Filesystem.dest
|
||||
Filesystem.file_create_time Filesystem.file_name Filesystem.file_path | `drop_dm_object_name(Filesystem)`
|
||||
| fields _time dest file_create_time file_name file_path process_name process_path
|
||||
process] | dedup file_create_time | table dest, process_name, process, file_create_time,
|
||||
file_name, file_path | `office_product_writing_cab_or_inf_filter`'
|
||||
search: '| tstats `security_content_summariesonly` count FROM datamodel=Endpoint.Processes
|
||||
where Processes.process_name IN ("winword.exe","excel.exe","powerpnt.exe","mspub.exe","visio.exe","wordpad.exe","wordview.exe")
|
||||
by _time span=1h Processes.process_id Processes.process_name Processes.process Processes.dest Processes.process_guid
|
||||
| `drop_dm_object_name(Processes)`
|
||||
|rename process_guid as proc_guid
|
||||
| join proc_guid, _time [
|
||||
| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime FROM datamodel=Endpoint.Filesystem
|
||||
where Filesystem.file_name IN ("*.inf","*.cab")
|
||||
by _time span=1h Filesystem.dest Filesystem.file_create_time Filesystem.file_name Filesystem.file_path Filesystem.process_guid
|
||||
| `drop_dm_object_name(Filesystem)`
|
||||
|rename process_guid as proc_guid
|
||||
| fields _time dest file_create_time file_name file_path process_name process_path process proc_guid]
|
||||
| dedup file_create_time
|
||||
| table dest, process_name, process, file_create_time, file_name, file_path, proc_guid
|
||||
| `office_product_writing_cab_or_inf_filter`'
|
||||
how_to_implement: To successfully implement this search you need to be ingesting information
|
||||
on process that include the name of the process responsible for the changes from
|
||||
your endpoints into the `Endpoint` datamodel in the `Processes` node and `Filesystem`
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: Suspicious WAV file in Appdata Folder
|
||||
id: 5be109e6-1ac5-11ec-b421-acde48001122
|
||||
version: 1
|
||||
date: '2021-09-21'
|
||||
version: 2
|
||||
date: '2022-07-07'
|
||||
author: Teoderick Contreras, Splunk
|
||||
type: TTP
|
||||
datamodel:
|
||||
@@ -12,15 +12,19 @@ description: This analytic is to detect a suspicious creation of .wav file in ap
|
||||
to its C2 server as part of its exfiltration to the compromised machine. creation
|
||||
of wav files in this folder path is not a ussual disk place used by user to save
|
||||
audio format file.
|
||||
search: '| tstats `security_content_summariesonly` count FROM datamodel=Endpoint.Processes
|
||||
where Processes.process_name=*.exe Processes.process_path="*\\appdata\\Roaming\\*"
|
||||
by _time span=1h Processes.process_id Processes.process_name Processes.process Processes.dest
|
||||
| `drop_dm_object_name(Processes)` | join process_guid, _time [| tstats `security_content_summariesonly`
|
||||
count min(_time) as firstTime max(_time) as lastTime FROM datamodel=Endpoint.Filesystem
|
||||
where Filesystem.file_name IN ("*.wav") Filesystem.file_path = "*\\appdata\\Roaming\\*"
|
||||
by _time span=1h Filesystem.dest Filesystem.file_create_time Filesystem.file_name
|
||||
Filesystem.file_path | `drop_dm_object_name(Filesystem)` | fields file_name file_path
|
||||
process_name process_path process dest file_create_time _time ] | `suspicious_wav_file_in_appdata_folder_filter`'
|
||||
search: '| tstats `security_content_summariesonly` count FROM datamodel=Endpoint.Processes
|
||||
where Processes.process_name=*.exe Processes.process_path="*\\appdata\\Roaming\\*"
|
||||
by _time span=1h Processes.process_id Processes.process_name Processes.process Processes.dest Processes.process_guid
|
||||
| `drop_dm_object_name(Processes)`
|
||||
|rename process_guid as proc_guid
|
||||
| join proc_guid, _time [
|
||||
| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime FROM datamodel=Endpoint.Filesystem
|
||||
where Filesystem.file_name IN ("*.wav") Filesystem.file_path = "*\\appdata\\Roaming\\*"
|
||||
by _time span=1h Filesystem.dest Filesystem.file_create_time Filesystem.file_name Filesystem.file_path Filesystem.process_guid
|
||||
| `drop_dm_object_name(Filesystem)`
|
||||
|rename process_guid as proc_guid
|
||||
| fields file_name file_path process_name process_path process dest file_create_time _time proc_guid]
|
||||
| `suspicious_wav_file_in_appdata_folder_filter`'
|
||||
how_to_implement: To successfully implement this search, you need to be ingesting
|
||||
logs with the process name, parent process, file_name, file_path and command-line
|
||||
executions from your endpoints. If you are using Sysmon, you must have at least
|
||||
|
||||
Reference in New Issue
Block a user