diff --git a/playbooks/CrowdStrike_OAuth_API_Dynamic_Analysis.json b/playbooks/CrowdStrike_OAuth_API_Dynamic_Analysis.json index 7cd4867db8..7e276adf27 100644 --- a/playbooks/CrowdStrike_OAuth_API_Dynamic_Analysis.json +++ b/playbooks/CrowdStrike_OAuth_API_Dynamic_Analysis.json @@ -4,7 +4,7 @@ "category": "Dynamic Analysis", "coa": { "data": { - "description": "Accepts a URL or File_Hash and does reputation 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\nRef: https://d3fend.mitre.org/technique/d3f:IdentifierReputationAnalysis/", + "description": "Accepts a URL or File_Hash and does reputation 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", @@ -96,25 +96,6 @@ "targetNode": "12", "targetPort": "12_in" }, - { - "id": "port_8_to_port_13", - "sourceNode": "8", - "sourcePort": "8_out", - "targetNode": "13", - "targetPort": "13_in" - }, - { - "conditions": [ - { - "index": 0 - } - ], - "id": "port_13_to_port_10", - "sourceNode": "13", - "sourcePort": "13_out", - "targetNode": "10", - "targetPort": "10_in" - }, { "id": "port_12_to_port_14", "sourceNode": "12", @@ -137,23 +118,18 @@ "targetPort": "1_in" }, { - "conditions": [ - { - "index": 1 - } - ], - "id": "port_13_to_port_16", - "sourceNode": "13", - "sourcePort": "13_out", - "targetNode": "16", - "targetPort": "16_in" + "id": "port_8_to_port_32", + "sourceNode": "8", + "sourcePort": "8_out", + "targetNode": "32", + "targetPort": "32_in" }, { - "id": "port_16_to_port_17", - "sourceNode": "16", - "sourcePort": "16_out", - "targetNode": "17", - "targetPort": "17_in" + "id": "port_32_to_port_35", + "sourceNode": "32", + "sourcePort": "32_out", + "targetNode": "35", + "targetPort": "35_in" }, { "conditions": [ @@ -161,140 +137,15 @@ "index": 0 } ], - "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_20", - "sourceNode": "19", - "sourcePort": "19_out", - "targetNode": "20", - "targetPort": "20_in" - }, - { - "id": "port_20_to_port_1", - "sourceNode": "20", - "sourcePort": "20_out", - "targetNode": "1", - "targetPort": "1_in" - }, - { - "conditions": [ - { - "index": 3 - } - ], - "id": "port_13_to_port_21", - "sourceNode": "13", - "sourcePort": "13_out", - "targetNode": "21", - "targetPort": "21_in" - }, - { - "id": "port_21_to_port_22", - "sourceNode": "21", - "sourcePort": "21_out", - "targetNode": "22", - "targetPort": "22_in" - }, - { - "conditions": [ - { - "index": 0 - } - ], - "id": "port_22_to_port_23", - "sourceNode": "22", - "sourcePort": "22_out", - "targetNode": "23", - "targetPort": "23_in" - }, - { - "id": "port_23_to_port_24", - "sourceNode": "23", - "sourcePort": "23_out", - "targetNode": "24", - "targetPort": "24_in" - }, - { - "id": "port_24_to_port_25", - "sourceNode": "24", - "sourcePort": "24_out", - "targetNode": "25", - "targetPort": "25_in" - }, - { - "id": "port_25_to_port_1", - "sourceNode": "25", - "sourcePort": "25_out", - "targetNode": "1", - "targetPort": "1_in" - }, - { - "conditions": [ - { - "index": 2 - } - ], - "id": "port_13_to_port_26", - "sourceNode": "13", - "sourcePort": "13_out", - "targetNode": "26", - "targetPort": "26_in" - }, - { - "id": "port_26_to_port_27", - "sourceNode": "26", - "sourcePort": "26_out", - "targetNode": "27", - "targetPort": "27_in" - }, - { - "conditions": [ - { - "index": 0 - } - ], - "id": "port_27_to_port_28", - "sourceNode": "27", - "sourcePort": "27_out", - "targetNode": "28", - "targetPort": "28_in" - }, - { - "id": "port_28_to_port_29", - "sourceNode": "28", - "sourcePort": "28_out", - "targetNode": "29", - "targetPort": "29_in" - }, - { - "id": "port_29_to_port_30", - "sourceNode": "29", - "sourcePort": "29_out", - "targetNode": "30", - "targetPort": "30_in" - }, - { - "id": "port_30_to_port_1", - "sourceNode": "30", - "sourcePort": "30_out", - "targetNode": "1", - "targetPort": "1_in" + "id": "port_35_to_port_10", + "sourceNode": "35", + "sourcePort": "35_out", + "targetNode": "10", + "targetPort": "10_in" } ], "globalCustomCode": "\n\n\nimport os", - "hash": "5cff0f179c8b9ff466ffcb9d12d541f2062d3637", + "hash": "f4a238d5963ad546bde73d3ec8b4283699f52a43", "nodes": { "0": { "data": { @@ -309,8 +160,8 @@ "id": "0", "type": "start", "warnings": {}, - "x": 530, - "y": -3.197442310920451e-13 + "x": 250, + "y": -7.034373084024992e-13 }, "1": { "data": { @@ -324,17 +175,17 @@ "errors": {}, "id": "1", "type": "end", - "userCode": "\n # Write your custom code here...\n format_report_url = phantom.get_format_data(name=\"format_report_url\")\n format_report_win_file = phantom.get_format_data(name=\"format_report_win_file\")\n format_report_linux_file = phantom.get_format_data(name=\"format_report_linux_file\")\n format_report_android_file = phantom.get_format_data(name=\"format_report_android_file\")\n format_report_mac_file = phantom.get_format_data(name=\"format_report_mac_file\")\n markdown_report_combined_value = phantom.concatenate(format_report_url, format_report_win_file, format_report_linux_file, format_report_android_file, format_report_mac_file, format_report_mac_file)\n output['markdown_report'] = markdown_report_combined_value\n", + "userCode": "\n # Write your custom code here...\n\n", "warnings": {}, - "x": 700, - "y": 1580 + "x": 260, + "y": 1920 }, "10": { "data": { "action": "detonate file", "actionType": "generic", "advanced": { - "customName": "windows file detonation", + "customName": "file detonation", "customNameId": 0, "description": "Queries CrowdStrike for information about the provided vault_id(s)", "join": [], @@ -342,19 +193,36 @@ }, "connector": "CrowdStrike OAuth API", "connectorConfigs": [ - "crowdstrike_url_reputation" + "crowdstrike" ], "connectorId": "ae971ba5-3117-444a-8ac5-6ce779f3a232", "connectorVersion": "v1", + "customDatapaths": { + "list_demux": { + "data.output.sandbox_type": { + "contains": [], + "isCustomDatapath": true, + "isDatapathArray": true, + "label": "data.output.sandbox_type", + "value": "list_demux:custom_function_result.data.output.sandbox_type" + }, + "data.output.value": { + "contains": [], + "isCustomDatapath": true, + "isDatapathArray": true, + "label": "data.output.value", + "value": "list_demux:custom_function_result.data.output.value" + } + } + }, "functionId": 1, - "functionName": "windows_file_detonation", + "functionName": "file_detonation", "id": "10", "parameters": { - "detail_report": true, - "environment": "Windows 10, 64-bit", - "is_confidential": false, + "environment": "list_demux:custom_function_result.data.output.sandbox_type", + "is_confidential": true, "limit": 50, - "vault_id": "playbook_input:vault_id" + "vault_id": "list_demux:custom_function_result.data.output.value" }, "requiredParameters": [ { @@ -381,14 +249,15 @@ "errors": {}, "id": "10", "type": "action", + "userCode": "\n # Write your custom code here...\n", "warnings": {}, - "x": 340, - "y": 680 + "x": 0, + "y": 1000 }, "11": { "data": { "advanced": { - "customName": "windows sandbox filter", + "customName": "sandbox filter", "customNameId": 0, "description": "Filters successful file detonation results.", "join": [], @@ -400,17 +269,17 @@ { "conditionIndex": 0, "op": "==", - "param": "windows_file_detonation:action_result.status", + "param": "file_detonation:action_result.status", "value": "success" } ], "conditionIndex": 0, - "customName": "win_sandbox_status_filter", + "customName": "sandbox_status_filter", "logic": "and" } ], "functionId": 4, - "functionName": "windows_sandbox_filter", + "functionName": "sandbox_filter", "id": "11", "type": "filter" }, @@ -418,186 +287,94 @@ "id": "11", "type": "filter", "warnings": {}, - "x": 400, - "y": 866 + "x": 60, + "y": 1192 }, "12": { "data": { "advanced": { - "customName": "normalized win file detonation output", + "customName": "normalized file detonation 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": 4, - "functionName": "normalized_win_file_detonation_output", + "functionName": "normalized_file_detonation_output", "id": "12", "inputParameters": [ - "filtered-data:windows_sandbox_filter:condition_1:windows_file_detonation:action_result.parameter.vault_id", - "filtered-data:windows_sandbox_filter:condition_1:windows_file_detonation:action_result.data.*.verdict", - "filtered-data:windows_sandbox_filter:condition_1:windows_file_detonation:action_result.data.*.sandbox.*.threat_score", - "filtered-data:windows_sandbox_filter:condition_1:windows_file_detonation:action_result.data.*.sandbox.*.signatures.*.category", - "filtered-data:windows_sandbox_filter:condition_1:windows_file_detonation:action_result.data.*.sandbox.*.verdict" + "filtered-data:sandbox_filter:condition_1:file_detonation:action_result.parameter.vault_id", + "filtered-data:sandbox_filter:condition_1:file_detonation:action_result.data.*.verdict", + "filtered-data:sandbox_filter:condition_1:file_detonation:action_result.data.*.sandbox.*.threat_score", + "filtered-data:sandbox_filter:condition_1:file_detonation:action_result.data.*.sandbox.*.signatures.*.category", + "filtered-data:sandbox_filter:condition_1:file_detonation:action_result.data.*.sandbox.*.verdict" ], "outputVariables": [ "file_score_object", "scores", "categories", - "confidence" + "score_id" ], "type": "code" }, "errors": {}, "id": "12", "type": "code", - "userCode": "\n # Write your custom code here...\n normalized_win_file_detonation_output__file_score_object = []\n normalized_win_file_detonation_output__scores = []\n normalized_win_file_detonation_output__categories = []\n normalized_win_file_detonation_output__confidence = []\n ## normalized NoneType value to avoid enumeration failure\n file_detonation_param_list = [(i or \"\") for i in filtered_result_0_parameter_vault_id] \n file_detonation_threat_score_list = [(i or \"\") for i in filtered_result_0_data___sandbox___threat_score] \n file_detonation_category_list = [(i or \"\") for i in filtered_result_0_data___sandbox___signatures___category] \n file_detonation_verdict_list = [(i or \"\") for i in filtered_result_0_data___sandbox___verdict] \n \n ## get the set() or unique input vault id parameter.\n \n index_file_dict = {}\n set_vault_id_inputs = set(file_detonation_param_list)\n \n for vault_id_input in set_vault_id_inputs:\n ## crowdstrike detonation can have a multiple phase of score, verdict and category during detonation. we will try to get all the unique values of each\n ## object filed we want to include in report. \n \n file_list = []\n score_list = []\n verdict_list = []\n category_list = []\n \n ## getting the index of each detonation phase of the url/file. group the result for each detonation\n vault_id_input_index = [indx for indx, vault_id_val in enumerate(file_detonation_param_list) if vault_id_val == vault_id_input]\n index_file_dict[vault_id_input] = vault_id_input_index\n phantom.debug(\"vault_id: {} vault_id_list: {}\".format(vault_id_input, index_file_dict))\n \n for idx,(_vault_id, _score, _verdict, _category) in enumerate(zip(file_detonation_param_list, file_detonation_verdict_list, file_detonation_threat_score_list, file_detonation_category_list)):\n if _vault_id == vault_id_input and idx in index_file_dict[vault_id_input]:\n file_list.append(_vault_id)\n score_list.append(_score)\n verdict_list.append(_verdict)\n category_list.append(_category)\n \n # Attach final object\n normalized_win_file_detonation_output__file_score_object.append({'score': list(set(score_list))[0], 'confidence': list(set(verdict_list))[0], 'categories': list(set(category_list))})\n normalized_win_file_detonation_output__scores.append(list(set(score_list))[0])\n normalized_win_file_detonation_output__categories.append(list(set(category_list)))\n normalized_win_file_detonation_output__confidence.append(list(set(verdict_list))[0])\n phantom.debug(\"normalized_win_file_detonation_output__file_score_object: {}\".format(normalized_win_file_detonation_output__file_score_object))\n phantom.debug(\"normalized_win_file_detonation_output__scores: {}\".format(normalized_win_file_detonation_output__scores))\n phantom.debug(\"normalized_win_file_detonation_output__categories: {}\".format(normalized_win_file_detonation_output__categories))\n", + "userCode": "\n # Write your custom code here...\n normalized_file_detonation_output__file_score_object = []\n normalized_file_detonation_output__scores = []\n normalized_file_detonation_output__categories = []\n normalized_file_detonation_output__score_id = []\n ## normalized NoneType value to avoid enumeration failure\n file_detonation_param_list = [(i or \"\") for i in filtered_result_0_parameter_vault_id] \n file_detonation_threat_score_list = [(i or \"\") for i in filtered_result_0_data___sandbox___threat_score] \n file_detonation_category_list = [(i or \"\") for i in filtered_result_0_data___sandbox___signatures___category] \n file_detonation_verdict_list = [(i or \"\") for i in filtered_result_0_data___sandbox___verdict] \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 ## get the set() or unique input vault id parameter.\n \n index_file_dict = {}\n set_vault_id_inputs = set(file_detonation_param_list)\n \n for vault_id_input in set_vault_id_inputs:\n ## crowdstrike detonation can have a multiple phase of score, verdict and category during detonation. we will try to get all the unique values of each\n ## object filed we want to include in report. \n \n file_list = []\n score_list = []\n verdict_list = []\n category_list = []\n \n ## getting the index of each detonation phase of the url/file. group the result for each detonation\n vault_id_input_index = [indx for indx, vault_id_val in enumerate(file_detonation_param_list) if vault_id_val == vault_id_input]\n index_file_dict[vault_id_input] = vault_id_input_index\n #phantom.debug(\"vault_id: {} vault_id_list: {}\".format(vault_id_input, index_file_dict))\n \n for idx,(_vault_id, _score, _verdict, _category) in enumerate(zip(file_detonation_param_list, file_detonation_verdict_list, file_detonation_threat_score_list, file_detonation_category_list)):\n if _vault_id == vault_id_input and idx in index_file_dict[vault_id_input]:\n file_list.append(_vault_id)\n score_list.append(_score)\n verdict_list.append(_verdict)\n category_list.append(_category)\n \n # Attach final object\n score_id = round(list(set(verdict_list))[0] / 10)\n score = score_table[str(score_id)]\n \n normalized_file_detonation_output__file_score_object.append({'score': score, 'score_id': score_id,'confidence': list(set(score_list))[0], 'categories': list(set(category_list))})\n normalized_file_detonation_output__scores.append(score)\n normalized_file_detonation_output__categories.append(list(set(category_list)))\n normalized_file_detonation_output__score_id.append(score_id)\n #phantom.debug(\"normalized_file_detonation_output__file_score_object: {}\".format(normalized_file_detonation_output__file_score_object))\n #phantom.debug(\"normalized_file_detonation_output__scores: {}\".format(normalized_file_detonation_output__scores))\n #phantom.debug(\"normalized_file_detonation_output__categories: {}\".format(normalized_file_detonation_output__categories))\n", "warnings": {}, - "x": 340, - "y": 1040 - }, - "13": { - "data": { - "advanced": { - "description": "Determine branches based on file metadata like available file type, mime-type or file extensions.", - "join": [], - "note": "Determine branches based on file metadata like available file type, mime-type or file extensions." - }, - "conditions": [ - { - "comparisons": [ - { - "conditionIndex": 0, - "op": "==", - "param": "get_vault_id_information:custom_function:sandbox_type", - "value": "windows" - } - ], - "conditionIndex": 0, - "customName": "windows_sandbox", - "display": "If", - "logic": "and", - "type": "if" - }, - { - "comparisons": [ - { - "conditionIndex": 1, - "op": "==", - "param": "get_vault_id_information:custom_function:sandbox_type", - "value": "linux" - } - ], - "conditionIndex": 1, - "customName": "linux_sandbox", - "display": "Else If", - "logic": "and", - "type": "elif" - }, - { - "comparisons": [ - { - "conditionIndex": 2, - "op": "==", - "param": "get_vault_id_information:custom_function:sandbox_type", - "value": "mac" - } - ], - "conditionIndex": 2, - "customName": "mac_sandbox", - "display": "Else If", - "logic": "and", - "type": "elif" - }, - { - "comparisons": [ - { - "conditionIndex": 3, - "op": "==", - "param": "get_vault_id_information:custom_function:sandbox_type", - "value": "android" - } - ], - "conditionIndex": 3, - "customName": "android_sandbox", - "display": "Else If", - "logic": "and", - "type": "elif" - }, - { - "comparisons": [ - { - "conditionIndex": 4, - "op": "==", - "param": "", - "value": "" - } - ], - "conditionIndex": 4, - "customName": "windows_sandbox", - "display": "Else", - "logic": "and", - "type": "else" - } - ], - "functionId": 1, - "functionName": "decision_1", - "id": "13", - "type": "decision" - }, - "errors": {}, - "id": "13", - "type": "decision", - "warnings": {}, - "x": 940, - "y": 500 + "x": 0, + "y": 1380 }, "14": { "data": { "advanced": { - "customName": "format report win file", + "customName": "format report file", "customNameId": 0, "description": "Format a summary table with the information gathered from the playbook.", "join": [], "note": "Format a summary table with the information gathered from the playbook." }, "functionId": 2, - "functionName": "format_report_win_file", + "functionName": "format_report_file", "id": "14", "parameters": [ - "filtered-data:windows_sandbox_filter:condition_1:windows_file_detonation:action_result.parameter.vault_id", - "normalized_win_file_detonation_output:custom_function:scores", - "normalized_win_file_detonation_output:custom_function:confidence", - "normalized_win_file_detonation_output:custom_function:categories", + "filtered-data:sandbox_filter:condition_1:file_detonation:action_result.parameter.vault_id", + "normalized_file_detonation_output:custom_function:scores", + "normalized_file_detonation_output:custom_function:score_id", + "normalized_file_detonation_output:custom_function:categories", "filtered-data:windows_sandbox_filter:condition_1:windows_file_detonation:action_result.data.*.id" ], - "template": "SOAR analyzed URL(s) using CrowdStrike. The table below shows a summary of the information gathered.\n\n| File hash | Score | Confidence |Categories | Report Link | Source |\n| --- | --- | --- | --- | --- |\n%%\n| `{0}` | {1} | {2} | {3} |https://falcon.crowdstrike.com/intelligence/sandbox/reports/{4} | CrowdStrike OAuth API |\n%%\n{1}\n{2}\n{3}\n{4}\n\n", + "template": "SOAR analyzed File(s) using CrowdStrike. The table below shows a summary of the information gathered.\n\n| vault_id | Normalized Score | score id |Categories | Report Link | Source |\n| --- | --- | --- | --- | --- | --- |\n%%\n| `{0}` | {1} | {2} | {3} |https://falcon.crowdstrike.com/intelligence/sandbox/reports/{4} | CrowdStrike OAuth API |\n%%\n\n\n", "type": "format" }, "errors": {}, "id": "14", "type": "format", "userCode": "\n # Write your custom code here...\n #phantom.debug(phantom.format(container=container, template=template, parameters=parameters, name=\"format_report_win_file\"))\n", - "warnings": {}, - "x": 340, - "y": 1220 + "warnings": { + "config": [ + "Reconfigure invalid datapath." + ] + }, + "x": 0, + "y": 1560 }, "15": { "data": { "advanced": { - "customName": "build win file output", + "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": 5, - "functionName": "build_win_file_output", + "functionName": "build_file_output", "id": "15", "inputParameters": [ "playbook_input:vault_id", - "filtered-data:windows_sandbox_filter:condition_1:windows_file_detonation:action_result.data.*.id", - "normalized_win_file_detonation_output:custom_function:file_score_object" + "filtered-data:sandbox_filter:condition_1:file_detonation:action_result.data.*.id", + "normalized_file_detonation_output:custom_function:file_score_object" ], "outputVariables": [ "observable_array" @@ -607,166 +384,14 @@ "errors": {}, "id": "15", "type": "code", - "userCode": "\n # Write your custom code here...\n build_win_file_output__observable_array = []\n for _vault_id, external_id, file_object in zip(playbook_input_vault_id_values, filtered_result_0_data___id, normalized_win_file_detonation_output__file_score_object):\n observable_object = {\n \n \"value\": _vault_id,\n \"type\": \"hash\",\n \"sandbox\": {\n \"score\": file_object['score'],\n \"confidence\": file_object['confidence'],\n \"categories\": file_object['categories']\n },\n \"enrichment\": {\n \"provider\": \"CrowdStrike OAuth API\",\n \"type\": \"file\",\n \n },\n \"source\": \"CrowdStrike OAuth API\",\n \"source_link\":f\"https://falcon.crowdstrike.com/intelligence/sandbox/reports/{external_id}\"\n }\n build_win_file_output__observable_array.append(observable_object)\n phantom.debug(\"build_win_file_output__observable_array: {}\".format(build_win_file_output__observable_array))\n", - "warnings": {}, - "x": 340, - "y": 1400 - }, - "16": { - "data": { - "action": "detonate file", - "actionType": "generic", - "advanced": { - "customName": "linux file detonation", - "customNameId": 0, - "description": "Queries CrowdStrike for information about the provided vault_id(s)", - "join": [], - "note": "Queries CrowdStrike for information about the provided vault_id(s)" - }, - "connector": "CrowdStrike OAuth API", - "connectorConfigs": [ - "crowdstrike_url_reputation" - ], - "connectorId": "ae971ba5-3117-444a-8ac5-6ce779f3a232", - "connectorVersion": "v1", - "functionId": 2, - "functionName": "linux_file_detonation", - "id": "16", - "parameters": { - "environment": "Linux Ubuntu 16.04, 64-bit", - "is_confidential": true, - "limit": 50, - "vault_id": "playbook_input:vault_id" - }, - "requiredParameters": [ - { - "data_type": "numeric", - "default": 50, - "field": "limit" - }, - { - "data_type": "string", - "field": "vault_id" - }, - { - "data_type": "string", - "field": "environment" - }, - { - "data_type": "boolean", - "default": true, - "field": "is_confidential" - } - ], - "type": "action" + "userCode": "\n # Write your custom code here...\n build_file_output__observable_array = []\n for _vault_id, external_id, file_object in zip(playbook_input_vault_id_values, filtered_result_0_data___id, normalized_file_detonation_output__file_score_object):\n observable_object = {\n \n \"value\": _vault_id,\n \"type\": \"hash\",\n \"reputation\": {\n \"score\": file_object['score'],\n \"score_id\": file_object['score_id'],\n \"confidence\": file_object['confidence'],\n \"categories\": file_object['categories']\n },\n \"enrichment\": {\n \"provider\": \"CrowdStrike OAuth API\",\n \"type\": \"file\",\n \n },\n \"source\": \"CrowdStrike OAuth API\",\n \"source_link\":f\"https://falcon.crowdstrike.com/intelligence/sandbox/reports/{external_id}\"\n }\n build_file_output__observable_array.append(observable_object)\n #phantom.debug(\"build_file_output__observable_array: {}\".format(build_file_output__observable_array))\n", + "warnings": { + "config": [ + "Reconfigure invalid datapath." + ] }, - "errors": {}, - "id": "16", - "type": "action", - "warnings": {}, - "x": 680, - "y": 700 - }, - "17": { - "data": { - "advanced": { - "customName": "linux sandbox filter", - "customNameId": 0, - "description": "Filters successful file detonation results.", - "join": [], - "note": "Filters successful file detonation results." - }, - "conditions": [ - { - "comparisons": [ - { - "conditionIndex": 0, - "op": "==", - "param": "linux_file_detonation:action_result.status", - "value": "success" - } - ], - "conditionIndex": 0, - "customName": "linux_sandbox_status_filter", - "logic": "and" - } - ], - "functionId": 6, - "functionName": "linux_sandbox_filter", - "id": "17", - "type": "filter" - }, - "errors": {}, - "id": "17", - "type": "filter", - "warnings": {}, - "x": 740, - "y": 860 - }, - "18": { - "data": { - "advanced": { - "customName": "normalized linux file detonation 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": 7, - "functionName": "normalized_linux_file_detonation_output", - "id": "18", - "inputParameters": [ - "filtered-data:linux_sandbox_filter:condition_1:linux_file_detonation:action_result.parameter.vault_id", - "filtered-data:linux_sandbox_filter:condition_1:linux_file_detonation:action_result.data.*.verdict", - "filtered-data:linux_sandbox_filter:condition_1:linux_file_detonation:action_result.data.*.sandbox.*.threat_score", - "filtered-data:linux_sandbox_filter:condition_1:linux_file_detonation:action_result.data.*.sandbox.*.signatures.*.category", - "filtered-data:linux_sandbox_filter:condition_1:linux_file_detonation:action_result.data.*.sandbox.*.verdict" - ], - "outputVariables": [ - "file_score_object", - "scores", - "categories", - "confidence" - ], - "type": "code" - }, - "errors": {}, - "id": "18", - "type": "code", - "userCode": "\n # Write your custom code here...\n normalized_linux_file_detonation_output__file_score_object = []\n normalized_linux_file_detonation_output__scores = []\n normalized_linux_file_detonation_output__categories = []\n normalized_linux_file_detonation_output__confidence = []\n \n ## normalized NoneType value to avoid enumeration failure\n file_detonation_param_list = [(i or \"\") for i in filtered_result_0_parameter_vault_id] \n file_detonation_threat_score_list = [(i or \"\") for i in filtered_result_0_data___sandbox___threat_score] \n file_detonation_category_list = [(i or \"\") for i in filtered_result_0_data___sandbox___signatures___category] \n file_detonation_verdict_list = [(i or \"\") for i in filtered_result_0_data___sandbox___verdict] \n \n ## get the set() or unique input vault id parameter.\n \n index_file_dict = {}\n set_vault_id_inputs = set(file_detonation_param_list)\n \n for vault_id_input in set_vault_id_inputs:\n ## crowdstrike detonation can have a multiple phase of score, verdict and category during detonation. we will try to get all the unique values of each\n ## object filed we want to include in report. \n \n file_list = []\n score_list = []\n verdict_list = []\n category_list = []\n \n ## getting the index of each detonation phase of the url/file. group the result for each detonation\n vault_id_input_index = [indx for indx, vault_id_val in enumerate(file_detonation_param_list) if vault_id_val == vault_id_input]\n index_file_dict[vault_id_input] = vault_id_input_index\n phantom.debug(\"vault_id: {} vault_id_list: {}\".format(vault_id_input, index_file_dict))\n \n for idx,(_vault_id, _score, _verdict, _category) in enumerate(zip(file_detonation_param_list, file_detonation_verdict_list, file_detonation_threat_score_list, file_detonation_category_list)):\n if _vault_id == vault_id_input and idx in index_file_dict[vault_id_input]:\n file_list.append(_vault_id)\n score_list.append(_score)\n verdict_list.append(_verdict)\n category_list.append(_category)\n \n # Attach final object\n normalized_linux_file_detonation_output__file_score_object.append({'score': list(set(score_list))[0], 'confidence': list(set(verdict_list))[0], 'categories': list(set(category_list))})\n normalized_linux_file_detonation_output__scores.append(list(set(score_list))[0])\n normalized_linux_file_detonation_output__categories.append(list(set(category_list)))\n normalized_linux_file_detonation_output__confidence.append(list(set(verdict_list))[0])\n phantom.debug(\"normalized_linux_file_detonation_output__file_score_object: {}\".format(normalized_linux_file_detonation_output__file_score_object))\n phantom.debug(\"normalized_linux_file_detonation_output__scores: {}\".format(normalized_linux_file_detonation_output__scores))\n phantom.debug(\"normalized_linux_file_detonation_output__categories: {}\".format(normalized_linux_file_detonation_output__categories))\n", - "warnings": {}, - "x": 680, - "y": 1046 - }, - "19": { - "data": { - "advanced": { - "customName": "format report linux file", - "customNameId": 0, - "description": "Format a summary table with the information gathered from the playbook.", - "join": [], - "note": "Format a summary table with the information gathered from the playbook." - }, - "functionId": 3, - "functionName": "format_report_linux_file", - "id": "19", - "parameters": [ - "filtered-data:linux_sandbox_filter:condition_1:linux_file_detonation:action_result.parameter.vault_id", - "normalized_linux_file_detonation_output:custom_function:scores", - "normalized_linux_file_detonation_output:custom_function:confidence", - "normalized_linux_file_detonation_output:custom_function:categories", - "filtered-data:linux_sandbox_filter:condition_1:linux_file_detonation:action_result.data.*.id" - ], - "template": "SOAR analyzed URL(s) using CrowdStrike. The table below shows a summary of the information gathered.\n\n| File hash | Score | Confidence |Categories | Report Link | Source |\n| --- | --- | --- | --- | --- |\n%%\n| `{0}` | {1} | {2} | {3} |https://falcon.crowdstrike.com/intelligence/sandbox/reports/{4} | CrowdStrike OAuth API |\n%%\n{1}\n{2}\n{3}\n{4}\n\n", - "type": "format" - }, - "errors": {}, - "id": "19", - "type": "format", - "userCode": "\n # Write your custom code here...\n #phantom.debug(phantom.format(container=container, template=template, parameters=parameters, name=\"format_report_linux_file\"))\n", - "warnings": {}, - "x": 680, - "y": 1220 + "x": 0, + "y": 1740 }, "2": { "data": { @@ -814,387 +439,15 @@ "id": "2", "type": "filter", "warnings": {}, - "x": 580, - "y": 140 - }, - "20": { - "data": { - "advanced": { - "customName": "build linux 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_linux_file_output", - "id": "20", - "inputParameters": [ - "playbook_input:vault_id", - "filtered-data:linux_sandbox_filter:condition_1:linux_file_detonation:action_result.data.*.id", - "normalized_linux_file_detonation_output:custom_function:file_score_object" - ], - "outputVariables": [ - "observable_array" - ], - "type": "code" - }, - "errors": {}, - "id": "20", - "type": "code", - "userCode": "\n # Write your custom code here...\n build_linux_file_output__observable_array = []\n for _vault_id, external_id, file_object in zip(playbook_input_vault_id_values, filtered_result_0_data___id, normalized_linux_file_detonation_output__file_score_object):\n observable_object = {\n \n \"value\": _vault_id,\n \"type\": \"hash\",\n \"sandbox\": {\n \"score\": file_object['score'],\n \"confidence\": file_object['confidence'],\n \"categories\": file_object['categories']\n },\n \"enrichment\": {\n \"provider\": \"CrowdStrike OAuth API\",\n \"type\": \"file\",\n \n },\n \"source\": \"CrowdStrike OAuth API\",\n \"source_link\":f\"https://falcon.crowdstrike.com/intelligence/sandbox/reports/{external_id}\"\n }\n build_linux_file_output__observable_array.append(observable_object)\n phantom.debug(\"build_linux_file_output__observable_array: {}\".format(build_linux_file_output__observable_array))\n\n", - "warnings": {}, - "x": 680, - "y": 1400 - }, - "21": { - "data": { - "action": "detonate file", - "actionType": "generic", - "advanced": { - "customName": "android file detonation", - "customNameId": 0, - "description": "Queries CrowdStrike for information about the provided vault_id(s)", - "join": [], - "note": "Queries CrowdStrike for information about the provided vault_id(s)" - }, - "connector": "CrowdStrike OAuth API", - "connectorConfigs": [ - "crowdstrike_url_reputation" - ], - "connectorId": "ae971ba5-3117-444a-8ac5-6ce779f3a232", - "connectorVersion": "v1", - "functionId": 3, - "functionName": "android_file_detonation", - "id": "21", - "parameters": { - "environment": "Android (static analysis)", - "is_confidential": true, - "limit": 50, - "vault_id": "playbook_input:vault_id" - }, - "requiredParameters": [ - { - "data_type": "numeric", - "default": 50, - "field": "limit" - }, - { - "data_type": "string", - "field": "vault_id" - }, - { - "data_type": "string", - "field": "environment" - }, - { - "data_type": "boolean", - "default": true, - "field": "is_confidential" - } - ], - "type": "action" - }, - "errors": {}, - "id": "21", - "type": "action", - "warnings": {}, - "x": 1020, - "y": 695 - }, - "22": { - "data": { - "advanced": { - "customName": "android sandbox filter", - "customNameId": 0, - "description": "Filters successful file detonation results.", - "join": [], - "note": "Filters successful file detonation results." - }, - "conditions": [ - { - "comparisons": [ - { - "conditionIndex": 0, - "op": "==", - "param": "android_file_detonation:action_result.status", - "value": "success" - } - ], - "conditionIndex": 0, - "customName": "android_sandbox_status_filter", - "logic": "and" - } - ], - "functionId": 5, - "functionName": "android_sandbox_filter", - "id": "22", - "type": "filter" - }, - "errors": {}, - "id": "22", - "type": "filter", - "warnings": {}, - "x": 1080, - "y": 860 - }, - "23": { - "data": { - "advanced": { - "customName": "normalized android file detonation 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": 8, - "functionName": "normalized_android_file_detonation_output", - "id": "23", - "inputParameters": [ - "filtered-data:android_sandbox_filter:condition_1:android_file_detonation:action_result.parameter.vault_id", - "filtered-data:android_sandbox_filter:condition_1:android_file_detonation:action_result.data.*.verdict", - "filtered-data:android_sandbox_filter:condition_1:android_file_detonation:action_result.data.*.sandbox.*.threat_score", - "filtered-data:android_sandbox_filter:condition_1:android_file_detonation:action_result.data.*.sandbox.*.signatures.*.category", - "filtered-data:android_sandbox_filter:condition_1:android_file_detonation:action_result.data.*.sandbox.*.verdict" - ], - "outputVariables": [ - "file_score_object", - "scores", - "categories", - "confidence" - ], - "type": "code" - }, - "errors": {}, - "id": "23", - "type": "code", - "userCode": "\n # Write your custom code here...\n normalized_android_file_detonation_output__file_score_object = []\n normalized_android_file_detonation_output__scores = []\n normalized_android_file_detonation_output__categories = []\n normalized_android_file_detonation_output__confidence = []\n \n ## normalized NoneType value to avoid enumeration failure\n file_detonation_param_list = [(i or \"\") for i in filtered_result_0_parameter_vault_id] \n file_detonation_threat_score_list = [(i or \"\") for i in filtered_result_0_data___sandbox___threat_score] \n file_detonation_category_list = [(i or \"\") for i in filtered_result_0_data___sandbox___signatures___category] \n file_detonation_verdict_list = [(i or \"\") for i in filtered_result_0_data___sandbox___verdict] \n \n ## get the set() or unique input vault id parameter.\n \n index_file_dict = {}\n set_vault_id_inputs = set(file_detonation_param_list)\n \n for vault_id_input in set_vault_id_inputs:\n ## crowdstrike detonation can have a multiple phase of score, verdict and category during detonation. we will try to get all the unique values of each\n ## object filed we want to include in report. \n \n file_list = []\n score_list = []\n verdict_list = []\n category_list = []\n \n ## getting the index of each detonation phase of the url/file. group the result for each detonation\n vault_id_input_index = [indx for indx, vault_id_val in enumerate(file_detonation_param_list) if vault_id_val == vault_id_input]\n index_file_dict[vault_id_input] = vault_id_input_index\n phantom.debug(\"vault_id: {} vault_id_list: {}\".format(vault_id_input, index_file_dict))\n \n for idx,(_vault_id, _score, _verdict, _category) in enumerate(zip(file_detonation_param_list, file_detonation_verdict_list, file_detonation_threat_score_list, file_detonation_category_list)):\n if _vault_id == vault_id_input and idx in index_file_dict[vault_id_input]:\n file_list.append(_vault_id)\n score_list.append(_score)\n verdict_list.append(_verdict)\n category_list.append(_category)\n \n # Attach final object\n normalized_android_file_detonation_output__file_score_object.append({'score': list(set(score_list))[0], 'confidence': list(set(verdict_list))[0], 'categories': list(set(category_list))})\n normalized_android_file_detonation_output__scores.append(list(set(score_list))[0])\n normalized_android_file_detonation_output__categories.append(list(set(category_list)))\n normalized_android_file_detonation_output__confidence.append(list(set(verdict_list))[0])\n phantom.debug(\"normalized_android_file_detonation_output__file_score_object: {}\".format(normalized_android_file_detonation_output__file_score_object))\n phantom.debug(\"normalized_android_file_detonation_output__scores: {}\".format(normalized_android_file_detonation_output__scores))\n phantom.debug(\"normalized_android_file_detonation_output__categories: {}\".format(normalized_android_file_detonation_output__categories))\n", - "warnings": {}, - "x": 1020, - "y": 1040 - }, - "24": { - "data": { - "advanced": { - "customName": "format report android file", - "customNameId": 0, - "description": "Format a summary table with the information gathered from the playbook.", - "join": [], - "note": "Format a summary table with the information gathered from the playbook." - }, - "functionId": 4, - "functionName": "format_report_android_file", - "id": "24", - "parameters": [ - "filtered-data:android_sandbox_filter:condition_1:android_file_detonation:action_result.parameter.vault_id", - "normalized_android_file_detonation_output:custom_function:scores", - "normalized_android_file_detonation_output:custom_function:confidence", - "normalized_android_file_detonation_output:custom_function:categories", - "filtered-data:android_sandbox_filter:condition_1:android_file_detonation:action_result.data.*.id" - ], - "template": "SOAR analyzed URL(s) using CrowdStrike. The table below shows a summary of the information gathered.\n\n| File hash | Score | Confidence |Categories | Report Link | Source |\n| --- | --- | --- | --- | --- |\n%%\n| `{0}` | {1} | {2} | {3} |https://falcon.crowdstrike.com/intelligence/sandbox/reports/{4} | CrowdStrike OAuth API |\n%%\n{1}\n{2}\n{3}\n{4}\n\n\n", - "type": "format" - }, - "errors": {}, - "id": "24", - "type": "format", - "userCode": "\n # Write your custom code here...\n #phantom.debug(phantom.format(container=container, template=template, parameters=parameters, name=\"format_report_android_file\"))\n", - "warnings": {}, - "x": 1020, - "y": 1217 - }, - "25": { - "data": { - "advanced": { - "customName": "build android 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": 9, - "functionName": "build_android_file_output", - "id": "25", - "inputParameters": [ - "playbook_input:vault_id", - "filtered-data:android_sandbox_filter:condition_1:android_file_detonation:action_result.data.*.id", - "normalized_android_file_detonation_output:custom_function:file_score_object" - ], - "outputVariables": [ - "observable_array" - ], - "type": "code" - }, - "errors": {}, - "id": "25", - "type": "code", - "userCode": "\n # Write your custom code here...\n build_android_file_output__observable_array = []\n for _vault_id, external_id, file_object in zip(playbook_input_vault_id_values, filtered_result_0_data___id, normalized_android_file_detonation_output__file_score_object):\n observable_object = {\n \n \"value\": _vault_id,\n \"type\": \"hash\",\n \"sandbox\": {\n \"score\": file_object['score'],\n \"confidence\": file_object['confidence'],\n \"categories\": file_object['categories']\n },\n \"enrichment\": {\n \"provider\": \"CrowdStrike OAuth API\",\n \"type\": \"file\",\n \n },\n \"source\": \"CrowdStrike OAuth API\",\n \"source_link\":f\"https://falcon.crowdstrike.com/intelligence/sandbox/reports/{external_id}\"\n }\n build_android_file_output__observable_array.append(observable_object)\n phantom.debug(\"build_android_file_output__observable_array: {}\".format(build_android_file_output__observable_array))\n", - "warnings": {}, - "x": 1020, - "y": 1380 - }, - "26": { - "data": { - "action": "detonate file", - "actionType": "generic", - "advanced": { - "customName": "mac file detonation", - "customNameId": 0, - "description": "Queries CrowdStrike for information about the provided vault_id(s)", - "join": [], - "note": "Queries CrowdStrike for information about the provided vault_id(s)" - }, - "connector": "CrowdStrike OAuth API", - "connectorConfigs": [ - "crowdstrike_url_reputation" - ], - "connectorId": "ae971ba5-3117-444a-8ac5-6ce779f3a232", - "connectorVersion": "v1", - "functionId": 4, - "functionName": "mac_file_detonation", - "id": "26", - "parameters": { - "environment": "Linux Ubuntu 16.04, 64-bit", - "is_confidential": true, - "limit": 50, - "vault_id": "playbook_input:vault_id" - }, - "requiredParameters": [ - { - "data_type": "numeric", - "default": 50, - "field": "limit" - }, - { - "data_type": "string", - "field": "vault_id" - }, - { - "data_type": "string", - "field": "environment" - }, - { - "data_type": "boolean", - "default": true, - "field": "is_confidential" - } - ], - "type": "action" - }, - "errors": {}, - "id": "26", - "type": "action", - "warnings": {}, - "x": 1360, - "y": 700 - }, - "27": { - "data": { - "advanced": { - "customName": "mac sandbox filter", - "customNameId": 0, - "description": "Filters successful file detonation results.", - "join": [], - "note": "Filters successful file detonation results." - }, - "conditions": [ - { - "comparisons": [ - { - "conditionIndex": 0, - "op": "==", - "param": "mac_file_detonation:action_result.status", - "value": "success" - } - ], - "conditionIndex": 0, - "customName": "mac_sandbox_status_filter", - "logic": "and" - } - ], - "functionId": 7, - "functionName": "mac_sandbox_filter", - "id": "27", - "type": "filter" - }, - "errors": {}, - "id": "27", - "type": "filter", - "warnings": {}, - "x": 1420, - "y": 866 - }, - "28": { - "data": { - "advanced": { - "customName": "normalized mac file detonation 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": 10, - "functionName": "normalized_mac_file_detonation_output", - "id": "28", - "inputParameters": [ - "filtered-data:mac_sandbox_filter:condition_1:mac_file_detonation:action_result.parameter.vault_id", - "filtered-data:mac_sandbox_filter:condition_1:mac_file_detonation:action_result.data.*.verdict", - "filtered-data:mac_sandbox_filter:condition_1:mac_file_detonation:action_result.data.*.sandbox.*.threat_score", - "filtered-data:mac_sandbox_filter:condition_1:mac_file_detonation:action_result.data.*.sandbox.*.signatures.*.category", - "filtered-data:mac_sandbox_filter:condition_1:mac_file_detonation:action_result.data.*.sandbox.*.verdict" - ], - "outputVariables": [ - "url_score_object", - "scores", - "categories", - "confidence" - ], - "type": "code" - }, - "errors": {}, - "id": "28", - "type": "code", - "userCode": "\n # Write your custom code here...\n\n normalized_mac_file_detonation_output__url_score_object = []\n normalized_mac_file_detonation_output__scores = []\n normalized_mac_file_detonation_output__categories = []\n normalized_mac_file_detonation_output__confidence = []\n \n ## normalized NoneType value to avoid enumeration failure\n file_detonation_param_list = [(i or \"\") for i in filtered_result_0_parameter_vault_id] \n file_detonation_threat_score_list = [(i or \"\") for i in filtered_result_0_data___sandbox___threat_score] \n file_detonation_category_list = [(i or \"\") for i in filtered_result_0_data___sandbox___signatures___category] \n file_detonation_verdict_list = [(i or \"\") for i in filtered_result_0_data___sandbox___verdict] \n \n ## get the set() or unique input vault id parameter.\n \n index_file_dict = {}\n set_vault_id_inputs = set(file_detonation_param_list)\n \n for vault_id_input in set_vault_id_inputs:\n ## crowdstrike detonation can have a multiple phase of score, verdict and category during detonation. we will try to get all the unique values of each\n ## object filed we want to include in report. \n \n file_list = []\n score_list = []\n verdict_list = []\n category_list = []\n \n ## getting the index of each detonation phase of the url/file. group the result for each detonation\n vault_id_input_index = [indx for indx, vault_id_val in enumerate(file_detonation_param_list) if vault_id_val == vault_id_input]\n index_file_dict[vault_id_input] = vault_id_input_index\n phantom.debug(\"vault_id: {} vault_id_list: {}\".format(vault_id_input, index_file_dict))\n \n for idx,(_vault_id, _score, _verdict, _category) in enumerate(zip(file_detonation_param_list, file_detonation_verdict_list, file_detonation_threat_score_list, file_detonation_category_list)):\n if _vault_id == vault_id_input and idx in index_file_dict[vault_id_input]:\n file_list.append(_vault_id)\n score_list.append(_score)\n verdict_list.append(_verdict)\n category_list.append(_category)\n \n # Attach final object\n normalized_mac_file_detonation_output__url_score_object.append({'score': list(set(score_list))[0], 'confidence': list(set(verdict_list))[0], 'categories': list(set(category_list))})\n normalized_mac_file_detonation_output__scores.append(list(set(score_list))[0])\n normalized_mac_file_detonation_output__categories.append(list(set(category_list)))\n normalized_mac_file_detonation_output__confidence.append(list(set(verdict_list))[0])\n phantom.debug(\"normalized_mac_file_detonation_output__url_score_object: {}\".format(normalized_mac_file_detonation_output__url_score_object))\n phantom.debug(\"normalized_mac_file_detonation_output__scores: {}\".format(normalized_mac_file_detonation_output__scores))\n phantom.debug(\"normalized_mac_file_detonation_output__categories: {}\".format(normalized_mac_file_detonation_output__categories))\n", - "warnings": {}, - "x": 1380, - "y": 1040 - }, - "29": { - "data": { - "advanced": { - "customName": "format report mac file", - "customNameId": 0, - "description": "Format a summary table with the information gathered from the playbook.", - "join": [], - "note": "Format a summary table with the information gathered from the playbook." - }, - "functionId": 5, - "functionName": "format_report_mac_file", - "id": "29", - "parameters": [ - "filtered-data:mac_sandbox_filter:condition_1:mac_file_detonation:action_result.parameter.vault_id", - "normalized_mac_file_detonation_output:custom_function:scores", - "normalized_mac_file_detonation_output:custom_function:confidence", - "normalized_mac_file_detonation_output:custom_function:categories", - "filtered-data:mac_sandbox_filter:condition_1:mac_file_detonation:action_result.data.*.id" - ], - "template": "SOAR analyzed URL(s) using CrowdStrike. The table below shows a summary of the information gathered.\n\n| File hash | Score | Confidence |Categories | Report Link | Source |\n| --- | --- | --- | --- | --- |\n%%\n| `{0}` | {1} | {2} | {3} |https://falcon.crowdstrike.com/intelligence/sandbox/reports/{4} | CrowdStrike OAuth API |\n%%\n{1}\n{2}\n{3}\n{4}\n\n{1}\n{2}\n{3}\n{4}\n", - "type": "format" - }, - "errors": {}, - "id": "29", - "type": "format", - "userCode": "\n # Write your custom code here...\n #phantom.debug(phantom.format(container=container, template=template, parameters=parameters, name=\"format_report_mac_file\"))\n", - "warnings": {}, - "x": 1360, - "y": 1220 + "x": 290, + "y": 148 }, "3": { "data": { "action": "detonate url", "actionType": "generic", "advanced": { - "customName": "crowdstrike url detonation", + "customName": "url detonation", "customNameId": 0, "description": "Queries CrowdStrike for information about the provided URL(s)", "join": [], @@ -1202,12 +455,12 @@ }, "connector": "CrowdStrike OAuth API", "connectorConfigs": [ - "crowdstrike_url_reputation" + "crowdstrike" ], "connectorId": "ae971ba5-3117-444a-8ac5-6ce779f3a232", "connectorVersion": "v1", "functionId": 1, - "functionName": "crowdstrike_url_detonation", + "functionName": "url_detonation", "id": "3", "parameters": { "environment": "Windows 7, 64-bit", @@ -1234,39 +487,109 @@ "errors": {}, "id": "3", "type": "action", - "warnings": {}, - "x": 0, - "y": 680 + "warnings": { + "config": [ + "Reconfigure invalid datapath." + ] + }, + "x": 460, + "y": 1000 }, - "30": { + "32": { "data": { "advanced": { - "customName": "build mac file output", + "customName": "list demux", "customNameId": 0, - "description": "This block uses custom code to generate an observable dictionary to output into the observables data path.", + "description": "A utility to create a dictionary contains the vault id and sandbox name type that will be used to distinguish sandboxes to be executed depending on the basic file type checking of vault id.", "join": [], - "note": "This block uses custom code to generate an observable dictionary to output into the observables data path." + "note": "A utility to create a dictionary contains the vault id and sandbox name type that will be used to distinguish sandboxes to be executed depending on the basic file type checking of vault id." }, - "functionId": 11, - "functionName": "build_mac_file_output", - "id": "30", - "inputParameters": [ - "playbook_input:vault_id", - "filtered-data:mac_sandbox_filter:condition_1:mac_file_detonation:action_result.data.*.id", - "normalized_mac_file_detonation_output:custom_function:url_score_object" - ], - "outputVariables": [ - "observable_array" - ], - "type": "code" + "customFunction": { + "draftMode": false, + "name": "list_demux", + "repoName": "community" + }, + "functionId": 1, + "functionName": "list_demux", + "id": "32", + "selectMore": false, + "type": "utility", + "utilities": { + "list_demux": { + "description": "Accepts a single list and converts it into multiple custom function output results. All output will be placed in the \"output\" datapath. Sub-items and sub-item variable names are dependent on the input.", + "fields": [ + { + "dataTypes": [ + "*" + ], + "description": "A list of objects. Nested lists are not unpacked.", + "inputType": "item", + "label": "input_list", + "name": "input_list", + "placeholder": "[\"list_item_1\", \"list_item_2\", \"list_item_3\"]", + "renderType": "datapath", + "required": false + } + ], + "label": "list_demux", + "name": "list_demux" + } + }, + "utilityType": "custom_function", + "values": { + "list_demux": { + "input_list": "get_vault_id_information:custom_function:sandbox_type" + } + } }, "errors": {}, - "id": "30", - "type": "code", - "userCode": "\n # Write your custom code here...\n build_mac_file_output__observable_array = []\n for _vault_id, external_id, file_object in zip(playbook_input_vault_id_values, filtered_result_0_data___id, normalized_mac_file_detonation_output__url_score_object):\n observable_object = {\n \n \"value\": _vault_id,\n \"type\": \"hash\",\n \"sandbox\": {\n \"score\": file_object['score'],\n \"confidence\": file_object['confidence'],\n \"categories\": file_object['categories']\n },\n \"enrichment\": {\n \"provider\": \"CrowdStrike OAuth API\",\n \"type\": \"file\",\n \n },\n \"source\": \"CrowdStrike OAuth API\",\n \"source_link\":f\"https://falcon.crowdstrike.com/intelligence/sandbox/reports/{external_id}\"\n }\n build_mac_file_output__observable_array.append(observable_object)\n phantom.debug(\"build_mac_file_output__observable_array: {}\".format(build_mac_file_output__observable_array))\n", + "id": "32", + "type": "utility", "warnings": {}, - "x": 1360, - "y": 1396 + "x": 140, + "y": 520 + }, + "35": { + "data": { + "advanced": { + "customName": "list demux filter", + "customNameId": 0, + "description": "filter check if list demux output exist.", + "join": [], + "note": "filter check if list demux output exist." + }, + "conditions": [ + { + "comparisons": [ + { + "conditionIndex": 0, + "op": "==", + "param": "list_demux:custom_function_result.success", + "value": "True" + }, + { + "conditionIndex": 0, + "op": "!=", + "param": "list_demux:custom_function_result.message", + "value": "\"Timed out while waiting for the result\"" + } + ], + "conditionIndex": 0, + "customName": "sandbox_type_exist", + "logic": "and" + } + ], + "functionId": 8, + "functionName": "list_demux_filter", + "id": "35", + "type": "filter" + }, + "errors": {}, + "id": "35", + "type": "filter", + "warnings": {}, + "x": 60, + "y": 680 }, "4": { "data": { @@ -1283,7 +606,7 @@ { "conditionIndex": 0, "op": "==", - "param": "crowdstrike_url_detonation:action_result.status", + "param": "url_detonation:action_result.status", "value": "success" } ], @@ -1301,8 +624,8 @@ "id": "4", "type": "filter", "warnings": {}, - "x": 60, - "y": 860 + "x": 520, + "y": 1192 }, "5": { "customCode": null, @@ -1328,17 +651,17 @@ "url_score_object", "scores", "categories", - "confidence" + "score_id" ], "type": "code" }, "errors": {}, "id": "5", "type": "code", - "userCode": "\n # Write your custom code here...\n #phantom.debug(\"filtered_result_0_parameter_url: {}\".format(filtered_result_0_parameter_url))\n #phantom.debug(\"filtered_result_0_data: {}\".format(filtered_result_0_data)) \n #phantom.debug(\"filtered_result_0_data___verdict: {}\".format(filtered_result_0_data___verdict))\n #phantom.debug(\"filtered_result_0_data___sandbox___threat_score: {}\".format(filtered_result_0_data___sandbox___threat_score))\n #phantom.debug(\"filtered_result_0_data___sandbox___signatures___category: {}\".format(filtered_result_0_data___sandbox___signatures___category))\n #phantom.debug(\"filtered_result_0_summary_verdict: {}\".format(filtered_result_0_summary_verdict))\n #phantom.debug(\"filtered_result_0_data___sandbox___verdict: {}\".format(filtered_result_0_data___sandbox___verdict))\n #phantom.debug(\"crowdstrike_url_detonation_result_data: {}\".format(crowdstrike_url_detonation_result_data)) \n \n ## define variables for easy code debugging\n \n normalized_url_detonation_output__url_score_object = []\n normalized_url_detonation_output__scores = []\n normalized_url_detonation_output__categories = []\n normalized_url_detonation_output__confidence = []\n \n url_detonation_param_list = [(i or \"\") for i in filtered_result_0_parameter_url] \n url_detonation_verdict_list = [(i or \"\") for i in filtered_result_0_data___sandbox___verdict] \n url_detonation_threat_score_list = [(i or \"\") for i in filtered_result_0_data___sandbox___threat_score] \n url_detonation_category_list = [(i or \"\") for i in filtered_result_0_data___sandbox___signatures___category] \n \n ## get the set() or unique input url parameter.\n \n index_url_dict = {}\n set_url_inputs = set(url_detonation_param_list)\n \n \n for url_input in set_url_inputs:\n url_list = []\n score_list = []\n verdict_list = []\n category_list = []\n \n ## getting the index of each detonation phase of the url group the result for each url detonation\n url_input_index = [indx for indx, url_val in enumerate(url_detonation_param_list) if url_val == url_input]\n index_url_dict[url_input] = url_input_index\n \n for idx,(_url, _score, _verdict, _category) in enumerate(zip(url_detonation_param_list, url_detonation_verdict_list, url_detonation_threat_score_list, url_detonation_category_list)):\n if _url == url_input and idx in index_url_dict[url_input]:\n url_list.append(_url)\n score_list.append(_score)\n verdict_list.append(_verdict)\n category_list.append(_category)\n \n # Attach final object\n normalized_url_detonation_output__url_score_object.append({'score': list(set(score_list))[0], 'confidence': list(set(verdict_list))[0], 'categories': list(set(category_list))})\n normalized_url_detonation_output__scores.append(list(set(score_list))[0])\n normalized_url_detonation_output__categories.append(list(set(category_list)))\n normalized_url_detonation_output__confidence.append(list(set(verdict_list))[0])\n phantom.debug(\"normalized_url_detonation_output__url_score_object: {}\".format(normalized_url_detonation_output__url_score_object))\n phantom.debug(\"normalized_url_detonation_output__scores: {}\".format(normalized_url_detonation_output__scores))\n phantom.debug(\"normalized_url_detonation_output__categories: {}\".format(normalized_url_detonation_output__categories))\n \n \n", + "userCode": "\n # Write your custom code here...\n #phantom.debug(\"filtered_result_0_parameter_url: {}\".format(filtered_result_0_parameter_url))\n #phantom.debug(\"filtered_result_0_data: {}\".format(filtered_result_0_data)) \n #phantom.debug(\"filtered_result_0_data___verdict: {}\".format(filtered_result_0_data___verdict))\n #phantom.debug(\"filtered_result_0_data___sandbox___threat_score: {}\".format(filtered_result_0_data___sandbox___threat_score))\n #phantom.debug(\"filtered_result_0_data___sandbox___signatures___category: {}\".format(filtered_result_0_data___sandbox___signatures___category))\n #phantom.debug(\"filtered_result_0_summary_verdict: {}\".format(filtered_result_0_summary_verdict))\n #phantom.debug(\"filtered_result_0_data___sandbox___verdict: {}\".format(filtered_result_0_data___sandbox___verdict))\n #phantom.debug(\"crowdstrike_url_detonation_result_data: {}\".format(crowdstrike_url_detonation_result_data)) \n \n ## define variables for easy code debugging\n \n normalized_url_detonation_output__url_score_object = []\n normalized_url_detonation_output__scores = []\n normalized_url_detonation_output__categories = []\n normalized_url_detonation_output__score_id = []\n \n url_detonation_param_list = [(i or \"\") for i in filtered_result_0_parameter_url] \n url_detonation_verdict_list = [(i or \"\") for i in filtered_result_0_data___sandbox___verdict] \n url_detonation_threat_score_list = [(i or \"\") for i in filtered_result_0_data___sandbox___threat_score] \n url_detonation_category_list = [(i or \"\") for i in filtered_result_0_data___sandbox___signatures___category] \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 ## get the set() or unique input url parameter.\n \n index_url_dict = {}\n set_url_inputs = set(url_detonation_param_list)\n \n \n for url_input in set_url_inputs:\n url_list = []\n score_list = []\n verdict_list = []\n category_list = []\n \n ## getting the index of each detonation phase of the url group the result for each url detonation\n url_input_index = [indx for indx, url_val in enumerate(url_detonation_param_list) if url_val == url_input]\n index_url_dict[url_input] = url_input_index\n \n for idx,(_url, _score, _verdict, _category) in enumerate(zip(url_detonation_param_list, url_detonation_verdict_list, url_detonation_threat_score_list, url_detonation_category_list)):\n if _url == url_input and idx in index_url_dict[url_input]:\n url_list.append(_url)\n score_list.append(_score)\n verdict_list.append(_verdict)\n category_list.append(_category)\n \n score_id = round(list(set(verdict_list))[0] / 10)\n score = score_table[str(score_id)]\n \n # Attach final object\n normalized_url_detonation_output__url_score_object.append({'score': score, 'score_id': score_id,'confidence': list(set(score_list))[0], 'categories': list(set(category_list))})\n normalized_url_detonation_output__scores.append(score)\n normalized_url_detonation_output__categories.append(list(set(category_list)))\n normalized_url_detonation_output__score_id.append(score_id)\n #phantom.debug(\"normalized_url_detonation_output__url_score_object: {}\".format(normalized_url_detonation_output__url_score_object))\n #phantom.debug(\"normalized_url_detonation_output__scores: {}\".format(normalized_url_detonation_output__scores))\n #phantom.debug(\"normalized_url_detonation_output__categories: {}\".format(normalized_url_detonation_output__categories))\n \n \n", "warnings": {}, - "x": 0, - "y": 1040 + "x": 460, + "y": 1380 }, "6": { "data": { @@ -1355,20 +678,24 @@ "parameters": [ "playbook_input:url", "normalized_url_detonation_output:custom_function:scores", - "normalized_url_detonation_output:custom_function:confidence", + "normalized_url_detonation_output:custom_function:score_id", "normalized_url_detonation_output:custom_function:categories", - "crowdstrike_url_detonation:action_result.data.*.id" + "url_detonation:action_result.data.*.id" ], - "template": "SOAR analyzed URL(s) using Crowdstrike. The table below shows a summary of the information gathered.\n\n| URL | Score | Confidence |Categories | Report Link | Source |\n| --- | --- | --- | --- | --- |\n%%\n| `{0}` | {1} | {2} | {3} |https://falcon.crowdstrike.com/intelligence/sandbox/reports/{4} | CrowdStrike OAuth API |\n%%\n{1}\n{2}\n{3}\n{4}\n", + "template": "SOAR analyzed URL(s) or File using Crowdstrike. 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://falcon.crowdstrike.com/intelligence/sandbox/reports/{4} | CrowdStrike OAuth API |\n%%\n\n", "type": "format" }, "errors": {}, "id": "6", "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": 20, - "y": 1220 + "warnings": { + "config": [ + "Reconfigure invalid datapath." + ] + }, + "x": 460, + "y": 1560 }, "7": { "data": { @@ -1384,7 +711,7 @@ "id": "7", "inputParameters": [ "playbook_input:url", - "crowdstrike_url_detonation:action_result.data.*.id", + "url_detonation:action_result.data.*.id", "normalized_url_detonation_output:custom_function:url_score_object" ], "outputVariables": [ @@ -1395,10 +722,14 @@ "errors": {}, "id": "7", "type": "code", - "userCode": "\n # Write your custom code here...\n# Write your custom code here...\n from urllib.parse import urlparse\n build_url_output__observable_array = []\n \n # Build URL\n for url, external_id, url_object in zip(playbook_input_url_values, crowdstrike_url_detonation_result_item_0, normalized_url_detonation_output__url_score_object):\n parsed_url = urlparse(url)\n phantom.debug(\"parsed_url: {}, url_object: {}\".format(parsed_url, url_object))\n observable_object = {\n \"value\": url,\n \"type\": \"url\",\n \"sandbox\": {\n \"score\": url_object['score'],\n \"confidence\": url_object['confidence'],\n \"categories\": url_object['categories']\n },\n \"attributes\": {\n \"hostname\": parsed_url.hostname,\n \"scheme\": parsed_url.scheme\n },\n \n \"source\": \"CrowdStrike OAuth API\",\n \"source_link\": f\"https://falcon.crowdstrike.com/intelligence/sandbox/reports/{external_id}\"\n }\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": 20, - "y": 1400 + "userCode": "\n # Write your custom code here...\n# Write your custom code here...\n from urllib.parse import urlparse\n build_url_output__observable_array = []\n \n # Build URL\n for url, external_id, url_object in zip(playbook_input_url_values, url_detonation_result_item_0, normalized_url_detonation_output__url_score_object):\n parsed_url = urlparse(url)\n phantom.debug(\"parsed_url: {}, url_object: {}\".format(parsed_url, url_object))\n observable_object = {\n \"value\": url,\n \"type\": \"url\",\n \"reputation\": {\n \"score\": url_object['score'],\n \"score_id\": url_object['score_id'],\n \"confidence\": url_object['confidence'],\n \"categories\": url_object['categories']\n },\n \"attributes\": {\n \"hostname\": parsed_url.hostname,\n \"scheme\": parsed_url.scheme\n },\n \n \"source\": \"CrowdStrike OAuth API\",\n \"source_link\": f\"https://falcon.crowdstrike.com/intelligence/sandbox/reports/{external_id}\"\n }\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": { + "config": [ + "Reconfigure invalid datapath." + ] + }, + "x": 460, + "y": 1740 }, "8": { "data": { @@ -1423,13 +754,13 @@ "errors": {}, "id": "8", "type": "code", - "userCode": "\n # Write your custom code here...\n get_vault_id_information__sandbox_type = \"\"\n \n for vault_id_value in playbook_input_vault_id_values:\n success, msg, vault_info = phantom.vault_info(vault_id=vault_id_value, file_name=None, container_id=None, trace=False)\n phantom.debug(\"vault_info: {}, success: {}, msg: {}\".format(vault_info, success, msg))\n\n if success == True:\n detonation_file_name = vault_info[0]['name']\n detonation_mime_type = vault_info[0]['mime_type']\n detonation_meta_data = vault_info[0]['contains']\n \n file_name, file_ext = os.path.splitext(detonation_file_name)\n \n if file_ext == \".exe\" or file_ext == \".dll\" or file_ext == \".sys\" or \"pe file\" in detonation_meta_data or \"dosexec\" in detonation_mime_type:\n sandbox_type = \"windows\"\n \n elif file_ext == \".dmg\":\n sandbox_type = \"mac\"\n \n elif file_ext == \".apk\" and \"application/zip\" in detonation_mime_type:\n sandbox_type = \"android\"\n \n elif file_ext == \"\" and \"x-executable\" in detonation_mime_type:\n sandbox_type = \"linux\"\n \n else:\n sandbox_type = \"windows\"\n \n get_vault_id_information__sandbox_type = sandbox_type\n phantom.debug(\"vaultd_id: {} get_vault_id_information__sandbox_type: {}\".format(vault_id_value, get_vault_id_information__sandbox_type))\n\n", + "userCode": "\n # Write your custom code here...\n get_vault_id_information__sandbox_type = []\n \n for vault_id_value in playbook_input_vault_id_values:\n success, msg, vault_info = phantom.vault_info(vault_id=vault_id_value, file_name=None, container_id=None, trace=False)\n phantom.debug(\"vault_info: {}, success: {}, msg: {}\".format(vault_info, success, msg))\n\n if success == True:\n detonation_file_name = vault_info[0]['name']\n detonation_mime_type = vault_info[0]['mime_type']\n detonation_meta_data = vault_info[0]['contains']\n \n file_name, file_ext = os.path.splitext(detonation_file_name)\n \n if file_ext == \".exe\" or file_ext == \".dll\" or file_ext == \".sys\" or \"pe file\" in detonation_meta_data or \"dosexec\" in detonation_mime_type:\n #get_vault_id_information__sandbox_type.append({vault_id_value: \"Windows 10, 64-bit\"})\n get_vault_id_information__sandbox_type.append({\"value\": vault_id_value, \"sandbox_type\": \"Windows 10, 64-bit\"})\n \n elif file_ext == \".dmg\":\n #get_vault_id_information__sandbox_type.append({vault_id_value: \"Linux Ubuntu 16.04, 64-bit\"})\n get_vault_id_information__sandbox_type.append({\"value\": vault_id_value, \"sandbox_type\": \"Linux Ubuntu 16.04, 64-bit\"})\n \n elif file_ext == \".apk\" and \"application/zip\" in detonation_mime_type:\n #get_vault_id_information__sandbox_type.append({vault_id_value: \"Android (static analysis)\"})\n get_vault_id_information__sandbox_type.append({\"value\": vault_id_value, \"sandbox_type\": \"Android (static analysis)\"})\n \n elif \"x-executable\" in detonation_mime_type:\n #get_vault_id_information__sandbox_type.append({vault_id_value: \"Linux Ubuntu 16.04, 64-bit\"})\n get_vault_id_information__sandbox_type.append({\"value\": vault_id_value, \"sandbox_type\":\"Linux Ubuntu 16.04, 64-bit\"})\n \n else:\n #get_vault_id_information__sandbox_type.append({vault_id_value: \"Windows 10, 64-bit\"})\n get_vault_id_information__sandbox_type.append({\"value\": vault_id_value, \"sandbox_type\": \"Windows 10, 64-bit\"})\n \n\n phantom.debug(\"vaultd_id: {} get_vault_id_information__sandbox_type: {}\".format(vault_id_value, get_vault_id_information__sandbox_type))\n\n", "warnings": {}, - "x": 860, + "x": 140, "y": 320 } }, - "notes": "Inputs: url, file_hash\nInteractions: Crowdstrike\nActions: url detonation, , file detonation\nOutputs: report, observables" + "notes": "Inputs: url, vault_id\nInteractions: Crowdstrike\nActions: url detonation, , file detonation\nOutputs: report, observables" }, "input_spec": [ { @@ -1451,39 +782,41 @@ { "contains": [], "datapaths": [ - "build_win_file_output:custom_function:observable_array", - "build_linux_file_output:custom_function:observable_array", - "build_android_file_output:custom_function:observable_array", - "build_mac_file_output:custom_function:observable_array", + "build_file_output:custom_function:observable_array", "build_url_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_report_url:formatted_data", + "format_report_file:formatted_data" + ], + "deduplicate": false, + "description": "a report with value, score, confidence, and categories.", + "metadata": {}, + "name": "report" } ], "playbook_type": "data", "python_version": "3", - "schema": "5.0.8", - "version": "5.5.0.108488" + "schema": "5.0.9", + "version": "6.0.0.114895" }, - "create_time": "2023-03-24T14:42:42.435739+00:00", + "create_time": "2023-04-13T14:17:13.149883+00:00", "draft_mode": false, "labels": [ "*" ], "tags": [ - "file_hash", "url", - "D3-IPRA", - "domain", - "D3-FHRA", - "D3-DNRA", - "D3-URA", "sandbox", - "D3-IRA", - "ip", - "CrowdStrike_OAuth_API" + "CrowdStrike_OAuth_API", + "vault_id", + "D3-DA" ] } \ No newline at end of file diff --git a/playbooks/CrowdStrike_OAuth_API_Dynamic_Analysis.png b/playbooks/CrowdStrike_OAuth_API_Dynamic_Analysis.png index b88dfa900c..bbdd2adfa8 100644 Binary files a/playbooks/CrowdStrike_OAuth_API_Dynamic_Analysis.png and b/playbooks/CrowdStrike_OAuth_API_Dynamic_Analysis.png differ diff --git a/playbooks/CrowdStrike_OAuth_API_Dynamic_Analysis.py b/playbooks/CrowdStrike_OAuth_API_Dynamic_Analysis.py index c6cb5423ac..38ce0c0163 100644 --- a/playbooks/CrowdStrike_OAuth_API_Dynamic_Analysis.py +++ b/playbooks/CrowdStrike_OAuth_API_Dynamic_Analysis.py @@ -1,5 +1,5 @@ """ -Accepts a URL or File_Hash and does reputation 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\nRef: https://d3fend.mitre.org/technique/d3f:IdentifierReputationAnalysis/ +Accepts a URL or File_Hash and does reputation 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 """ @@ -46,7 +46,7 @@ def input_filter(action=None, success=None, container=None, results=None, handle # call connected blocks if filtered artifacts or results if matched_artifacts_1 or matched_results_1: - crowdstrike_url_detonation(action=action, success=success, container=container, results=results, handle=handle, filtered_artifacts=matched_artifacts_1, filtered_results=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( @@ -64,8 +64,8 @@ def input_filter(action=None, success=None, container=None, results=None, handle @phantom.playbook_block() -def crowdstrike_url_detonation(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): - phantom.debug("crowdstrike_url_detonation() called") +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'))) @@ -77,12 +77,12 @@ def crowdstrike_url_detonation(action=None, success=None, container=None, result parameters = [] - # build parameters list for 'crowdstrike_url_detonation' call + # build parameters list for 'url_detonation' call for playbook_input_url_item in playbook_input_url: if playbook_input_url_item[0] is not None: parameters.append({ - "url": playbook_input_url_item[0], "limit": 50, + "url": playbook_input_url_item[0], "environment": "Windows 7, 64-bit", }) @@ -96,7 +96,7 @@ def crowdstrike_url_detonation(action=None, success=None, container=None, result ## Custom Code End ################################################################################ - phantom.act("detonate url", parameters=parameters, name="crowdstrike_url_detonation", assets=["crowdstrike_url_reputation"], callback=url_detonation_filter) + phantom.act("detonate url", parameters=parameters, name="url_detonation", assets=["crowdstrike"], callback=url_detonation_filter) return @@ -113,7 +113,7 @@ def url_detonation_filter(action=None, success=None, container=None, results=Non matched_artifacts_1, matched_results_1 = phantom.condition( container=container, conditions=[ - ["crowdstrike_url_detonation:action_result.status", "==", "success"] + ["url_detonation:action_result.status", "==", "success"] ], name="url_detonation_filter:condition_1") @@ -144,7 +144,7 @@ def normalized_url_detonation_output(action=None, success=None, container=None, normalized_url_detonation_output__url_score_object = None normalized_url_detonation_output__scores = None normalized_url_detonation_output__categories = None - normalized_url_detonation_output__confidence = None + normalized_url_detonation_output__score_id = None ################################################################################ ## Custom Code Start @@ -165,13 +165,26 @@ def normalized_url_detonation_output(action=None, success=None, container=None, normalized_url_detonation_output__url_score_object = [] normalized_url_detonation_output__scores = [] normalized_url_detonation_output__categories = [] - normalized_url_detonation_output__confidence = [] + normalized_url_detonation_output__score_id = [] url_detonation_param_list = [(i or "") for i in filtered_result_0_parameter_url] url_detonation_verdict_list = [(i or "") for i in filtered_result_0_data___sandbox___verdict] url_detonation_threat_score_list = [(i or "") for i in filtered_result_0_data___sandbox___threat_score] url_detonation_category_list = [(i or "") for i in filtered_result_0_data___sandbox___signatures___category] - + + 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" + } ## get the set() or unique input url parameter. index_url_dict = {} @@ -194,12 +207,15 @@ def normalized_url_detonation_output(action=None, success=None, container=None, score_list.append(_score) verdict_list.append(_verdict) category_list.append(_category) - + + score_id = round(list(set(verdict_list))[0] / 10) + score = score_table[str(score_id)] + # Attach final object - normalized_url_detonation_output__url_score_object.append({'score': list(set(score_list))[0], 'confidence': list(set(verdict_list))[0], 'categories': list(set(category_list))}) - normalized_url_detonation_output__scores.append(list(set(score_list))[0]) + normalized_url_detonation_output__url_score_object.append({'score': score, 'score_id': score_id,'confidence': list(set(score_list))[0], 'categories': list(set(category_list))}) + normalized_url_detonation_output__scores.append(score) normalized_url_detonation_output__categories.append(list(set(category_list))) - normalized_url_detonation_output__confidence.append(list(set(verdict_list))[0]) + normalized_url_detonation_output__score_id.append(score_id) #phantom.debug("normalized_url_detonation_output__url_score_object: {}".format(normalized_url_detonation_output__url_score_object)) #phantom.debug("normalized_url_detonation_output__scores: {}".format(normalized_url_detonation_output__scores)) #phantom.debug("normalized_url_detonation_output__categories: {}".format(normalized_url_detonation_output__categories)) @@ -212,7 +228,7 @@ def normalized_url_detonation_output(action=None, success=None, container=None, phantom.save_run_data(key="normalized_url_detonation_output:url_score_object", value=json.dumps(normalized_url_detonation_output__url_score_object)) phantom.save_run_data(key="normalized_url_detonation_output:scores", value=json.dumps(normalized_url_detonation_output__scores)) phantom.save_run_data(key="normalized_url_detonation_output:categories", value=json.dumps(normalized_url_detonation_output__categories)) - phantom.save_run_data(key="normalized_url_detonation_output:confidence", value=json.dumps(normalized_url_detonation_output__confidence)) + phantom.save_run_data(key="normalized_url_detonation_output:score_id", value=json.dumps(normalized_url_detonation_output__score_id)) format_report_url(container=container) @@ -227,15 +243,15 @@ def format_report_url(action=None, success=None, container=None, results=None, h # Format a summary table with the information gathered from the playbook. ################################################################################ - template = """SOAR analyzed URL(s) using Crowdstrike. The table below shows a summary of the information gathered.\n\n| URL | Score | Confidence |Categories | Report Link | Source |\n| --- | --- | --- | --- | --- |\n%%\n| `{0}` | {1} | {2} | {3} |https://falcon.crowdstrike.com/intelligence/sandbox/reports/{4} | CrowdStrike OAuth API |\n%%\n{1}\n{2}\n{3}\n{4}\n""" + template = """SOAR analyzed URL(s) or File using Crowdstrike. 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://falcon.crowdstrike.com/intelligence/sandbox/reports/{4} | CrowdStrike OAuth API |\n%%\n\n""" # parameter list for template variable replacement parameters = [ "playbook_input:url", "normalized_url_detonation_output:custom_function:scores", - "normalized_url_detonation_output:custom_function:confidence", + "normalized_url_detonation_output:custom_function:score_id", "normalized_url_detonation_output:custom_function:categories", - "crowdstrike_url_detonation:action_result.data.*.id" + "url_detonation:action_result.data.*.id" ] ################################################################################ @@ -265,11 +281,11 @@ def build_url_output(action=None, success=None, container=None, results=None, ha ################################################################################ playbook_input_url = phantom.collect2(container=container, datapath=["playbook_input:url"]) - crowdstrike_url_detonation_result_data = phantom.collect2(container=container, datapath=["crowdstrike_url_detonation:action_result.data.*.id"], action_results=results) + url_detonation_result_data = phantom.collect2(container=container, datapath=["url_detonation:action_result.data.*.id"], action_results=results) normalized_url_detonation_output__url_score_object = json.loads(_ if (_ := phantom.get_run_data(key="normalized_url_detonation_output:url_score_object")) != "" else "null") # pylint: disable=used-before-assignment playbook_input_url_values = [item[0] for item in playbook_input_url] - crowdstrike_url_detonation_result_item_0 = [item[0] for item in crowdstrike_url_detonation_result_data] + url_detonation_result_item_0 = [item[0] for item in url_detonation_result_data] build_url_output__observable_array = None @@ -283,14 +299,15 @@ def build_url_output(action=None, success=None, container=None, results=None, ha build_url_output__observable_array = [] # Build URL - for url, external_id, url_object in zip(playbook_input_url_values, crowdstrike_url_detonation_result_item_0, normalized_url_detonation_output__url_score_object): + for url, external_id, url_object in zip(playbook_input_url_values, url_detonation_result_item_0, normalized_url_detonation_output__url_score_object): parsed_url = urlparse(url) phantom.debug("parsed_url: {}, url_object: {}".format(parsed_url, url_object)) observable_object = { "value": url, "type": "url", - "sandbox": { + "reputation": { "score": url_object['score'], + "score_id": url_object['score_id'], "confidence": url_object['confidence'], "categories": url_object['categories'] }, @@ -341,7 +358,7 @@ def get_vault_id_information(action=None, success=None, container=None, results= ################################################################################ # Write your custom code here... - get_vault_id_information__sandbox_type = "" + get_vault_id_information__sandbox_type = [] for vault_id_value in playbook_input_vault_id_values: success, msg, vault_info = phantom.vault_info(vault_id=vault_id_value, file_name=None, container_id=None, trace=False) @@ -355,22 +372,27 @@ def get_vault_id_information(action=None, success=None, container=None, results= file_name, file_ext = os.path.splitext(detonation_file_name) if file_ext == ".exe" or file_ext == ".dll" or file_ext == ".sys" or "pe file" in detonation_meta_data or "dosexec" in detonation_mime_type: - sandbox_type = "windows" + #get_vault_id_information__sandbox_type.append({vault_id_value: "Windows 10, 64-bit"}) + get_vault_id_information__sandbox_type.append({"value": vault_id_value, "sandbox_type": "Windows 10, 64-bit"}) elif file_ext == ".dmg": - sandbox_type = "mac" + #get_vault_id_information__sandbox_type.append({vault_id_value: "Linux Ubuntu 16.04, 64-bit"}) + get_vault_id_information__sandbox_type.append({"value": vault_id_value, "sandbox_type": "Linux Ubuntu 16.04, 64-bit"}) elif file_ext == ".apk" and "application/zip" in detonation_mime_type: - sandbox_type = "android" + #get_vault_id_information__sandbox_type.append({vault_id_value: "Android (static analysis)"}) + get_vault_id_information__sandbox_type.append({"value": vault_id_value, "sandbox_type": "Android (static analysis)"}) - elif file_ext == "" and "x-executable" in detonation_mime_type: - sandbox_type = "linux" + elif "x-executable" in detonation_mime_type: + #get_vault_id_information__sandbox_type.append({vault_id_value: "Linux Ubuntu 16.04, 64-bit"}) + get_vault_id_information__sandbox_type.append({"value": vault_id_value, "sandbox_type":"Linux Ubuntu 16.04, 64-bit"}) else: - sandbox_type = "windows" + #get_vault_id_information__sandbox_type.append({vault_id_value: "Windows 10, 64-bit"}) + get_vault_id_information__sandbox_type.append({"value": vault_id_value, "sandbox_type": "Windows 10, 64-bit"}) - get_vault_id_information__sandbox_type = sandbox_type - phantom.debug("vaultd_id: {} get_vault_id_information__sandbox_type: {}".format(vault_id_value, get_vault_id_information__sandbox_type)) + + phantom.debug("vaultd_id: {} get_vault_id_information__sandbox_type: {}".format(vault_id_value, get_vault_id_information__sandbox_type)) ################################################################################ ## Custom Code End @@ -378,14 +400,14 @@ def get_vault_id_information(action=None, success=None, container=None, results= phantom.save_run_data(key="get_vault_id_information:sandbox_type", value=json.dumps(get_vault_id_information__sandbox_type)) - decision_1(container=container) + list_demux(container=container) return @phantom.playbook_block() -def windows_file_detonation(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): - phantom.debug("windows_file_detonation() called") +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'))) @@ -393,19 +415,18 @@ def windows_file_detonation(action=None, success=None, container=None, results=N # Queries CrowdStrike for information about the provided vault_id(s) ################################################################################ - playbook_input_vault_id = phantom.collect2(container=container, datapath=["playbook_input:vault_id"]) + list_demux__result = phantom.collect2(container=container, datapath=["list_demux:custom_function_result.data.output.value","list_demux:custom_function_result.data.output.sandbox_type"]) parameters = [] - # build parameters list for 'windows_file_detonation' call - for playbook_input_vault_id_item in playbook_input_vault_id: - if playbook_input_vault_id_item[0] is not None: + # build parameters list for 'file_detonation' call + for list_demux__result_item in list_demux__result: + if list_demux__result_item[0] is not None and list_demux__result_item[1] is not None: parameters.append({ "limit": 50, - "vault_id": playbook_input_vault_id_item[0], - "environment": "Windows 10, 64-bit", - "detail_report": True, - "is_confidential": False, + "is_confidential": True, + "vault_id": list_demux__result_item[0], + "environment": list_demux__result_item[1], }) ################################################################################ @@ -413,19 +434,18 @@ def windows_file_detonation(action=None, success=None, container=None, results=N ################################################################################ # Write your custom code here... - ################################################################################ ## Custom Code End ################################################################################ - phantom.act("detonate file", parameters=parameters, name="windows_file_detonation", assets=["crowdstrike_url_reputation"], callback=windows_sandbox_filter) + phantom.act("detonate file", parameters=parameters, name="file_detonation", assets=["crowdstrike"], callback=sandbox_filter) return @phantom.playbook_block() -def windows_sandbox_filter(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): - phantom.debug("windows_sandbox_filter() called") +def sandbox_filter(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): + phantom.debug("sandbox_filter() called") ################################################################################ # Filters successful file detonation results. @@ -435,54 +455,68 @@ def windows_sandbox_filter(action=None, success=None, container=None, results=No matched_artifacts_1, matched_results_1 = phantom.condition( container=container, conditions=[ - ["windows_file_detonation:action_result.status", "==", "success"] + ["file_detonation:action_result.status", "==", "success"] ], - name="windows_sandbox_filter:condition_1") + name="sandbox_filter:condition_1") # call connected blocks if filtered artifacts or results if matched_artifacts_1 or matched_results_1: - normalized_win_file_detonation_output(action=action, success=success, container=container, results=results, handle=handle, filtered_artifacts=matched_artifacts_1, filtered_results=matched_results_1) + normalized_file_detonation_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_win_file_detonation_output(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): - phantom.debug("normalized_win_file_detonation_output() called") +def normalized_file_detonation_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_detonation_output() called") ################################################################################ # This block uses custom code for normalizing score. Adjust the logic as desired # in the documented sections. ################################################################################ - filtered_result_0_data_windows_sandbox_filter = phantom.collect2(container=container, datapath=["filtered-data:windows_sandbox_filter:condition_1:windows_file_detonation:action_result.parameter.vault_id","filtered-data:windows_sandbox_filter:condition_1:windows_file_detonation:action_result.data.*.verdict","filtered-data:windows_sandbox_filter:condition_1:windows_file_detonation:action_result.data.*.sandbox.*.threat_score","filtered-data:windows_sandbox_filter:condition_1:windows_file_detonation:action_result.data.*.sandbox.*.signatures.*.category","filtered-data:windows_sandbox_filter:condition_1:windows_file_detonation:action_result.data.*.sandbox.*.verdict"]) + filtered_result_0_data_sandbox_filter = phantom.collect2(container=container, datapath=["filtered-data:sandbox_filter:condition_1:file_detonation:action_result.parameter.vault_id","filtered-data:sandbox_filter:condition_1:file_detonation:action_result.data.*.verdict","filtered-data:sandbox_filter:condition_1:file_detonation:action_result.data.*.sandbox.*.threat_score","filtered-data:sandbox_filter:condition_1:file_detonation:action_result.data.*.sandbox.*.signatures.*.category","filtered-data:sandbox_filter:condition_1:file_detonation:action_result.data.*.sandbox.*.verdict"]) - filtered_result_0_parameter_vault_id = [item[0] for item in filtered_result_0_data_windows_sandbox_filter] - filtered_result_0_data___verdict = [item[1] for item in filtered_result_0_data_windows_sandbox_filter] - filtered_result_0_data___sandbox___threat_score = [item[2] for item in filtered_result_0_data_windows_sandbox_filter] - filtered_result_0_data___sandbox___signatures___category = [item[3] for item in filtered_result_0_data_windows_sandbox_filter] - filtered_result_0_data___sandbox___verdict = [item[4] for item in filtered_result_0_data_windows_sandbox_filter] + filtered_result_0_parameter_vault_id = [item[0] for item in filtered_result_0_data_sandbox_filter] + filtered_result_0_data___verdict = [item[1] for item in filtered_result_0_data_sandbox_filter] + filtered_result_0_data___sandbox___threat_score = [item[2] for item in filtered_result_0_data_sandbox_filter] + filtered_result_0_data___sandbox___signatures___category = [item[3] for item in filtered_result_0_data_sandbox_filter] + filtered_result_0_data___sandbox___verdict = [item[4] for item in filtered_result_0_data_sandbox_filter] - normalized_win_file_detonation_output__file_score_object = None - normalized_win_file_detonation_output__scores = None - normalized_win_file_detonation_output__categories = None - normalized_win_file_detonation_output__confidence = None + normalized_file_detonation_output__file_score_object = None + normalized_file_detonation_output__scores = None + normalized_file_detonation_output__categories = None + normalized_file_detonation_output__score_id = None ################################################################################ ## Custom Code Start ################################################################################ # Write your custom code here... - normalized_win_file_detonation_output__file_score_object = [] - normalized_win_file_detonation_output__scores = [] - normalized_win_file_detonation_output__categories = [] - normalized_win_file_detonation_output__confidence = [] + normalized_file_detonation_output__file_score_object = [] + normalized_file_detonation_output__scores = [] + normalized_file_detonation_output__categories = [] + normalized_file_detonation_output__score_id = [] ## normalized NoneType value to avoid enumeration failure file_detonation_param_list = [(i or "") for i in filtered_result_0_parameter_vault_id] file_detonation_threat_score_list = [(i or "") for i in filtered_result_0_data___sandbox___threat_score] file_detonation_category_list = [(i or "") for i in filtered_result_0_data___sandbox___signatures___category] file_detonation_verdict_list = [(i or "") for i in filtered_result_0_data___sandbox___verdict] + 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" + } + ## get the set() or unique input vault id parameter. index_file_dict = {} @@ -500,7 +534,7 @@ def normalized_win_file_detonation_output(action=None, success=None, container=N ## getting the index of each detonation phase of the url/file. group the result for each detonation vault_id_input_index = [indx for indx, vault_id_val in enumerate(file_detonation_param_list) if vault_id_val == vault_id_input] index_file_dict[vault_id_input] = vault_id_input_index - phantom.debug("vault_id: {} vault_id_list: {}".format(vault_id_input, index_file_dict)) + #phantom.debug("vault_id: {} vault_id_list: {}".format(vault_id_input, index_file_dict)) for idx,(_vault_id, _score, _verdict, _category) in enumerate(zip(file_detonation_param_list, file_detonation_verdict_list, file_detonation_threat_score_list, file_detonation_category_list)): if _vault_id == vault_id_input and idx in index_file_dict[vault_id_input]: @@ -508,105 +542,48 @@ def normalized_win_file_detonation_output(action=None, success=None, container=N score_list.append(_score) verdict_list.append(_verdict) category_list.append(_category) - + # Attach final object - normalized_win_file_detonation_output__file_score_object.append({'score': list(set(score_list))[0], 'confidence': list(set(verdict_list))[0], 'categories': list(set(category_list))}) - normalized_win_file_detonation_output__scores.append(list(set(score_list))[0]) - normalized_win_file_detonation_output__categories.append(list(set(category_list))) - normalized_win_file_detonation_output__confidence.append(list(set(verdict_list))[0]) - #phantom.debug("normalized_win_file_detonation_output__file_score_object: {}".format(normalized_win_file_detonation_output__file_score_object)) - #phantom.debug("normalized_win_file_detonation_output__scores: {}".format(normalized_win_file_detonation_output__scores)) - #phantom.debug("normalized_win_file_detonation_output__categories: {}".format(normalized_win_file_detonation_output__categories)) + score_id = round(list(set(verdict_list))[0] / 10) + score = score_table[str(score_id)] + + normalized_file_detonation_output__file_score_object.append({'score': score, 'score_id': score_id,'confidence': list(set(score_list))[0], 'categories': list(set(category_list))}) + normalized_file_detonation_output__scores.append(score) + normalized_file_detonation_output__categories.append(list(set(category_list))) + normalized_file_detonation_output__score_id.append(score_id) + #phantom.debug("normalized_file_detonation_output__file_score_object: {}".format(normalized_file_detonation_output__file_score_object)) + #phantom.debug("normalized_file_detonation_output__scores: {}".format(normalized_file_detonation_output__scores)) + #phantom.debug("normalized_file_detonation_output__categories: {}".format(normalized_file_detonation_output__categories)) ################################################################################ ## Custom Code End ################################################################################ - phantom.save_run_data(key="normalized_win_file_detonation_output:file_score_object", value=json.dumps(normalized_win_file_detonation_output__file_score_object)) - phantom.save_run_data(key="normalized_win_file_detonation_output:scores", value=json.dumps(normalized_win_file_detonation_output__scores)) - phantom.save_run_data(key="normalized_win_file_detonation_output:categories", value=json.dumps(normalized_win_file_detonation_output__categories)) - phantom.save_run_data(key="normalized_win_file_detonation_output:confidence", value=json.dumps(normalized_win_file_detonation_output__confidence)) + phantom.save_run_data(key="normalized_file_detonation_output:file_score_object", value=json.dumps(normalized_file_detonation_output__file_score_object)) + phantom.save_run_data(key="normalized_file_detonation_output:scores", value=json.dumps(normalized_file_detonation_output__scores)) + phantom.save_run_data(key="normalized_file_detonation_output:categories", value=json.dumps(normalized_file_detonation_output__categories)) + phantom.save_run_data(key="normalized_file_detonation_output:score_id", value=json.dumps(normalized_file_detonation_output__score_id)) - format_report_win_file(container=container) + format_report_file(container=container) return @phantom.playbook_block() -def decision_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): - phantom.debug("decision_1() called") - - ################################################################################ - # Determine branches based on file metadata like available file type, mime-type - # or file extensions. - ################################################################################ - - # check for 'if' condition 1 - found_match_1 = phantom.decision( - container=container, - conditions=[ - ["get_vault_id_information:custom_function:sandbox_type", "==", "windows"] - ]) - - # call connected blocks if condition 1 matched - if found_match_1: - windows_file_detonation(action=action, success=success, container=container, results=results, handle=handle) - return - - # check for 'elif' condition 2 - found_match_2 = phantom.decision( - container=container, - conditions=[ - ["get_vault_id_information:custom_function:sandbox_type", "==", "linux"] - ]) - - # call connected blocks if condition 2 matched - if found_match_2: - linux_file_detonation(action=action, success=success, container=container, results=results, handle=handle) - return - - # check for 'elif' condition 3 - found_match_3 = phantom.decision( - container=container, - conditions=[ - ["get_vault_id_information:custom_function:sandbox_type", "==", "mac"] - ]) - - # call connected blocks if condition 3 matched - if found_match_3: - mac_file_detonation(action=action, success=success, container=container, results=results, handle=handle) - return - - # check for 'elif' condition 4 - found_match_4 = phantom.decision( - container=container, - conditions=[ - ["get_vault_id_information:custom_function:sandbox_type", "==", "android"] - ]) - - # call connected blocks if condition 4 matched - if found_match_4: - android_file_detonation(action=action, success=success, container=container, results=results, handle=handle) - return - - return - - -@phantom.playbook_block() -def format_report_win_file(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): - phantom.debug("format_report_win_file() called") +def format_report_file(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): + phantom.debug("format_report_file() called") ################################################################################ # Format a summary table with the information gathered from the playbook. ################################################################################ - template = """SOAR analyzed URL(s) using CrowdStrike. The table below shows a summary of the information gathered.\n\n| File hash | Score | Confidence |Categories | Report Link | Source |\n| --- | --- | --- | --- | --- |\n%%\n| `{0}` | {1} | {2} | {3} |https://falcon.crowdstrike.com/intelligence/sandbox/reports/{4} | CrowdStrike OAuth API |\n%%\n{1}\n{2}\n{3}\n{4}\n\n""" + template = """SOAR analyzed File(s) using CrowdStrike. The table below shows a summary of the information gathered.\n\n| vault_id | Normalized Score | score id |Categories | Report Link | Source |\n| --- | --- | --- | --- | --- | --- |\n%%\n| `{0}` | {1} | {2} | {3} |https://falcon.crowdstrike.com/intelligence/sandbox/reports/{4} | CrowdStrike OAuth API |\n%%\n\n\n""" # parameter list for template variable replacement parameters = [ - "filtered-data:windows_sandbox_filter:condition_1:windows_file_detonation:action_result.parameter.vault_id", - "normalized_win_file_detonation_output:custom_function:scores", - "normalized_win_file_detonation_output:custom_function:confidence", - "normalized_win_file_detonation_output:custom_function:categories", + "filtered-data:sandbox_filter:condition_1:file_detonation:action_result.parameter.vault_id", + "normalized_file_detonation_output:custom_function:scores", + "normalized_file_detonation_output:custom_function:score_id", + "normalized_file_detonation_output:custom_function:categories", "filtered-data:windows_sandbox_filter:condition_1:windows_file_detonation:action_result.data.*.id" ] @@ -620,16 +597,16 @@ def format_report_win_file(action=None, success=None, container=None, results=No ## Custom Code End ################################################################################ - phantom.format(container=container, template=template, parameters=parameters, name="format_report_win_file") + phantom.format(container=container, template=template, parameters=parameters, name="format_report_file") - build_win_file_output(container=container) + build_file_output(container=container) return @phantom.playbook_block() -def build_win_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_win_file_output() called") +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 @@ -637,27 +614,28 @@ def build_win_file_output(action=None, success=None, container=None, results=Non ################################################################################ playbook_input_vault_id = phantom.collect2(container=container, datapath=["playbook_input:vault_id"]) - filtered_result_0_data_windows_sandbox_filter = phantom.collect2(container=container, datapath=["filtered-data:windows_sandbox_filter:condition_1:windows_file_detonation:action_result.data.*.id"]) - normalized_win_file_detonation_output__file_score_object = json.loads(_ if (_ := phantom.get_run_data(key="normalized_win_file_detonation_output:file_score_object")) != "" else "null") # pylint: disable=used-before-assignment + filtered_result_0_data_sandbox_filter = phantom.collect2(container=container, datapath=["filtered-data:sandbox_filter:condition_1:file_detonation:action_result.data.*.id"]) + normalized_file_detonation_output__file_score_object = json.loads(_ if (_ := phantom.get_run_data(key="normalized_file_detonation_output:file_score_object")) != "" else "null") # pylint: disable=used-before-assignment playbook_input_vault_id_values = [item[0] for item in playbook_input_vault_id] - filtered_result_0_data___id = [item[0] for item in filtered_result_0_data_windows_sandbox_filter] + filtered_result_0_data___id = [item[0] for item in filtered_result_0_data_sandbox_filter] - build_win_file_output__observable_array = None + build_file_output__observable_array = None ################################################################################ ## Custom Code Start ################################################################################ # Write your custom code here... - build_win_file_output__observable_array = [] - for _vault_id, external_id, file_object in zip(playbook_input_vault_id_values, filtered_result_0_data___id, normalized_win_file_detonation_output__file_score_object): + build_file_output__observable_array = [] + for _vault_id, external_id, file_object in zip(playbook_input_vault_id_values, filtered_result_0_data___id, normalized_file_detonation_output__file_score_object): observable_object = { "value": _vault_id, "type": "hash", - "sandbox": { + "reputation": { "score": file_object['score'], + "score_id": file_object['score_id'], "confidence": file_object['confidence'], "categories": file_object['categories'] }, @@ -669,40 +647,34 @@ def build_win_file_output(action=None, success=None, container=None, results=Non "source": "CrowdStrike OAuth API", "source_link":f"https://falcon.crowdstrike.com/intelligence/sandbox/reports/{external_id}" } - build_win_file_output__observable_array.append(observable_object) - #phantom.debug("build_win_file_output__observable_array: {}".format(build_win_file_output__observable_array)) + 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_win_file_output:observable_array", value=json.dumps(build_win_file_output__observable_array)) + phantom.save_run_data(key="build_file_output:observable_array", value=json.dumps(build_file_output__observable_array)) return @phantom.playbook_block() -def linux_file_detonation(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): - phantom.debug("linux_file_detonation() called") - - # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED'))) +def list_demux(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): + phantom.debug("list_demux() called") ################################################################################ - # Queries CrowdStrike for information about the provided vault_id(s) + # A utility to create a dictionary contains the vault id and sandbox name type + # that will be used to distinguish sandboxes to be executed depending on the basic + # file type checking of vault id. ################################################################################ - playbook_input_vault_id = phantom.collect2(container=container, datapath=["playbook_input:vault_id"]) + get_vault_id_information__sandbox_type = json.loads(_ if (_ := phantom.get_run_data(key="get_vault_id_information:sandbox_type")) != "" else "null") # pylint: disable=used-before-assignment parameters = [] - # build parameters list for 'linux_file_detonation' call - for playbook_input_vault_id_item in playbook_input_vault_id: - if playbook_input_vault_id_item[0] is not None: - parameters.append({ - "limit": 50, - "vault_id": playbook_input_vault_id_item[0], - "environment": "Linux Ubuntu 16.04, 64-bit", - "is_confidential": True, - }) + parameters.append({ + "input_list": get_vault_id_information__sandbox_type, + }) ################################################################################ ## Custom Code Start @@ -714,681 +686,32 @@ def linux_file_detonation(action=None, success=None, container=None, results=Non ## Custom Code End ################################################################################ - phantom.act("detonate file", parameters=parameters, name="linux_file_detonation", assets=["crowdstrike_url_reputation"], callback=linux_sandbox_filter) + phantom.custom_function(custom_function="community/list_demux", parameters=parameters, name="list_demux", callback=list_demux_filter) return @phantom.playbook_block() -def linux_sandbox_filter(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): - phantom.debug("linux_sandbox_filter() called") +def list_demux_filter(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): + phantom.debug("list_demux_filter() called") ################################################################################ - # Filters successful file detonation results. + # filter check if list demux output exist. ################################################################################ # collect filtered artifact ids and results for 'if' condition 1 matched_artifacts_1, matched_results_1 = phantom.condition( container=container, + logical_operator="and", conditions=[ - ["linux_file_detonation:action_result.status", "==", "success"] + ["list_demux:custom_function_result.success", "==", True], + ["list_demux:custom_function_result.message", "!=", "\"Timed out while waiting for the result\""] ], - name="linux_sandbox_filter:condition_1") + name="list_demux_filter:condition_1") # call connected blocks if filtered artifacts or results if matched_artifacts_1 or matched_results_1: - normalized_linux_file_detonation_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_linux_file_detonation_output(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): - phantom.debug("normalized_linux_file_detonation_output() called") - - ################################################################################ - # This block uses custom code for normalizing score. Adjust the logic as desired - # in the documented sections. - ################################################################################ - - filtered_result_0_data_linux_sandbox_filter = phantom.collect2(container=container, datapath=["filtered-data:linux_sandbox_filter:condition_1:linux_file_detonation:action_result.parameter.vault_id","filtered-data:linux_sandbox_filter:condition_1:linux_file_detonation:action_result.data.*.verdict","filtered-data:linux_sandbox_filter:condition_1:linux_file_detonation:action_result.data.*.sandbox.*.threat_score","filtered-data:linux_sandbox_filter:condition_1:linux_file_detonation:action_result.data.*.sandbox.*.signatures.*.category","filtered-data:linux_sandbox_filter:condition_1:linux_file_detonation:action_result.data.*.sandbox.*.verdict"]) - - filtered_result_0_parameter_vault_id = [item[0] for item in filtered_result_0_data_linux_sandbox_filter] - filtered_result_0_data___verdict = [item[1] for item in filtered_result_0_data_linux_sandbox_filter] - filtered_result_0_data___sandbox___threat_score = [item[2] for item in filtered_result_0_data_linux_sandbox_filter] - filtered_result_0_data___sandbox___signatures___category = [item[3] for item in filtered_result_0_data_linux_sandbox_filter] - filtered_result_0_data___sandbox___verdict = [item[4] for item in filtered_result_0_data_linux_sandbox_filter] - - normalized_linux_file_detonation_output__file_score_object = None - normalized_linux_file_detonation_output__scores = None - normalized_linux_file_detonation_output__categories = None - normalized_linux_file_detonation_output__confidence = None - - ################################################################################ - ## Custom Code Start - ################################################################################ - - # Write your custom code here... - normalized_linux_file_detonation_output__file_score_object = [] - normalized_linux_file_detonation_output__scores = [] - normalized_linux_file_detonation_output__categories = [] - normalized_linux_file_detonation_output__confidence = [] - - ## normalized NoneType value to avoid enumeration failure - file_detonation_param_list = [(i or "") for i in filtered_result_0_parameter_vault_id] - file_detonation_threat_score_list = [(i or "") for i in filtered_result_0_data___sandbox___threat_score] - file_detonation_category_list = [(i or "") for i in filtered_result_0_data___sandbox___signatures___category] - file_detonation_verdict_list = [(i or "") for i in filtered_result_0_data___sandbox___verdict] - - ## get the set() or unique input vault id parameter. - - index_file_dict = {} - set_vault_id_inputs = set(file_detonation_param_list) - - for vault_id_input in set_vault_id_inputs: - ## crowdstrike detonation can have a multiple phase of score, verdict and category during detonation. we will try to get all the unique values of each - ## object filed we want to include in report. - - file_list = [] - score_list = [] - verdict_list = [] - category_list = [] - - ## getting the index of each detonation phase of the url/file. group the result for each detonation - vault_id_input_index = [indx for indx, vault_id_val in enumerate(file_detonation_param_list) if vault_id_val == vault_id_input] - index_file_dict[vault_id_input] = vault_id_input_index - phantom.debug("vault_id: {} vault_id_list: {}".format(vault_id_input, index_file_dict)) - - for idx,(_vault_id, _score, _verdict, _category) in enumerate(zip(file_detonation_param_list, file_detonation_verdict_list, file_detonation_threat_score_list, file_detonation_category_list)): - if _vault_id == vault_id_input and idx in index_file_dict[vault_id_input]: - file_list.append(_vault_id) - score_list.append(_score) - verdict_list.append(_verdict) - category_list.append(_category) - - # Attach final object - normalized_linux_file_detonation_output__file_score_object.append({'score': list(set(score_list))[0], 'confidence': list(set(verdict_list))[0], 'categories': list(set(category_list))}) - normalized_linux_file_detonation_output__scores.append(list(set(score_list))[0]) - normalized_linux_file_detonation_output__categories.append(list(set(category_list))) - normalized_linux_file_detonation_output__confidence.append(list(set(verdict_list))[0]) - #phantom.debug("normalized_linux_file_detonation_output__file_score_object: {}".format(normalized_linux_file_detonation_output__file_score_object)) - #phantom.debug("normalized_linux_file_detonation_output__scores: {}".format(normalized_linux_file_detonation_output__scores)) - #phantom.debug("normalized_linux_file_detonation_output__categories: {}".format(normalized_linux_file_detonation_output__categories)) - ################################################################################ - ## Custom Code End - ################################################################################ - - phantom.save_run_data(key="normalized_linux_file_detonation_output:file_score_object", value=json.dumps(normalized_linux_file_detonation_output__file_score_object)) - phantom.save_run_data(key="normalized_linux_file_detonation_output:scores", value=json.dumps(normalized_linux_file_detonation_output__scores)) - phantom.save_run_data(key="normalized_linux_file_detonation_output:categories", value=json.dumps(normalized_linux_file_detonation_output__categories)) - phantom.save_run_data(key="normalized_linux_file_detonation_output:confidence", value=json.dumps(normalized_linux_file_detonation_output__confidence)) - - format_report_linux_file(container=container) - - return - - -@phantom.playbook_block() -def format_report_linux_file(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): - phantom.debug("format_report_linux_file() called") - - ################################################################################ - # Format a summary table with the information gathered from the playbook. - ################################################################################ - - template = """SOAR analyzed URL(s) using CrowdStrike. The table below shows a summary of the information gathered.\n\n| File hash | Score | Confidence |Categories | Report Link | Source |\n| --- | --- | --- | --- | --- |\n%%\n| `{0}` | {1} | {2} | {3} |https://falcon.crowdstrike.com/intelligence/sandbox/reports/{4} | CrowdStrike OAuth API |\n%%\n{1}\n{2}\n{3}\n{4}\n\n""" - - # parameter list for template variable replacement - parameters = [ - "filtered-data:linux_sandbox_filter:condition_1:linux_file_detonation:action_result.parameter.vault_id", - "normalized_linux_file_detonation_output:custom_function:scores", - "normalized_linux_file_detonation_output:custom_function:confidence", - "normalized_linux_file_detonation_output:custom_function:categories", - "filtered-data:linux_sandbox_filter:condition_1:linux_file_detonation:action_result.data.*.id" - ] - - ################################################################################ - ## Custom Code Start - ################################################################################ - - # Write your custom code here... - #phantom.debug(phantom.format(container=container, template=template, parameters=parameters, name="format_report_linux_file")) - ################################################################################ - ## Custom Code End - ################################################################################ - - phantom.format(container=container, template=template, parameters=parameters, name="format_report_linux_file") - - build_linux_file_output(container=container) - - return - - -@phantom.playbook_block() -def build_linux_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_linux_file_output() called") - - ################################################################################ - # This block uses custom code to generate an observable dictionary to output into - # the observables data path. - ################################################################################ - - playbook_input_vault_id = phantom.collect2(container=container, datapath=["playbook_input:vault_id"]) - filtered_result_0_data_linux_sandbox_filter = phantom.collect2(container=container, datapath=["filtered-data:linux_sandbox_filter:condition_1:linux_file_detonation:action_result.data.*.id"]) - normalized_linux_file_detonation_output__file_score_object = json.loads(_ if (_ := phantom.get_run_data(key="normalized_linux_file_detonation_output:file_score_object")) != "" else "null") # pylint: disable=used-before-assignment - - playbook_input_vault_id_values = [item[0] for item in playbook_input_vault_id] - filtered_result_0_data___id = [item[0] for item in filtered_result_0_data_linux_sandbox_filter] - - build_linux_file_output__observable_array = None - - ################################################################################ - ## Custom Code Start - ################################################################################ - - # Write your custom code here... - build_linux_file_output__observable_array = [] - for _vault_id, external_id, file_object in zip(playbook_input_vault_id_values, filtered_result_0_data___id, normalized_linux_file_detonation_output__file_score_object): - observable_object = { - - "value": _vault_id, - "type": "hash", - "sandbox": { - "score": file_object['score'], - "confidence": file_object['confidence'], - "categories": file_object['categories'] - }, - "enrichment": { - "provider": "CrowdStrike OAuth API", - "type": "file", - - }, - "source": "CrowdStrike OAuth API", - "source_link":f"https://falcon.crowdstrike.com/intelligence/sandbox/reports/{external_id}" - } - build_linux_file_output__observable_array.append(observable_object) - #phantom.debug("build_linux_file_output__observable_array: {}".format(build_linux_file_output__observable_array)) - - ################################################################################ - ## Custom Code End - ################################################################################ - - phantom.save_run_data(key="build_linux_file_output:observable_array", value=json.dumps(build_linux_file_output__observable_array)) - - return - - -@phantom.playbook_block() -def android_file_detonation(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): - phantom.debug("android_file_detonation() called") - - # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED'))) - - ################################################################################ - # Queries CrowdStrike for information about the provided vault_id(s) - ################################################################################ - - playbook_input_vault_id = phantom.collect2(container=container, datapath=["playbook_input:vault_id"]) - - parameters = [] - - # build parameters list for 'android_file_detonation' call - for playbook_input_vault_id_item in playbook_input_vault_id: - if playbook_input_vault_id_item[0] is not None: - parameters.append({ - "limit": 50, - "vault_id": playbook_input_vault_id_item[0], - "environment": "Android (static analysis)", - "is_confidential": True, - }) - - ################################################################################ - ## Custom Code Start - ################################################################################ - - # Write your custom code here... - - ################################################################################ - ## Custom Code End - ################################################################################ - - phantom.act("detonate file", parameters=parameters, name="android_file_detonation", assets=["crowdstrike_url_reputation"], callback=android_sandbox_filter) - - return - - -@phantom.playbook_block() -def android_sandbox_filter(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): - phantom.debug("android_sandbox_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=[ - ["android_file_detonation:action_result.status", "==", "success"] - ], - name="android_sandbox_filter:condition_1") - - # call connected blocks if filtered artifacts or results - if matched_artifacts_1 or matched_results_1: - normalized_android_file_detonation_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_android_file_detonation_output(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): - phantom.debug("normalized_android_file_detonation_output() called") - - ################################################################################ - # This block uses custom code for normalizing score. Adjust the logic as desired - # in the documented sections. - ################################################################################ - - filtered_result_0_data_android_sandbox_filter = phantom.collect2(container=container, datapath=["filtered-data:android_sandbox_filter:condition_1:android_file_detonation:action_result.parameter.vault_id","filtered-data:android_sandbox_filter:condition_1:android_file_detonation:action_result.data.*.verdict","filtered-data:android_sandbox_filter:condition_1:android_file_detonation:action_result.data.*.sandbox.*.threat_score","filtered-data:android_sandbox_filter:condition_1:android_file_detonation:action_result.data.*.sandbox.*.signatures.*.category","filtered-data:android_sandbox_filter:condition_1:android_file_detonation:action_result.data.*.sandbox.*.verdict"]) - - filtered_result_0_parameter_vault_id = [item[0] for item in filtered_result_0_data_android_sandbox_filter] - filtered_result_0_data___verdict = [item[1] for item in filtered_result_0_data_android_sandbox_filter] - filtered_result_0_data___sandbox___threat_score = [item[2] for item in filtered_result_0_data_android_sandbox_filter] - filtered_result_0_data___sandbox___signatures___category = [item[3] for item in filtered_result_0_data_android_sandbox_filter] - filtered_result_0_data___sandbox___verdict = [item[4] for item in filtered_result_0_data_android_sandbox_filter] - - normalized_android_file_detonation_output__file_score_object = None - normalized_android_file_detonation_output__scores = None - normalized_android_file_detonation_output__categories = None - normalized_android_file_detonation_output__confidence = None - - ################################################################################ - ## Custom Code Start - ################################################################################ - - # Write your custom code here... - normalized_android_file_detonation_output__file_score_object = [] - normalized_android_file_detonation_output__scores = [] - normalized_android_file_detonation_output__categories = [] - normalized_android_file_detonation_output__confidence = [] - - ## normalized NoneType value to avoid enumeration failure - file_detonation_param_list = [(i or "") for i in filtered_result_0_parameter_vault_id] - file_detonation_threat_score_list = [(i or "") for i in filtered_result_0_data___sandbox___threat_score] - file_detonation_category_list = [(i or "") for i in filtered_result_0_data___sandbox___signatures___category] - file_detonation_verdict_list = [(i or "") for i in filtered_result_0_data___sandbox___verdict] - - ## get the set() or unique input vault id parameter. - - index_file_dict = {} - set_vault_id_inputs = set(file_detonation_param_list) - - for vault_id_input in set_vault_id_inputs: - ## crowdstrike detonation can have a multiple phase of score, verdict and category during detonation. we will try to get all the unique values of each - ## object filed we want to include in report. - - file_list = [] - score_list = [] - verdict_list = [] - category_list = [] - - ## getting the index of each detonation phase of the url/file. group the result for each detonation - vault_id_input_index = [indx for indx, vault_id_val in enumerate(file_detonation_param_list) if vault_id_val == vault_id_input] - index_file_dict[vault_id_input] = vault_id_input_index - phantom.debug("vault_id: {} vault_id_list: {}".format(vault_id_input, index_file_dict)) - - for idx,(_vault_id, _score, _verdict, _category) in enumerate(zip(file_detonation_param_list, file_detonation_verdict_list, file_detonation_threat_score_list, file_detonation_category_list)): - if _vault_id == vault_id_input and idx in index_file_dict[vault_id_input]: - file_list.append(_vault_id) - score_list.append(_score) - verdict_list.append(_verdict) - category_list.append(_category) - - # Attach final object - normalized_android_file_detonation_output__file_score_object.append({'score': list(set(score_list))[0], 'confidence': list(set(verdict_list))[0], 'categories': list(set(category_list))}) - normalized_android_file_detonation_output__scores.append(list(set(score_list))[0]) - normalized_android_file_detonation_output__categories.append(list(set(category_list))) - normalized_android_file_detonation_output__confidence.append(list(set(verdict_list))[0]) - #phantom.debug("normalized_android_file_detonation_output__file_score_object: {}".format(normalized_android_file_detonation_output__file_score_object)) - #phantom.debug("normalized_android_file_detonation_output__scores: {}".format(normalized_android_file_detonation_output__scores)) - #phantom.debug("normalized_android_file_detonation_output__categories: {}".format(normalized_android_file_detonation_output__categories)) - ################################################################################ - ## Custom Code End - ################################################################################ - - phantom.save_run_data(key="normalized_android_file_detonation_output:file_score_object", value=json.dumps(normalized_android_file_detonation_output__file_score_object)) - phantom.save_run_data(key="normalized_android_file_detonation_output:scores", value=json.dumps(normalized_android_file_detonation_output__scores)) - phantom.save_run_data(key="normalized_android_file_detonation_output:categories", value=json.dumps(normalized_android_file_detonation_output__categories)) - phantom.save_run_data(key="normalized_android_file_detonation_output:confidence", value=json.dumps(normalized_android_file_detonation_output__confidence)) - - format_report_android_file(container=container) - - return - - -@phantom.playbook_block() -def format_report_android_file(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): - phantom.debug("format_report_android_file() called") - - ################################################################################ - # Format a summary table with the information gathered from the playbook. - ################################################################################ - - template = """SOAR analyzed URL(s) using CrowdStrike. The table below shows a summary of the information gathered.\n\n| File hash | Score | Confidence |Categories | Report Link | Source |\n| --- | --- | --- | --- | --- |\n%%\n| `{0}` | {1} | {2} | {3} |https://falcon.crowdstrike.com/intelligence/sandbox/reports/{4} | CrowdStrike OAuth API |\n%%\n{1}\n{2}\n{3}\n{4}\n\n\n""" - - # parameter list for template variable replacement - parameters = [ - "filtered-data:android_sandbox_filter:condition_1:android_file_detonation:action_result.parameter.vault_id", - "normalized_android_file_detonation_output:custom_function:scores", - "normalized_android_file_detonation_output:custom_function:confidence", - "normalized_android_file_detonation_output:custom_function:categories", - "filtered-data:android_sandbox_filter:condition_1:android_file_detonation:action_result.data.*.id" - ] - - ################################################################################ - ## Custom Code Start - ################################################################################ - - # Write your custom code here... - #phantom.debug(phantom.format(container=container, template=template, parameters=parameters, name="format_report_android_file")) - ################################################################################ - ## Custom Code End - ################################################################################ - - phantom.format(container=container, template=template, parameters=parameters, name="format_report_android_file") - - build_android_file_output(container=container) - - return - - -@phantom.playbook_block() -def build_android_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_android_file_output() called") - - ################################################################################ - # This block uses custom code to generate an observable dictionary to output into - # the observables data path. - ################################################################################ - - playbook_input_vault_id = phantom.collect2(container=container, datapath=["playbook_input:vault_id"]) - filtered_result_0_data_android_sandbox_filter = phantom.collect2(container=container, datapath=["filtered-data:android_sandbox_filter:condition_1:android_file_detonation:action_result.data.*.id"]) - normalized_android_file_detonation_output__file_score_object = json.loads(_ if (_ := phantom.get_run_data(key="normalized_android_file_detonation_output:file_score_object")) != "" else "null") # pylint: disable=used-before-assignment - - playbook_input_vault_id_values = [item[0] for item in playbook_input_vault_id] - filtered_result_0_data___id = [item[0] for item in filtered_result_0_data_android_sandbox_filter] - - build_android_file_output__observable_array = None - - ################################################################################ - ## Custom Code Start - ################################################################################ - - # Write your custom code here... - build_android_file_output__observable_array = [] - for _vault_id, external_id, file_object in zip(playbook_input_vault_id_values, filtered_result_0_data___id, normalized_android_file_detonation_output__file_score_object): - observable_object = { - - "value": _vault_id, - "type": "hash", - "sandbox": { - "score": file_object['score'], - "confidence": file_object['confidence'], - "categories": file_object['categories'] - }, - "enrichment": { - "provider": "CrowdStrike OAuth API", - "type": "file", - - }, - "source": "CrowdStrike OAuth API", - "source_link":f"https://falcon.crowdstrike.com/intelligence/sandbox/reports/{external_id}" - } - build_android_file_output__observable_array.append(observable_object) - #phantom.debug("build_android_file_output__observable_array: {}".format(build_android_file_output__observable_array)) - ################################################################################ - ## Custom Code End - ################################################################################ - - phantom.save_run_data(key="build_android_file_output:observable_array", value=json.dumps(build_android_file_output__observable_array)) - - return - - -@phantom.playbook_block() -def mac_file_detonation(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): - phantom.debug("mac_file_detonation() called") - - # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED'))) - - ################################################################################ - # Queries CrowdStrike for information about the provided vault_id(s) - ################################################################################ - - playbook_input_vault_id = phantom.collect2(container=container, datapath=["playbook_input:vault_id"]) - - parameters = [] - - # build parameters list for 'mac_file_detonation' call - for playbook_input_vault_id_item in playbook_input_vault_id: - if playbook_input_vault_id_item[0] is not None: - parameters.append({ - "limit": 50, - "vault_id": playbook_input_vault_id_item[0], - "environment": "Linux Ubuntu 16.04, 64-bit", - "is_confidential": True, - }) - - ################################################################################ - ## Custom Code Start - ################################################################################ - - # Write your custom code here... - - ################################################################################ - ## Custom Code End - ################################################################################ - - phantom.act("detonate file", parameters=parameters, name="mac_file_detonation", assets=["crowdstrike_url_reputation"], callback=mac_sandbox_filter) - - return - - -@phantom.playbook_block() -def mac_sandbox_filter(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): - phantom.debug("mac_sandbox_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=[ - ["mac_file_detonation:action_result.status", "==", "success"] - ], - name="mac_sandbox_filter:condition_1") - - # call connected blocks if filtered artifacts or results - if matched_artifacts_1 or matched_results_1: - normalized_mac_file_detonation_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_mac_file_detonation_output(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): - phantom.debug("normalized_mac_file_detonation_output() called") - - ################################################################################ - # This block uses custom code for normalizing score. Adjust the logic as desired - # in the documented sections. - ################################################################################ - - filtered_result_0_data_mac_sandbox_filter = phantom.collect2(container=container, datapath=["filtered-data:mac_sandbox_filter:condition_1:mac_file_detonation:action_result.parameter.vault_id","filtered-data:mac_sandbox_filter:condition_1:mac_file_detonation:action_result.data.*.verdict","filtered-data:mac_sandbox_filter:condition_1:mac_file_detonation:action_result.data.*.sandbox.*.threat_score","filtered-data:mac_sandbox_filter:condition_1:mac_file_detonation:action_result.data.*.sandbox.*.signatures.*.category","filtered-data:mac_sandbox_filter:condition_1:mac_file_detonation:action_result.data.*.sandbox.*.verdict"]) - - filtered_result_0_parameter_vault_id = [item[0] for item in filtered_result_0_data_mac_sandbox_filter] - filtered_result_0_data___verdict = [item[1] for item in filtered_result_0_data_mac_sandbox_filter] - filtered_result_0_data___sandbox___threat_score = [item[2] for item in filtered_result_0_data_mac_sandbox_filter] - filtered_result_0_data___sandbox___signatures___category = [item[3] for item in filtered_result_0_data_mac_sandbox_filter] - filtered_result_0_data___sandbox___verdict = [item[4] for item in filtered_result_0_data_mac_sandbox_filter] - - normalized_mac_file_detonation_output__url_score_object = None - normalized_mac_file_detonation_output__scores = None - normalized_mac_file_detonation_output__categories = None - normalized_mac_file_detonation_output__confidence = None - - ################################################################################ - ## Custom Code Start - ################################################################################ - - # Write your custom code here... - - normalized_mac_file_detonation_output__url_score_object = [] - normalized_mac_file_detonation_output__scores = [] - normalized_mac_file_detonation_output__categories = [] - normalized_mac_file_detonation_output__confidence = [] - - ## normalized NoneType value to avoid enumeration failure - file_detonation_param_list = [(i or "") for i in filtered_result_0_parameter_vault_id] - file_detonation_threat_score_list = [(i or "") for i in filtered_result_0_data___sandbox___threat_score] - file_detonation_category_list = [(i or "") for i in filtered_result_0_data___sandbox___signatures___category] - file_detonation_verdict_list = [(i or "") for i in filtered_result_0_data___sandbox___verdict] - - ## get the set() or unique input vault id parameter. - - index_file_dict = {} - set_vault_id_inputs = set(file_detonation_param_list) - - for vault_id_input in set_vault_id_inputs: - ## crowdstrike detonation can have a multiple phase of score, verdict and category during detonation. we will try to get all the unique values of each - ## object filed we want to include in report. - - file_list = [] - score_list = [] - verdict_list = [] - category_list = [] - - ## getting the index of each detonation phase of the url/file. group the result for each detonation - vault_id_input_index = [indx for indx, vault_id_val in enumerate(file_detonation_param_list) if vault_id_val == vault_id_input] - index_file_dict[vault_id_input] = vault_id_input_index - phantom.debug("vault_id: {} vault_id_list: {}".format(vault_id_input, index_file_dict)) - - for idx,(_vault_id, _score, _verdict, _category) in enumerate(zip(file_detonation_param_list, file_detonation_verdict_list, file_detonation_threat_score_list, file_detonation_category_list)): - if _vault_id == vault_id_input and idx in index_file_dict[vault_id_input]: - file_list.append(_vault_id) - score_list.append(_score) - verdict_list.append(_verdict) - category_list.append(_category) - - # Attach final object - normalized_mac_file_detonation_output__url_score_object.append({'score': list(set(score_list))[0], 'confidence': list(set(verdict_list))[0], 'categories': list(set(category_list))}) - normalized_mac_file_detonation_output__scores.append(list(set(score_list))[0]) - normalized_mac_file_detonation_output__categories.append(list(set(category_list))) - normalized_mac_file_detonation_output__confidence.append(list(set(verdict_list))[0]) - #phantom.debug("normalized_mac_file_detonation_output__url_score_object: {}".format(normalized_mac_file_detonation_output__url_score_object)) - #phantom.debug("normalized_mac_file_detonation_output__scores: {}".format(normalized_mac_file_detonation_output__scores)) - #phantom.debug("normalized_mac_file_detonation_output__categories: {}".format(normalized_mac_file_detonation_output__categories)) - ################################################################################ - ## Custom Code End - ################################################################################ - - phantom.save_run_data(key="normalized_mac_file_detonation_output:url_score_object", value=json.dumps(normalized_mac_file_detonation_output__url_score_object)) - phantom.save_run_data(key="normalized_mac_file_detonation_output:scores", value=json.dumps(normalized_mac_file_detonation_output__scores)) - phantom.save_run_data(key="normalized_mac_file_detonation_output:categories", value=json.dumps(normalized_mac_file_detonation_output__categories)) - phantom.save_run_data(key="normalized_mac_file_detonation_output:confidence", value=json.dumps(normalized_mac_file_detonation_output__confidence)) - - format_report_mac_file(container=container) - - return - - -@phantom.playbook_block() -def format_report_mac_file(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): - phantom.debug("format_report_mac_file() called") - - ################################################################################ - # Format a summary table with the information gathered from the playbook. - ################################################################################ - - template = """SOAR analyzed URL(s) using CrowdStrike. The table below shows a summary of the information gathered.\n\n| File hash | Score | Confidence |Categories | Report Link | Source |\n| --- | --- | --- | --- | --- |\n%%\n| `{0}` | {1} | {2} | {3} |https://falcon.crowdstrike.com/intelligence/sandbox/reports/{4} | CrowdStrike OAuth API |\n%%\n{1}\n{2}\n{3}\n{4}\n\n{1}\n{2}\n{3}\n{4}\n""" - - # parameter list for template variable replacement - parameters = [ - "filtered-data:mac_sandbox_filter:condition_1:mac_file_detonation:action_result.parameter.vault_id", - "normalized_mac_file_detonation_output:custom_function:scores", - "normalized_mac_file_detonation_output:custom_function:confidence", - "normalized_mac_file_detonation_output:custom_function:categories", - "filtered-data:mac_sandbox_filter:condition_1:mac_file_detonation:action_result.data.*.id" - ] - - ################################################################################ - ## Custom Code Start - ################################################################################ - - # Write your custom code here... - #phantom.debug(phantom.format(container=container, template=template, parameters=parameters, name="format_report_mac_file")) - ################################################################################ - ## Custom Code End - ################################################################################ - - phantom.format(container=container, template=template, parameters=parameters, name="format_report_mac_file") - - build_mac_file_output(container=container) - - return - - -@phantom.playbook_block() -def build_mac_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_mac_file_output() called") - - ################################################################################ - # This block uses custom code to generate an observable dictionary to output into - # the observables data path. - ################################################################################ - - playbook_input_vault_id = phantom.collect2(container=container, datapath=["playbook_input:vault_id"]) - filtered_result_0_data_mac_sandbox_filter = phantom.collect2(container=container, datapath=["filtered-data:mac_sandbox_filter:condition_1:mac_file_detonation:action_result.data.*.id"]) - normalized_mac_file_detonation_output__url_score_object = json.loads(_ if (_ := phantom.get_run_data(key="normalized_mac_file_detonation_output:url_score_object")) != "" else "null") # pylint: disable=used-before-assignment - - playbook_input_vault_id_values = [item[0] for item in playbook_input_vault_id] - filtered_result_0_data___id = [item[0] for item in filtered_result_0_data_mac_sandbox_filter] - - build_mac_file_output__observable_array = None - - ################################################################################ - ## Custom Code Start - ################################################################################ - - # Write your custom code here... - build_mac_file_output__observable_array = [] - for _vault_id, external_id, file_object in zip(playbook_input_vault_id_values, filtered_result_0_data___id, normalized_mac_file_detonation_output__url_score_object): - observable_object = { - - "value": _vault_id, - "type": "hash", - "sandbox": { - "score": file_object['score'], - "confidence": file_object['confidence'], - "categories": file_object['categories'] - }, - "enrichment": { - "provider": "CrowdStrike OAuth API", - "type": "file", - - }, - "source": "CrowdStrike OAuth API", - "source_link":f"https://falcon.crowdstrike.com/intelligence/sandbox/reports/{external_id}" - } - build_mac_file_output__observable_array.append(observable_object) - #phantom.debug("build_mac_file_output__observable_array: {}".format(build_mac_file_output__observable_array)) - ################################################################################ - ## Custom Code End - ################################################################################ - - phantom.save_run_data(key="build_mac_file_output:observable_array", value=json.dumps(build_mac_file_output__observable_array)) + file_detonation(action=action, success=success, container=container, results=results, handle=handle, filtered_artifacts=matched_artifacts_1, filtered_results=matched_results_1) return @@ -1397,16 +720,17 @@ def build_mac_file_output(action=None, success=None, container=None, results=Non def on_finish(container, summary): phantom.debug("on_finish() called") - build_win_file_output__observable_array = json.loads(_ if (_ := phantom.get_run_data(key="build_win_file_output:observable_array")) != "" else "null") # pylint: disable=used-before-assignment - build_linux_file_output__observable_array = json.loads(_ if (_ := phantom.get_run_data(key="build_linux_file_output:observable_array")) != "" else "null") # pylint: disable=used-before-assignment - build_android_file_output__observable_array = json.loads(_ if (_ := phantom.get_run_data(key="build_android_file_output:observable_array")) != "" else "null") # pylint: disable=used-before-assignment - build_mac_file_output__observable_array = json.loads(_ if (_ := phantom.get_run_data(key="build_mac_file_output:observable_array")) != "" else "null") # pylint: disable=used-before-assignment + format_report_url = phantom.get_format_data(name="format_report_url") + format_report_file = phantom.get_format_data(name="format_report_file") + 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 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 - observable_combined_value = phantom.concatenate(build_win_file_output__observable_array, build_linux_file_output__observable_array, build_android_file_output__observable_array, build_mac_file_output__observable_array, build_url_output__observable_array) + observable_combined_value = phantom.concatenate(build_file_output__observable_array, build_url_output__observable_array) + report_combined_value = phantom.concatenate(format_report_url, format_report_file) output = { "observable": observable_combined_value, + "report": report_combined_value, } ################################################################################ @@ -1414,17 +738,11 @@ def on_finish(container, summary): ################################################################################ # Write your custom code here... - format_report_url = phantom.get_format_data(name="format_report_url") - format_report_win_file = phantom.get_format_data(name="format_report_win_file") - format_report_linux_file = phantom.get_format_data(name="format_report_linux_file") - format_report_android_file = phantom.get_format_data(name="format_report_android_file") - format_report_mac_file = phantom.get_format_data(name="format_report_mac_file") - markdown_report_combined_value = phantom.concatenate(format_report_url, format_report_win_file, format_report_linux_file, format_report_android_file, format_report_mac_file, format_report_mac_file) - output['markdown_report'] = markdown_report_combined_value + ################################################################################ ## Custom Code End ################################################################################ phantom.save_playbook_output_data(output=output) - return + return \ No newline at end of file