diff --git a/playbooks/CrowdStrike_OAuth_API_Dynamic_Analysis.json b/playbooks/CrowdStrike_OAuth_API_Dynamic_Analysis.json new file mode 100644 index 0000000000..7cd4867db8 --- /dev/null +++ b/playbooks/CrowdStrike_OAuth_API_Dynamic_Analysis.json @@ -0,0 +1,1489 @@ +{ + "blockly": false, + "blockly_xml": "", + "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/", + "edges": [ + { + "id": "port_0_to_port_2", + "sourceNode": "0", + "sourcePort": "0_out", + "targetNode": "2", + "targetPort": "2_in" + }, + { + "conditions": [ + { + "index": 0 + } + ], + "id": "port_2_to_port_3", + "sourceNode": "2", + "sourcePort": "2_out", + "targetNode": "3", + "targetPort": "3_in" + }, + { + "id": "port_3_to_port_4", + "sourceNode": "3", + "sourcePort": "3_out", + "targetNode": "4", + "targetPort": "4_in" + }, + { + "conditions": [ + { + "index": 0 + } + ], + "id": "port_4_to_port_5", + "sourceNode": "4", + "sourcePort": "4_out", + "targetNode": "5", + "targetPort": "5_in" + }, + { + "id": "port_5_to_port_6", + "sourceNode": "5", + "sourcePort": "5_out", + "targetNode": "6", + "targetPort": "6_in" + }, + { + "id": "port_6_to_port_7", + "sourceNode": "6", + "sourcePort": "6_out", + "targetNode": "7", + "targetPort": "7_in" + }, + { + "id": "port_7_to_port_1", + "sourceNode": "7", + "sourcePort": "7_out", + "targetNode": "1", + "targetPort": "1_in" + }, + { + "conditions": [ + { + "index": 1 + } + ], + "id": "port_2_to_port_8", + "sourceNode": "2", + "sourcePort": "2_out", + "targetNode": "8", + "targetPort": "8_in" + }, + { + "id": "port_10_to_port_11", + "sourceNode": "10", + "sourcePort": "10_out", + "targetNode": "11", + "targetPort": "11_in" + }, + { + "conditions": [ + { + "index": 0 + } + ], + "id": "port_11_to_port_12", + "sourceNode": "11", + "sourcePort": "11_out", + "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", + "sourcePort": "12_out", + "targetNode": "14", + "targetPort": "14_in" + }, + { + "id": "port_14_to_port_15", + "sourceNode": "14", + "sourcePort": "14_out", + "targetNode": "15", + "targetPort": "15_in" + }, + { + "id": "port_15_to_port_1", + "sourceNode": "15", + "sourcePort": "15_out", + "targetNode": "1", + "targetPort": "1_in" + }, + { + "conditions": [ + { + "index": 1 + } + ], + "id": "port_13_to_port_16", + "sourceNode": "13", + "sourcePort": "13_out", + "targetNode": "16", + "targetPort": "16_in" + }, + { + "id": "port_16_to_port_17", + "sourceNode": "16", + "sourcePort": "16_out", + "targetNode": "17", + "targetPort": "17_in" + }, + { + "conditions": [ + { + "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" + } + ], + "globalCustomCode": "\n\n\nimport os", + "hash": "5cff0f179c8b9ff466ffcb9d12d541f2062d3637", + "nodes": { + "0": { + "data": { + "advanced": { + "join": [] + }, + "functionName": "on_start", + "id": "0", + "type": "start" + }, + "errors": {}, + "id": "0", + "type": "start", + "warnings": {}, + "x": 530, + "y": -3.197442310920451e-13 + }, + "1": { + "data": { + "advanced": { + "join": [] + }, + "functionName": "on_finish", + "id": "1", + "type": "end" + }, + "errors": {}, + "id": "1", + "type": "end", + "userCode": "\n # Write your custom code here...\n 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", + "warnings": {}, + "x": 700, + "y": 1580 + }, + "10": { + "data": { + "action": "detonate file", + "actionType": "generic", + "advanced": { + "customName": "windows 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": 1, + "functionName": "windows_file_detonation", + "id": "10", + "parameters": { + "detail_report": true, + "environment": "Windows 10, 64-bit", + "is_confidential": false, + "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": "10", + "type": "action", + "warnings": {}, + "x": 340, + "y": 680 + }, + "11": { + "data": { + "advanced": { + "customName": "windows sandbox filter", + "customNameId": 0, + "description": "Filters successful file detonation results.", + "join": [], + "note": "Filters successful file detonation results." + }, + "conditions": [ + { + "comparisons": [ + { + "conditionIndex": 0, + "op": "==", + "param": "windows_file_detonation:action_result.status", + "value": "success" + } + ], + "conditionIndex": 0, + "customName": "win_sandbox_status_filter", + "logic": "and" + } + ], + "functionId": 4, + "functionName": "windows_sandbox_filter", + "id": "11", + "type": "filter" + }, + "errors": {}, + "id": "11", + "type": "filter", + "warnings": {}, + "x": 400, + "y": 866 + }, + "12": { + "data": { + "advanced": { + "customName": "normalized win 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", + "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" + ], + "outputVariables": [ + "file_score_object", + "scores", + "categories", + "confidence" + ], + "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", + "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 + }, + "14": { + "data": { + "advanced": { + "customName": "format report win 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", + "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: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", + "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 + }, + "15": { + "data": { + "advanced": { + "customName": "build win 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", + "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" + ], + "outputVariables": [ + "observable_array" + ], + "type": "code" + }, + "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" + }, + "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 + }, + "2": { + "data": { + "advanced": { + "customName": "input filter", + "customNameId": 0, + "description": "Determine branches based on provided inputs.", + "join": [], + "note": "Determine branches based on provided inputs." + }, + "conditions": [ + { + "comparisons": [ + { + "conditionIndex": 0, + "op": "!=", + "param": "playbook_input:url", + "value": "" + } + ], + "conditionIndex": 0, + "customName": "url_input", + "logic": "and" + }, + { + "comparisons": [ + { + "conditionIndex": 1, + "op": "!=", + "param": "playbook_input:vault_id", + "value": "" + } + ], + "conditionIndex": 1, + "customName": "vault_id_input", + "logic": "and" + } + ], + "functionId": 1, + "functionName": "input_filter", + "id": "2", + "type": "filter" + }, + "errors": {}, + "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 + }, + "3": { + "data": { + "action": "detonate url", + "actionType": "generic", + "advanced": { + "customName": "crowdstrike url detonation", + "customNameId": 0, + "description": "Queries CrowdStrike for information about the provided URL(s)", + "join": [], + "note": "Queries CrowdStrike for information about the provided URL(s)" + }, + "connector": "CrowdStrike OAuth API", + "connectorConfigs": [ + "crowdstrike_url_reputation" + ], + "connectorId": "ae971ba5-3117-444a-8ac5-6ce779f3a232", + "connectorVersion": "v1", + "functionId": 1, + "functionName": "crowdstrike_url_detonation", + "id": "3", + "parameters": { + "environment": "Windows 7, 64-bit", + "limit": 50, + "url": "playbook_input:url" + }, + "requiredParameters": [ + { + "data_type": "string", + "field": "url" + }, + { + "data_type": "numeric", + "default": 50, + "field": "limit" + }, + { + "data_type": "string", + "field": "environment" + } + ], + "type": "action" + }, + "errors": {}, + "id": "3", + "type": "action", + "warnings": {}, + "x": 0, + "y": 680 + }, + "30": { + "data": { + "advanced": { + "customName": "build mac 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": 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" + }, + "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", + "warnings": {}, + "x": 1360, + "y": 1396 + }, + "4": { + "data": { + "advanced": { + "customName": "url detonation filter", + "customNameId": 0, + "description": "Filters successful url detonation results.", + "join": [], + "note": "Filters successful url detonation results." + }, + "conditions": [ + { + "comparisons": [ + { + "conditionIndex": 0, + "op": "==", + "param": "crowdstrike_url_detonation:action_result.status", + "value": "success" + } + ], + "conditionIndex": 0, + "customName": "url_detonation_success", + "logic": "and" + } + ], + "functionId": 2, + "functionName": "url_detonation_filter", + "id": "4", + "type": "filter" + }, + "errors": {}, + "id": "4", + "type": "filter", + "warnings": {}, + "x": 60, + "y": 860 + }, + "5": { + "customCode": null, + "data": { + "advanced": { + "customName": "normalized url 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": 1, + "functionName": "normalized_url_detonation_output", + "id": "5", + "inputParameters": [ + "filtered-data:url_detonation_filter:condition_1:crowdstrike_url_detonation:action_result.parameter.url", + "filtered-data:url_detonation_filter:condition_1:crowdstrike_url_detonation:action_result.data.*.verdict", + "filtered-data:url_detonation_filter:condition_1:crowdstrike_url_detonation:action_result.data.*.sandbox.*.threat_score", + "filtered-data:url_detonation_filter:condition_1:crowdstrike_url_detonation:action_result.data.*.sandbox.*.signatures.*.category", + "filtered-data:url_detonation_filter:condition_1:crowdstrike_url_detonation:action_result.data.*.sandbox.*.verdict" + ], + "outputVariables": [ + "url_score_object", + "scores", + "categories", + "confidence" + ], + "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", + "warnings": {}, + "x": 0, + "y": 1040 + }, + "6": { + "data": { + "advanced": { + "customName": "format report url", + "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": 1, + "functionName": "format_report_url", + "id": "6", + "parameters": [ + "playbook_input:url", + "normalized_url_detonation_output:custom_function:scores", + "normalized_url_detonation_output:custom_function:confidence", + "normalized_url_detonation_output:custom_function:categories", + "crowdstrike_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", + "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 + }, + "7": { + "data": { + "advanced": { + "customName": "build url output", + "customNameId": 0, + "description": "This block uses custom code to generate an observable dictionary to output into the observables data path.", + "join": [], + "note": "This block uses custom code to generate an observable dictionary to output into the observables data path." + }, + "functionId": 2, + "functionName": "build_url_output", + "id": "7", + "inputParameters": [ + "playbook_input:url", + "crowdstrike_url_detonation:action_result.data.*.id", + "normalized_url_detonation_output:custom_function:url_score_object" + ], + "outputVariables": [ + "observable_array" + ], + "type": "code" + }, + "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 + }, + "8": { + "data": { + "advanced": { + "customName": "get vault_id information", + "customNameId": 0, + "description": "This block uses custom code for retrieving metadata of vault id that will distinguish what sandbox will be executed.", + "join": [], + "note": "This block uses custom code for retrieving metadata of vault id that will distinguish what sandbox will be executed." + }, + "functionId": 3, + "functionName": "get_vault_id_information", + "id": "8", + "inputParameters": [ + "playbook_input:vault_id" + ], + "outputVariables": [ + "sandbox_type" + ], + "type": "code" + }, + "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", + "warnings": {}, + "x": 860, + "y": 320 + } + }, + "notes": "Inputs: url, file_hash\nInteractions: Crowdstrike\nActions: url detonation, , file detonation\nOutputs: report, observables" + }, + "input_spec": [ + { + "contains": [ + "url" + ], + "description": "A URL provided for reputation analysis - crowdstrike", + "name": "url" + }, + { + "contains": [ + "vault id" + ], + "description": "A vault_id provided for reputation analysis - crowdstrike", + "name": "vault_id" + } + ], + "output_spec": [ + { + "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_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" + } + ], + "playbook_type": "data", + "python_version": "3", + "schema": "5.0.8", + "version": "5.5.0.108488" + }, + "create_time": "2023-03-24T14:42:42.435739+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" + ] +} \ No newline at end of file diff --git a/playbooks/CrowdStrike_OAuth_API_Dynamic_Analysis.png b/playbooks/CrowdStrike_OAuth_API_Dynamic_Analysis.png new file mode 100644 index 0000000000..b88dfa900c Binary files /dev/null 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 new file mode 100644 index 0000000000..c6cb5423ac --- /dev/null +++ b/playbooks/CrowdStrike_OAuth_API_Dynamic_Analysis.py @@ -0,0 +1,1430 @@ +""" +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/ +""" + + +import phantom.rules as phantom +import json +from datetime import datetime, timedelta + + +################################################################################ +## Global Custom Code Start +################################################################################ + + + +import os +################################################################################ +## Global Custom Code End +################################################################################ + +@phantom.playbook_block() +def on_start(container): + phantom.debug('on_start() called') + + # call 'input_filter' block + input_filter(container=container) + + return + +@phantom.playbook_block() +def input_filter(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): + phantom.debug("input_filter() called") + + ################################################################################ + # Determine branches based on provided inputs. + ################################################################################ + + # collect filtered artifact ids and results for 'if' condition 1 + matched_artifacts_1, matched_results_1 = phantom.condition( + container=container, + conditions=[ + ["playbook_input:url", "!=", ""] + ], + name="input_filter:condition_1") + + # 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) + + # collect filtered artifact ids and results for 'if' condition 2 + matched_artifacts_2, matched_results_2 = phantom.condition( + container=container, + conditions=[ + ["playbook_input:vault_id", "!=", ""] + ], + name="input_filter:condition_2") + + # call connected blocks if filtered artifacts or results + if matched_artifacts_2 or matched_results_2: + get_vault_id_information(action=action, success=success, container=container, results=results, handle=handle, filtered_artifacts=matched_artifacts_2, filtered_results=matched_results_2) + + return + + +@phantom.playbook_block() +def 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") + + # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED'))) + + ################################################################################ + # Queries CrowdStrike for information about the provided URL(s) + ################################################################################ + + playbook_input_url = phantom.collect2(container=container, datapath=["playbook_input:url"]) + + parameters = [] + + # build parameters list for 'crowdstrike_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, + "environment": "Windows 7, 64-bit", + }) + + ################################################################################ + ## Custom Code Start + ################################################################################ + + # Write your custom code here... + + ################################################################################ + ## Custom Code End + ################################################################################ + + phantom.act("detonate url", parameters=parameters, name="crowdstrike_url_detonation", assets=["crowdstrike_url_reputation"], callback=url_detonation_filter) + + return + + +@phantom.playbook_block() +def url_detonation_filter(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): + phantom.debug("url_detonation_filter() called") + + ################################################################################ + # Filters successful url detonation results. + ################################################################################ + + # collect filtered artifact ids and results for 'if' condition 1 + matched_artifacts_1, matched_results_1 = phantom.condition( + container=container, + conditions=[ + ["crowdstrike_url_detonation:action_result.status", "==", "success"] + ], + name="url_detonation_filter:condition_1") + + # call connected blocks if filtered artifacts or results + if matched_artifacts_1 or matched_results_1: + normalized_url_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_url_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_url_detonation_output() called") + + ################################################################################ + # This block uses custom code for normalizing score. Adjust the logic as desired + # in the documented sections. + ################################################################################ + + filtered_result_0_data_url_detonation_filter = phantom.collect2(container=container, datapath=["filtered-data:url_detonation_filter:condition_1:crowdstrike_url_detonation:action_result.parameter.url","filtered-data:url_detonation_filter:condition_1:crowdstrike_url_detonation:action_result.data.*.verdict","filtered-data:url_detonation_filter:condition_1:crowdstrike_url_detonation:action_result.data.*.sandbox.*.threat_score","filtered-data:url_detonation_filter:condition_1:crowdstrike_url_detonation:action_result.data.*.sandbox.*.signatures.*.category","filtered-data:url_detonation_filter:condition_1:crowdstrike_url_detonation:action_result.data.*.sandbox.*.verdict"]) + + filtered_result_0_parameter_url = [item[0] for item in filtered_result_0_data_url_detonation_filter] + filtered_result_0_data___verdict = [item[1] for item in filtered_result_0_data_url_detonation_filter] + filtered_result_0_data___sandbox___threat_score = [item[2] for item in filtered_result_0_data_url_detonation_filter] + filtered_result_0_data___sandbox___signatures___category = [item[3] for item in filtered_result_0_data_url_detonation_filter] + filtered_result_0_data___sandbox___verdict = [item[4] for item in filtered_result_0_data_url_detonation_filter] + + 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 + + ################################################################################ + ## Custom Code Start + ################################################################################ + + # Write your custom code here... + #phantom.debug("filtered_result_0_parameter_url: {}".format(filtered_result_0_parameter_url)) + #phantom.debug("filtered_result_0_data: {}".format(filtered_result_0_data)) + #phantom.debug("filtered_result_0_data___verdict: {}".format(filtered_result_0_data___verdict)) + #phantom.debug("filtered_result_0_data___sandbox___threat_score: {}".format(filtered_result_0_data___sandbox___threat_score)) + #phantom.debug("filtered_result_0_data___sandbox___signatures___category: {}".format(filtered_result_0_data___sandbox___signatures___category)) + #phantom.debug("filtered_result_0_summary_verdict: {}".format(filtered_result_0_summary_verdict)) + #phantom.debug("filtered_result_0_data___sandbox___verdict: {}".format(filtered_result_0_data___sandbox___verdict)) + #phantom.debug("crowdstrike_url_detonation_result_data: {}".format(crowdstrike_url_detonation_result_data)) + + ## define variables for easy code debugging + + normalized_url_detonation_output__url_score_object = [] + normalized_url_detonation_output__scores = [] + normalized_url_detonation_output__categories = [] + normalized_url_detonation_output__confidence = [] + + 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] + + ## get the set() or unique input url parameter. + + index_url_dict = {} + set_url_inputs = set(url_detonation_param_list) + + + for url_input in set_url_inputs: + url_list = [] + score_list = [] + verdict_list = [] + category_list = [] + + ## getting the index of each detonation phase of the url group the result for each url detonation + url_input_index = [indx for indx, url_val in enumerate(url_detonation_param_list) if url_val == url_input] + index_url_dict[url_input] = url_input_index + + 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)): + if _url == url_input and idx in index_url_dict[url_input]: + url_list.append(_url) + score_list.append(_score) + verdict_list.append(_verdict) + category_list.append(_category) + + # 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__categories.append(list(set(category_list))) + normalized_url_detonation_output__confidence.append(list(set(verdict_list))[0]) + #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)) + + + ################################################################################ + ## Custom Code End + ################################################################################ + + 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)) + + format_report_url(container=container) + + return + + +@phantom.playbook_block() +def format_report_url(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): + phantom.debug("format_report_url() 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| 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""" + + # 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:categories", + "crowdstrike_url_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_url")) + ################################################################################ + ## Custom Code End + ################################################################################ + + phantom.format(container=container, template=template, parameters=parameters, name="format_report_url") + + build_url_output(container=container) + + return + + +@phantom.playbook_block() +def build_url_output(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): + phantom.debug("build_url_output() called") + + ################################################################################ + # This block uses custom code to generate an observable dictionary to output into + # the observables data path. + ################################################################################ + + 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) + 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] + + build_url_output__observable_array = None + + ################################################################################ + ## Custom Code Start + ################################################################################ + + # Write your custom code here... +# Write your custom code here... + from urllib.parse import urlparse + 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): + parsed_url = urlparse(url) + phantom.debug("parsed_url: {}, url_object: {}".format(parsed_url, url_object)) + observable_object = { + "value": url, + "type": "url", + "sandbox": { + "score": url_object['score'], + "confidence": url_object['confidence'], + "categories": url_object['categories'] + }, + "attributes": { + "hostname": parsed_url.hostname, + "scheme": parsed_url.scheme + }, + + "source": "CrowdStrike OAuth API", + "source_link": f"https://falcon.crowdstrike.com/intelligence/sandbox/reports/{external_id}" + } + + if parsed_url.path: + observable_object['attributes']['path'] = parsed_url.path + if parsed_url.query: + observable_object['attributes']['query'] = parsed_url.query + if parsed_url.port: + observable_object['attributes']['port'] = parsed_url.port + + build_url_output__observable_array.append(observable_object) + #phantom.debug("build_url_output__observable_array: {}".format(build_url_output__observable_array)) + ################################################################################ + ## Custom Code End + ################################################################################ + + phantom.save_run_data(key="build_url_output:observable_array", value=json.dumps(build_url_output__observable_array)) + + return + + +@phantom.playbook_block() +def get_vault_id_information(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): + phantom.debug("get_vault_id_information() called") + + ################################################################################ + # This block uses custom code for retrieving metadata of vault id that will distinguish + # what sandbox will be executed. + ################################################################################ + + playbook_input_vault_id = phantom.collect2(container=container, datapath=["playbook_input:vault_id"]) + + playbook_input_vault_id_values = [item[0] for item in playbook_input_vault_id] + + get_vault_id_information__sandbox_type = None + + ################################################################################ + ## Custom Code Start + ################################################################################ + + # Write your custom code here... + 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) + phantom.debug("vault_info: {}, success: {}, msg: {}".format(vault_info, success, msg)) + + if success == True: + detonation_file_name = vault_info[0]['name'] + detonation_mime_type = vault_info[0]['mime_type'] + detonation_meta_data = vault_info[0]['contains'] + + 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" + + elif file_ext == ".dmg": + sandbox_type = "mac" + + elif file_ext == ".apk" and "application/zip" in detonation_mime_type: + sandbox_type = "android" + + elif file_ext == "" and "x-executable" in detonation_mime_type: + sandbox_type = "linux" + + else: + sandbox_type = "windows" + + 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)) + + ################################################################################ + ## Custom Code End + ################################################################################ + + phantom.save_run_data(key="get_vault_id_information:sandbox_type", value=json.dumps(get_vault_id_information__sandbox_type)) + + decision_1(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") + + # 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 '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: + parameters.append({ + "limit": 50, + "vault_id": playbook_input_vault_id_item[0], + "environment": "Windows 10, 64-bit", + "detail_report": True, + "is_confidential": False, + }) + + ################################################################################ + ## Custom Code Start + ################################################################################ + + # 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) + + 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") + + ################################################################################ + # 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=[ + ["windows_file_detonation:action_result.status", "==", "success"] + ], + name="windows_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) + + 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") + + ################################################################################ + # 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_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] + + 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 + + ################################################################################ + ## 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 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_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)) + ################################################################################ + ## 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)) + + format_report_win_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") + + ################################################################################ + # 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: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:windows_sandbox_filter:condition_1:windows_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_win_file")) + ################################################################################ + ## Custom Code End + ################################################################################ + + phantom.format(container=container, template=template, parameters=parameters, name="format_report_win_file") + + build_win_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") + + ################################################################################ + # 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_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 + + 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] + + build_win_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): + 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_win_file_output__observable_array.append(observable_object) + #phantom.debug("build_win_file_output__observable_array: {}".format(build_win_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)) + + 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'))) + + ################################################################################ + # 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 '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, + }) + + ################################################################################ + ## Custom Code Start + ################################################################################ + + # Write your custom code here... + + ################################################################################ + ## Custom Code End + ################################################################################ + + phantom.act("detonate file", parameters=parameters, name="linux_file_detonation", assets=["crowdstrike_url_reputation"], callback=linux_sandbox_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") + + ################################################################################ + # 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=[ + ["linux_file_detonation:action_result.status", "==", "success"] + ], + name="linux_sandbox_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)) + + return + + +@phantom.playbook_block() +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 + 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) + + output = { + "observable": observable_combined_value, + } + + ################################################################################ + ## Custom Code Start + ################################################################################ + + # 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 diff --git a/playbooks/CrowdStrike_OAuth_API_Dynamic_Analysis.yml b/playbooks/CrowdStrike_OAuth_API_Dynamic_Analysis.yml new file mode 100644 index 0000000000..441e004c36 --- /dev/null +++ b/playbooks/CrowdStrike_OAuth_API_Dynamic_Analysis.yml @@ -0,0 +1,25 @@ +name: CrowdStrike OAuth API Dynamic Analysis +id: 5299d9dc-e9d5-41fb-b051-92ace0ff816d +version: 1 +date: '2023-03-23' +author: Teoderick Contreras, Splunk +type: Investigation +description: "Accepts url link, domain or vault_id (hash) to be detonated using CrowdStrike OAuth API connector. This playbook produces a normalized output for each user and device." +playbook: CrowdStrike_OAuth_API_Dynamic_Analysis +how_to_implement: This input playbook requires the Crowdstrike OAuth API connector to be configured. It is designed to work in conjunction with the Dynamic Attribute Lookup playbook or other playbooks in the same style. +references: [] +app_list: + - CrowdStrike OAuth API +tags: + platform_tags: + - reputation + - url + - domain + - sandbox + - ip + - file_hash + playbook_type: Input + vpe_type: Modern + playbook_fields: [] + product: + - Splunk SOAR