Files
splunk-security_content/playbooks/Splunk_Attack_Analyzer_Dynamic_Analysis.py
2023-08-16 17:30:08 +02:00

716 lines
36 KiB
Python

"""
Accepts a URL or vault_id and does detonation analysis on the objects. Generates a global report and a per observable sub-report and normalized score. The score can be customized based on a variety of factors.\n\n
"""
import phantom.rules as phantom
import json
from datetime import datetime, timedelta
@phantom.playbook_block()
def on_start(container):
phantom.debug('on_start() called')
# call 'saa_input_filter' block
saa_input_filter(container=container)
return
@phantom.playbook_block()
def saa_input_filter(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
phantom.debug("saa_input_filter() called")
################################################################################
# Determine branches based on provided inputs.
################################################################################
# collect filtered artifact ids and results for 'if' condition 1
matched_artifacts_1, matched_results_1 = phantom.condition(
container=container,
conditions=[
["playbook_input:url", "!=", ""]
],
name="saa_input_filter:condition_1",
delimiter=",")
# call connected blocks if filtered artifacts or results
if matched_artifacts_1 or matched_results_1:
url_detonation(action=action, success=success, container=container, results=results, handle=handle, filtered_artifacts=matched_artifacts_1, filtered_results=matched_results_1)
# collect filtered artifact ids and results for 'if' condition 2
matched_artifacts_2, matched_results_2 = phantom.condition(
container=container,
conditions=[
["playbook_input:vault_id", "!=", ""]
],
name="saa_input_filter:condition_2",
delimiter=",")
# call connected blocks if filtered artifacts or results
if matched_artifacts_2 or matched_results_2:
file_detonation(action=action, success=success, container=container, results=results, handle=handle, filtered_artifacts=matched_artifacts_2, filtered_results=matched_results_2)
return
@phantom.playbook_block()
def url_detonation(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
phantom.debug("url_detonation() called")
# phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
################################################################################
# Queries SAA for information about the provided URL(s)
################################################################################
filtered_input_0_url = phantom.collect2(container=container, datapath=["filtered-data:saa_input_filter:condition_1:playbook_input:url"])
parameters = []
# build parameters list for 'url_detonation' call
for filtered_input_0_url_item in filtered_input_0_url:
if filtered_input_0_url_item[0] is not None:
parameters.append({
"url": filtered_input_0_url_item[0],
})
################################################################################
## Custom Code Start
################################################################################
# Write your custom code here...
################################################################################
## Custom Code End
################################################################################
phantom.act("detonate url", parameters=parameters, name="url_detonation", assets=["splunk attack analyzer app"], callback=url_status_filter)
return
@phantom.playbook_block()
def detonation_status_filter(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
phantom.debug("detonation_status_filter() called")
################################################################################
# Filters successful file detonation results.
################################################################################
# collect filtered artifact ids and results for 'if' condition 1
matched_artifacts_1, matched_results_1 = phantom.condition(
container=container,
conditions=[
["file_detonation:action_result.status", "==", "success"]
],
name="detonation_status_filter:condition_1",
delimiter=",")
# call connected blocks if filtered artifacts or results
if matched_artifacts_1 or matched_results_1:
get_file_forensics_output(action=action, success=success, container=container, results=results, handle=handle, filtered_artifacts=matched_artifacts_1, filtered_results=matched_results_1)
return
@phantom.playbook_block()
def get_url_forensics_output(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
phantom.debug("get_url_forensics_output() called")
# phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
################################################################################
# Queries SAA Forensics data relative to the JobID of URL(s) or File(s) needs
# to be detonated.
################################################################################
filtered_result_0_data_url_status_filter = phantom.collect2(container=container, datapath=["filtered-data:url_status_filter:condition_1:url_detonation:action_result.data.*.JobID"])
parameters = []
# build parameters list for 'get_url_forensics_output' call
for filtered_result_0_item_url_status_filter in filtered_result_0_data_url_status_filter:
if filtered_result_0_item_url_status_filter[0] is not None:
parameters.append({
"job_id": filtered_result_0_item_url_status_filter[0],
"timeout": 2,
})
################################################################################
## Custom Code Start
################################################################################
# Write your custom code here...
#parameters = []
#for job_ids in url_jobid_detonation_output__jobid:
# for job in job_ids:
# if job is not None:
# parameters.append({
# "job_id": job,
# "timeout": 5,
# })
#phantom.debug(parameters)
################################################################################
## Custom Code End
################################################################################
phantom.act("get job forensics", parameters=parameters, name="get_url_forensics_output", assets=["splunk attack analyzer app"], callback=get_jobid_forensic_filter)
return
@phantom.playbook_block()
def get_jobid_forensic_filter(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
phantom.debug("get_jobid_forensic_filter() called")
################################################################################
# Filters successful url detonation job forensic results.
################################################################################
# collect filtered artifact ids and results for 'if' condition 1
matched_artifacts_1, matched_results_1 = phantom.condition(
container=container,
conditions=[
["get_url_forensics_output:action_result.status", "==", "success"]
],
name="get_jobid_forensic_filter:condition_1",
delimiter=",")
# call connected blocks if filtered artifacts or results
if matched_artifacts_1 or matched_results_1:
normalized_url_forensic_output(action=action, success=success, container=container, results=results, handle=handle, filtered_artifacts=matched_artifacts_1, filtered_results=matched_results_1)
return
@phantom.playbook_block()
def normalized_url_forensic_output(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
phantom.debug("normalized_url_forensic_output() called")
################################################################################
# This block uses custom code for normalizing score. Adjust the logic as desired
# in the documented sections.
################################################################################
filtered_result_0_data_url_status_filter = phantom.collect2(container=container, datapath=["filtered-data:url_status_filter:condition_1:url_detonation:action_result.parameter.url","filtered-data:url_status_filter:condition_1:url_detonation:action_result.data.*.JobID"])
filtered_result_1_data_get_jobid_forensic_filter = phantom.collect2(container=container, datapath=["filtered-data:get_jobid_forensic_filter:condition_1:get_url_forensics_output:action_result.parameter.job_id","filtered-data:get_jobid_forensic_filter:condition_1:get_url_forensics_output:action_result.data.*.DisplayScore","filtered-data:get_jobid_forensic_filter:condition_1:get_url_forensics_output:action_result.data.*.Detections"])
filtered_result_0_parameter_url = [item[0] for item in filtered_result_0_data_url_status_filter]
filtered_result_0_data___jobid = [item[1] for item in filtered_result_0_data_url_status_filter]
filtered_result_1_parameter_job_id = [item[0] for item in filtered_result_1_data_get_jobid_forensic_filter]
filtered_result_1_data___displayscore = [item[1] for item in filtered_result_1_data_get_jobid_forensic_filter]
filtered_result_1_data___detections = [item[2] for item in filtered_result_1_data_get_jobid_forensic_filter]
normalized_url_forensic_output__url_score_object = None
normalized_url_forensic_output__scores = None
normalized_url_forensic_output__categories = None
normalized_url_forensic_output__score_id = None
normalized_url_forensic_output__url = None
normalized_url_forensic_output__job_id = None
################################################################################
## Custom Code Start
################################################################################
# Write your custom code here...
score_id =0
score_table = {
"0":"Unknown",
"1":"Very_Safe",
"2":"Safe",
"3":"Probably_Safe",
"4":"Leans_Safe",
"5":"May_not_be_Safe",
"6":"Exercise_Caution",
"7":"Suspicious_or_Risky",
"8":"Possibly_Malicious",
"9":"Probably_Malicious",
"10":"Malicious"
}
normalized_url_forensic_output__url_score_object = []
normalized_url_forensic_output__scores = []
normalized_url_forensic_output__categories = []
normalized_url_forensic_output__score_id = []
normalized_url_forensic_output__url = []
normalized_url_forensic_output__job_id = []
## pair forensic job results with url detonated
job_url_dict = {}
for orig_url, orig_job in zip(filtered_result_0_parameter_url, filtered_result_0_data___jobid):
for filtered_job in filtered_result_0_data___jobid:
if orig_job == filtered_job:
job_url_dict[filtered_job] = orig_url
for job, score_num, detections in zip(filtered_result_1_parameter_job_id, filtered_result_1_data___displayscore, filtered_result_1_data___detections):
## translate scores
score_id = int(score_num/10) if score_num > 0 else 0
score = score_table[str(score_id)]
url = job_url_dict[job]
categories = [item.get('Description') for item in detections]
# Attach final object
normalized_url_forensic_output__url_score_object.append({'value': url, 'base_score': score_num, 'score': score, 'score_id': score_id, 'categories': categories})
normalized_url_forensic_output__scores.append(score)
normalized_url_forensic_output__categories.append(", ".join(categories))
normalized_url_forensic_output__score_id.append(score_id)
normalized_url_forensic_output__url.append(url)
normalized_url_forensic_output__job_id.append(job)
################################################################################
## Custom Code End
################################################################################
phantom.save_run_data(key="normalized_url_forensic_output:url_score_object", value=json.dumps(normalized_url_forensic_output__url_score_object))
phantom.save_run_data(key="normalized_url_forensic_output:scores", value=json.dumps(normalized_url_forensic_output__scores))
phantom.save_run_data(key="normalized_url_forensic_output:categories", value=json.dumps(normalized_url_forensic_output__categories))
phantom.save_run_data(key="normalized_url_forensic_output:score_id", value=json.dumps(normalized_url_forensic_output__score_id))
phantom.save_run_data(key="normalized_url_forensic_output:url", value=json.dumps(normalized_url_forensic_output__url))
phantom.save_run_data(key="normalized_url_forensic_output:job_id", value=json.dumps(normalized_url_forensic_output__job_id))
format_url_report(container=container)
return
@phantom.playbook_block()
def format_url_report(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
phantom.debug("format_url_report() called")
################################################################################
# Format a summary table with the information gathered from the playbook.
################################################################################
template = """SOAR analyzed URL(s) using Splunk Attack Analyzer. The table below shows a summary of the information gathered.\n\n| URL | Normalized Score | Score Id | Categories | Report Link | Source |\n| --- | --- | --- | --- | --- | --- |\n%%\n| `{0}` | {1} | {2} | {3} | https://app.twinwave.io/job/{4} | Splunk Attack Analyzer (SAA) |\n%%\n\n\n"""
# parameter list for template variable replacement
parameters = [
"normalized_url_forensic_output:custom_function:url",
"normalized_url_forensic_output:custom_function:scores",
"normalized_url_forensic_output:custom_function:score_id",
"normalized_url_forensic_output:custom_function:categories",
"normalized_url_forensic_output:custom_function:job_id"
]
################################################################################
## Custom Code Start
################################################################################
# Write your custom code here...
#phantom.debug(phantom.format(container=container, template=template, parameters=parameters, name="format_report_url"))
################################################################################
## Custom Code End
################################################################################
phantom.format(container=container, template=template, parameters=parameters, name="format_url_report")
build_url_output(container=container)
return
@phantom.playbook_block()
def build_url_output(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
phantom.debug("build_url_output() called")
################################################################################
# This block uses custom code to generate an observable dictionary to output into
# the observables data path.
################################################################################
normalized_url_forensic_output__url = json.loads(_ if (_ := phantom.get_run_data(key="normalized_url_forensic_output:url")) != "" else "null") # pylint: disable=used-before-assignment
normalized_url_forensic_output__job_id = json.loads(_ if (_ := phantom.get_run_data(key="normalized_url_forensic_output:job_id")) != "" else "null") # pylint: disable=used-before-assignment
normalized_url_forensic_output__url_score_object = json.loads(_ if (_ := phantom.get_run_data(key="normalized_url_forensic_output:url_score_object")) != "" else "null") # pylint: disable=used-before-assignment
build_url_output__observable_array = None
################################################################################
## Custom Code Start
################################################################################
# Write your custom code here...
from urllib.parse import urlparse
build_url_output__observable_array = []
#phantom.debug(playbook_input_url_values)
# Build URL
for url, external_id, url_object in zip(normalized_url_forensic_output__url, normalized_url_forensic_output__job_id, normalized_url_forensic_output__url_score_object):
parsed_url = urlparse(url)
#phantom.debug("url: {} jobs_id:{}".format(url, external_id))
#phantom.debug("parsed_url: {}, url_object: {}".format(parsed_url, url_object))
observable_object = {
"value": url,
"type": "url",
"reputation": {
"base_score": url_object['base_score'],
"score": url_object['score'],
"score_id": url_object['score_id'],
"confidence": url_object['base_score'] #Attack Analyzer's score has confidence baked in.
},
"attributes": {
"hostname": parsed_url.hostname,
"scheme": parsed_url.scheme
},
"classifications": url_object['categories'],
"source": "Splunk Attack Analyzer",
"source_link": f"https://app.twinwave.io/job/{external_id}"
}
if parsed_url.path:
observable_object['attributes']['path'] = parsed_url.path
if parsed_url.query:
observable_object['attributes']['query'] = parsed_url.query
if parsed_url.port:
observable_object['attributes']['port'] = parsed_url.port
build_url_output__observable_array.append(observable_object)
#phantom.debug("build_url_output__observable_array: {}".format(build_url_output__observable_array))
################################################################################
## Custom Code End
################################################################################
phantom.save_run_data(key="build_url_output:observable_array", value=json.dumps(build_url_output__observable_array))
return
@phantom.playbook_block()
def file_detonation(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
phantom.debug("file_detonation() called")
# phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
################################################################################
# Queries SAA for information about the provided vault_id(s)
################################################################################
filtered_input_0_vault_id = phantom.collect2(container=container, datapath=["filtered-data:saa_input_filter:condition_2:playbook_input:vault_id"])
parameters = []
# build parameters list for 'file_detonation' call
for filtered_input_0_vault_id_item in filtered_input_0_vault_id:
if filtered_input_0_vault_id_item[0] is not None:
parameters.append({
"file": filtered_input_0_vault_id_item[0],
})
################################################################################
## Custom Code Start
################################################################################
# Write your custom code here...
################################################################################
## Custom Code End
################################################################################
phantom.act("detonate file", parameters=parameters, name="file_detonation", assets=["splunk attack analyzer app"], callback=detonation_status_filter)
return
@phantom.playbook_block()
def get_file_forensics_output(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
phantom.debug("get_file_forensics_output() called")
# phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
################################################################################
# Queries SAA Forensics data relative to the JobID of URL(s) or File(s) needs
# to be detonated.
################################################################################
filtered_result_0_data_detonation_status_filter = phantom.collect2(container=container, datapath=["filtered-data:detonation_status_filter:condition_1:file_detonation:action_result.data.*.JobID"])
parameters = []
# build parameters list for 'get_file_forensics_output' call
for filtered_result_0_item_detonation_status_filter in filtered_result_0_data_detonation_status_filter:
if filtered_result_0_item_detonation_status_filter[0] is not None:
parameters.append({
"job_id": filtered_result_0_item_detonation_status_filter[0],
"timeout": 2,
})
################################################################################
## Custom Code Start
################################################################################
# Write your custom code here...
#parameters = []
#for job_ids in file_jobid_detonation_output__jobid:
# for job in job_ids:
# if job is not None:
# parameters.append({
# "job_id": job,
# "timeout": 5,
# })
#phantom.debug(parameters)
################################################################################
## Custom Code End
################################################################################
phantom.act("get job forensics", parameters=parameters, name="get_file_forensics_output", assets=["splunk attack analyzer app"], callback=file_forensics_filter)
return
@phantom.playbook_block()
def normalized_file_forensic_output(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
phantom.debug("normalized_file_forensic_output() called")
################################################################################
# This block uses custom code for normalizing score. Adjust the logic as desired
# in the documented sections.
################################################################################
filtered_result_0_data_detonation_status_filter = phantom.collect2(container=container, datapath=["filtered-data:detonation_status_filter:condition_1:file_detonation:action_result.parameter.file","filtered-data:detonation_status_filter:condition_1:file_detonation:action_result.data.*.JobID"])
filtered_result_1_data_file_forensics_filter = phantom.collect2(container=container, datapath=["filtered-data:file_forensics_filter:condition_1:get_file_forensics_output:action_result.parameter.job_id","filtered-data:file_forensics_filter:condition_1:get_file_forensics_output:action_result.data.*.DisplayScore","filtered-data:file_forensics_filter:condition_1:get_file_forensics_output:action_result.data.*.Detections"])
filtered_result_0_parameter_file = [item[0] for item in filtered_result_0_data_detonation_status_filter]
filtered_result_0_data___jobid = [item[1] for item in filtered_result_0_data_detonation_status_filter]
filtered_result_1_parameter_job_id = [item[0] for item in filtered_result_1_data_file_forensics_filter]
filtered_result_1_data___displayscore = [item[1] for item in filtered_result_1_data_file_forensics_filter]
filtered_result_1_data___detections = [item[2] for item in filtered_result_1_data_file_forensics_filter]
normalized_file_forensic_output__file_score_object = None
normalized_file_forensic_output__scores = None
normalized_file_forensic_output__categories = None
normalized_file_forensic_output__score_id = None
normalized_file_forensic_output__file = None
normalized_file_forensic_output__job_id = None
################################################################################
## Custom Code Start
################################################################################
# Write your custom code here...
score_id =0
score_table = {
"0":"Unknown",
"1":"Very_Safe",
"2":"Safe",
"3":"Probably_Safe",
"4":"Leans_Safe",
"5":"May_not_be_Safe",
"6":"Exercise_Caution",
"7":"Suspicious_or_Risky",
"8":"Possibly_Malicious",
"9":"Probably_Malicious",
"10":"Malicious"
}
normalized_file_forensic_output__file_score_object = []
normalized_file_forensic_output__scores = []
normalized_file_forensic_output__categories = []
normalized_file_forensic_output__score_id = []
normalized_file_forensic_output__file = []
normalized_file_forensic_output__job_id = []
## pair forensic job results with url detonated
job_file_dict = {}
for orig_file, orig_job in zip(filtered_result_0_parameter_file, filtered_result_0_data___jobid):
for filtered_job in filtered_result_0_data___jobid:
if orig_job == filtered_job:
job_file_dict[filtered_job] = orig_file
for job, score_num, detections in zip(filtered_result_1_parameter_job_id, filtered_result_1_data___displayscore, filtered_result_1_data___detections):
## translate scores
score_id = int(score_num/10) if score_num > 0 else 0
score = score_table[str(score_id)]
file = job_file_dict[job]
categories = [item.get('Description') for item in detections]
normalized_file_forensic_output__file_score_object.append({'value': file, 'base_score': score_num, 'score': score, 'score_id': score_id, 'categories': categories})
normalized_file_forensic_output__scores.append(score)
normalized_file_forensic_output__categories.append(", ".join(categories))
normalized_file_forensic_output__score_id.append(score_id)
normalized_file_forensic_output__file.append(file)
normalized_file_forensic_output__job_id.append(job)
################################################################################
## Custom Code End
################################################################################
phantom.save_run_data(key="normalized_file_forensic_output:file_score_object", value=json.dumps(normalized_file_forensic_output__file_score_object))
phantom.save_run_data(key="normalized_file_forensic_output:scores", value=json.dumps(normalized_file_forensic_output__scores))
phantom.save_run_data(key="normalized_file_forensic_output:categories", value=json.dumps(normalized_file_forensic_output__categories))
phantom.save_run_data(key="normalized_file_forensic_output:score_id", value=json.dumps(normalized_file_forensic_output__score_id))
phantom.save_run_data(key="normalized_file_forensic_output:file", value=json.dumps(normalized_file_forensic_output__file))
phantom.save_run_data(key="normalized_file_forensic_output:job_id", value=json.dumps(normalized_file_forensic_output__job_id))
format_file_report(container=container)
return
@phantom.playbook_block()
def format_file_report(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
phantom.debug("format_file_report() called")
################################################################################
# Format a summary table with the information gathered from the playbook.
################################################################################
template = """SOAR analyzed File(s) using Splunk Attack Analyzer. The table below shows a summary of the information gathered.\n\n| Vauld Id | Normalized Score | Score Id | Categories | Report Link | Source |\n| --- | --- | --- | --- | --- | --- |\n%%\n| `{0}` | {1} | {2} | {3} | https://app.twinwave.io/job/{4} | Splunk Attack Analyzer (SAA) |\n%%\n\n\n"""
# parameter list for template variable replacement
parameters = [
"normalized_file_forensic_output:custom_function:file",
"normalized_file_forensic_output:custom_function:score",
"normalized_file_forensic_output:custom_function:score_id",
"normalized_file_forensic_output:custom_function:categories",
"normalized_file_forensic_output:custom_function:job_id"
]
################################################################################
## Custom Code Start
################################################################################
# Write your custom code here...
#phantom.debug(phantom.format(container=container, template=template, parameters=parameters, name="format_report_file"))
################################################################################
## Custom Code End
################################################################################
phantom.format(container=container, template=template, parameters=parameters, name="format_file_report")
build_file_output(container=container)
return
@phantom.playbook_block()
def build_file_output(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
phantom.debug("build_file_output() called")
################################################################################
# This block uses custom code to generate an observable dictionary to output into
# the observables data path.
################################################################################
normalized_file_forensic_output__file = json.loads(_ if (_ := phantom.get_run_data(key="normalized_file_forensic_output:file")) != "" else "null") # pylint: disable=used-before-assignment
normalized_file_forensic_output__job_id = json.loads(_ if (_ := phantom.get_run_data(key="normalized_file_forensic_output:job_id")) != "" else "null") # pylint: disable=used-before-assignment
normalized_file_forensic_output__file_score_object = json.loads(_ if (_ := phantom.get_run_data(key="normalized_file_forensic_output:file_score_object")) != "" else "null") # pylint: disable=used-before-assignment
build_file_output__observable_array = None
################################################################################
## Custom Code Start
################################################################################
# Write your custom code here...
build_file_output__observable_array = []
for _vault_id, external_id, file_object in zip(normalized_file_forensic_output__file, normalized_file_forensic_output__job_id, normalized_file_forensic_output__file_score_object):
#phantom.debug("vault: {} id: {}".format(_vault_id, external_id))
observable_object = {
"value": _vault_id,
"type": "hash",
"reputation": {
"base_score": file_object['base_score'],
"score": file_object['score'],
"score_id": file_object['score_id'],
"confidence": file_object['base_score'] #Attack Analyzer's score has confidence baked in.
},
"classifications": file_object['categories'],
"source": "Splunk Attack Analyzer",
"source_link":f"https://app.twinwave.io/job/{external_id}"
}
build_file_output__observable_array.append(observable_object)
#phantom.debug("build_file_output__observable_array: {}".format(build_file_output__observable_array))
################################################################################
## Custom Code End
################################################################################
phantom.save_run_data(key="build_file_output:observable_array", value=json.dumps(build_file_output__observable_array))
return
@phantom.playbook_block()
def url_status_filter(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
phantom.debug("url_status_filter() called")
################################################################################
# Filters url detonation results.
################################################################################
# collect filtered artifact ids and results for 'if' condition 1
matched_artifacts_1, matched_results_1 = phantom.condition(
container=container,
conditions=[
["url_detonation:action_result.status", "==", "success"]
],
name="url_status_filter:condition_1",
delimiter=",")
# call connected blocks if filtered artifacts or results
if matched_artifacts_1 or matched_results_1:
get_url_forensics_output(action=action, success=success, container=container, results=results, handle=handle, filtered_artifacts=matched_artifacts_1, filtered_results=matched_results_1)
return
@phantom.playbook_block()
def file_forensics_filter(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
phantom.debug("file_forensics_filter() called")
################################################################################
# Filters successful file detonation job forensic results.
################################################################################
# collect filtered artifact ids and results for 'if' condition 1
matched_artifacts_1, matched_results_1 = phantom.condition(
container=container,
conditions=[
["get_file_forensics_output:action_result.status", "==", "success"]
],
name="file_forensics_filter:condition_1",
delimiter=",")
# call connected blocks if filtered artifacts or results
if matched_artifacts_1 or matched_results_1:
normalized_file_forensic_output(action=action, success=success, container=container, results=results, handle=handle, filtered_artifacts=matched_artifacts_1, filtered_results=matched_results_1)
return
@phantom.playbook_block()
def on_finish(container, summary):
phantom.debug("on_finish() called")
format_url_report = phantom.get_format_data(name="format_url_report")
format_file_report = phantom.get_format_data(name="format_file_report")
build_url_output__observable_array = json.loads(_ if (_ := phantom.get_run_data(key="build_url_output:observable_array")) != "" else "null") # pylint: disable=used-before-assignment
build_file_output__observable_array = json.loads(_ if (_ := phantom.get_run_data(key="build_file_output:observable_array")) != "" else "null") # pylint: disable=used-before-assignment
observable_combined_value = phantom.concatenate(build_url_output__observable_array, build_file_output__observable_array)
report_combined_value = phantom.concatenate(format_url_report, format_file_report)
output = {
"observable": observable_combined_value,
"report": report_combined_value,
}
################################################################################
## Custom Code Start
################################################################################
# Write your custom code here...
#phantom.debug(output)
################################################################################
## Custom Code End
################################################################################
phantom.save_playbook_output_data(output=output)
return