{ "blockly": false, "blockly_xml": "", "category": "Dynamic Analysis", "coa": { "data": { "description": "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", "edges": [ { "id": "port_0_to_port_2", "sourceNode": "0", "sourcePort": "0_out", "targetNode": "2", "targetPort": "2_in" }, { "conditions": [ { "index": 0 } ], "id": "port_2_to_port_3", "sourceNode": "2", "sourcePort": "2_out", "targetNode": "3", "targetPort": "3_in" }, { "id": "port_8_to_port_10", "sourceNode": "8", "sourcePort": "8_out", "targetNode": "10", "targetPort": "10_in" }, { "id": "port_10_to_port_11", "sourceNode": "10", "sourcePort": "10_out", "targetNode": "11", "targetPort": "11_in" }, { "id": "port_11_to_port_1", "sourceNode": "11", "sourcePort": "11_out", "targetNode": "1", "targetPort": "1_in" }, { "conditions": [ { "index": 1 } ], "id": "port_2_to_port_12", "sourceNode": "2", "sourcePort": "2_out", "targetNode": "12", "targetPort": "12_in" }, { "id": "port_17_to_port_18", "sourceNode": "17", "sourcePort": "17_out", "targetNode": "18", "targetPort": "18_in" }, { "id": "port_18_to_port_19", "sourceNode": "18", "sourcePort": "18_out", "targetNode": "19", "targetPort": "19_in" }, { "id": "port_19_to_port_1", "sourceNode": "19", "sourcePort": "19_out", "targetNode": "1", "targetPort": "1_in" }, { "id": "port_12_to_port_4", "sourceNode": "12", "sourcePort": "12_out", "targetNode": "4", "targetPort": "4_in" }, { "id": "port_6_to_port_7", "sourceNode": "6", "sourcePort": "6_out", "targetNode": "7", "targetPort": "7_in" }, { "id": "port_3_to_port_22", "sourceNode": "3", "sourcePort": "3_out", "targetNode": "22", "targetPort": "22_in" }, { "conditions": [ { "index": 0 } ], "id": "port_22_to_port_6", "sourceNode": "22", "sourcePort": "22_out", "targetNode": "6", "targetPort": "6_in" }, { "conditions": [ { "index": 0 } ], "id": "port_4_to_port_15", "sourceNode": "4", "sourcePort": "4_out", "targetNode": "15", "targetPort": "15_in" }, { "id": "port_15_to_port_23", "sourceNode": "15", "sourcePort": "15_out", "targetNode": "23", "targetPort": "23_in" }, { "conditions": [ { "index": 0 } ], "id": "port_7_to_port_24", "sourceNode": "7", "sourcePort": "7_out", "targetNode": "24", "targetPort": "24_in" }, { "id": "port_24_to_port_8", "sourceNode": "24", "sourcePort": "24_out", "targetNode": "8", "targetPort": "8_in" }, { "conditions": [ { "index": 0 } ], "id": "port_23_to_port_25", "sourceNode": "23", "sourcePort": "23_out", "targetNode": "25", "targetPort": "25_in" }, { "id": "port_25_to_port_17", "sourceNode": "25", "sourcePort": "25_out", "targetNode": "17", "targetPort": "17_in" }, { "id": "port_24_to_port_26", "sourceNode": "24", "sourcePort": "24_out", "targetNode": "26", "targetPort": "26_in" }, { "id": "port_25_to_port_27", "sourceNode": "25", "sourcePort": "25_out", "targetNode": "27", "targetPort": "27_in" }, { "id": "port_27_to_port_18", "sourceNode": "27", "sourcePort": "27_out", "targetNode": "18", "targetPort": "18_in" }, { "id": "port_26_to_port_10", "sourceNode": "26", "sourcePort": "26_out", "targetNode": "10", "targetPort": "10_in" } ], "globalCustomCode": null, "hash": "74a51ccf79fc9363135cdd3b63ffe935edbeec5a", "nodes": { "0": { "data": { "advanced": { "join": [] }, "functionName": "on_start", "id": "0", "type": "start" }, "errors": {}, "id": "0", "type": "start", "warnings": {}, "x": 190, "y": -8.952838470577262e-13 }, "1": { "data": { "advanced": { "join": [] }, "functionName": "on_finish", "id": "1", "type": "end" }, "errors": {}, "id": "1", "type": "end", "userCode": "\n # Write your custom code here...\n #phantom.debug(output)\n", "warnings": {}, "x": 190, "y": 1994 }, "10": { "data": { "advanced": { "customName": "format url report ", "customNameId": 0, "description": "Format a summary table with the information gathered from the playbook.", "drop_none": true, "join": [], "note": "Format a summary table with the information gathered from the playbook." }, "functionId": 1, "functionName": "format_url_report", "id": "10", "parameters": [ "normalized_url_summary_output:custom_function:url", "normalized_url_summary_output:custom_function:scores", "normalized_url_summary_output:custom_function:score_id", "normalized_url_summary_output:custom_function:classifications", "normalized_url_summary_output:custom_function:job_id", "url_screenshot_formatting:custom_function:report", "get_url_summary_output:action_result.summary.AppURL" ], "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 | Classifications | Report Link | Source |\n| --- | --- | --- | --- | --- | --- |\n%%\n| `{0}` | {1} | {2} | {3} | {6} | Splunk Attack Analyzer (SAA) |\n%%\n\nScreenshots associated with the detonated URLs are shown below (if available):\n\n{5}\n", "type": "format" }, "errors": {}, "id": "10", "type": "format", "userCode": "\n # Write your custom code here...\n #phantom.debug(phantom.format(container=container, template=template, parameters=parameters, name=\"format_report_url\"))\n", "warnings": {}, "x": 0, "y": 1640 }, "11": { "data": { "advanced": { "customName": "build url output", "customNameId": 0, "description": "This block uses custom code to generate an observable dictionary to output into the observables data path.", "join": [], "note": "This block uses custom code to generate an observable dictionary to output into the observables data path." }, "functionId": 3, "functionName": "build_url_output", "id": "11", "inputParameters": [ "normalized_url_summary_output:custom_function:url", "normalized_url_summary_output:custom_function:job_id", "normalized_url_summary_output:custom_function:url_score_object", "get_url_summary_output:action_result.summary.AppURL" ], "outputVariables": [ "observable_array" ], "type": "code" }, "errors": {}, "id": "11", "type": "code", "userCode": "\n # Write your custom code here...\n from urllib.parse import urlparse\n build_url_output__observable_array = []\n #phantom.debug(playbook_input_url_values)\n # Build URL\n\n \n for url, external_id, url_object, app_url in zip(normalized_url_summary_output__url, normalized_url_summary_output__job_id, normalized_url_summary_output__url_score_object, get_url_summary_output_summary_appurl):\n parsed_url = urlparse(url)\n #phantom.debug(\"url: {} jobs_id:{}\".format(url, external_id))\n #phantom.debug(\"parsed_url: {}, url_object: {}\".format(parsed_url, url_object))\n observable_object = {\n \"value\": url,\n \"type\": \"url\",\n \"reputation\": {\n \"orig_score\": url_object['orig_score'],\n \"score\": url_object['score'],\n \"score_id\": url_object['score_id']\n },\n \"attributes\": {\n \"hostname\": parsed_url.hostname,\n \"scheme\": parsed_url.scheme\n },\n \"malware\": {\n \"classifications\": url_object['classifications'],\n \"classification_ids\": url_object['classification_ids']\n },\n \"source\": \"Splunk Attack Analyzer\",\n \"source_link\": f\"{app_url}\"\n }\n if url_object.get('related_observables'):\n observable_object[\"related_observables\"] = url_object['related_observables']\n \n if parsed_url.path:\n observable_object['attributes']['path'] = parsed_url.path\n if parsed_url.query:\n observable_object['attributes']['query'] = parsed_url.query\n if parsed_url.port:\n observable_object['attributes']['port'] = parsed_url.port\n\n build_url_output__observable_array.append(observable_object)\n #phantom.debug(\"build_url_output__observable_array: {}\".format(build_url_output__observable_array))\n", "warnings": {}, "x": 0, "y": 1820 }, "12": { "data": { "action": "detonate file", "actionType": "generic", "advanced": { "customName": "file detonation", "customNameId": 0, "delayTime": 0, "description": "Queries SAA for information about the provided vault_id(s)", "join": [], "note": "Queries SAA for information about the provided vault_id(s)" }, "connector": "Splunk Attack Analyzer Connector for Splunk SOAR", "connectorConfigs": [ "splunk_attack_analyzer" ], "connectorId": "de681fee-c552-45bf-9212-827b1c7529f8", "connectorVersion": "v1", "functionId": 1, "functionName": "file_detonation", "id": "12", "loop": { "enabled": false, "exitAfterUnit": "m", "exitAfterValue": 10, "exitConditionEnabled": false, "exitLoopAfter": 2, "pauseUnit": "m", "pauseValue": 2 }, "parameters": { "file": "filtered-data:saa_input_filter:condition_2:playbook_input:vault_id" }, "requiredParameters": [ { "data_type": "string", "field": "file" } ], "type": "action" }, "errors": {}, "id": "12", "type": "action", "warnings": {}, "x": 340, "y": 328 }, "15": { "data": { "action": "get job summary", "actionType": "investigate", "advanced": { "customName": "get file summary output", "customNameId": 0, "delayTime": 0, "description": "Queries SAA Forensics data relative to the JobID of URL(s) or File(s) needs to be detonated.", "join": [], "note": "Queries SAA Forensics data relative to the JobID of URL(s) or File(s) needs to be detonated." }, "connector": "Splunk Attack Analyzer Connector for Splunk SOAR", "connectorConfigs": [ "splunk_attack_analyzer" ], "connectorId": "de681fee-c552-45bf-9212-827b1c7529f8", "connectorVersion": "v1", "functionId": 2, "functionName": "get_file_summary_output", "id": "15", "loop": { "conditions": [ { "comparisons": [ { "conditionIndex": 0, "op": "==", "param": "get_file_summary_output:action_result.data.*.State", "value": "done" } ], "conditionIndex": 0, "display": "If", "logic": "and", "type": "if" } ], "enabled": true, "exitAfterUnit": "m", "exitAfterValue": 30, "exitConditionEnabled": true, "exitLoopAfter": 15, "pauseUnit": "m", "pauseValue": 2 }, "parameters": { "job_id": "filtered-data:detonation_status_filter:condition_1:file_detonation:action_result.data.*.JobID", "timeout": "" }, "requiredParameters": [ { "data_type": "string", "field": "job_id" } ], "type": "action" }, "errors": {}, "id": "15", "type": "action", "userCode": "\n # Write your custom code here...\n #parameters = []\n #for job_ids in file_jobid_detonation_output__jobid:\n # for job in job_ids:\n # if job is not None:\n # parameters.append({\n # \"job_id\": job,\n # \"timeout\": 5,\n # })\n #phantom.debug(parameters)\n", "warnings": {}, "x": 340, "y": 686 }, "17": { "data": { "advanced": { "customName": "normalized file summary output", "customNameId": 0, "description": "This block uses custom code for normalizing score. Adjust the logic as desired in the documented sections.", "join": [], "note": "This block uses custom code for normalizing score. Adjust the logic as desired in the documented sections." }, "functionId": 5, "functionName": "normalized_file_summary_output", "id": "17", "inputParameters": [ "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-data:file_summary_filter:condition_1:get_file_summary_output:action_result.parameter.job_id", "filtered-data:file_summary_filter:condition_1:get_file_summary_output:action_result.data.*.Submission.Name", "filtered-data:file_summary_filter:condition_1:get_file_summary_output:action_result.summary.Score", "filtered-data:file_summary_filter:condition_1:get_file_summary_output:action_result.data.*.Resources", "filtered-data:file_summary_filter:condition_1:get_file_summary_output:action_result.data.*.Verdict", "filtered-data:file_summary_filter:condition_1:get_file_summary_output:action_result.data.*.Tasks" ], "outputVariables": [ "file_score_object", "scores", "categories", "score_id", "file", "job_id", "classifications", "file_name" ], "type": "code" }, "errors": {}, "id": "17", "type": "code", "userCode": " \n \n score_table = {\n \"0\":\"Unknown\",\n \"1\":\"Very_Safe\",\n \"2\":\"Safe\",\n \"3\":\"Probably_Safe\",\n \"4\":\"Leans_Safe\",\n \"5\":\"May_not_be_Safe\",\n \"6\":\"Exercise_Caution\",\n \"7\":\"Suspicious_or_Risky\",\n \"8\":\"Possibly_Malicious\",\n \"9\":\"Probably_Malicious\",\n \"10\":\"Malicious\"\n }\n\n classification_ids = {\n \"Unknown\": 0,\n \"Adware\": 1,\n \"Backdoor\": 2,\n \"Bot\": 3,\n \"Bootkit\": 4,\n \"DDOS\": 5,\n \"Downloader\": 6,\n \"Dropper\": 7,\n \"Exploit-Kit\": 8,\n \"Keylogger\": 9,\n \"Ransomware\": 10,\n \"Remote-Access-Trojan\": 11,\n \"Resource-Exploitation\": 13,\n \"Rogue-Security-Software\": 14,\n \"Rootkit\": 15,\n \"Screen-Capture\": 16,\n \"Spyware\": 17,\n \"Trojan\": 18,\n \"Virus\": 19,\n \"Webshell\": 20,\n \"Wiper\": 21,\n \"Worm\": 22,\n \"Other\": 99\n }\n\n normalized_file_summary_output__file_score_object = []\n normalized_file_summary_output__scores = []\n normalized_file_summary_output__categories = []\n normalized_file_summary_output__score_id = []\n normalized_file_summary_output__file = []\n normalized_file_summary_output__job_id = []\n normalized_file_summary_output__classifications = []\n normalized_file_summary_output__file_name = []\n \n \n def find_sha1_details(target_id, task_list):\n '''\n Attempt to find the detail object with a sha1\n '''\n for task in task_list:\n if (target_id == task.get('ResourceID')\n and task.get('Results',{}).get('Details', {}).get('sha1')):\n task_result_details = task['Results']['Details']\n task_result_details.pop('RootTaskID', None)\n return task_result_details\n return None\n\n \n ## pair forensic job results with url detonated\n job_file_dict = {}\n for orig_file, orig_job, filtered_job in zip(filtered_result_0_parameter_file, filtered_result_0_data___jobid, filtered_result_1_parameter_job_id):\n if orig_job == filtered_job:\n job_file_dict[filtered_job] = orig_file\n \n for job, file_name, score_num, resources, verdict, tasks in zip(\n filtered_result_1_parameter_job_id, \n filtered_result_1_data___submission_name, \n filtered_result_1_summary_score, \n filtered_result_1_data___resources, \n filtered_result_1_data___verdict,\n filtered_result_1_data___tasks\n ):\n \n ## translate scores\n score_id = int(score_num/10) if score_num > 0 else 0\n score = score_table[str(score_id)]\n file = job_file_dict[job]\n attributes = {}\n \n ## build.a sub dictionary of high priority related observables\n related_observables = []\n for sub_observ in resources:\n if sub_observ['Name'] != file_name:\n \n details = find_sha1_details(sub_observ['ID'], tasks)\n second_num = sub_observ['DisplayScore']\n second_num_id = int(second_num/10) if second_num > 0 else 0\n sub_observ_dict = {\n 'value': sub_observ['Name'],\n 'type': sub_observ['Type'].lower(),\n 'reputation': {\n 'score': score_table[str(second_num_id)],\n 'orig_score': second_num,\n 'score_id': second_num_id\n },\n 'source': 'Splunk Attack Analyzer'\n }\n if details:\n details['name'] = sub_observ['Name']\n details.pop('exiftool', None)\n sub_observ_dict['attributes'] = details\n # check if observ is already in related_observables\n skip_observ = False\n for idx, item in enumerate(related_observables):\n if (sub_observ.get('FileMetadata', {}).get('SHA256', 'null_one') \n == item.get('attributes', {}).get('sha256', 'null_two')\n and sub_observ['DisplayScore'] > item['reputation']['orig_score']):\n related_observables[idx] = sub_observ_dict\n skip_observ = True\n elif sub_observ['Name'] == item['value']:\n skip_observ = True\n if not skip_observ:\n related_observables.append(sub_observ_dict)\n elif sub_observ['Name'] == file_name:\n details = find_sha1_details(sub_observ['ID'], tasks)\n if details:\n details.pop('exiftool', None)\n details['name'] = file_name\n attributes = details\n else:\n file_metadata = sub_observ.get('FileMetadata', {})\n attributes = {\n 'name': file_name,\n 'sha256': file_metadata.get('SHA256'),\n 'md5': file_metadata.get('MD5'),\n 'size': file_metadata.get('Size')\n }\n if file_metadata.get('MimeType'):\n attributes['mime_type'] = file_metadata['MimeType']\n \n normalized_file_summary_output__file_score_object.append({\n 'value': file, \n 'orig_score': score_num, \n 'score': score, \n 'score_id': score_id, \n 'classifications': [verdict if verdict else \"Unknown\"],\n 'classification_ids': [classification_ids.get(verdict, 99) if verdict else 0],\n 'related_observables': related_observables,\n 'attributes': attributes\n \n })\n normalized_file_summary_output__scores.append(score)\n normalized_file_summary_output__score_id.append(score_id)\n normalized_file_summary_output__file.append(file)\n normalized_file_summary_output__file_name.append(file_name)\n normalized_file_summary_output__job_id.append(job)\n normalized_file_summary_output__classifications.append([verdict if verdict else \"Unknown\"])\n \n \n", "warnings": {}, "x": 340, "y": 1440 }, "18": { "data": { "advanced": { "customName": "format file report ", "customNameId": 0, "description": "Format a summary table with the information gathered from the playbook.", "drop_none": true, "join": [], "note": "Format a summary table with the information gathered from the playbook." }, "functionId": 2, "functionName": "format_file_report", "id": "18", "parameters": [ "normalized_file_summary_output:custom_function:file_name", "normalized_file_summary_output:custom_function:scores", "normalized_file_summary_output:custom_function:score_id", "normalized_file_summary_output:custom_function:classifications", "normalized_file_summary_output:custom_function:job_id", "file_screenshot_formatting:custom_function:report", "get_file_summary_output:action_result.summary.AppURL" ], "template": "SOAR analyzed File(s) using Splunk Attack Analyzer. The table below shows a summary of the information gathered.\n\n| File Name | Normalized Score | Score Id | Classifications | Report Link | Source |\n| --- | --- | --- | --- | --- | --- |\n%%\n| `{0}` | {1} | {2} | {3} | {6} | Splunk Attack Analyzer (SAA) |\n%%\n\nScreenshots associated with the detonated Files are shown below (if available):\n\n{5}\n\n", "type": "format" }, "errors": {}, "id": "18", "type": "format", "userCode": "\n # Write your custom code here...\n #phantom.debug(phantom.format(container=container, template=template, parameters=parameters, name=\"format_report_file\"))\n", "warnings": {}, "x": 340, "y": 1638 }, "19": { "data": { "advanced": { "customName": "build file output", "customNameId": 0, "description": "This block uses custom code to generate an observable dictionary to output into the observables data path.", "join": [], "note": "This block uses custom code to generate an observable dictionary to output into the observables data path." }, "functionId": 6, "functionName": "build_file_output", "id": "19", "inputParameters": [ "normalized_file_summary_output:custom_function:file", "normalized_file_summary_output:custom_function:job_id", "normalized_file_summary_output:custom_function:file_score_object", "get_file_summary_output:action_result.summary.AppURL" ], "outputVariables": [ "observable_array" ], "type": "code" }, "errors": {}, "id": "19", "type": "code", "userCode": "\n # Write your custom code here...\n build_file_output__observable_array = []\n for _vault_id, external_id, file_object, app_url in zip(normalized_file_summary_output__file, normalized_file_summary_output__job_id, normalized_file_summary_output__file_score_object, get_file_summary_output_summary_appurl):\n #phantom.debug(\"vault: {} id: {}\".format(_vault_id, external_id))\n observable_object = {\n \"value\": _vault_id,\n \"type\": \"hash\",\n \"attributes\": file_object['attributes'],\n \"reputation\": {\n \"orig_score\": file_object['orig_score'],\n \"score\": file_object['score'],\n \"score_id\": file_object['score_id']\n },\n \"malware\": {\n \"classifications\": file_object['classifications'],\n \"classification_ids\": file_object['classification_ids']\n },\n \"source\": \"Splunk Attack Analyzer\",\n \"source_link\":f\"{app_url}\"\n }\n if file_object.get('related_observables'):\n observable_object[\"related_observables\"] = file_object['related_observables']\n \n build_file_output__observable_array.append(observable_object)\n \n", "warnings": {}, "x": 340, "y": 1820 }, "2": { "data": { "advanced": { "customName": "saa input filter", "customNameId": 0, "delimiter": ",", "delimiter_enabled": true, "description": "Determine branches based on provided inputs.", "join": [], "note": "Determine branches based on provided inputs." }, "conditions": [ { "comparisons": [ { "conditionIndex": 0, "op": "!=", "param": "playbook_input:url", "value": "" } ], "conditionIndex": 0, "customName": "saa_url_input", "logic": "and" }, { "comparisons": [ { "conditionIndex": 1, "op": "!=", "param": "playbook_input:vault_id", "value": "" } ], "conditionIndex": 1, "customName": "saa_vault_id_input", "logic": "and" } ], "functionId": 1, "functionName": "saa_input_filter", "id": "2", "type": "filter" }, "errors": {}, "id": "2", "type": "filter", "warnings": {}, "x": 230, "y": 148 }, "22": { "data": { "advanced": { "customName": "url status filter", "customNameId": 0, "delimiter": ",", "delimiter_enabled": true, "description": "Filters url detonation results.", "join": [], "note": "Filters url detonation results." }, "conditions": [ { "comparisons": [ { "conditionIndex": 0, "op": "==", "param": "url_detonation:action_result.status", "value": "success" } ], "conditionIndex": 0, "customName": "saa_url_success_status", "logic": "and" } ], "functionId": 5, "functionName": "url_status_filter", "id": "22", "type": "filter" }, "errors": {}, "id": "22", "type": "filter", "warnings": {}, "x": 60, "y": 506 }, "23": { "data": { "advanced": { "customName": "file summary filter", "customNameId": 0, "delimiter": ",", "delimiter_enabled": true, "description": "Filters successful file detonation job forensic results.", "join": [], "note": "Filters successful file detonation job forensic results." }, "conditions": [ { "comparisons": [ { "conditionIndex": 0, "op": "==", "param": "get_file_summary_output:action_result.status", "value": "success" } ], "conditionIndex": 0, "customName": "get_job_file_summary_sucess", "logic": "and" } ], "functionId": 6, "functionName": "file_summary_filter", "id": "23", "type": "filter" }, "errors": {}, "id": "23", "type": "filter", "warnings": {}, "x": 400, "y": 864 }, "24": { "data": { "action": "get job screenshots", "actionType": "investigate", "advanced": { "customName": "get url job screenshots", "customNameId": 0, "description": "Add the job screenshots to the vault", "join": [], "note": "Add the job screenshots to the vault" }, "connector": "Splunk Attack Analyzer Connector for Splunk SOAR", "connectorConfigs": [ "splunk_attack_analyzer" ], "connectorId": "de681fee-c552-45bf-9212-827b1c7529f8", "connectorVersion": "v1", "functionId": 1, "functionName": "get_url_job_screenshots", "id": "24", "loop": { "enabled": false, "exitAfterUnit": "m", "exitAfterValue": 10, "exitConditionEnabled": false, "exitLoopAfter": 2, "pauseUnit": "m", "pauseValue": 2 }, "parameters": { "job_id": "filtered-data:url_summary_filter:condition_1:get_url_summary_output:action_result.parameter.job_id" }, "requiredParameters": [ { "data_type": "string", "field": "job_id" } ], "type": "action" }, "errors": {}, "id": "24", "type": "action", "warnings": {}, "x": 0, "y": 1220 }, "25": { "data": { "action": "get job screenshots", "actionType": "investigate", "advanced": { "customName": "get file job screenshots", "customNameId": 0, "description": "Add the job screenshots to the vault", "join": [], "note": "Add the job screenshots to the vault" }, "connector": "Splunk Attack Analyzer Connector for Splunk SOAR", "connectorConfigs": [ "splunk_attack_analyzer" ], "connectorId": "de681fee-c552-45bf-9212-827b1c7529f8", "connectorVersion": "v1", "functionId": 2, "functionName": "get_file_job_screenshots", "id": "25", "loop": { "enabled": false, "exitAfterUnit": "m", "exitAfterValue": 10, "exitConditionEnabled": false, "exitLoopAfter": 2, "pauseUnit": "m", "pauseValue": 2 }, "parameters": { "job_id": "filtered-data:file_summary_filter:condition_1:get_file_summary_output:action_result.parameter.job_id" }, "requiredParameters": [ { "data_type": "string", "field": "job_id" } ], "type": "action" }, "errors": {}, "id": "25", "type": "action", "warnings": {}, "x": 340, "y": 1220 }, "26": { "data": { "advanced": { "customName": "url screenshot formatting", "customNameId": 0, "description": "Custom formatting for the markdown report that shows screenshots grouped by detonated URL", "join": [], "note": "Custom formatting for the markdown report that shows screenshots grouped by detonated URL" }, "functionId": 1, "functionName": "url_screenshot_formatting", "id": "26", "inputParameters": [ "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", "get_url_job_screenshots:action_result.parameter.job_id", "get_url_job_screenshots:action_result.data.*.file_name", "get_url_job_screenshots:action_result.data.*.id" ], "outputVariables": [ "report" ], "type": "code" }, "errors": {}, "id": "26", "type": "code", "userCode": " url_screenshot_formatting__report = \"\"\n \n for url, job_id in zip(filtered_result_0_parameter_url, filtered_result_0_data___jobid):\n url_screenshot_formatting__report += f\"#### {url}\\n\"\n for screenshot_job, screenshot_name, screenshot_id in zip(get_url_job_screenshots_parameter_job_id, get_url_job_screenshots_result_item_1, get_url_job_screenshots_result_item_2):\n if job_id == screenshot_job:\n url_screenshot_formatting__report += f\"![{screenshot_name}](/view?id={screenshot_id})\\n\"\n\n", "warnings": {}, "x": -320, "y": 1440 }, "27": { "data": { "advanced": { "customName": "file screenshot formatting", "customNameId": 0, "description": "Custom formatting for the markdown report that shows screenshots grouped by detonated file.", "join": [], "note": "Custom formatting for the markdown report that shows screenshots grouped by detonated file" }, "functionId": 4, "functionName": "file_screenshot_formatting", "id": "27", "inputParameters": [ "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", "get_file_job_screenshots:action_result.parameter.job_id", "get_file_job_screenshots:action_result.data.*.file_name", "get_file_job_screenshots:action_result.data.*.id" ], "outputVariables": [ "report" ], "type": "code" }, "errors": {}, "id": "27", "type": "code", "userCode": "\n file_screenshot_formatting__report = \"\"\n \n for file, job_id in zip(filtered_result_0_parameter_file, filtered_result_0_data___jobid):\n file_screenshot_formatting__report += f\"#### {file}\\n\"\n for screenshot_job, screenshot_name, screenshot_id in zip(get_file_job_screenshots_parameter_job_id, get_file_job_screenshots_result_item_1, get_file_job_screenshots_result_item_2):\n if job_id == screenshot_job:\n file_screenshot_formatting__report += f\"![{screenshot_name}](/view?id={screenshot_id})\\n\"\n\n", "warnings": {}, "x": 680, "y": 1440 }, "3": { "data": { "action": "detonate url", "actionType": "generic", "advanced": { "customName": "url detonation", "customNameId": 0, "delayTime": 0, "description": "Queries SAA for information about the provided URL(s)", "join": [], "note": "Queries SAA for information about the provided URL(s)" }, "connector": "Splunk Attack Analyzer Connector for Splunk SOAR", "connectorConfigs": [ "splunk_attack_analyzer" ], "connectorId": "de681fee-c552-45bf-9212-827b1c7529f8", "connectorVersion": "v1", "functionId": 1, "functionName": "url_detonation", "id": "3", "loop": { "enabled": false, "exitAfterUnit": "m", "exitAfterValue": 10, "exitConditionEnabled": false, "exitLoopAfter": 2, "pauseUnit": "m", "pauseValue": 2 }, "parameters": { "url": "filtered-data:saa_input_filter:condition_1:playbook_input:url" }, "requiredParameters": [ { "data_type": "string", "field": "url" } ], "type": "action" }, "errors": {}, "id": "3", "type": "action", "userCode": "\n # Write your custom code here...\n\n", "warnings": {}, "x": 0, "y": 320 }, "4": { "data": { "advanced": { "customName": "detonation status filter", "customNameId": 0, "delimiter": ",", "delimiter_enabled": true, "description": "Filters successful file detonation results.", "join": [], "note": "Filters successful file detonation results." }, "conditions": [ { "comparisons": [ { "conditionIndex": 0, "op": "==", "param": "file_detonation:action_result.status", "value": "success" } ], "conditionIndex": 0, "customName": "saa_file_success_status", "logic": "and" } ], "functionId": 2, "functionName": "detonation_status_filter", "id": "4", "type": "filter" }, "errors": {}, "id": "4", "type": "filter", "warnings": {}, "x": 400, "y": 506 }, "6": { "data": { "action": "get job summary", "actionType": "investigate", "advanced": { "customName": "get url summary output", "customNameId": 0, "delayTime": 0, "description": "Queries SAA Forensics data relative to the JobID of URL(s) or File(s) needs to be detonated.", "join": [], "note": "Queries SAA Forensics data relative to the JobID of URL(s) or File(s) needs to be detonated.", "reviewer": "" }, "connector": "Splunk Attack Analyzer Connector for Splunk SOAR", "connectorConfigs": [ "splunk_attack_analyzer" ], "connectorId": "de681fee-c552-45bf-9212-827b1c7529f8", "connectorVersion": "v1", "functionId": 1, "functionName": "get_url_summary_output", "id": "6", "loop": { "conditions": [ { "comparisons": [ { "conditionIndex": 0, "op": "==", "param": "get_url_summary_output:action_result.data.*.State", "value": "done" } ], "conditionIndex": 0, "display": "If", "logic": "and", "type": "if" } ], "enabled": true, "exitAfterUnit": "m", "exitAfterValue": 30, "exitConditionEnabled": true, "exitLoopAfter": 15, "pauseUnit": "m", "pauseValue": 2 }, "parameters": { "job_id": "filtered-data:url_status_filter:condition_1:url_detonation:action_result.data.*.JobID", "timeout": "" }, "requiredParameters": [ { "data_type": "string", "field": "job_id" } ], "type": "action" }, "errors": {}, "id": "6", "type": "action", "userCode": "\n # Write your custom code here...\n #parameters = []\n #for job_ids in url_jobid_detonation_output__jobid:\n # for job in job_ids:\n # if job is not None:\n # parameters.append({\n # \"job_id\": job,\n # \"timeout\": 5,\n # })\n #phantom.debug(parameters)\n", "warnings": {}, "x": -1.4210854715202004e-14, "y": 686 }, "7": { "data": { "advanced": { "customName": "url summary filter", "customNameId": 0, "delimiter": ",", "delimiter_enabled": true, "description": "Filters successful url detonation job forensic results.", "join": [], "note": "Filters successful url detonation job forensic results." }, "conditions": [ { "comparisons": [ { "conditionIndex": 0, "op": "==", "param": "get_url_summary_output:action_result.status", "value": "success" } ], "conditionIndex": 0, "customName": "get_job_summary_success", "logic": "and" } ], "functionId": 3, "functionName": "url_summary_filter", "id": "7", "type": "filter" }, "errors": {}, "id": "7", "type": "filter", "warnings": {}, "x": 60, "y": 864 }, "8": { "data": { "advanced": { "customName": "normalized url summary output", "customNameId": 0, "description": "This block uses custom code for normalizing score. Adjust the logic as desired in the documented sections.", "join": [], "note": "This block uses custom code for normalizing score. Adjust the logic as desired in the documented sections." }, "functionId": 2, "functionName": "normalized_url_summary_output", "id": "8", "inputParameters": [ "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-data:url_summary_filter:condition_1:get_url_summary_output:action_result.parameter.job_id", "filtered-data:url_summary_filter:condition_1:get_url_summary_output:action_result.summary.Score", "filtered-data:url_summary_filter:condition_1:get_url_summary_output:action_result.data.*.Resources", "filtered-data:url_summary_filter:condition_1:get_url_summary_output:action_result.data.*.Verdict" ], "outputVariables": [ "url_score_object", "scores", "classifications", "score_id", "url", "job_id" ], "type": "code" }, "errors": {}, "id": "8", "type": "code", "userCode": "\n score_table = {\n \"0\":\"Unknown\",\n \"1\":\"Very_Safe\",\n \"2\":\"Safe\",\n \"3\":\"Probably_Safe\",\n \"4\":\"Leans_Safe\",\n \"5\":\"May_not_be_Safe\",\n \"6\":\"Exercise_Caution\",\n \"7\":\"Suspicious_or_Risky\",\n \"8\":\"Possibly_Malicious\",\n \"9\":\"Probably_Malicious\",\n \"10\":\"Malicious\"\n }\n classification_ids = {\n \"Unknown\": 0,\n \"Adware\": 1,\n \"Backdoor\": 2,\n \"Bot\": 3,\n \"Bootkit\": 4,\n \"DDOS\": 5,\n \"Downloader\": 6,\n \"Dropper\": 7,\n \"Exploit-Kit\": 8,\n \"Keylogger\": 9,\n \"Ransomware\": 10,\n \"Remote-Access-Trojan\": 11,\n \"Resource-Exploitation\": 13,\n \"Rogue-Security-Software\": 14,\n \"Rootkit\": 15,\n \"Screen-Capture\": 16,\n \"Spyware\": 17,\n \"Trojan\": 18,\n \"Virus\": 19,\n \"Webshell\": 20,\n \"Wiper\": 21,\n \"Worm\": 22,\n \"Other\": 99\n }\n normalized_url_summary_output__url_score_object = []\n normalized_url_summary_output__scores = []\n normalized_url_summary_output__classifications = []\n normalized_url_summary_output__score_id = []\n normalized_url_summary_output__url = []\n normalized_url_summary_output__job_id = []\n \n ## pair forensic job results with url detonated\n job_url_dict = {}\n for orig_url, orig_job, filtered_job in zip(filtered_result_0_parameter_url, filtered_result_0_data___jobid, filtered_result_1_parameter_job_id):\n if orig_job == filtered_job:\n job_url_dict[filtered_job] = orig_url\n \n \n for job, score_num, resources, verdict in zip(filtered_result_1_parameter_job_id, filtered_result_1_summary_score, filtered_result_1_data___resources, filtered_result_1_data___verdict):\n \n ## translate scores\n score_id = int(score_num/10) if score_num > 0 else 0\n score = score_table[str(score_id)]\n url = job_url_dict[job]\n \n ## build a sub dictionary of high priority related observables\n related_observables = []\n for sub_observ in resources:\n if sub_observ['Name'] != url:\n second_num = sub_observ['DisplayScore']\n second_num_id = int(second_num/10) if second_num > 0 else 0\n related_observables.append({\n 'value': sub_observ['Name'],\n 'type': sub_observ['Type'].lower(),\n 'reputation': {\n 'score': score_table[str(second_num_id)],\n 'orig_score': second_num,\n 'score_id': second_num_id\n },\n 'source': 'Splunk Attack Analyzer'\n })\n \n # Attach final object\n normalized_url_summary_output__url_score_object.append({\n 'value': url, \n 'orig_score': score_num, \n 'score': score, \n 'score_id': score_id, \n 'classifications': [verdict if verdict else \"Unknown\"],\n 'classification_ids': [classification_ids.get(verdict, 99) if verdict else 0],\n 'related_observables': related_observables\n })\n normalized_url_summary_output__scores.append(score)\n normalized_url_summary_output__score_id.append(score_id)\n normalized_url_summary_output__url.append(url)\n normalized_url_summary_output__job_id.append(job)\n normalized_url_summary_output__classifications.append([verdict if verdict else \"Unknown\"])\n \n\n", "warnings": {}, "x": 0, "y": 1440 } }, "notes": "Inputs: url, vault_id\nInteractions: Splunk Attack Analyzer\nActions: url detonation, , file detonation\nOutputs: report, observables" }, "input_spec": [ { "contains": [ "url" ], "description": "A URL provided for reputation analysis - Splunk Attack Analyzer", "name": "url" }, { "contains": [ "vault id" ], "description": "A vault_id provided for reputation analysis - Splunk Attack Analyzer", "name": "vault_id" } ], "output_spec": [ { "contains": [], "datapaths": [ "build_url_output:custom_function:observable_array", "build_file_output:custom_function:observable_array" ], "deduplicate": false, "description": "An array of observable dictionaries with value, type, score, score_id, and categories.", "metadata": {}, "name": "observable" }, { "contains": [], "datapaths": [ "format_url_report:formatted_data", "format_file_report:formatted_data" ], "deduplicate": false, "description": "a report contains value, score, confidence and categories", "metadata": {}, "name": "report" } ], "playbook_type": "data", "python_version": "3.13", "schema": "5.0.11", "version": "6.2.0.355" }, "create_time": "2024-03-19T15:17:38.130754+00:00", "draft_mode": false, "labels": [ "*" ], "tags": [ "url", "ip", "domain", "sandbox", "D3-DA", "vault_id", "splunk_attack_analyzer" ] }