diff --git a/playbooks/Cisco_Umbrella_DNS_Denylisting.json b/playbooks/Cisco_Umbrella_DNS_Denylisting.json index 96ef5a32b2..622115d8a9 100644 --- a/playbooks/Cisco_Umbrella_DNS_Denylisting.json +++ b/playbooks/Cisco_Umbrella_DNS_Denylisting.json @@ -1,7 +1,7 @@ { "blockly": false, "blockly_xml": "", - "category": "Isolation", + "category": "DNS Denylisting", "coa": { "data": { "description": "Accepts a domain or list of domains as input. Blocks the given domains in Cisco Umbrella.\n\nhttps://d3fend.mitre.org/technique/d3f:DNSDenylisting/", @@ -33,14 +33,26 @@ "targetPort": "1_in" }, { - "id": "port_3_to_port_5", + "id": "port_3_to_port_6", "sourceNode": "3", "sourcePort": "3_out", + "targetNode": "6", + "targetPort": "6_in" + }, + { + "conditions": [ + { + "index": 0 + } + ], + "id": "port_6_to_port_5", + "sourceNode": "6", + "sourcePort": "6_out", "targetNode": "5", "targetPort": "5_in" } ], - "hash": "f8d4da70df5e5a54ebf27deb4aebb548deca61dd", + "hash": "3ef6e0e09a728ad1f2aea6b5c89f41b9f5671f50", "nodes": { "0": { "data": { @@ -56,7 +68,7 @@ "type": "start", "warnings": {}, "x": 1000, - "y": 419.99999999999966 + "y": 419.99999999999955 }, "1": { "data": { @@ -72,7 +84,7 @@ "type": "end", "warnings": {}, "x": 1000, - "y": 1060 + "y": 1200 }, "2": { "data": { @@ -89,7 +101,7 @@ { "conditionIndex": 0, "op": "!=", - "param": "playbook_input:input_domain", + "param": "playbook_input:domain", "value": "None" } ], @@ -131,7 +143,7 @@ "functionName": "block_domain", "id": "3", "parameters": { - "domain": "filtered-data:domain_input_filter:condition_1:playbook_input:input_domain" + "domain": "playbook_input:domain" }, "requiredParameters": [ { @@ -144,11 +156,7 @@ "errors": {}, "id": "3", "type": "action", - "warnings": { - "config": [ - "Reconfigure invalid datapath." - ] - }, + "warnings": {}, "x": 980, "y": 740 }, @@ -165,8 +173,8 @@ "functionName": "build_observable", "id": "5", "inputParameters": [ - "block_domain:action_result.parameter.domain", - "block_domain:action_result.status" + "filtered-data:success_filter:condition_1:block_domain:action_result.parameter.domain", + "filtered-data:success_filter:condition_1:block_domain:action_result.status" ], "outputVariables": [ "observable_array" @@ -176,14 +184,46 @@ "errors": {}, "id": "5", "type": "code", - "userCode": "\n build_observable__observable_array = list()\n for status, domain in zip(block_domain_result_item_1, block_domain_parameter_domain):\n if status == \"success\":\n observable = {\n \"type\": \"domain\",\n \"value\": domain,\n \"source\": \"Cisco Umbrella\",\n \"status\": \"blocked\"\n }\n \n build_observable__observable_array.append(observable)\n\n", - "warnings": { - "config": [ - "Reconfigure invalid datapath." - ] - }, + "userCode": "\n build_observable__observable_array = list()\n for status, domain in zip(filtered_result_0_status, filtered_result_0_parameter_domain):\n if status == \"success\":\n observable = {\n \"type\": \"domain\",\n \"value\": domain,\n \"source\": \"Cisco Umbrella\",\n \"status\": \"blocked\"\n }\n \n build_observable__observable_array.append(observable)\n\n", + "warnings": {}, "x": 980, - "y": 900 + "y": 1060 + }, + "6": { + "data": { + "advanced": { + "customName": "success filter", + "customNameId": 0, + "description": "Determine if the block domain was successful.", + "join": [], + "note": "Determine if the block domain was successful." + }, + "conditions": [ + { + "comparisons": [ + { + "conditionIndex": 0, + "op": "==", + "param": "block_domain:action_result.status", + "value": "success" + } + ], + "conditionIndex": 0, + "customName": "success", + "logic": "and" + } + ], + "functionId": 2, + "functionName": "success_filter", + "id": "6", + "type": "filter" + }, + "errors": {}, + "id": "6", + "type": "filter", + "warnings": {}, + "x": 1040, + "y": 880 } }, "notes": "Inputs: domain\nInteractions: Cisco Umbrella\nActions: block domain\nOutputs: observables" @@ -194,7 +234,7 @@ "domain" ], "description": "Accepts domain and block them", - "name": "input_domain" + "name": "domain" } ], "output_spec": [ @@ -212,9 +252,9 @@ "playbook_type": "data", "python_version": "3", "schema": "5.0.10", - "version": "6.0.1.123902" + "version": "6.1.0.131" }, - "create_time": "2023-07-25T11:48:03.067743+00:00", + "create_time": "2023-08-02T11:29:36.835550+00:00", "draft_mode": false, "labels": [ "*" diff --git a/playbooks/Cisco_Umbrella_DNS_Denylisting.py b/playbooks/Cisco_Umbrella_DNS_Denylisting.py index 0b958c4d0a..e989b47e99 100644 --- a/playbooks/Cisco_Umbrella_DNS_Denylisting.py +++ b/playbooks/Cisco_Umbrella_DNS_Denylisting.py @@ -29,7 +29,7 @@ def domain_input_filter(action=None, success=None, container=None, results=None, matched_artifacts_1, matched_results_1 = phantom.condition( container=container, conditions=[ - ["playbook_input:input_domain", "!=", None] + ["playbook_input:domain", "!=", None] ], name="domain_input_filter:condition_1", delimiter=None) @@ -51,15 +51,15 @@ def block_domain(action=None, success=None, container=None, results=None, handle # Block domains in Cisco Umbrella based on given domains. ################################################################################ - filtered_input_0_input_domain = phantom.collect2(container=container, datapath=["filtered-data:domain_input_filter:condition_1:playbook_input:input_domain"]) + playbook_input_domain = phantom.collect2(container=container, datapath=["playbook_input:domain"]) parameters = [] # build parameters list for 'block_domain' call - for filtered_input_0_input_domain_item in filtered_input_0_input_domain: - if filtered_input_0_input_domain_item[0] is not None: + for playbook_input_domain_item in playbook_input_domain: + if playbook_input_domain_item[0] is not None: parameters.append({ - "domain": filtered_input_0_input_domain_item[0], + "domain": playbook_input_domain_item[0], }) ################################################################################ @@ -72,7 +72,7 @@ def block_domain(action=None, success=None, container=None, results=None, handle ## Custom Code End ################################################################################ - phantom.act("block domain", parameters=parameters, name="block_domain", assets=["cisco_umbrella"], callback=build_observable) + phantom.act("block domain", parameters=parameters, name="block_domain", assets=["cisco_umbrella"], callback=success_filter) return @@ -86,10 +86,10 @@ def build_observable(action=None, success=None, container=None, results=None, ha # the observables data path. ################################################################################ - block_domain_result_data = phantom.collect2(container=container, datapath=["block_domain:action_result.parameter.domain","block_domain:action_result.status"], action_results=results) + filtered_result_0_data_success_filter = phantom.collect2(container=container, datapath=["filtered-data:success_filter:condition_1:block_domain:action_result.parameter.domain","filtered-data:success_filter:condition_1:block_domain:action_result.status"]) - block_domain_parameter_domain = [item[0] for item in block_domain_result_data] - block_domain_result_item_1 = [item[1] for item in block_domain_result_data] + filtered_result_0_parameter_domain = [item[0] for item in filtered_result_0_data_success_filter] + filtered_result_0_status = [item[1] for item in filtered_result_0_data_success_filter] build_observable__observable_array = None @@ -98,7 +98,7 @@ def build_observable(action=None, success=None, container=None, results=None, ha ################################################################################ build_observable__observable_array = list() - for status, domain in zip(block_domain_result_item_1, block_domain_parameter_domain): + for status, domain in zip(filtered_result_0_status, filtered_result_0_parameter_domain): if status == "success": observable = { "type": "domain", @@ -118,6 +118,30 @@ def build_observable(action=None, success=None, container=None, results=None, ha return +@phantom.playbook_block() +def success_filter(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): + phantom.debug("success_filter() called") + + ################################################################################ + # Determine if the block domain was successful. + ################################################################################ + + # collect filtered artifact ids and results for 'if' condition 1 + matched_artifacts_1, matched_results_1 = phantom.condition( + container=container, + conditions=[ + ["block_domain:action_result.status", "==", "success"] + ], + name="success_filter:condition_1", + delimiter=None) + + # call connected blocks if filtered artifacts or results + if matched_artifacts_1 or matched_results_1: + build_observable(action=action, success=success, container=container, results=results, handle=handle, filtered_artifacts=matched_artifacts_1, filtered_results=matched_results_1) + + return + + @phantom.playbook_block() def on_finish(container, summary): phantom.debug("on_finish() called")