diff --git a/recorded_future_artifact_enrichment.json b/recorded_future_artifact_enrichment.json
new file mode 100644
index 00000000..47c21d4d
--- /dev/null
+++ b/recorded_future_artifact_enrichment.json
@@ -0,0 +1,504 @@
+{
+ "blockly": false,
+ "blockly_xml": "",
+ "category": "Uncategorized",
+ "coa": {
+ "data": {
+ "description": "Enriches ingested events that contain file hashes, IP addresses, domain names, or URLs in some of the most common fields. This enrichment pulls a variety of threat intelligence details from Recorded Future into the investigation, allowing further analysis and contextual actions.",
+ "edges": [
+ {
+ "id": "port_0_to_port_2",
+ "sourceNode": "0",
+ "sourcePort": "0_out",
+ "targetNode": "2",
+ "targetPort": "2_in"
+ },
+ {
+ "id": "port_0_to_port_3",
+ "sourceNode": "0",
+ "sourcePort": "0_out",
+ "targetNode": "3",
+ "targetPort": "3_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 2
+ }
+ ],
+ "id": "port_2_to_port_6",
+ "sourceNode": "2",
+ "sourcePort": "2_out",
+ "targetNode": "6",
+ "targetPort": "6_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 0
+ }
+ ],
+ "id": "port_3_to_port_7",
+ "sourceNode": "3",
+ "sourcePort": "3_out",
+ "targetNode": "7",
+ "targetPort": "7_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 1
+ }
+ ],
+ "id": "port_3_to_port_8",
+ "sourceNode": "3",
+ "sourcePort": "3_out",
+ "targetNode": "8",
+ "targetPort": "8_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 2
+ }
+ ],
+ "id": "port_3_to_port_9",
+ "sourceNode": "3",
+ "sourcePort": "3_out",
+ "targetNode": "9",
+ "targetPort": "9_in"
+ },
+ {
+ "id": "port_6_to_port_1",
+ "sourceNode": "6",
+ "sourcePort": "6_out",
+ "targetNode": "1",
+ "targetPort": "1_in"
+ },
+ {
+ "id": "port_9_to_port_1",
+ "sourceNode": "9",
+ "sourcePort": "9_out",
+ "targetNode": "1",
+ "targetPort": "1_in"
+ },
+ {
+ "id": "port_5_to_port_1",
+ "sourceNode": "5",
+ "sourcePort": "5_out",
+ "targetNode": "1",
+ "targetPort": "1_in"
+ },
+ {
+ "id": "port_7_to_port_1",
+ "sourceNode": "7",
+ "sourcePort": "7_out",
+ "targetNode": "1",
+ "targetPort": "1_in"
+ },
+ {
+ "id": "port_8_to_port_1",
+ "sourceNode": "8",
+ "sourcePort": "8_out",
+ "targetNode": "1",
+ "targetPort": "1_in"
+ },
+ {
+ "id": "port_4_to_port_1",
+ "sourceNode": "4",
+ "sourcePort": "4_out",
+ "targetNode": "1",
+ "targetPort": "1_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 0
+ }
+ ],
+ "id": "port_2_to_port_5",
+ "sourceNode": "2",
+ "sourcePort": "2_out",
+ "targetNode": "5",
+ "targetPort": "5_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 1
+ }
+ ],
+ "id": "port_2_to_port_4",
+ "sourceNode": "2",
+ "sourcePort": "2_out",
+ "targetNode": "4",
+ "targetPort": "4_in"
+ }
+ ],
+ "hash": "6d4bf9725a7a1289b5181a200cb44b893a3a253b",
+ "nodes": {
+ "0": {
+ "data": {
+ "advanced": {
+ "join": []
+ },
+ "functionName": "on_start",
+ "id": "0",
+ "type": "start"
+ },
+ "errors": {},
+ "id": "0",
+ "type": "start",
+ "x": 1000,
+ "y": 419.9999999999998
+ },
+ "1": {
+ "data": {
+ "advanced": {
+ "join": []
+ },
+ "functionId": 1,
+ "functionName": "on_finish",
+ "id": "1",
+ "type": "end"
+ },
+ "errors": {},
+ "id": "1",
+ "type": "end",
+ "userCode": "\n # This function is called after all actions are completed.\n # summary of all the action and/or all details of actions\n # can be collected here.\n\n # summary_json = phantom.get_summary()\n # if 'result' in summary_json:\n # for action_result in summary_json['result']:\n # if 'action_run_id' in action_result:\n # action_results = phantom.get_action_results(action_run_id=action_result['action_run_id'], result_data=False, flatten=False)\n # phantom.debug(action_results)\n\n",
+ "x": 980,
+ "y": 900
+ },
+ "2": {
+ "data": {
+ "advanced": {
+ "customName": "Filter hash and IP",
+ "customNameId": 0,
+ "join": []
+ },
+ "conditions": [
+ {
+ "comparisons": [
+ {
+ "conditionIndex": 0,
+ "op": "!=",
+ "param": "artifact:*.cef.sourceAddress",
+ "value": ""
+ }
+ ],
+ "conditionIndex": 0,
+ "logic": "and"
+ },
+ {
+ "comparisons": [
+ {
+ "conditionIndex": 1,
+ "op": "!=",
+ "param": "artifact:*.cef.destinationAddress",
+ "value": ""
+ }
+ ],
+ "conditionIndex": 1,
+ "logic": "and"
+ },
+ {
+ "comparisons": [
+ {
+ "conditionIndex": 2,
+ "op": "!=",
+ "param": "artifact:*.cef.fileHash",
+ "value": ""
+ }
+ ],
+ "conditionIndex": 2,
+ "logic": "and"
+ }
+ ],
+ "functionId": 1,
+ "functionName": "filter_hash_and_ip",
+ "id": "2",
+ "type": "filter"
+ },
+ "errors": {},
+ "id": "2",
+ "type": "filter",
+ "x": 900,
+ "y": 540
+ },
+ "3": {
+ "data": {
+ "advanced": {
+ "customName": "Filter domain and URL",
+ "customNameId": 0,
+ "join": []
+ },
+ "conditions": [
+ {
+ "comparisons": [
+ {
+ "conditionIndex": 0,
+ "op": "!=",
+ "param": "artifact:*.cef.destinationDnsDomain",
+ "value": ""
+ }
+ ],
+ "conditionIndex": 0,
+ "logic": "and"
+ },
+ {
+ "comparisons": [
+ {
+ "conditionIndex": 1,
+ "op": "!=",
+ "param": "artifact:*.cef.requestURL",
+ "value": ""
+ }
+ ],
+ "conditionIndex": 1,
+ "logic": "and"
+ },
+ {
+ "comparisons": [
+ {
+ "conditionIndex": 2,
+ "op": "!=",
+ "param": "artifact:*.cef.sourceDnsDomain",
+ "value": ""
+ }
+ ],
+ "conditionIndex": 2,
+ "logic": "and"
+ }
+ ],
+ "functionId": 2,
+ "functionName": "filter_domain_and_url",
+ "id": "3",
+ "type": "filter"
+ },
+ "errors": {},
+ "id": "3",
+ "type": "filter",
+ "x": 1160,
+ "y": 540
+ },
+ "4": {
+ "data": {
+ "action": "ip intelligence",
+ "actionType": "investigate",
+ "advanced": {
+ "customName": "IP Intel Destination Address",
+ "customNameId": 0,
+ "description": "Gather threat intelligence about destination IP addresses in the event",
+ "join": [],
+ "note": "Gather threat intelligence about destination IP addresses in the event"
+ },
+ "connector": "Recorded Future",
+ "connectorConfigs": [
+ "recorded future"
+ ],
+ "connectorId": "6efe0e1b-76ac-4ffd-8fa0-ac58fd6efd77",
+ "connectorVersion": "v1",
+ "functionId": 1,
+ "functionName": "ip_intel_destination_address",
+ "id": "4",
+ "parameters": {
+ "ip": "filtered-data:filter_hash_and_ip:condition_2:artifact:*.cef.destinationAddress"
+ },
+ "requiredParameters": [
+ "ip"
+ ],
+ "type": "action"
+ },
+ "errors": {},
+ "id": "4",
+ "type": "action",
+ "x": 560,
+ "y": 700
+ },
+ "5": {
+ "data": {
+ "action": "ip intelligence",
+ "actionType": "investigate",
+ "advanced": {
+ "customName": "IP Intel Source Address",
+ "customNameId": 0,
+ "description": "Gather threat intelligence about source IP addresses in the event",
+ "join": [],
+ "note": "Gather threat intelligence about source IP addresses in the event"
+ },
+ "connector": "Recorded Future",
+ "connectorConfigs": [
+ "recorded future"
+ ],
+ "connectorId": "6efe0e1b-76ac-4ffd-8fa0-ac58fd6efd77",
+ "connectorVersion": "v1",
+ "functionId": 2,
+ "functionName": "ip_intel_source_address",
+ "id": "5",
+ "parameters": {
+ "ip": "filtered-data:filter_hash_and_ip:condition_1:artifact:*.cef.sourceAddress"
+ },
+ "requiredParameters": [
+ "ip"
+ ],
+ "type": "action"
+ },
+ "errors": {},
+ "id": "5",
+ "type": "action",
+ "x": 280,
+ "y": 680
+ },
+ "6": {
+ "data": {
+ "action": "file intelligence",
+ "actionType": "investigate",
+ "advanced": {
+ "customName": "File Intelligence",
+ "customNameId": 0,
+ "description": "Gather threat intelligence about file hashes in the event",
+ "join": [],
+ "note": "Gather threat intelligence about file hashes in the event"
+ },
+ "connector": "Recorded Future",
+ "connectorConfigs": [
+ "recorded future"
+ ],
+ "connectorId": "6efe0e1b-76ac-4ffd-8fa0-ac58fd6efd77",
+ "connectorVersion": "v1",
+ "functionId": 1,
+ "functionName": "file_intelligence",
+ "id": "6",
+ "parameters": {
+ "hash": "filtered-data:filter_hash_and_ip:condition_3:artifact:*.cef.fileHash"
+ },
+ "requiredParameters": [
+ "hash"
+ ],
+ "type": "action"
+ },
+ "errors": {},
+ "id": "6",
+ "type": "action",
+ "x": 840,
+ "y": 720
+ },
+ "7": {
+ "data": {
+ "action": "domain intelligence",
+ "actionType": "investigate",
+ "advanced": {
+ "customName": "Domain Intel Destination DNS",
+ "customNameId": 0,
+ "description": "Gather threat intelligence about destination domain names in the event",
+ "join": [],
+ "note": "Gather threat intelligence about destination domain names in the event"
+ },
+ "connector": "Recorded Future",
+ "connectorConfigs": [
+ "recorded future"
+ ],
+ "connectorId": "6efe0e1b-76ac-4ffd-8fa0-ac58fd6efd77",
+ "connectorVersion": "v1",
+ "functionId": 1,
+ "functionName": "domain_intel_destination_dns",
+ "id": "7",
+ "parameters": {
+ "domain": "filtered-data:filter_domain_and_url:condition_1:artifact:*.cef.destinationDnsDomain"
+ },
+ "requiredParameters": [
+ "domain"
+ ],
+ "type": "action"
+ },
+ "errors": {},
+ "id": "7",
+ "type": "action",
+ "x": 1100,
+ "y": 720
+ },
+ "8": {
+ "data": {
+ "action": "url intelligence",
+ "actionType": "investigate",
+ "advanced": {
+ "customName": "URL Intelligence",
+ "customNameId": 0,
+ "description": "Gather threat intelligence about URLs in the event",
+ "join": [],
+ "note": "Gather threat intelligence about URLs in the event"
+ },
+ "connector": "Recorded Future",
+ "connectorConfigs": [
+ "recorded future"
+ ],
+ "connectorId": "6efe0e1b-76ac-4ffd-8fa0-ac58fd6efd77",
+ "connectorVersion": "v1",
+ "functionId": 1,
+ "functionName": "url_intelligence",
+ "id": "8",
+ "parameters": {
+ "url": "filtered-data:filter_domain_and_url:condition_2:artifact:*.cef.requestURL"
+ },
+ "requiredParameters": [
+ "url"
+ ],
+ "type": "action"
+ },
+ "errors": {},
+ "id": "8",
+ "type": "action",
+ "x": 1360,
+ "y": 700
+ },
+ "9": {
+ "data": {
+ "action": "domain intelligence",
+ "actionType": "investigate",
+ "advanced": {
+ "customName": "Domain Intel Source DNS",
+ "customNameId": 0,
+ "description": "Gather threat intelligence about source domain names in the event",
+ "join": [],
+ "note": "Gather threat intelligence about source domain names in the event"
+ },
+ "connector": "Recorded Future",
+ "connectorConfigs": [
+ "recorded future"
+ ],
+ "connectorId": "6efe0e1b-76ac-4ffd-8fa0-ac58fd6efd77",
+ "connectorVersion": "v1",
+ "functionId": 2,
+ "functionName": "domain_intel_source_dns",
+ "id": "9",
+ "parameters": {
+ "domain": "filtered-data:filter_domain_and_url:condition_3:artifact:*.cef.sourceDnsDomain"
+ },
+ "requiredParameters": [
+ "domain"
+ ],
+ "type": "action"
+ },
+ "errors": {},
+ "id": "9",
+ "type": "action",
+ "x": 1620,
+ "y": 680
+ }
+ },
+ "notes": "This playbook uses the following Apps:\n - Recorded Future (file intelligence, ip intelligence, domain intelligence, url intelligence) [asset name = recorded_future] - gather threat intelligence about four types of indicators"
+ },
+ "input_spec": null,
+ "output_spec": null,
+ "playbook_type": "automation",
+ "python_version": "3",
+ "schema": "5.0.4",
+ "version": "5.1.0.70187"
+ },
+ "create_time": "2022-06-22T17:57:01.771646+00:00",
+ "draft_mode": false,
+ "labels": [
+ "*"
+ ],
+ "tags": []
+}
\ No newline at end of file
diff --git a/recorded_future_artifact_enrichment.png b/recorded_future_artifact_enrichment.png
new file mode 100644
index 00000000..157594b9
Binary files /dev/null and b/recorded_future_artifact_enrichment.png differ
diff --git a/recorded_future_artifact_enrichment.py b/recorded_future_artifact_enrichment.py
new file mode 100644
index 00000000..e0269fe5
--- /dev/null
+++ b/recorded_future_artifact_enrichment.py
@@ -0,0 +1,337 @@
+"""
+Enriches ingested events that contain file hashes, IP addresses, domain names, or URLs in some of the most common fields. This enrichment pulls a variety of threat intelligence details from Recorded Future into the investigation, allowing further analysis and contextual actions.
+"""
+
+
+import phantom.rules as phantom
+import json
+from datetime import datetime, timedelta
+
+
+def on_start(container):
+ phantom.debug('on_start() called')
+
+ # call 'filter_hash_and_ip' block
+ filter_hash_and_ip(container=container)
+ # call 'filter_domain_and_url' block
+ filter_domain_and_url(container=container)
+
+ return
+
+def filter_hash_and_ip(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("filter_hash_and_ip() called")
+
+ # collect filtered artifact ids and results for 'if' condition 1
+ matched_artifacts_1, matched_results_1 = phantom.condition(
+ container=container,
+ conditions=[
+ ["artifact:*.cef.sourceAddress", "!=", ""]
+ ],
+ name="filter_hash_and_ip:condition_1")
+
+ # call connected blocks if filtered artifacts or results
+ if matched_artifacts_1 or matched_results_1:
+ ip_intel_source_address(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=[
+ ["artifact:*.cef.destinationAddress", "!=", ""]
+ ],
+ name="filter_hash_and_ip:condition_2")
+
+ # call connected blocks if filtered artifacts or results
+ if matched_artifacts_2 or matched_results_2:
+ ip_intel_destination_address(action=action, success=success, container=container, results=results, handle=handle, filtered_artifacts=matched_artifacts_2, filtered_results=matched_results_2)
+
+ # collect filtered artifact ids and results for 'if' condition 3
+ matched_artifacts_3, matched_results_3 = phantom.condition(
+ container=container,
+ conditions=[
+ ["artifact:*.cef.fileHash", "!=", ""]
+ ],
+ name="filter_hash_and_ip:condition_3")
+
+ # call connected blocks if filtered artifacts or results
+ if matched_artifacts_3 or matched_results_3:
+ file_intelligence(action=action, success=success, container=container, results=results, handle=handle, filtered_artifacts=matched_artifacts_3, filtered_results=matched_results_3)
+
+ return
+
+
+def filter_domain_and_url(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("filter_domain_and_url() called")
+
+ # collect filtered artifact ids and results for 'if' condition 1
+ matched_artifacts_1, matched_results_1 = phantom.condition(
+ container=container,
+ conditions=[
+ ["artifact:*.cef.destinationDnsDomain", "!=", ""]
+ ],
+ name="filter_domain_and_url:condition_1")
+
+ # call connected blocks if filtered artifacts or results
+ if matched_artifacts_1 or matched_results_1:
+ domain_intel_destination_dns(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=[
+ ["artifact:*.cef.requestURL", "!=", ""]
+ ],
+ name="filter_domain_and_url:condition_2")
+
+ # call connected blocks if filtered artifacts or results
+ if matched_artifacts_2 or matched_results_2:
+ url_intelligence(action=action, success=success, container=container, results=results, handle=handle, filtered_artifacts=matched_artifacts_2, filtered_results=matched_results_2)
+
+ # collect filtered artifact ids and results for 'if' condition 3
+ matched_artifacts_3, matched_results_3 = phantom.condition(
+ container=container,
+ conditions=[
+ ["artifact:*.cef.sourceDnsDomain", "!=", ""]
+ ],
+ name="filter_domain_and_url:condition_3")
+
+ # call connected blocks if filtered artifacts or results
+ if matched_artifacts_3 or matched_results_3:
+ domain_intel_source_dns(action=action, success=success, container=container, results=results, handle=handle, filtered_artifacts=matched_artifacts_3, filtered_results=matched_results_3)
+
+ return
+
+
+def ip_intel_destination_address(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("ip_intel_destination_address() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ ################################################################################
+ # Gather threat intelligence about destination IP addresses in the event
+ ################################################################################
+
+ filtered_artifact_0_data_filter_hash_and_ip = phantom.collect2(container=container, datapath=["filtered-data:filter_hash_and_ip:condition_2:artifact:*.cef.destinationAddress"])
+
+ parameters = []
+
+ # build parameters list for 'ip_intel_destination_address' call
+ for filtered_artifact_0_item_filter_hash_and_ip in filtered_artifact_0_data_filter_hash_and_ip:
+ if filtered_artifact_0_item_filter_hash_and_ip[0] is not None:
+ parameters.append({
+ "ip": filtered_artifact_0_item_filter_hash_and_ip[0],
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("ip intelligence", parameters=parameters, name="ip_intel_destination_address", assets=["recorded future"])
+
+ return
+
+
+def ip_intel_source_address(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("ip_intel_source_address() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ ################################################################################
+ # Gather threat intelligence about source IP addresses in the event
+ ################################################################################
+
+ filtered_artifact_0_data_filter_hash_and_ip = phantom.collect2(container=container, datapath=["filtered-data:filter_hash_and_ip:condition_1:artifact:*.cef.sourceAddress"])
+
+ parameters = []
+
+ # build parameters list for 'ip_intel_source_address' call
+ for filtered_artifact_0_item_filter_hash_and_ip in filtered_artifact_0_data_filter_hash_and_ip:
+ if filtered_artifact_0_item_filter_hash_and_ip[0] is not None:
+ parameters.append({
+ "ip": filtered_artifact_0_item_filter_hash_and_ip[0],
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("ip intelligence", parameters=parameters, name="ip_intel_source_address", assets=["recorded future"])
+
+ return
+
+
+def file_intelligence(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("file_intelligence() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ ################################################################################
+ # Gather threat intelligence about file hashes in the event
+ ################################################################################
+
+ filtered_artifact_0_data_filter_hash_and_ip = phantom.collect2(container=container, datapath=["filtered-data:filter_hash_and_ip:condition_3:artifact:*.cef.fileHash"])
+
+ parameters = []
+
+ # build parameters list for 'file_intelligence' call
+ for filtered_artifact_0_item_filter_hash_and_ip in filtered_artifact_0_data_filter_hash_and_ip:
+ if filtered_artifact_0_item_filter_hash_and_ip[0] is not None:
+ parameters.append({
+ "hash": filtered_artifact_0_item_filter_hash_and_ip[0],
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("file intelligence", parameters=parameters, name="file_intelligence", assets=["recorded future"])
+
+ return
+
+
+def domain_intel_destination_dns(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("domain_intel_destination_dns() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ ################################################################################
+ # Gather threat intelligence about destination domain names in the event
+ ################################################################################
+
+ filtered_artifact_0_data_filter_domain_and_url = phantom.collect2(container=container, datapath=["filtered-data:filter_domain_and_url:condition_1:artifact:*.cef.destinationDnsDomain"])
+
+ parameters = []
+
+ # build parameters list for 'domain_intel_destination_dns' call
+ for filtered_artifact_0_item_filter_domain_and_url in filtered_artifact_0_data_filter_domain_and_url:
+ if filtered_artifact_0_item_filter_domain_and_url[0] is not None:
+ parameters.append({
+ "domain": filtered_artifact_0_item_filter_domain_and_url[0],
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("domain intelligence", parameters=parameters, name="domain_intel_destination_dns", assets=["recorded future"])
+
+ return
+
+
+def url_intelligence(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("url_intelligence() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ ################################################################################
+ # Gather threat intelligence about URLs in the event
+ ################################################################################
+
+ filtered_artifact_0_data_filter_domain_and_url = phantom.collect2(container=container, datapath=["filtered-data:filter_domain_and_url:condition_2:artifact:*.cef.requestURL"])
+
+ parameters = []
+
+ # build parameters list for 'url_intelligence' call
+ for filtered_artifact_0_item_filter_domain_and_url in filtered_artifact_0_data_filter_domain_and_url:
+ if filtered_artifact_0_item_filter_domain_and_url[0] is not None:
+ parameters.append({
+ "url": filtered_artifact_0_item_filter_domain_and_url[0],
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("url intelligence", parameters=parameters, name="url_intelligence", assets=["recorded future"])
+
+ return
+
+
+def domain_intel_source_dns(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("domain_intel_source_dns() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ ################################################################################
+ # Gather threat intelligence about source domain names in the event
+ ################################################################################
+
+ filtered_artifact_0_data_filter_domain_and_url = phantom.collect2(container=container, datapath=["filtered-data:filter_domain_and_url:condition_3:artifact:*.cef.sourceDnsDomain"])
+
+ parameters = []
+
+ # build parameters list for 'domain_intel_source_dns' call
+ for filtered_artifact_0_item_filter_domain_and_url in filtered_artifact_0_data_filter_domain_and_url:
+ if filtered_artifact_0_item_filter_domain_and_url[0] is not None:
+ parameters.append({
+ "domain": filtered_artifact_0_item_filter_domain_and_url[0],
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("domain intelligence", parameters=parameters, name="domain_intel_source_dns", assets=["recorded future"])
+
+ return
+
+
+def on_finish(container, summary):
+ phantom.debug("on_finish() called")
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # This function is called after all actions are completed.
+ # summary of all the action and/or all details of actions
+ # can be collected here.
+
+ # summary_json = phantom.get_summary()
+ # if 'result' in summary_json:
+ # for action_result in summary_json['result']:
+ # if 'action_run_id' in action_result:
+ # action_results = phantom.get_action_results(action_run_id=action_result['action_run_id'], result_data=False, flatten=False)
+ # phantom.debug(action_results)
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ return
\ No newline at end of file
diff --git a/recorded_future_leaked_credential_handling.json b/recorded_future_leaked_credential_handling.json
new file mode 100644
index 00000000..098906de
--- /dev/null
+++ b/recorded_future_leaked_credential_handling.json
@@ -0,0 +1,458 @@
+{
+ "blockly": false,
+ "blockly_xml": "",
+ "category": "Uncategorized",
+ "coa": {
+ "data": {
+ "description": "This playbook responds to Recorded Future monitoring of leaked credentials exposed on the internet. The accounts are verified to be enabled/disabled or if they exist in the LDAP environment.\n\nThen, a manual prompt to 'soft reset' the account at next logon is issued.",
+ "edges": [
+ {
+ "id": "port_14_to_port_16",
+ "sourceNode": "14",
+ "sourcePort": "14_out",
+ "targetNode": "16",
+ "targetPort": "16_in"
+ },
+ {
+ "id": "port_17_to_port_1",
+ "sourceNode": "17",
+ "sourcePort": "17_out",
+ "targetNode": "1",
+ "targetPort": "1_in"
+ },
+ {
+ "id": "port_18_to_port_19",
+ "sourceNode": "18",
+ "sourcePort": "18_out",
+ "targetNode": "19",
+ "targetPort": "19_in"
+ },
+ {
+ "id": "port_0_to_port_12",
+ "sourceNode": "0",
+ "sourcePort": "0_out",
+ "targetNode": "12",
+ "targetPort": "12_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 0
+ }
+ ],
+ "id": "port_19_to_port_17",
+ "sourceNode": "19",
+ "sourcePort": "19_out",
+ "targetNode": "17",
+ "targetPort": "17_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 1
+ }
+ ],
+ "id": "port_19_to_port_20",
+ "sourceNode": "19",
+ "sourcePort": "19_out",
+ "targetNode": "20",
+ "targetPort": "20_in"
+ },
+ {
+ "id": "port_20_to_port_27",
+ "sourceNode": "20",
+ "sourcePort": "20_out",
+ "targetNode": "27",
+ "targetPort": "27_in"
+ },
+ {
+ "id": "port_27_to_port_1",
+ "sourceNode": "27",
+ "sourcePort": "27_out",
+ "targetNode": "1",
+ "targetPort": "1_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 0
+ }
+ ],
+ "id": "port_12_to_port_14",
+ "sourceNode": "12",
+ "sourcePort": "12_out",
+ "targetNode": "14",
+ "targetPort": "14_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 0
+ }
+ ],
+ "id": "port_16_to_port_18",
+ "sourceNode": "16",
+ "sourcePort": "16_out",
+ "targetNode": "18",
+ "targetPort": "18_in"
+ }
+ ],
+ "hash": "345746562794783b9516f3aff5f10dba0b6f608b",
+ "nodes": {
+ "0": {
+ "data": {
+ "advanced": {
+ "join": []
+ },
+ "functionName": "on_start",
+ "id": "0",
+ "type": "start"
+ },
+ "errors": {},
+ "id": "0",
+ "type": "start",
+ "x": 1000,
+ "y": 320
+ },
+ "1": {
+ "data": {
+ "advanced": {
+ "join": []
+ },
+ "functionId": 1,
+ "functionName": "on_finish",
+ "id": "1",
+ "type": "end"
+ },
+ "errors": {},
+ "id": "1",
+ "type": "end",
+ "userCode": "\n # This function is called after all actions are completed.\n # summary of all the action and/or all details of actions\n # can be collected here.\n\n # summary_json = phantom.get_summary()\n # if 'result' in summary_json:\n # for action_result in summary_json['result']:\n # if 'action_run_id' in action_result:\n # action_results = phantom.get_action_results(action_run_id=action_result['action_run_id'], result_data=False, flatten=False)\n # phantom.debug(action_results)\n\n",
+ "x": 1000,
+ "y": 1640
+ },
+ "12": {
+ "data": {
+ "advanced": {
+ "customName": "Filter Artifacts",
+ "customNameId": 0,
+ "join": [],
+ "note": "Collect email's from the Recorded Future leaked credential alert."
+ },
+ "conditions": [
+ {
+ "comparisons": [
+ {
+ "conditionIndex": 0,
+ "op": "in",
+ "param": "EMAIL",
+ "value": "artifact:*.name"
+ }
+ ],
+ "conditionIndex": 0,
+ "logic": "and"
+ }
+ ],
+ "functionId": 2,
+ "functionName": "filter_artifacts",
+ "id": "12",
+ "type": "filter"
+ },
+ "errors": {},
+ "id": "12",
+ "type": "filter",
+ "x": 1040,
+ "y": 440
+ },
+ "14": {
+ "data": {
+ "action": "get attributes",
+ "actionType": "investigate",
+ "advanced": {
+ "customName": "Get Account LDAP Attributes",
+ "customNameId": 0,
+ "join": [],
+ "note": "Query LDAP for the accounts attributes. These attributes will be used to determine if the account credentials require intervention."
+ },
+ "connector": "AD LDAP",
+ "connectorConfigs": [
+ "ldap"
+ ],
+ "connectorId": "a5730e5d-a396-4695-92c2-35ff391aaf45",
+ "connectorVersion": "v1",
+ "functionId": 2,
+ "functionName": "get_account_ldap_attributes",
+ "id": "14",
+ "parameters": {
+ "attributes": "sAMAccountName;pwdLastSet;userAccountControl;mail",
+ "principals": "filtered-data:filter_artifacts:condition_1:artifact:*.cef.email"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "default": "sAMAccountName",
+ "field": "attributes"
+ },
+ {
+ "data_type": "string",
+ "default": "",
+ "field": "principals"
+ }
+ ],
+ "tab": "byConnector",
+ "type": "action"
+ },
+ "errors": {},
+ "id": "14",
+ "type": "action",
+ "x": 980,
+ "y": 620
+ },
+ "16": {
+ "data": {
+ "advanced": {
+ "customName": "Filter Active Accounts",
+ "customNameId": 0,
+ "join": [],
+ "note": "Filter active/enabled accounts."
+ },
+ "conditions": [
+ {
+ "comparisons": [
+ {
+ "conditionIndex": 0,
+ "op": "!=",
+ "param": "get_account_ldap_attributes:action_result.status",
+ "value": "failed"
+ },
+ {
+ "conditionIndex": 0,
+ "op": "!=",
+ "param": "get_account_ldap_attributes:action_result.data.*.samaccountname",
+ "value": ""
+ },
+ {
+ "conditionIndex": 0,
+ "op": "==",
+ "param": "get_account_ldap_attributes:action_result.summary.state",
+ "value": "Enabled"
+ }
+ ],
+ "conditionIndex": 0,
+ "logic": "and"
+ }
+ ],
+ "functionId": 1,
+ "functionName": "filter_active_accounts",
+ "id": "16",
+ "type": "filter"
+ },
+ "errors": {},
+ "id": "16",
+ "type": "filter",
+ "x": 1040,
+ "y": 800
+ },
+ "17": {
+ "data": {
+ "action": "reset password",
+ "actionType": "generic",
+ "advanced": {
+ "customName": "Soft Reset Password",
+ "customNameId": 0,
+ "join": [],
+ "note": "Forse user to reset their password at next logon."
+ },
+ "connector": "AD LDAP",
+ "connectorConfigs": [
+ "ldap"
+ ],
+ "connectorId": "a5730e5d-a396-4695-92c2-35ff391aaf45",
+ "connectorVersion": "v1",
+ "functionId": 1,
+ "functionName": "soft_reset_password",
+ "id": "17",
+ "parameters": {
+ "use_samaccountname": true,
+ "user": "filtered-data:filter_active_accounts:condition_1:get_account_ldap_attributes:action_result.data.*.samaccountname"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "default": "",
+ "field": "user"
+ }
+ ],
+ "type": "action"
+ },
+ "errors": {},
+ "id": "17",
+ "type": "action",
+ "x": 740,
+ "y": 1300
+ },
+ "18": {
+ "data": {
+ "advanced": {
+ "customName": "Prompt analyst",
+ "customNameId": 0,
+ "join": [],
+ "notRequiredJoins": [
+ "get_account_ldap_attributes"
+ ],
+ "note": "Manual prompt to confirm resetting the user's password at next logon. Remove this manual prompt to fully automate this playbook."
+ },
+ "approver": "Administrator",
+ "functionId": 1,
+ "functionName": "prompt_analyst",
+ "id": "18",
+ "message": "The following user accounts have recently had their credentials exposed on the internet:\n\n{0}\n\nWould you like to force the users to reset their password at next logon or inform the user via email?",
+ "parameters": [
+ "filtered-data:filter_active_accounts:condition_1:get_account_ldap_attributes:action_result.data.*.mail"
+ ],
+ "responseTime": 30,
+ "responses": [
+ {
+ "responseOptions": [
+ "Soft reset",
+ "Email user"
+ ],
+ "responsePrompt": "Reset password at next logon?",
+ "responseType": "customList"
+ }
+ ],
+ "type": "prompt"
+ },
+ "errors": {},
+ "id": "18",
+ "type": "prompt",
+ "x": 1060,
+ "y": 980
+ },
+ "19": {
+ "data": {
+ "advanced": {
+ "join": [],
+ "note": "Check if the manual prompt response was Yes or No."
+ },
+ "conditions": [
+ {
+ "comparisons": [
+ {
+ "conditionIndex": 0,
+ "op": "==",
+ "param": "prompt_analyst:action_result.summary.responses.0",
+ "value": "Soft reset"
+ }
+ ],
+ "conditionIndex": 0,
+ "display": "If",
+ "logic": "and",
+ "type": "if"
+ },
+ {
+ "comparisons": [
+ {
+ "conditionIndex": 1,
+ "op": "==",
+ "param": "",
+ "value": ""
+ }
+ ],
+ "conditionIndex": 1,
+ "display": "Else",
+ "logic": "and",
+ "type": "else"
+ }
+ ],
+ "functionId": 1,
+ "functionName": "decision_1",
+ "id": "19",
+ "type": "decision"
+ },
+ "errors": {},
+ "id": "19",
+ "type": "decision",
+ "x": 1060,
+ "y": 1120
+ },
+ "20": {
+ "data": {
+ "advanced": {
+ "customName": "Format email",
+ "customNameId": 0,
+ "join": [],
+ "note": "Format the email for the end user informing them their credential has been exposed and they need to reset their password."
+ },
+ "functionId": 1,
+ "functionName": "format_email",
+ "id": "20",
+ "parameters": [],
+ "template": "We have found the account credentials belonging to your email address on the internet. We have omitted the password in this email for security reasons. \n\nPlease reset your password as soon as possible.\n\nSincerely,\nSecurity Operations",
+ "type": "format"
+ },
+ "errors": {},
+ "id": "20",
+ "type": "format",
+ "x": 1300,
+ "y": 1300
+ },
+ "27": {
+ "data": {
+ "action": "send email",
+ "actionType": "generic",
+ "advanced": {
+ "customName": "Email compromised user",
+ "customNameId": 0,
+ "join": [],
+ "note": "Email the user to inform them their account has been compromised on the internet and request they reset their password. (Edit the sender parameter)"
+ },
+ "connector": "SMTP",
+ "connectorConfigs": [
+ "smtp"
+ ],
+ "connectorId": "45bb6f37-4478-499b-b4a3-51ecfa62b78c",
+ "connectorVersion": "v1",
+ "functionId": 1,
+ "functionName": "email_compromised_user",
+ "id": "27",
+ "parameters": {
+ "body": "format_email:formatted_data",
+ "subject": "Compromised Account",
+ "to": "filtered-data:filter_active_accounts:condition_1:get_account_ldap_attributes:action_result.data.*.mail"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "field": "to"
+ },
+ {
+ "data_type": "string",
+ "field": "body"
+ }
+ ],
+ "type": "action"
+ },
+ "errors": {},
+ "id": "27",
+ "type": "action",
+ "x": 1300,
+ "y": 1440
+ }
+ },
+ "notes": ""
+ },
+ "input_spec": null,
+ "output_spec": null,
+ "playbook_type": "automation",
+ "python_version": "3",
+ "schema": "5.0.8",
+ "version": "5.3.4.95226"
+ },
+ "create_time": "2022-09-23T17:54:43.823401+00:00",
+ "draft_mode": false,
+ "labels": [
+ "*"
+ ],
+ "tags": []
+}
\ No newline at end of file
diff --git a/recorded_future_leaked_credential_handling.png b/recorded_future_leaked_credential_handling.png
new file mode 100644
index 00000000..477f505f
Binary files /dev/null and b/recorded_future_leaked_credential_handling.png differ
diff --git a/recorded_future_leaked_credential_handling.py b/recorded_future_leaked_credential_handling.py
new file mode 100644
index 00000000..fae7f9e8
--- /dev/null
+++ b/recorded_future_leaked_credential_handling.py
@@ -0,0 +1,267 @@
+"""
+This playbook responds to Recorded Future monitoring of leaked credentials exposed on the internet. The accounts are verified to be enabled/disabled or if they exist in the LDAP environment.\n\nThen, a manual prompt to 'soft reset' the account at next logon is issued.
+"""
+
+
+import phantom.rules as phantom
+import json
+from datetime import datetime, timedelta
+
+
+@phantom.playbook_block()
+def on_start(container):
+ phantom.debug('on_start() called')
+
+ # call 'filter_artifacts' block
+ filter_artifacts(container=container)
+
+ return
+
+@phantom.playbook_block()
+def filter_artifacts(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("filter_artifacts() called")
+
+ # collect filtered artifact ids and results for 'if' condition 1
+ matched_artifacts_1, matched_results_1 = phantom.condition(
+ container=container,
+ conditions=[
+ ["EMAIL", "in", "artifact:*.name"]
+ ],
+ name="filter_artifacts:condition_1")
+
+ # call connected blocks if filtered artifacts or results
+ if matched_artifacts_1 or matched_results_1:
+ get_account_ldap_attributes(action=action, success=success, container=container, results=results, handle=handle, filtered_artifacts=matched_artifacts_1, filtered_results=matched_results_1)
+
+ return
+
+
+@phantom.playbook_block()
+def get_account_ldap_attributes(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("get_account_ldap_attributes() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ filtered_artifact_0_data_filter_artifacts = phantom.collect2(container=container, datapath=["filtered-data:filter_artifacts:condition_1:artifact:*.cef.email","filtered-data:filter_artifacts:condition_1:artifact:*.id"])
+
+ parameters = []
+
+ # build parameters list for 'get_account_ldap_attributes' call
+ for filtered_artifact_0_item_filter_artifacts in filtered_artifact_0_data_filter_artifacts:
+ if filtered_artifact_0_item_filter_artifacts[0] is not None:
+ parameters.append({
+ "attributes": "sAMAccountName;pwdLastSet;userAccountControl;mail",
+ "principals": filtered_artifact_0_item_filter_artifacts[0],
+ "context": {'artifact_id': filtered_artifact_0_item_filter_artifacts[1]},
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("get attributes", parameters=parameters, name="get_account_ldap_attributes", assets=["ldap"], callback=filter_active_accounts)
+
+ return
+
+
+@phantom.playbook_block()
+def filter_active_accounts(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("filter_active_accounts() called")
+
+ # collect filtered artifact ids and results for 'if' condition 1
+ matched_artifacts_1, matched_results_1 = phantom.condition(
+ container=container,
+ logical_operator="and",
+ conditions=[
+ ["get_account_ldap_attributes:action_result.status", "!=", "failed"],
+ ["get_account_ldap_attributes:action_result.data.*.samaccountname", "!=", ""],
+ ["get_account_ldap_attributes:action_result.summary.state", "==", "Enabled"]
+ ],
+ name="filter_active_accounts:condition_1")
+
+ # call connected blocks if filtered artifacts or results
+ if matched_artifacts_1 or matched_results_1:
+ prompt_analyst(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 soft_reset_password(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("soft_reset_password() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ filtered_result_0_data_filter_active_accounts = phantom.collect2(container=container, datapath=["filtered-data:filter_active_accounts:condition_1:get_account_ldap_attributes:action_result.data.*.samaccountname"])
+
+ parameters = []
+
+ # build parameters list for 'soft_reset_password' call
+ for filtered_result_0_item_filter_active_accounts in filtered_result_0_data_filter_active_accounts:
+ if filtered_result_0_item_filter_active_accounts[0] is not None:
+ parameters.append({
+ "user": filtered_result_0_item_filter_active_accounts[0],
+ "use_samaccountname": True,
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("reset password", parameters=parameters, name="soft_reset_password", assets=["ldap"])
+
+ return
+
+
+@phantom.playbook_block()
+def prompt_analyst(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("prompt_analyst() called")
+
+ # set user and message variables for phantom.prompt call
+
+ user = "Administrator"
+ message = """The following user accounts have recently had their credentials exposed on the internet:\n\n{0}\n\nWould you like to force the users to reset their password at next logon or inform the user via email?"""
+
+ # parameter list for template variable replacement
+ parameters = [
+ "filtered-data:filter_active_accounts:condition_1:get_account_ldap_attributes:action_result.data.*.mail"
+ ]
+
+ # responses
+ response_types = [
+ {
+ "prompt": "Reset password at next logon?",
+ "options": {
+ "type": "list",
+ "choices": [
+ "Soft reset",
+ "Email user"
+ ],
+ },
+ }
+ ]
+
+ phantom.prompt2(container=container, user=user, message=message, respond_in_mins=30, name="prompt_analyst", parameters=parameters, response_types=response_types, callback=decision_1)
+
+ 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")
+
+ # check for 'if' condition 1
+ found_match_1 = phantom.decision(
+ container=container,
+ conditions=[
+ ["prompt_analyst:action_result.summary.responses.0", "==", "Soft reset"]
+ ])
+
+ # call connected blocks if condition 1 matched
+ if found_match_1:
+ soft_reset_password(action=action, success=success, container=container, results=results, handle=handle)
+ return
+
+ # check for 'else' condition 2
+ format_email(action=action, success=success, container=container, results=results, handle=handle)
+
+ return
+
+
+@phantom.playbook_block()
+def format_email(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("format_email() called")
+
+ template = """We have found the account credentials belonging to your email address on the internet. We have omitted the password in this email for security reasons. \n\nPlease reset your password as soon as possible.\n\nSincerely,\nSecurity Operations"""
+
+ # parameter list for template variable replacement
+ parameters = []
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.format(container=container, template=template, parameters=parameters, name="format_email")
+
+ email_compromised_user(container=container)
+
+ return
+
+
+@phantom.playbook_block()
+def email_compromised_user(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("email_compromised_user() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ filtered_result_0_data_filter_active_accounts = phantom.collect2(container=container, datapath=["filtered-data:filter_active_accounts:condition_1:get_account_ldap_attributes:action_result.data.*.mail"])
+ format_email = phantom.get_format_data(name="format_email")
+
+ parameters = []
+
+ # build parameters list for 'email_compromised_user' call
+ for filtered_result_0_item_filter_active_accounts in filtered_result_0_data_filter_active_accounts:
+ if filtered_result_0_item_filter_active_accounts[0] is not None and format_email is not None:
+ parameters.append({
+ "to": filtered_result_0_item_filter_active_accounts[0],
+ "subject": "Compromised Account",
+ "body": format_email,
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("send email", parameters=parameters, name="email_compromised_user", assets=["smtp"])
+
+ return
+
+
+@phantom.playbook_block()
+def on_finish(container, summary):
+ phantom.debug("on_finish() called")
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # This function is called after all actions are completed.
+ # summary of all the action and/or all details of actions
+ # can be collected here.
+
+ # summary_json = phantom.get_summary()
+ # if 'result' in summary_json:
+ # for action_result in summary_json['result']:
+ # if 'action_run_id' in action_result:
+ # action_results = phantom.get_action_results(action_run_id=action_result['action_run_id'], result_data=False, flatten=False)
+ # phantom.debug(action_results)
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ return
\ No newline at end of file
diff --git a/recorded_future_threat_hunting.json b/recorded_future_threat_hunting.json
index 25c804d4..3909d0ac 100644
--- a/recorded_future_threat_hunting.json
+++ b/recorded_future_threat_hunting.json
@@ -1,7905 +1,1334 @@
{
"blockly": false,
"blockly_xml": "",
- "category": "Use Cases",
+ "category": "Uncategorized",
"coa": {
"data": {
- "clean": true,
- "code_block": "",
- "description": "Starting with a single IP address, this playbook gathers a list of related IP addresses, domain names, file hashes, and vulnerability CVE's from Recorded Future. Then Splunk is used to build threat hunting lookup tables and search across multiple data sources for events containing the related entities. Finally, IP addresses are blocked if approved by an analyst and an email is sent to notify a responder if more than 10 of a certain kind of entity are matched at once.",
- "hash": "fa075a4d6c461b259e09030f6d972ddc6d8234f4",
- "joint": {
- "cells": [
- {
- "0": "S",
- "1": "T",
- "2": "A",
- "3": "R",
- "4": "T",
- "active": false,
- "angle": 0,
- "attrs": {
- ".background": {
- "fill": "#000000",
- "stroke": "#5C6773"
- },
- ".color-band": {
- "fill": "#3C444D"
- },
- ".outPorts>.port-out": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".outPorts>.port-out>.port-body": {
- "port": {
- "id": "out",
- "type": "out"
- }
- },
- ".title": {
- "ref-x": 33,
- "ref-y": 8,
- "text": "START"
- },
- "g.delete": {
- "display": "none"
- },
- "g.error": {
- "opacity": 0
- },
- "g.icon image": {
- "ref-x": 13,
- "xlink:href": "/inc/coa/img/block_icon_start.svg"
- },
- "g.notes": {
- "display": "block"
- }
- },
- "block_code": "def on_start(container):\n phantom.debug('on_start() called')\n \n # call 'ip_reputation_1' block\n ip_reputation_1(container=container)\n\n return",
- "callback_code": "# read-only block view not available",
- "callback_start": 1,
- "callsback": false,
- "connected_to_start": true,
- "connection_name": "",
- "connection_type": "",
- "custom_callback": "",
- "custom_code": "",
- "custom_join": "",
- "custom_name": "",
- "description": "",
- "has_custom": false,
- "has_custom_block": false,
- "has_custom_callback": false,
- "has_custom_join": false,
- "id": "3a49b8a8-2670-4c0d-b3cf-b7ec600724ee",
- "inPorts": [],
- "join_code": "# read-only block view not available",
- "join_optional": [],
- "join_start": 1,
- "line_end": 16,
- "line_start": 8,
- "name": "",
- "notes": "",
- "number": 0,
- "order": 1,
- "outPorts": [
- "out"
- ],
- "ports": {
- "groups": {
- "in": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "left"
- }
- },
- "position": {
- "name": "left"
- }
- },
- "out": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "right"
- }
- },
- "position": {
- "name": "right"
- }
- }
- }
- },
- "position": {
- "x": -40,
- "y": -40
- },
- "previous_function": "",
- "previous_name": "",
- "show_number": true,
- "size": {
- "height": 54,
- "width": 80
- },
- "status": "",
- "title": "START",
- "type": "coa.StartEnd",
- "warn": false,
- "z": 1
- },
- {
- "0": "E",
- "1": "N",
- "2": "D",
- "active": false,
- "angle": 0,
- "attrs": {
- ".background": {
- "fill": "#000000",
- "stroke": "#5C6773"
- },
- ".color-band": {
- "fill": "#3C444D"
- },
- ".inPorts>.port-in": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".inPorts>.port-in>.port-body": {
- "port": {
- "id": "in",
- "type": "in"
- }
- },
- ".title": {
- "text": "END"
- },
- "g.delete": {
- "display": "none"
- },
- "g.error": {
- "opacity": 0
- },
- "g.icon image": {
- "xlink:href": "/inc/coa/img/block_icon_end.svg"
- },
- "g.notes": {
- "display": "block"
- }
- },
- "block_code": "def on_finish(container, summary):\n phantom.debug('on_finish() called')\n # This function is called after all actions are completed.\n # summary of all the action and/or all details of actions\n # can be collected here.\n\n # summary_json = phantom.get_summary()\n # if 'result' in summary_json:\n # for action_result in summary_json['result']:\n # if 'action_run_id' in action_result:\n # action_results = phantom.get_action_results(action_run_id=action_result['action_run_id'], result_data=False, flatten=False)\n # phantom.debug(action_results)\n\n return",
- "callback_code": "# read-only block view not available",
- "callback_start": 1,
- "callsback": false,
- "connected_to_start": true,
- "connection_name": "recorded_future_threat_hunting_block_ip, send email",
- "connection_type": "action",
- "custom_callback": "",
- "custom_code": "",
- "custom_join": "",
- "custom_name": "",
- "description": "",
- "has_custom": false,
- "has_custom_block": false,
- "has_custom_callback": false,
- "has_custom_join": false,
- "id": "e3c1ff50-556d-43d8-b1f8-c80188c1de12",
- "inPorts": [
- "in"
- ],
- "join_code": "# read-only block view not available",
- "join_optional": [],
- "join_start": 1,
- "line_end": 612,
- "line_start": 599,
- "name": "",
- "notes": "",
- "number": 0,
- "order": 24,
- "outPorts": [],
- "ports": {
- "groups": {
- "in": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "left"
- }
- },
- "position": {
- "name": "left"
- }
- },
- "out": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "right"
- }
- },
- "position": {
- "name": "right"
- }
- }
- }
- },
- "position": {
- "x": 2200,
- "y": -120
- },
- "previous_function": "",
- "previous_name": "",
- "show_number": true,
- "size": {
- "height": 54,
- "width": 80
- },
- "status": "",
- "title": "END",
- "type": "coa.StartEnd",
- "warn": false,
- "z": 2
- },
- {
- "attrs": {
- ".connection": {
- "stroke": "#6C7A89",
- "stroke-width": 2
- },
- ".marker-target": {
- "d": "M 10 0 L 0 5 L 10 10 z",
- "fill": "#6a6c8a",
- "stroke": "#6a6c8a"
- }
- },
- "connector": {
- "args": {
- "radius": 5
- },
- "name": "rounded"
- },
- "endDirections": [
- "left"
- ],
- "id": "afc329a9-6949-4502-8977-6b8e4a2f8155",
- "router": {
- "name": "metro"
- },
- "source": {
- "id": "168d14e9-de64-4a76-8cb9-5488d711f22e",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(2) > g:nth-child(1) > circle:nth-child(1)"
- },
- "startDirections": [
- "right"
- ],
- "target": {
- "id": "ad2d40e7-adc6-488e-95bf-6dc68b3111ee",
- "selector": ".port-body[type=\"input\"]"
- },
- "type": "link",
- "z": 34
- },
- {
- "attrs": {
- ".connection": {
- "stroke": "#6C7A89",
- "stroke-width": 2
- },
- ".marker-target": {
- "d": "M 10 0 L 0 5 L 10 10 z",
- "fill": "#6a6c8a",
- "stroke": "#6a6c8a"
- }
- },
- "connector": {
- "args": {
- "radius": 5
- },
- "name": "rounded"
- },
- "endDirections": [
- "left"
- ],
- "id": "cd9e9d65-2333-4134-8ff2-66decf95f366",
- "router": {
- "name": "metro"
- },
- "source": {
- "id": "f3a05260-dbbc-45da-9e59-644f83693e30",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(2) > g:nth-child(1) > circle:nth-child(1)"
- },
- "startDirections": [
- "right"
- ],
- "target": {
- "id": "4a326ccb-068c-44cb-807b-8d61e39d7fa0",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(1) > g:nth-child(1) > circle:nth-child(1)"
- },
- "type": "link",
- "z": 63
- },
- {
- "attrs": {
- ".connection": {
- "stroke": "#6C7A89",
- "stroke-width": 2
- },
- ".marker-target": {
- "d": "M 10 0 L 0 5 L 10 10 z",
- "fill": "#6a6c8a",
- "stroke": "#6a6c8a"
- }
- },
- "connector": {
- "args": {
- "radius": 5
- },
- "name": "rounded"
- },
- "endDirections": [
- "left"
- ],
- "id": "2ff2f8f4-5515-4554-b26c-788974b4ebed",
- "router": {
- "name": "metro"
- },
- "source": {
- "id": "74bc01bc-1ab1-4296-a880-4dbd087e42ed",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(2) > g:nth-child(1) > circle:nth-child(1)"
- },
- "startDirections": [
- "right"
- ],
- "target": {
- "id": "f3a05260-dbbc-45da-9e59-644f83693e30",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(1) > g:nth-child(1) > circle:nth-child(1)"
- },
- "type": "link",
- "z": 64
- },
- {
- "attrs": {
- ".connection": {
- "stroke": "#6C7A89",
- "stroke-width": 2
- },
- ".marker-target": {
- "d": "M 10 0 L 0 5 L 10 10 z",
- "fill": "#6a6c8a",
- "stroke": "#6a6c8a"
- }
- },
- "connector": {
- "args": {
- "radius": 5
- },
- "name": "rounded"
- },
- "endDirections": [
- "left"
- ],
- "id": "568a9f40-0e72-4072-89ad-b789e176acdf",
- "router": {
- "name": "metro"
- },
- "source": {
- "id": "ad2d40e7-adc6-488e-95bf-6dc68b3111ee",
- "port": "out-1",
- "selector": "g:nth-child(1) > g:nth-child(2) > g:nth-child(1) > circle:nth-child(1)"
- },
- "startDirections": [
- "right"
- ],
- "target": {
- "id": "98eaf55d-cfa9-4f15-bb6c-70a009cb10ef",
- "selector": ".port-body[type=\"input\"]"
- },
- "type": "link",
- "z": 75
- },
- {
- "attrs": {
- ".connection": {
- "stroke": "#6C7A89",
- "stroke-width": 2
- },
- ".marker-target": {
- "d": "M 10 0 L 0 5 L 10 10 z",
- "fill": "#6a6c8a",
- "stroke": "#6a6c8a"
- }
- },
- "connector": {
- "args": {
- "radius": 5
- },
- "name": "rounded"
- },
- "endDirections": [
- "left"
- ],
- "id": "37613476-e026-42f6-be5b-8d41bba6dcb3",
- "router": {
- "name": "metro"
- },
- "source": {
- "id": "98eaf55d-cfa9-4f15-bb6c-70a009cb10ef",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(2) > g:nth-child(1) > circle:nth-child(1)"
- },
- "startDirections": [
- "right"
- ],
- "target": {
- "id": "e3c1ff50-556d-43d8-b1f8-c80188c1de12",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(1) > g:nth-child(1) > circle:nth-child(1)"
- },
- "type": "link",
- "z": 80
- },
- {
- "attrs": {
- ".connection": {
- "stroke": "#6C7A89",
- "stroke-width": 2
- },
- ".marker-target": {
- "d": "M 10 0 L 0 5 L 10 10 z",
- "fill": "#6a6c8a",
- "stroke": "#6a6c8a"
- }
- },
- "connector": {
- "args": {
- "radius": 5
- },
- "name": "rounded"
- },
- "endDirections": [
- "left"
- ],
- "id": "974a1eaf-2715-4099-b13c-7d037927a195",
- "router": {
- "name": "metro"
- },
- "source": {
- "id": "4a326ccb-068c-44cb-807b-8d61e39d7fa0",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(2) > g:nth-child(1) > circle:nth-child(1)"
- },
- "startDirections": [
- "right"
- ],
- "target": {
- "id": "c0301f30-04f3-4248-9f5a-52a62e8fbecc",
- "selector": ".port-body[type=\"input\"]"
- },
- "type": "link",
- "z": 89
+ "description": "Starting with a single IP address, this playbook gathers a list of linked IP addresses, domain names, file hashes, urls, and vulnerability CVE's from Recorded Future. Then Splunk is used to build threat hunting lookup tables and search across multiple data sources for events containing the linked entities. Finally, IP addresses are blocked if approved by an analyst and an email is sent to notify a responder of the activity.",
+ "edges": [
+ {
+ "id": "port_0_to_port_2",
+ "sourceNode": "0",
+ "sourcePort": "0_out",
+ "targetNode": "2",
+ "targetPort": "2_in"
+ },
+ {
+ "id": "port_2_to_port_3",
+ "sourceNode": "2",
+ "sourcePort": "2_out",
+ "targetNode": "3",
+ "targetPort": "3_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 0
+ }
+ ],
+ "id": "port_3_to_port_4",
+ "sourceNode": "3",
+ "sourcePort": "3_out",
+ "targetNode": "4",
+ "targetPort": "4_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 0
+ }
+ ],
+ "id": "port_3_to_port_5",
+ "sourceNode": "3",
+ "sourcePort": "3_out",
+ "targetNode": "5",
+ "targetPort": "5_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 0
+ }
+ ],
+ "id": "port_3_to_port_6",
+ "sourceNode": "3",
+ "sourcePort": "3_out",
+ "targetNode": "6",
+ "targetPort": "6_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 0
+ }
+ ],
+ "id": "port_3_to_port_7",
+ "sourceNode": "3",
+ "sourcePort": "3_out",
+ "targetNode": "7",
+ "targetPort": "7_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 0
+ }
+ ],
+ "id": "port_3_to_port_8",
+ "sourceNode": "3",
+ "sourcePort": "3_out",
+ "targetNode": "8",
+ "targetPort": "8_in"
+ },
+ {
+ "id": "port_4_to_port_9",
+ "sourceNode": "4",
+ "sourcePort": "4_out",
+ "targetNode": "9",
+ "targetPort": "9_in"
+ },
+ {
+ "id": "port_5_to_port_10",
+ "sourceNode": "5",
+ "sourcePort": "5_out",
+ "targetNode": "10",
+ "targetPort": "10_in"
+ },
+ {
+ "id": "port_6_to_port_11",
+ "sourceNode": "6",
+ "sourcePort": "6_out",
+ "targetNode": "11",
+ "targetPort": "11_in"
+ },
+ {
+ "id": "port_7_to_port_12",
+ "sourceNode": "7",
+ "sourcePort": "7_out",
+ "targetNode": "12",
+ "targetPort": "12_in"
+ },
+ {
+ "id": "port_8_to_port_13",
+ "sourceNode": "8",
+ "sourcePort": "8_out",
+ "targetNode": "13",
+ "targetPort": "13_in"
+ },
+ {
+ "id": "port_9_to_port_14",
+ "sourceNode": "9",
+ "sourcePort": "9_out",
+ "targetNode": "14",
+ "targetPort": "14_in"
+ },
+ {
+ "id": "port_10_to_port_15",
+ "sourceNode": "10",
+ "sourcePort": "10_out",
+ "targetNode": "15",
+ "targetPort": "15_in"
+ },
+ {
+ "id": "port_11_to_port_16",
+ "sourceNode": "11",
+ "sourcePort": "11_out",
+ "targetNode": "16",
+ "targetPort": "16_in"
+ },
+ {
+ "id": "port_12_to_port_17",
+ "sourceNode": "12",
+ "sourcePort": "12_out",
+ "targetNode": "17",
+ "targetPort": "17_in"
+ },
+ {
+ "id": "port_13_to_port_18",
+ "sourceNode": "13",
+ "sourcePort": "13_out",
+ "targetNode": "18",
+ "targetPort": "18_in"
+ },
+ {
+ "id": "port_14_to_port_19",
+ "sourceNode": "14",
+ "sourcePort": "14_out",
+ "targetNode": "19",
+ "targetPort": "19_in"
+ },
+ {
+ "id": "port_19_to_port_20",
+ "sourceNode": "19",
+ "sourcePort": "19_out",
+ "targetNode": "20",
+ "targetPort": "20_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 0
+ }
+ ],
+ "id": "port_20_to_port_21",
+ "sourceNode": "20",
+ "sourcePort": "20_out",
+ "targetNode": "21",
+ "targetPort": "21_in"
+ },
+ {
+ "id": "port_15_to_port_22",
+ "sourceNode": "15",
+ "sourcePort": "15_out",
+ "targetNode": "22",
+ "targetPort": "22_in"
+ },
+ {
+ "id": "port_16_to_port_22",
+ "sourceNode": "16",
+ "sourcePort": "16_out",
+ "targetNode": "22",
+ "targetPort": "22_in"
+ },
+ {
+ "id": "port_17_to_port_22",
+ "sourceNode": "17",
+ "sourcePort": "17_out",
+ "targetNode": "22",
+ "targetPort": "22_in"
+ },
+ {
+ "id": "port_18_to_port_22",
+ "sourceNode": "18",
+ "sourcePort": "18_out",
+ "targetNode": "22",
+ "targetPort": "22_in"
+ },
+ {
+ "id": "port_14_to_port_22",
+ "sourceNode": "14",
+ "sourcePort": "14_out",
+ "targetNode": "22",
+ "targetPort": "22_in"
+ },
+ {
+ "id": "port_22_to_port_23",
+ "sourceNode": "22",
+ "sourcePort": "22_out",
+ "targetNode": "23",
+ "targetPort": "23_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 0
+ }
+ ],
+ "id": "port_23_to_port_25",
+ "sourceNode": "23",
+ "sourcePort": "23_out",
+ "targetNode": "25",
+ "targetPort": "25_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 0
+ }
+ ],
+ "id": "port_23_to_port_26",
+ "sourceNode": "23",
+ "sourcePort": "23_out",
+ "targetNode": "26",
+ "targetPort": "26_in"
+ },
+ {
+ "id": "port_26_to_port_1",
+ "sourceNode": "26",
+ "sourcePort": "26_out",
+ "targetNode": "1",
+ "targetPort": "1_in"
+ },
+ {
+ "id": "port_25_to_port_1",
+ "sourceNode": "25",
+ "sourcePort": "25_out",
+ "targetNode": "1",
+ "targetPort": "1_in"
+ },
+ {
+ "id": "port_21_to_port_1",
+ "sourceNode": "21",
+ "sourcePort": "21_out",
+ "targetNode": "1",
+ "targetPort": "1_in"
+ }
+ ],
+ "hash": "93ea468ac323c3efc201469bf59233c67b9179a2",
+ "nodes": {
+ "0": {
+ "data": {
+ "advanced": {
+ "join": []
+ },
+ "functionName": "on_start",
+ "id": "0",
+ "type": "start"
},
- {
- "attrs": {
- ".connection": {
- "stroke": "#6C7A89",
- "stroke-width": 2
- },
- ".marker-target": {
- "d": "M 10 0 L 0 5 L 10 10 z",
- "fill": "#6a6c8a",
- "stroke": "#6a6c8a"
- }
- },
- "connector": {
- "args": {
- "radius": 5
- },
- "name": "rounded"
- },
- "endDirections": [
- "left"
- ],
- "id": "e1e12c23-b246-4607-b0e2-5ad9044bc272",
- "router": {
- "name": "metro"
- },
- "source": {
- "id": "c0301f30-04f3-4248-9f5a-52a62e8fbecc",
- "port": "out-1",
- "selector": "g:nth-child(1) > g:nth-child(2) > g:nth-child(1) > circle:nth-child(1)"
- },
- "startDirections": [
- "right"
- ],
- "target": {
- "id": "f4638aa4-0b35-4b81-ba9c-21bf905d70ad",
- "selector": ".port-body[type=\"input\"]"
- },
- "type": "link",
- "z": 91
+ "errors": {},
+ "id": "0",
+ "type": "start",
+ "x": 1080,
+ "y": 359.9999999999999
+ },
+ "1": {
+ "data": {
+ "advanced": {
+ "join": []
+ },
+ "functionId": 1,
+ "functionName": "on_finish",
+ "id": "1",
+ "type": "end"
},
- {
- "attrs": {
- ".connection": {
- "stroke": "#6C7A89",
- "stroke-width": 2
+ "errors": {},
+ "id": "1",
+ "type": "end",
+ "userCode": "\n # This function is called after all actions are completed.\n # summary of all the action and/or all details of actions\n # can be collected here.\n\n # summary_json = phantom.get_summary()\n # if 'result' in summary_json:\n # for action_result in summary_json['result']:\n # if 'action_run_id' in action_result:\n # action_results = phantom.get_action_results(action_run_id=action_result['action_run_id'], result_data=False, flatten=False)\n # phantom.debug(action_results)\n\n",
+ "x": 1000,
+ "y": 1840
+ },
+ "10": {
+ "data": {
+ "action": "run query",
+ "actionType": "investigate",
+ "advanced": {
+ "customName": "build domain lookup",
+ "customNameId": 0,
+ "description": "Run the Splunk query that creates the lookup file",
+ "join": [],
+ "note": "Run the Splunk query that creates the lookup file"
+ },
+ "connector": "Splunk",
+ "connectorConfigs": [
+ "splunk"
+ ],
+ "connectorId": "91883aa8-9c81-470b-97a1-5d8f7995f560",
+ "connectorVersion": "v1",
+ "functionId": 2,
+ "functionName": "build_domain_lookup",
+ "id": "10",
+ "parameters": {
+ "command": "| makeresults",
+ "query": "format_linked_domain_lookup:formatted_data"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "field": "query"
},
- ".marker-target": {
- "d": "M 10 0 L 0 5 L 10 10 z",
- "fill": "#6a6c8a",
- "stroke": "#6a6c8a"
+ {
+ "data_type": "string",
+ "default": "search",
+ "field": "command"
}
- },
- "connector": {
- "args": {
- "radius": 5
- },
- "name": "rounded"
- },
- "endDirections": [
- "left"
- ],
- "id": "98196786-d28e-473f-b5cb-d25a0d8c2f65",
- "router": {
- "name": "metro"
- },
- "source": {
- "id": "f4638aa4-0b35-4b81-ba9c-21bf905d70ad",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(2) > g:nth-child(1) > circle:nth-child(1)"
- },
- "startDirections": [
- "right"
],
- "target": {
- "id": "6789cc3c-fa14-455f-a49f-a3077b1f483c",
- "selector": ".port-body[type=\"input\"]"
- },
- "type": "link",
- "z": 95
+ "type": "action"
},
- {
- "attrs": {
- ".connection": {
- "stroke": "#6C7A89",
- "stroke-width": 2
+ "errors": {},
+ "id": "10",
+ "type": "action",
+ "x": 740,
+ "y": 984.5
+ },
+ "11": {
+ "data": {
+ "action": "run query",
+ "actionType": "investigate",
+ "advanced": {
+ "customName": "build file lookup",
+ "customNameId": 0,
+ "description": "Run the Splunk query that creates the lookup file",
+ "join": [],
+ "note": "Run the Splunk query that creates the lookup file"
+ },
+ "connector": "Splunk",
+ "connectorConfigs": [
+ "splunk"
+ ],
+ "connectorId": "91883aa8-9c81-470b-97a1-5d8f7995f560",
+ "connectorVersion": "v1",
+ "functionId": 3,
+ "functionName": "build_file_lookup",
+ "id": "11",
+ "parameters": {
+ "command": "| makeresults",
+ "query": "format_linked_files_lookup:formatted_data"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "field": "query"
},
- ".marker-target": {
- "d": "M 10 0 L 0 5 L 10 10 z",
- "fill": "#6a6c8a",
- "stroke": "#6a6c8a"
+ {
+ "data_type": "string",
+ "default": "search",
+ "field": "command"
}
- },
- "connector": {
- "args": {
- "radius": 5
- },
- "name": "rounded"
- },
- "endDirections": [
- "left"
- ],
- "id": "1263797a-1c5d-4665-9cb2-ece516f4594e",
- "router": {
- "name": "metro"
- },
- "source": {
- "id": "6789cc3c-fa14-455f-a49f-a3077b1f483c",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(2) > g:nth-child(1) > circle:nth-child(1)"
- },
- "startDirections": [
- "right"
],
- "target": {
- "id": "e3c1ff50-556d-43d8-b1f8-c80188c1de12",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(1) > g:nth-child(1) > circle:nth-child(1)"
- },
- "type": "link",
- "z": 97
+ "type": "action"
},
- {
- "attrs": {
- ".connection": {
- "stroke": "#6C7A89",
- "stroke-width": 2
+ "errors": {},
+ "id": "11",
+ "type": "action",
+ "x": 1060,
+ "y": 1020
+ },
+ "12": {
+ "data": {
+ "action": "run query",
+ "actionType": "investigate",
+ "advanced": {
+ "customName": "build vuln lookup",
+ "customNameId": 0,
+ "description": "Run the Splunk query that creates the lookup file",
+ "join": [],
+ "note": "Run the Splunk query that creates the lookup file"
+ },
+ "connector": "Splunk",
+ "connectorConfigs": [
+ "splunk"
+ ],
+ "connectorId": "91883aa8-9c81-470b-97a1-5d8f7995f560",
+ "connectorVersion": "v1",
+ "functionId": 4,
+ "functionName": "build_vuln_lookup",
+ "id": "12",
+ "parameters": {
+ "command": "| makeresults",
+ "query": "format_linked_vuln_lookup:formatted_data"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "field": "query"
},
- ".marker-target": {
- "d": "M 10 0 L 0 5 L 10 10 z",
- "fill": "#6a6c8a",
- "stroke": "#6a6c8a"
+ {
+ "data_type": "string",
+ "default": "search",
+ "field": "command"
}
- },
- "connector": {
- "args": {
- "radius": 5
- },
- "name": "rounded"
- },
- "endDirections": [
- "left"
- ],
- "id": "a8694526-ed48-466c-97f3-9c96707dc6dd",
- "router": {
- "name": "metro"
- },
- "source": {
- "id": "a8a36be4-700d-45bb-a10f-ebe21cba0d62",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(2) > g:nth-child(1) > circle:nth-child(1)"
- },
- "startDirections": [
- "right"
],
- "target": {
- "id": "c121d149-c163-4140-bf66-bc31a20e99ad",
- "selector": ".port-body[type=\"input\"]"
- },
- "type": "link",
- "z": 113
+ "type": "action"
},
- {
- "attrs": {
- ".connection": {
- "stroke": "#6C7A89",
- "stroke-width": 2
+ "errors": {},
+ "id": "12",
+ "type": "action",
+ "x": 1380,
+ "y": 984.5
+ },
+ "13": {
+ "data": {
+ "action": "run query",
+ "actionType": "investigate",
+ "advanced": {
+ "customName": "build url lookup",
+ "customNameId": 0,
+ "description": "Run the Splunk query that creates the lookup file",
+ "join": [],
+ "note": "Run the Splunk query that creates the lookup file"
+ },
+ "connector": "Splunk",
+ "connectorConfigs": [
+ "splunk"
+ ],
+ "connectorId": "91883aa8-9c81-470b-97a1-5d8f7995f560",
+ "connectorVersion": "v1",
+ "functionId": 5,
+ "functionName": "build_url_lookup",
+ "id": "13",
+ "parameters": {
+ "command": "| makeresults",
+ "query": "format_linked_url_lookup:formatted_data"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "field": "query"
},
- ".marker-target": {
- "d": "M 10 0 L 0 5 L 10 10 z",
- "fill": "#6a6c8a",
- "stroke": "#6a6c8a"
+ {
+ "data_type": "string",
+ "default": "search",
+ "field": "command"
}
- },
- "connector": {
- "args": {
- "radius": 5
- },
- "name": "rounded"
- },
- "endDirections": [
- "left"
- ],
- "id": "34c5b44e-7073-4828-b92c-56cb3144cd83",
- "router": {
- "name": "metro"
- },
- "source": {
- "id": "f1d8c308-f8af-4466-9397-cfde303f21ac",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(2) > g:nth-child(1) > circle:nth-child(1)"
- },
- "startDirections": [
- "right"
],
- "target": {
- "id": "c5e8d349-03a6-41ad-9162-68f9db1a7486",
- "selector": ".port-body[type=\"input\"]"
- },
- "type": "link",
- "z": 119
+ "type": "action"
},
- {
- "attrs": {
- ".connection": {
- "stroke": "#6C7A89",
- "stroke-width": 2
+ "errors": {},
+ "id": "13",
+ "type": "action",
+ "x": 1680,
+ "y": 980
+ },
+ "14": {
+ "data": {
+ "action": "run query",
+ "actionType": "investigate",
+ "advanced": {
+ "customName": "search splunk for ips",
+ "customNameId": 0,
+ "description": "Search Palo Alto Networks firewall logs for any events with threat-related ip addresses in the dest_ip field",
+ "join": [],
+ "note": "Search Palo Alto Networks firewall logs for any events with threat-related ip addresses in the dest_ip field"
+ },
+ "connector": "Splunk",
+ "connectorConfigs": [
+ "splunk"
+ ],
+ "connectorId": "91883aa8-9c81-470b-97a1-5d8f7995f560",
+ "connectorVersion": "v1",
+ "functionId": 6,
+ "functionName": "search_splunk_for_ips",
+ "id": "14",
+ "parameters": {
+ "command": "search",
+ "query": "sourcetype=\"netscreen:firewall\" ((earliest=-24h latest=now)) |eval Name=dest_ip | lookup huntip.csv Name OUTPUT RF_Risk_Score | search RF_Risk_Score>24"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "field": "query"
},
- ".marker-target": {
- "d": "M 10 0 L 0 5 L 10 10 z",
- "fill": "#6a6c8a",
- "stroke": "#6a6c8a"
+ {
+ "data_type": "string",
+ "default": "search",
+ "field": "command"
}
- },
- "connector": {
- "args": {
- "radius": 5
- },
- "name": "rounded"
- },
- "endDirections": [
- "left"
- ],
- "id": "8960fe80-e9f0-4ea1-a085-8330bd9b26a0",
- "router": {
- "name": "metro"
- },
- "source": {
- "id": "2fc7308a-1d54-48f2-8d63-ab8e71a5c933",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(2) > g:nth-child(1) > circle:nth-child(1)"
- },
- "startDirections": [
- "right"
],
- "target": {
- "id": "bab7c570-8780-408c-a520-b56a5587964b",
- "selector": ".port-body[type=\"input\"]"
- },
- "type": "link",
- "z": 126
+ "type": "action"
},
- {
- "attrs": {
- ".connection": {
- "stroke": "#6C7A89",
- "stroke-width": 2
+ "errors": {},
+ "id": "14",
+ "type": "action",
+ "x": 440,
+ "y": 1180
+ },
+ "15": {
+ "data": {
+ "action": "run query",
+ "actionType": "investigate",
+ "advanced": {
+ "customName": "search splunk for domains",
+ "customNameId": 0,
+ "description": "Search Palo Alto Networks threat logs for any events with threat-related domain names in the dest_hostname field",
+ "join": [],
+ "note": "Search Palo Alto Networks threat logs for any events with threat-related domain names in the dest_hostname field"
+ },
+ "connector": "Splunk",
+ "connectorConfigs": [
+ "splunk"
+ ],
+ "connectorId": "91883aa8-9c81-470b-97a1-5d8f7995f560",
+ "connectorVersion": "v1",
+ "functionId": 7,
+ "functionName": "search_splunk_for_domains",
+ "id": "15",
+ "parameters": {
+ "command": "search",
+ "query": "sourcetype=\"netscreen:firewall\" ((earliest=-24h latest=now)) |eval Name=dest_ip | lookup huntip.csv Name OUTPUT RF_Risk_Score | search RF_Risk_Score>24"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "field": "query"
},
- ".marker-target": {
- "d": "M 10 0 L 0 5 L 10 10 z",
- "fill": "#6a6c8a",
- "stroke": "#6a6c8a"
+ {
+ "data_type": "string",
+ "default": "search",
+ "field": "command"
}
- },
- "connector": {
- "args": {
- "radius": 5
- },
- "name": "rounded"
- },
- "endDirections": [
- "left"
- ],
- "id": "81acc606-e94c-4b0d-8534-e4a4625e2cbe",
- "router": {
- "name": "metro"
- },
- "source": {
- "id": "c121d149-c163-4140-bf66-bc31a20e99ad",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(2) > g:nth-child(1) > circle:nth-child(1)"
- },
- "startDirections": [
- "right"
],
- "target": {
- "id": "27474fdc-e2a7-4347-a1ed-57a84fb43d10",
- "selector": ".port-body[type=\"input\"]"
- },
- "type": "link",
- "z": 140
+ "type": "action"
},
- {
- "attrs": {
- ".connection": {
- "stroke": "#6C7A89",
- "stroke-width": 2
+ "errors": {},
+ "id": "15",
+ "type": "action",
+ "x": 740,
+ "y": 1180
+ },
+ "16": {
+ "data": {
+ "action": "run query",
+ "actionType": "investigate",
+ "advanced": {
+ "customName": "search splunk for files",
+ "customNameId": 0,
+ "description": "Search Symantec Endpoint Protection logs for sightings of threat-related file hashes",
+ "join": [],
+ "note": "Search Symantec Endpoint Protection logs for sightings of threat-related file hashes"
+ },
+ "connector": "Splunk",
+ "connectorConfigs": [
+ "splunk"
+ ],
+ "connectorId": "91883aa8-9c81-470b-97a1-5d8f7995f560",
+ "connectorVersion": "v1",
+ "functionId": 8,
+ "functionName": "search_splunk_for_files",
+ "id": "16",
+ "parameters": {
+ "command": "search",
+ "query": "index=main sourcetype=symantec:ep:risk:file ((earliest=-1d latest=now)) |eval Name=file_hash | lookup huntfile.csv Name OUTPUT RF_Risk_Score | search RF_Risk_Score>24"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "field": "query"
},
- ".marker-target": {
- "d": "M 10 0 L 0 5 L 10 10 z",
- "fill": "#6a6c8a",
- "stroke": "#6a6c8a"
+ {
+ "data_type": "string",
+ "default": "search",
+ "field": "command"
}
- },
- "connector": {
- "args": {
- "radius": 5
- },
- "name": "rounded"
- },
- "endDirections": [
- "left"
- ],
- "id": "047f3664-c3ea-495c-8fc7-c67be4ec04f5",
- "router": {
- "name": "metro"
- },
- "source": {
- "id": "c5e8d349-03a6-41ad-9162-68f9db1a7486",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(2) > g:nth-child(1) > circle:nth-child(1)"
- },
- "startDirections": [
- "right"
],
- "target": {
- "id": "9a6151b0-b266-4c62-931d-bbaf3b943ebe",
- "selector": ".port-body[type=\"input\"]"
- },
- "type": "link",
- "z": 147
+ "type": "action"
},
- {
- "attrs": {
- ".connection": {
- "stroke": "#6C7A89",
- "stroke-width": 2
+ "errors": {},
+ "id": "16",
+ "type": "action",
+ "x": 1060,
+ "y": 1180
+ },
+ "17": {
+ "data": {
+ "action": "run query",
+ "actionType": "investigate",
+ "advanced": {
+ "customName": "search splunk for vulns",
+ "customNameId": 0,
+ "description": "Search Tenable vulnerability scanning logs for any vulnerabilities related to the initial IP addresses",
+ "join": [],
+ "note": "Search Tenable vulnerability scanning logs for any vulnerabilities related to the initial IP addresses"
+ },
+ "connector": "Splunk",
+ "connectorConfigs": [
+ "splunk"
+ ],
+ "connectorId": "91883aa8-9c81-470b-97a1-5d8f7995f560",
+ "connectorVersion": "v1",
+ "functionId": 9,
+ "functionName": "search_splunk_for_vulns",
+ "id": "17",
+ "parameters": {
+ "command": "search",
+ "query": "index=main sourcetype=\"tenable:sc:vuln\" ((earliest=-7d latest=now)) |eval Name=cve | lookup huntvuln.csv Name OUTPUT RF_Risk_Score | search RF_Risk_Score>24"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "field": "query"
},
- ".marker-target": {
- "d": "M 10 0 L 0 5 L 10 10 z",
- "fill": "#6a6c8a",
- "stroke": "#6a6c8a"
+ {
+ "data_type": "string",
+ "default": "search",
+ "field": "command"
}
- },
- "connector": {
- "args": {
- "radius": 5
- },
- "name": "rounded"
- },
- "endDirections": [
- "left"
- ],
- "id": "31fbd420-abe8-4bc5-be56-bd6c53bf3be8",
- "router": {
- "name": "metro"
- },
- "source": {
- "id": "bab7c570-8780-408c-a520-b56a5587964b",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(2) > g:nth-child(1) > circle:nth-child(1)"
- },
- "startDirections": [
- "right"
],
- "target": {
- "id": "2581c9e7-6a6c-488d-bff2-720a5e906763",
- "selector": ".port-body[type=\"input\"]"
- },
- "type": "link",
- "z": 150
+ "type": "action"
},
- {
- "attrs": {
- ".connection": {
- "stroke": "#6C7A89",
- "stroke-width": 2
+ "errors": {},
+ "id": "17",
+ "type": "action",
+ "x": 1380,
+ "y": 1164.5
+ },
+ "18": {
+ "data": {
+ "action": "run query",
+ "actionType": "investigate",
+ "advanced": {
+ "customName": "search splunk for urls",
+ "customNameId": 0,
+ "description": "Search Squid Proxy logs for any URLs related to the initial IP addresses",
+ "join": [],
+ "note": "Search Squid Proxy logs for any URLs related to the initial IP addresses"
+ },
+ "connector": "Splunk",
+ "connectorConfigs": [
+ "splunk"
+ ],
+ "connectorId": "91883aa8-9c81-470b-97a1-5d8f7995f560",
+ "connectorVersion": "v1",
+ "functionId": 10,
+ "functionName": "search_splunk_for_urls",
+ "id": "18",
+ "parameters": {
+ "command": "search",
+ "query": "index=main sourcetype=\"squid:access\" ((earliest=-24h latest=now)) |eval Name=url | lookup hunturl.csv Name OUTPUT RF_Risk_Score | search RF_Risk_Score>24"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "field": "query"
},
- ".marker-target": {
- "d": "M 10 0 L 0 5 L 10 10 z",
- "fill": "#6a6c8a",
- "stroke": "#6a6c8a"
+ {
+ "data_type": "string",
+ "default": "search",
+ "field": "command"
}
- },
- "connector": {
- "args": {
- "radius": 5
- },
- "name": "rounded"
- },
- "endDirections": [
- "left"
- ],
- "id": "2d81cf80-e389-4859-923a-00ca49be4096",
- "router": {
- "name": "metro"
- },
- "source": {
- "id": "27474fdc-e2a7-4347-a1ed-57a84fb43d10",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(2) > g:nth-child(1) > circle:nth-child(1)"
- },
- "startDirections": [
- "right"
],
- "target": {
- "id": "c0301f30-04f3-4248-9f5a-52a62e8fbecc",
- "port": "in",
- "selector": "g:nth-child(1) > g:nth-child(1) > g:nth-child(1) > circle:nth-child(1)"
- },
- "type": "link",
- "z": 153
+ "type": "action"
},
- {
- "attrs": {
- ".connection": {
- "stroke": "#6C7A89",
- "stroke-width": 2
- },
- ".marker-target": {
- "d": "M 10 0 L 0 5 L 10 10 z",
- "fill": "#6a6c8a",
- "stroke": "#6a6c8a"
- }
- },
- "connector": {
- "args": {
- "radius": 5
- },
- "name": "rounded"
- },
- "endDirections": [
- "left"
- ],
- "id": "601bac47-bed3-4589-8316-7d8e8e083399",
- "router": {
- "name": "metro"
- },
- "source": {
- "id": "9a6151b0-b266-4c62-931d-bbaf3b943ebe",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(2) > g:nth-child(1) > circle:nth-child(1)"
+ "errors": {},
+ "id": "18",
+ "type": "action",
+ "x": 1680,
+ "y": 1180
+ },
+ "19": {
+ "data": {
+ "advanced": {
+ "customName": "recorded_future_threat_hunting_block_ip",
+ "customNameId": 0,
+ "description": "Ask an analyst whether the discovered related IP addresses should be blocked",
+ "join": [],
+ "note": "Ask an analyst whether the discovered related IP addresses should be blocked"
},
- "startDirections": [
- "right"
+ "approver": "admin",
+ "functionId": 1,
+ "functionName": "recorded_future_threat_hunting_block_ip",
+ "id": "19",
+ "message": "Do you want to add the following IP(s) to the block IP block list:\n{0}",
+ "parameters": [
+ "search_splunk_for_ips:action_result.data.*.IP"
],
- "target": {
- "id": "c0301f30-04f3-4248-9f5a-52a62e8fbecc",
- "port": "in",
- "selector": "g:nth-child(1) > g:nth-child(1) > g:nth-child(1) > circle:nth-child(1)"
- },
- "type": "link",
- "z": 154
- },
- {
- "attrs": {
- ".connection": {
- "stroke": "#6C7A89",
- "stroke-width": 2
- },
- ".marker-target": {
- "d": "M 10 0 L 0 5 L 10 10 z",
- "fill": "#6a6c8a",
- "stroke": "#6a6c8a"
+ "responseTime": 30,
+ "responses": [
+ {
+ "responseOptions": [
+ "Yes",
+ "No"
+ ],
+ "responsePrompt": "Block IPs?",
+ "responseType": "yes/no"
}
- },
- "connector": {
- "args": {
- "radius": 5
- },
- "name": "rounded"
- },
- "endDirections": [
- "left"
- ],
- "id": "d6b3ed0c-8891-454e-9fbd-274ea56225b9",
- "router": {
- "name": "metro"
- },
- "source": {
- "id": "2581c9e7-6a6c-488d-bff2-720a5e906763",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(2) > g:nth-child(1) > circle:nth-child(1)"
- },
- "startDirections": [
- "right"
],
- "target": {
- "id": "c0301f30-04f3-4248-9f5a-52a62e8fbecc",
- "port": "in",
- "selector": "g:nth-child(1) > g:nth-child(1) > g:nth-child(1) > circle:nth-child(1)"
- },
- "type": "link",
- "z": 155
+ "type": "prompt"
},
- {
- "attrs": {
- ".connection": {
- "stroke": "#818D99",
- "stroke-width": 2
- },
- ".marker-target": {
- "d": "M 10 0 L 0 5 L 10 10 z",
- "fill": "#818D99",
- "stroke": "#818D99"
- }
- },
- "connector": {
- "args": {
- "radius": 5
- },
- "name": "rounded"
- },
- "endDirections": [
- "left"
- ],
- "id": "40d97d25-8df8-4ac4-a5c5-d93e1f3b809f",
- "router": {
- "name": "metro"
- },
- "source": {
- "id": "f94b9f2a-8c01-44a8-8d02-55e37d88a888",
- "port": "out-3",
- "selector": "g:nth-child(1) > g:nth-child(2) > g:nth-child(3) > circle:nth-child(1)"
- },
- "startDirections": [
- "right"
- ],
- "target": {
- "id": "74bc01bc-1ab1-4296-a880-4dbd087e42ed",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(1) > g:nth-child(1) > circle:nth-child(1)"
+ "errors": {},
+ "id": "19",
+ "type": "prompt",
+ "x": 520,
+ "y": 1340
+ },
+ "2": {
+ "data": {
+ "action": "ip intelligence",
+ "actionType": "investigate",
+ "advanced": {
+ "description": "Query for the full context about the IP address and related entities from Recorded Future",
+ "join": [],
+ "note": "Query for the full context about the IP address and related entities from Recorded Future"
+ },
+ "connector": "Recorded Future",
+ "connectorConfigs": [
+ "recorded future "
+ ],
+ "connectorId": "6efe0e1b-76ac-4ffd-8fa0-ac58fd6efd77",
+ "connectorVersion": "v1",
+ "functionId": 1,
+ "functionName": "ip_intelligence_1",
+ "id": "2",
+ "parameters": {
+ "ip": "artifact:*.cef.destinationAddress"
},
- "type": "link",
- "z": 221
- },
- {
- "attrs": {
- ".connection": {
- "stroke": "#818D99",
- "stroke-width": 2
- },
- ".marker-target": {
- "d": "M 10 0 L 0 5 L 10 10 z",
- "fill": "#818D99",
- "stroke": "#818D99"
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "field": "ip"
}
- },
- "connector": {
- "args": {
- "radius": 5
- },
- "name": "rounded"
- },
- "endDirections": [
- "left"
- ],
- "id": "c5a1e45f-e676-47a7-888a-43eb7f5500c5",
- "router": {
- "name": "metro"
- },
- "source": {
- "id": "f94b9f2a-8c01-44a8-8d02-55e37d88a888",
- "port": "out-4",
- "selector": "g:nth-child(1) > g:nth-child(2) > g:nth-child(4) > circle:nth-child(1)"
- },
- "startDirections": [
- "right"
- ],
- "target": {
- "id": "a8a36be4-700d-45bb-a10f-ebe21cba0d62",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(1) > g:nth-child(1) > circle:nth-child(1)"
- },
- "type": "link",
- "z": 222
- },
- {
- "attrs": {
- ".connection": {
- "stroke": "#818D99",
- "stroke-width": 2
- },
- ".marker-target": {
- "d": "M 10 0 L 0 5 L 10 10 z",
- "fill": "#818D99",
- "stroke": "#818D99"
- }
- },
- "connector": {
- "args": {
- "radius": 5
- },
- "name": "rounded"
- },
- "endDirections": [
- "left"
- ],
- "id": "1fd1517e-16da-43a7-ac04-714d2bd6d4da",
- "router": {
- "name": "metro"
- },
- "source": {
- "id": "f94b9f2a-8c01-44a8-8d02-55e37d88a888",
- "port": "out-1",
- "selector": "g:nth-child(1) > g:nth-child(2) > g:nth-child(1) > circle:nth-child(1)"
- },
- "startDirections": [
- "right"
- ],
- "target": {
- "id": "f1d8c308-f8af-4466-9397-cfde303f21ac",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(1) > g:nth-child(1) > circle:nth-child(1)"
- },
- "type": "link",
- "z": 224
- },
- {
- "attrs": {
- ".connection": {
- "stroke": "#818D99",
- "stroke-width": 2
- },
- ".marker-target": {
- "d": "M 10 0 L 0 5 L 10 10 z",
- "fill": "#818D99",
- "stroke": "#818D99"
- }
- },
- "connector": {
- "args": {
- "radius": 5
- },
- "name": "rounded"
- },
- "endDirections": [
- "left"
- ],
- "id": "30479cf7-14d2-4221-9867-fa2bf44055d2",
- "router": {
- "name": "metro"
- },
- "source": {
- "id": "f94b9f2a-8c01-44a8-8d02-55e37d88a888",
- "port": "out-2",
- "selector": "g:nth-child(1) > g:nth-child(2) > g:nth-child(2) > circle:nth-child(1)"
- },
- "startDirections": [
- "right"
- ],
- "target": {
- "id": "2fc7308a-1d54-48f2-8d63-ab8e71a5c933",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(1) > g:nth-child(1) > circle:nth-child(1)"
- },
- "type": "link",
- "z": 227
- },
- {
- "attrs": {
- ".connection": {
- "stroke": "#818D99",
- "stroke-width": 2
- },
- ".marker-target": {
- "d": "M 10 0 L 0 5 L 10 10 z",
- "fill": "#818D99",
- "stroke": "#818D99"
- }
- },
- "connector": {
- "args": {
- "radius": 5
- },
- "name": "rounded"
- },
- "endDirections": [
- "left"
- ],
- "id": "37902eff-dfe6-4c93-9408-f64fbcb9ebeb",
- "router": {
- "name": "metro"
- },
- "source": {
- "id": "3a49b8a8-2670-4c0d-b3cf-b7ec600724ee",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(2) > g:nth-child(1) > circle:nth-child(1)"
- },
- "startDirections": [
- "right"
- ],
- "target": {
- "id": "0330e559-47a5-40e6-96ac-629532bcbeac",
- "selector": ".port-body[type=\"input\"]"
- },
- "type": "link",
- "z": 238
- },
- {
- "attrs": {
- ".connection": {
- "stroke": "#818D99",
- "stroke-width": 2
- },
- ".marker-target": {
- "d": "M 10 0 L 0 5 L 10 10 z",
- "fill": "#818D99",
- "stroke": "#818D99"
- }
- },
- "connector": {
- "args": {
- "radius": 5
- },
- "name": "rounded"
- },
- "endDirections": [
- "left"
- ],
- "id": "68edc10c-f591-4890-891e-ea649e3de9d9",
- "router": {
- "name": "metro"
- },
- "source": {
- "id": "0330e559-47a5-40e6-96ac-629532bcbeac",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(2) > g:nth-child(1) > circle:nth-child(1)"
- },
- "startDirections": [
- "right"
- ],
- "target": {
- "id": "9a2f421f-4963-4326-a188-895a92cb08ee",
- "port": "in",
- "selector": "g:nth-child(1) > g:nth-child(1) > g:nth-child(1) > circle:nth-child(1)"
- },
- "type": "link",
- "z": 242
- },
- {
- "attrs": {
- ".connection": {
- "stroke": "#818D99",
- "stroke-width": 2
- },
- ".marker-target": {
- "d": "M 10 0 L 0 5 L 10 10 z",
- "fill": "#818D99",
- "stroke": "#818D99"
- }
- },
- "connector": {
- "args": {
- "radius": 5
- },
- "name": "rounded"
- },
- "endDirections": [
- "left"
- ],
- "id": "055fe7cf-2ff9-49ae-9e7c-ac5926a02756",
- "router": {
- "name": "metro"
- },
- "source": {
- "id": "8c84ebd6-735f-4014-88e1-8feffde0dcaa",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(2) > g:nth-child(1) > circle:nth-child(1)"
- },
- "startDirections": [
- "right"
- ],
- "target": {
- "id": "f94b9f2a-8c01-44a8-8d02-55e37d88a888",
- "port": "in",
- "selector": "g:nth-child(1) > g:nth-child(1) > g:nth-child(1) > circle:nth-child(1)"
- },
- "type": "link",
- "z": 244
- },
- {
- "action": "ip reputation",
- "action_type": "investigate",
- "active": false,
- "active_keys": {},
- "active_values": {
- "ip": "artifact:*.cef.destinationAddress"
- },
- "angle": 0,
- "app": "Recorded Future",
- "appid": "6efe0e1b-76ac-4ffd-8fa0-ac58fd6efd77",
- "approver": "",
- "assets": [
- {
- "action": "ip reputation",
- "actions": [
- "ip reputation",
- "ip intelligence",
- "domain reputation",
- "domain intelligence",
- "file reputation",
- "file intelligence",
- "vulnerability reputation",
- "vulnerability intelligence",
- "url reputation",
- "url intelligence",
- "alert rule lookup",
- "alert data lookup",
- "test connectivity"
- ],
- "active": true,
- "app_name": "Recorded Future",
- "app_version": "1.2.0",
- "appid": "6efe0e1b-76ac-4ffd-8fa0-ac58fd6efd77",
- "asset_name": "recorded-future",
- "config_type": "asset",
- "count": 0,
- "fields": {
- "ip": "artifact:*.cef.destinationAddress"
- },
- "has_app": true,
- "id": 6,
- "loaded": false,
- "missing": false,
- "name": "recorded_future",
- "output": [
- {
- "contains": [
- "recordedfuture result status"
- ],
- "data_path": "action_result.status",
- "data_type": "string",
- "example_values": [
- "success",
- "failed"
- ]
- },
- {
- "contains": [
- "recordedfuture entity id"
- ],
- "data_path": "action_result.data.*.id",
- "data_type": "string"
- },
- {
- "contains": [
- "ip",
- "ipv6"
- ],
- "data_path": "action_result.data.*.name",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture entity type"
- ],
- "data_path": "action_result.data.*.type",
- "data_type": "string",
- "example_values": [
- "IpAddress"
- ]
- },
- {
- "contains": [
- "recordedfuture risk level"
- ],
- "data_path": "action_result.data.*.risklevel",
- "data_type": "numeric"
- },
- {
- "contains": [
- "recordedfuture rule count"
- ],
- "data_path": "action_result.data.*.rulecount",
- "data_type": "numeric"
- },
- {
- "contains": [
- "recordedfuture risk rule id"
- ],
- "data_path": "action_result.data.*.evidence.ruleid",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture evidence timestamp"
- ],
- "data_path": "action_result.data.*.evidence.timestamp",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture evidence mitigation"
- ],
- "data_path": "action_result.data.*.evidence.mitigation",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture evidence description"
- ],
- "data_path": "action_result.data.*.evidence.description",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture risk rule"
- ],
- "data_path": "action_result.data.*.evidence.rule",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture evidence level"
- ],
- "data_path": "action_result.data.*.evidence.level",
- "data_type": "numeric"
- },
- {
- "contains": [
- "recordedfuture max rules"
- ],
- "data_path": "action_result.data.*.maxrules",
- "data_type": "numeric"
- },
- {
- "contains": [
- "recordedfuture risk score"
- ],
- "data_path": "action_result.data.*.riskscore",
- "data_type": "numeric"
- },
- {
- "contains": [
- "recordedfuture result message"
- ],
- "data_path": "action_result.message",
- "data_type": "string"
- },
- {
- "contains": [
- "ip",
- "ipv6"
- ],
- "data_path": "action_result.parameter.ip",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture risk score"
- ],
- "data_path": "action_result.summary.riskscore",
- "data_type": "numeric"
- },
- {
- "contains": [
- "recordedfuture entity type"
- ],
- "data_path": "action_result.summary.type",
- "data_type": "string",
- "example_values": [
- "IpAddress"
- ]
- },
- {
- "contains": [
- "recordedfuture risk level"
- ],
- "data_path": "action_result.summary.risklevel",
- "data_type": "numeric"
- },
- {
- "contains": [
- "recordedfuture total objects"
- ],
- "data_path": "summary.total_objects",
- "data_type": "numeric",
- "example_values": [
- 1
- ]
- },
- {
- "contains": [
- "recordedfuture total objects successful"
- ],
- "data_path": "summary.total_objects_successful",
- "data_type": "numeric",
- "example_values": [
- 1
- ]
- }
- ],
- "parameters": {
- "ip": {
- "contains": [
- "ip"
- ],
- "data_type": "string",
- "default": "",
- "description": "IP to query",
- "key": "ip",
- "order": 0,
- "primary": true,
- "required": true,
- "value_list": []
- }
- },
- "product_name": "Recorded Future App for Phantom",
- "product_vendor": "Recorded Future, Inc",
- "targets": "6",
- "type": "reputation"
- }
- ],
- "attrs": {
- ".action": {
- "text": "ip reputation"
- },
- ".background": {
- "fill": "#000000",
- "stroke": "#5C6773"
- },
- ".color-band": {
- "fill": "#3C444D"
- },
- ".inPorts>.port-in": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".inPorts>.port-in>.port-body": {
- "port": {
- "id": "in",
- "type": "in"
- }
- },
- ".message": {
- "opacity": 0,
- "ref-x": 5,
- "ref-y": 105,
- "text": "Configuring now"
- },
- ".outPorts>.port-out": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".outPorts>.port-out>.port-body": {
- "port": {
- "id": "out",
- "type": "out"
- }
- },
- ".title": {
- "text": "Investigate"
- },
- "g.approver image": {
- "opacity": 1
- },
- "g.code image": {
- "opacity": 1
- },
- "g.delete": {
- "display": "none"
- },
- "g.error": {
- "opacity": 0
- },
- "g.icon image": {
- "xlink:href": "/inc/coa/img/block_icon_investigate.svg"
- },
- "g.notes": {
- "display": "block"
- },
- "g.notes image": {
- "opacity": 1,
- "xlink:href": "/inc/coa/img/block_icon_note_dark_on.svg"
- },
- "g.timer image": {
- "opacity": 1
- }
- },
- "block_code": "def ip_reputation_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):\n phantom.debug('ip_reputation_1() called')\n\n # collect data for 'ip_reputation_1' call\n container_data = phantom.collect2(container=container, datapath=['artifact:*.cef.destinationAddress', 'artifact:*.id'])\n\n parameters = []\n \n # build parameters list for 'ip_reputation_1' call\n for container_item in container_data:\n if container_item[0]:\n parameters.append({\n 'ip': container_item[0],\n # context (artifact id) is added to associate results with the artifact\n 'context': {'artifact_id': container_item[1]},\n })\n\n phantom.act(action=\"ip reputation\", parameters=parameters, assets=['recorded_future'], callback=risk_score_threshold, name=\"ip_reputation_1\")\n\n return",
- "callback_code": "",
- "callback_start": 1,
- "callsback": true,
- "color": "",
- "connected_to_start": true,
- "connection_name": "",
- "connection_type": "",
- "custom_callback": "",
- "custom_code": "",
- "custom_join": "",
- "custom_name": "",
- "delay": 0,
- "description": "Query for the risk score from Recorded Future",
- "has_custom": false,
- "has_custom_block": false,
- "has_custom_callback": false,
- "has_custom_join": false,
- "id": "0330e559-47a5-40e6-96ac-629532bcbeac",
- "inPorts": [
- "in"
- ],
- "join_code": "",
- "join_optional": [],
- "join_start": 1,
- "line_end": 599,
- "line_start": 578,
- "message": "Configuring now",
- "name": "ip reputation",
- "notes": "Query for the risk score from Recorded Future",
- "number": 1,
- "order": 23,
- "outPorts": [
- "out"
- ],
- "ports": {
- "groups": {
- "in": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "left"
- }
- },
- "position": {
- "name": "left"
- }
- },
- "out": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "right"
- }
- },
- "position": {
- "name": "right"
- }
- }
- }
- },
- "position": {
- "x": 100,
- "y": -60
- },
- "previous_function": "",
- "previous_name": "ip_reputation_1",
- "required_params": {
- "ip": true
- },
- "reviewer": "",
- "show_number": false,
- "size": {
- "height": 100,
- "width": 180
- },
- "state": "app_action_assets",
- "status": "",
- "title": "Investigate",
- "type": "coa.Action",
- "warn": false,
- "z": 262
- },
- {
- "action": "ip intelligence",
- "action_type": "investigate",
- "active": false,
- "active_keys": {},
- "active_values": {
- "ip": "artifact:*.cef.destinationAddress"
- },
- "angle": 0,
- "app": "Recorded Future",
- "appid": "6efe0e1b-76ac-4ffd-8fa0-ac58fd6efd77",
- "approver": "",
- "assets": [
- {
- "action": "ip intelligence",
- "actions": [
- "ip reputation",
- "ip intelligence",
- "domain reputation",
- "domain intelligence",
- "file reputation",
- "file intelligence",
- "vulnerability reputation",
- "vulnerability intelligence",
- "url reputation",
- "url intelligence",
- "alert rule lookup",
- "alert data lookup",
- "test connectivity"
- ],
- "active": true,
- "app_name": "Recorded Future",
- "app_version": "2.0.0",
- "appid": "6efe0e1b-76ac-4ffd-8fa0-ac58fd6efd77",
- "asset_name": "recorded-future",
- "config_type": "asset",
- "count": 0,
- "fields": {
- "ip": "artifact:*.cef.destinationAddress"
- },
- "has_app": true,
- "id": 6,
- "loaded": false,
- "missing": false,
- "name": "recorded_future",
- "output": [
- {
- "contains": [
- "recordedfuture result status"
- ],
- "data_path": "action_result.status",
- "data_type": "string",
- "example_values": [
- "success",
- "failed"
- ]
- },
- {
- "contains": [
- "ip",
- "ipv6"
- ],
- "data_path": "action_result.parameter.ip",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture entity id"
- ],
- "data_path": "action_result.data.*.entity.id",
- "data_type": "string"
- },
- {
- "contains": [
- "ip",
- "ipv6"
- ],
- "data_path": "action_result.data.*.entity.name",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture entity type"
- ],
- "data_path": "action_result.data.*.entity.type",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture intelligence card url"
- ],
- "data_path": "action_result.data.*.intelCard",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture location asn"
- ],
- "data_path": "action_result.data.*.location.asn",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture location cidr id"
- ],
- "data_path": "action_result.data.*.location.cidr.id",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture location cidr name"
- ],
- "data_path": "action_result.data.*.location.cidr.name",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture location cidr type"
- ],
- "data_path": "action_result.data.*.location.cidr.type",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture location city"
- ],
- "data_path": "action_result.data.*.location.location.city",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture location continent"
- ],
- "data_path": "action_result.data.*.location.location.continent",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture location country"
- ],
- "data_path": "action_result.data.*.location.location.country",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture location organization"
- ],
- "data_path": "action_result.data.*.location.organization",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture metrics type"
- ],
- "data_path": "action_result.data.*.metrics.*.type",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture metrics value"
- ],
- "data_path": "action_result.data.*.metrics.*.value",
- "data_type": "numeric"
- },
- {
- "contains": [
- "recordedfuture related entities count"
- ],
- "data_path": "action_result.data.*.relatedEntities.*.entities.*.count",
- "data_type": "numeric"
- },
- {
- "contains": [
- "recordedfuture entity id"
- ],
- "data_path": "action_result.data.*.relatedEntities.*.entities.*.entity.id",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture entity name"
- ],
- "data_path": "action_result.data.*.relatedEntities.*.entities.*.entity.name",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture entity type"
- ],
- "data_path": "action_result.data.*.relatedEntities.*.entities.*.entity.type",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture related entity type"
- ],
- "data_path": "action_result.data.*.relatedEntities.*.type",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture risk criticality"
- ],
- "data_path": "action_result.data.*.risk.criticality",
- "data_type": "numeric"
- },
- {
- "contains": [
- "recordedfuture risk criticality label"
- ],
- "data_path": "action_result.data.*.risk.criticalityLabel",
- "data_type": "string",
- "example_values": [
- "Very Malicious"
- ]
- },
- {
- "contains": [
- "recordedfuture risk criticality"
- ],
- "data_path": "action_result.data.*.risk.evidenceDetails.*.criticality",
- "data_type": "numeric"
- },
- {
- "contains": [
- "recordedfuture risk criticality label"
- ],
- "data_path": "action_result.data.*.risk.evidenceDetails.*.criticalityLabel",
- "data_type": "string",
- "example_values": [
- "Unusual"
- ]
- },
- {
- "contains": [
- "recordedfuture evidence string"
- ],
- "data_path": "action_result.data.*.risk.evidenceDetails.*.evidenceString",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture mitigation string"
- ],
- "data_path": "action_result.data.*.risk.evidenceDetails.*.mitigationString",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture evidence rule"
- ],
- "data_path": "action_result.data.*.risk.evidenceDetails.*.rule",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture evidence timestamp"
- ],
- "data_path": "action_result.data.*.risk.evidenceDetails.*.timestamp",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture risk string"
- ],
- "data_path": "action_result.data.*.risk.riskString",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture risk summary"
- ],
- "data_path": "action_result.data.*.risk.riskSummary",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture risk rules"
- ],
- "data_path": "action_result.data.*.risk.rules",
- "data_type": "numeric"
- },
- {
- "contains": [
- "recordedfuture risk score"
- ],
- "data_path": "action_result.data.*.risk.score",
- "data_type": "numeric"
- },
- {
- "contains": [
- "recordedfuture evidence firstseen"
- ],
- "data_path": "action_result.data.*.timestamps.firstSeen",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture evidence lastseen"
- ],
- "data_path": "action_result.data.*.timestamps.lastSeen",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture risk criticality label"
- ],
- "data_path": "action_result.summary.criticalityLabel",
- "data_type": "string",
- "example_values": [
- "Very Malicious"
- ]
- },
- {
- "contains": [
- "recordedfuture evidence lastseen"
- ],
- "data_path": "action_result.summary.lastSeen",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture risk summary"
- ],
- "data_path": "action_result.summary.riskSummary",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture result message"
- ],
- "data_path": "action_result.message",
- "data_type": "string"
- },
- {
- "contains": [
- "recordedfuture total objects"
- ],
- "data_path": "summary.total_objects",
- "data_type": "numeric",
- "example_values": [
- 1
- ]
- },
- {
- "contains": [
- "recordedfuture total objects successful"
- ],
- "data_path": "summary.total_objects_successful",
- "data_type": "numeric",
- "example_values": [
- 1
- ]
- }
- ],
- "parameters": {
- "ip": {
- "contains": [
- "ip"
- ],
- "data_type": "string",
- "default": "",
- "description": "IP to query",
- "key": "ip",
- "order": 0,
- "primary": true,
- "required": true,
- "value_list": []
- }
- },
- "product_name": "Recorded Future App for Phantom",
- "product_vendor": "Recorded Future, Inc",
- "targets": "6",
- "type": "reputation"
- }
- ],
- "attrs": {
- ".action": {
- "text": "ip intelligence"
- },
- ".background": {
- "fill": "#000000",
- "stroke": "#5C6773"
- },
- ".color-band": {
- "fill": "#3C444D"
- },
- ".inPorts>.port-in": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".inPorts>.port-in>.port-body": {
- "port": {
- "id": "in",
- "type": "in"
- }
- },
- ".message": {
- "opacity": 0,
- "ref-x": 5,
- "ref-y": 105,
- "text": "Configuring now"
- },
- ".outPorts>.port-out": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".outPorts>.port-out>.port-body": {
- "port": {
- "id": "out",
- "type": "out"
- }
- },
- ".title": {
- "text": "Investigate"
- },
- "g.approver image": {
- "opacity": 1
- },
- "g.code image": {
- "opacity": 1
- },
- "g.delete": {
- "display": "none"
- },
- "g.error": {
- "opacity": 0
- },
- "g.error image": {
- "xlink:href": "/inc/coa/img/block_icon_warn.svg"
- },
- "g.icon image": {
- "xlink:href": "/inc/coa/img/block_icon_investigate.svg"
- },
- "g.notes": {
- "display": "block"
- },
- "g.notes image": {
- "opacity": 1,
- "xlink:href": "/inc/coa/img/block_icon_note_dark_on.svg"
- },
- "g.timer image": {
- "opacity": 1
- }
- },
- "block_code": "def ip_intelligence_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):\n phantom.debug('ip_intelligence_1() called')\n \n #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))\n \n # collect data for 'ip_intelligence_1' call\n container_data = phantom.collect2(container=container, datapath=['artifact:*.cef.destinationAddress', 'artifact:*.id'])\n\n parameters = []\n \n # build parameters list for 'ip_intelligence_1' call\n for container_item in container_data:\n if container_item[0]:\n parameters.append({\n 'ip': container_item[0],\n # context (artifact id) is added to associate results with the artifact\n 'context': {'artifact_id': container_item[1]},\n })\n\n phantom.act(action=\"ip intelligence\", parameters=parameters, assets=['recorded_future'], callback=Entity_Type_Filter, name=\"ip_intelligence_1\")\n\n return",
- "callback_code": "",
- "callback_start": 1,
- "callsback": true,
- "color": "",
- "connected_to_start": true,
- "connection_name": "ip reputation",
- "connection_type": "action",
- "custom_callback": "",
- "custom_code": "",
- "custom_join": "",
- "custom_name": "",
- "delay": 0,
- "description": "Query for the full context about the IP address and related entities from Recorded Future",
- "has_custom": false,
- "has_custom_block": false,
- "has_custom_callback": false,
- "has_custom_join": false,
- "id": "8c84ebd6-735f-4014-88e1-8feffde0dcaa",
- "inPorts": [
- "in"
- ],
- "join_code": "",
- "join_optional": [],
- "join_start": 1,
- "line_end": 515,
- "line_start": 492,
- "message": "Configuring now",
- "name": "ip intelligence",
- "notes": "Query for the full context about the IP address and related entities from Recorded Future",
- "number": 1,
- "order": 21,
- "outPorts": [
- "out"
- ],
- "ports": {
- "groups": {
- "in": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "left"
- }
- },
- "position": {
- "name": "left"
- }
- },
- "out": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "right"
- }
- },
- "position": {
- "name": "right"
- }
- }
- }
- },
- "position": {
- "x": 480,
- "y": -60
- },
- "previous_function": "",
- "previous_name": "ip_intelligence_1",
- "required_params": {
- "ip": true
- },
- "reviewer": "",
- "show_number": false,
- "size": {
- "height": 100,
- "width": 180
- },
- "state": "app_action_assets",
- "status": "",
- "title": "Investigate",
- "type": "coa.Action",
- "warn": false,
- "z": 273
- },
- {
- "active": false,
- "angle": 0,
- "attrs": {
- ".background": {
- "fill": "#000000",
- "stroke": "#5C6773",
- "transform": "rotate(45 30 70)"
- },
- ".inPorts>.port-0>.port-body": {
- "port": {
- "id": "in",
- "type": "in"
- }
- },
- ".number": {
- "text": 1
- },
- ".outPorts>.port-0": {
- "port": {
- "id": "out-1",
- "type": "out"
- },
- "ref-x": 83,
- "ref-y": 40
- },
- ".outPorts>.port-0>.port-body": {
- "port": {
- "id": "out-1",
- "type": "out"
- }
- },
- ".outPorts>.port-1": {
- "port": {
- "id": "out-2",
- "type": "out"
- },
- "ref-x": 41,
- "ref-y": 82
- },
- ".outPorts>.port-1>.port-body": {
- "port": {
- "id": "out-2",
- "type": "out"
- }
- },
- ".outPorts>.port-2": {
- "port": {
- "id": "out-3",
- "type": "out"
- },
- "ref-x": 41,
- "ref-y": -2
- },
- ".outPorts>.port-2>.port-body": {
- "port": {
- "id": "out-3",
- "type": "out"
- }
- },
- ".outPorts>.port-3": {
- "port": {
- "id": "out-4",
- "type": "out"
- },
- "ref-x": 67,
- "ref-y": 16
- },
- ".outPorts>.port-3>.port-body": {
- "port": {
- "id": "out-4",
- "type": "out"
- }
- },
- "g.delete": {
- "display": "none"
- },
- "g.delete image": {
- "x": 5
- },
- "g.error": {
- "opacity": 0
- },
- "g.error image": {
- "xlink:href": "/inc/coa/img/block_icon_warn.svg"
- },
- "g.notes": {
- "display": "block"
- },
- "g.notes image": {
- "opacity": 1,
- "xlink:href": "/inc/coa/img/block_icon_note_dark_on.svg"
- }
- },
- "block_code": "def Entity_Type_Filter(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):\n phantom.debug('Entity_Type_Filter() called')\n\n # collect filtered artifact ids for 'if' condition 1\n matched_artifacts_1, matched_results_1 = phantom.condition(\n container=container,\n action_results=results,\n conditions=[\n [\"ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.entity.type\", \"==\", \"Hash\"],\n ],\n name=\"Entity_Type_Filter:condition_1\")\n\n # call connected blocks if filtered artifacts or results\n if matched_artifacts_1 or matched_results_1:\n format_related_hash_lookup(action=action, success=success, container=container, results=results, handle=handle, custom_function=custom_function, filtered_artifacts=matched_artifacts_1, filtered_results=matched_results_1)\n\n # collect filtered artifact ids for 'if' condition 2\n matched_artifacts_2, matched_results_2 = phantom.condition(\n container=container,\n action_results=results,\n conditions=[\n [\"ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.entity.type\", \"==\", \"CyberVulnerability\"],\n ],\n name=\"Entity_Type_Filter:condition_2\")\n\n # call connected blocks if filtered artifacts or results\n if matched_artifacts_2 or matched_results_2:\n format_related_vuln_lookup(action=action, success=success, container=container, results=results, handle=handle, custom_function=custom_function, filtered_artifacts=matched_artifacts_2, filtered_results=matched_results_2)\n\n # collect filtered artifact ids for 'if' condition 3\n matched_artifacts_3, matched_results_3 = phantom.condition(\n container=container,\n action_results=results,\n conditions=[\n [\"ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.entity.type\", \"==\", \"IpAddress\"],\n ],\n name=\"Entity_Type_Filter:condition_3\")\n\n # call connected blocks if filtered artifacts or results\n if matched_artifacts_3 or matched_results_3:\n format_related_ip_lookup(action=action, success=success, container=container, results=results, handle=handle, custom_function=custom_function, filtered_artifacts=matched_artifacts_3, filtered_results=matched_results_3)\n\n # collect filtered artifact ids for 'if' condition 4\n matched_artifacts_4, matched_results_4 = phantom.condition(\n container=container,\n action_results=results,\n conditions=[\n [\"ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.entity.type\", \"==\", \"InternetDomainName\"],\n ],\n name=\"Entity_Type_Filter:condition_4\")\n\n # call connected blocks if filtered artifacts or results\n if matched_artifacts_4 or matched_results_4:\n format_related_domain_lookup(action=action, success=success, container=container, results=results, handle=handle, custom_function=custom_function, filtered_artifacts=matched_artifacts_4, filtered_results=matched_results_4)\n\n return",
- "callback_code": "",
- "callback_start": 1,
- "callsback": false,
- "connected_to_start": true,
- "connection_name": "ip intelligence",
- "connection_type": "action",
- "custom_callback": "",
- "custom_code": "",
- "custom_join": "",
- "custom_name": "Entity Type Filter",
- "description": "Filter four common entity types into different Splunk searches",
- "has_custom": false,
- "has_custom_block": false,
- "has_custom_callback": false,
- "has_custom_join": false,
- "id": "f94b9f2a-8c01-44a8-8d02-55e37d88a888",
- "inPorts": [
- "in"
- ],
- "join_code": "",
- "join_optional": [],
- "join_start": 1,
- "line_end": 575,
- "line_start": 518,
- "name": "filter",
- "notes": "Filter four common entity types into different Splunk searches",
- "number": 1,
- "order": 22,
- "outPorts": [
- "out-1",
- "out-2",
- "out-3",
- "out-4"
- ],
- "outputs": [
- {
- "conditions": [
- {
- "comparison": "==",
- "data_type": "",
- "param": "ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.entity.type",
- "value": "Hash"
- }
- ],
- "display": "If",
- "logic": "and",
- "type": "if"
- },
- {
- "conditions": [
- {
- "comparison": "==",
- "data_type": "",
- "param": "ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.entity.type",
- "value": "CyberVulnerability"
- }
- ],
- "display": "If",
- "logic": "and",
- "type": "if"
- },
- {
- "conditions": [
- {
- "comparison": "==",
- "data_type": "",
- "param": "ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.entity.type",
- "value": "IpAddress"
- }
- ],
- "display": "If",
- "logic": "and",
- "type": "if"
- },
- {
- "conditions": [
- {
- "comparison": "==",
- "data_type": "",
- "param": "ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.entity.type",
- "value": "InternetDomainName"
- }
- ],
- "display": "If",
- "logic": "and",
- "type": "if"
- }
- ],
- "ports": {
- "groups": {
- "in": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "left"
- }
- },
- "position": {
- "name": "left"
- }
- },
- "out": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "right"
- }
- },
- "position": {
- "name": "right"
- }
- }
- }
- },
- "position": {
- "x": 720,
- "y": -60
- },
- "previous_function": "",
- "previous_name": "Entity_Type_Filter",
- "show_number": true,
- "size": {
- "height": 82,
- "width": 82
- },
- "state": "filter",
- "status": "",
- "type": "coa.Filter",
- "warn": false,
- "z": 274
- },
- {
- "active": false,
- "angle": 0,
- "attrs": {
- ".background": {
- "fill": "#000000",
- "stroke": "#5C6773"
- },
- ".color-band": {
- "fill": "#3C444D"
- },
- ".format": {
- "text": "format related ip lookup"
- },
- ".inPorts>.port-in": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".inPorts>.port-in>.port-body": {
- "port": {
- "id": "in",
- "type": "in"
- }
- },
- ".message": {
- "opacity": 0,
- "text": "Configuring now"
- },
- ".outPorts>.port-out-1": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".outPorts>.port-out-1>.port-body": {
- "port": {
- "id": "out-1",
- "type": "out"
- }
- },
- ".title": {
- "text": "format"
- },
- "g.code image": {
- "opacity": 1
- },
- "g.delete": {
- "display": "none"
- },
- "g.error": {
- "opacity": 0
- },
- "g.error image": {
- "xlink:href": "/inc/coa/img/block_icon_warn.svg"
- },
- "g.notes": {
- "display": "block"
- },
- "g.notes image": {
- "opacity": 1,
- "xlink:href": "/inc/coa/img/block_icon_note_dark_on.svg"
- }
- },
- "block_code": "def format_related_ip_lookup(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):\n phantom.debug('format_related_ip_lookup() called')\n \n template = \"\"\"| makeresults | eval IP=\\\"{0}\\\" | makemv IP delim=\\\", \\\" | mvexpand IP | appendcols [| makeresults | eval RC=\\\"{1}\\\" | makemv RC delim=\\\", \\\" | mvexpand RC ] | outputlookup huntip.csv\"\"\"\n\n # parameter list for template variable replacement\n parameters = [\n \"filtered-data:Entity_Type_Filter:condition_3:ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.entity.name\",\n \"filtered-data:Entity_Type_Filter:condition_3:ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.count\",\n ]\n\n phantom.format(container=container, template=template, parameters=parameters, name=\"format_related_ip_lookup\")\n\n build_ip_lookup(container=container)\n\n return",
- "callback_code": "",
- "callback_start": 1,
- "callsback": false,
- "connected_to_start": true,
- "connection_name": "ip intelligence",
- "connection_type": "action",
- "custom_callback": "",
- "custom_code": "",
- "custom_join": "",
- "custom_name": "format related ip lookup",
- "description": "Build a Splunk query to turn a list of related entities from Recorded Future into a lookup table that can be used for threat hunting across any sourcetype or data model",
- "format": "format",
- "has_custom": false,
- "has_custom_block": false,
- "has_custom_callback": false,
- "has_custom_join": false,
- "id": "74bc01bc-1ab1-4296-a880-4dbd087e42ed",
- "inPorts": [
- "in"
- ],
- "join_code": "",
- "join_optional": [],
- "join_start": 1,
- "line_end": 57,
- "line_start": 40,
- "message": "Configuring now",
- "name": "format",
- "notes": "Build a Splunk query to turn a list of related entities from Recorded Future into a lookup table that can be used for threat hunting across any sourcetype or data model",
- "number": 1,
- "order": 3,
- "outPorts": [
- "out-1"
- ],
- "parameters": [
- {
- "position": 0,
- "type": "",
- "value": "filtered-data:Entity_Type_Filter:condition_3:ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.entity.name"
- },
- {
- "position": 1,
- "type": "",
- "value": "filtered-data:Entity_Type_Filter:condition_3:ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.count"
- }
- ],
- "ports": {
- "groups": {
- "in": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "left"
- }
- },
- "position": {
- "name": "left"
- }
- },
- "out": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "right"
- }
- },
- "position": {
- "name": "right"
- }
- }
- }
- },
- "position": {
- "x": 860,
- "y": -280
- },
- "previous_function": "",
- "previous_name": "format_related_ip_lookup",
- "show_number": true,
- "size": {
- "height": 100,
- "width": 180
- },
- "state": "format",
- "status": "",
- "template": "| makeresults | eval IP=\"{0}\" | makemv IP delim=\", \" | mvexpand IP | appendcols [| makeresults | eval RC=\"{1}\" | makemv RC delim=\", \" | mvexpand RC ] | outputlookup huntip.csv",
- "title": "format",
- "type": "coa.Format",
- "warn": false,
- "z": 296
- },
- {
- "active": false,
- "angle": 0,
- "attrs": {
- ".background": {
- "fill": "#000000",
- "stroke": "#5C6773"
- },
- ".color-band": {
- "fill": "#3C444D"
- },
- ".format": {
- "text": "format related vuln looku..."
- },
- ".inPorts>.port-in": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".inPorts>.port-in>.port-body": {
- "port": {
- "id": "in",
- "type": "in"
- }
- },
- ".message": {
- "opacity": 0,
- "text": "Configuring now"
- },
- ".outPorts>.port-out-1": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".outPorts>.port-out-1>.port-body": {
- "port": {
- "id": "out-1",
- "type": "out"
- }
- },
- ".title": {
- "text": "format"
- },
- "g.code image": {
- "opacity": 1
- },
- "g.delete": {
- "display": "none"
- },
- "g.error": {
- "opacity": 0
- },
- "g.error image": {
- "xlink:href": "/inc/coa/img/block_icon_warn.svg"
- },
- "g.notes": {
- "display": "block"
- },
- "g.notes image": {
- "opacity": 1,
- "xlink:href": "/inc/coa/img/block_icon_note_dark_on.svg"
- }
- },
- "block_code": "def format_related_vuln_lookup(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):\n phantom.debug('format_related_vuln_lookup() called')\n \n template = \"\"\"| makeresults | eval vuln=\\\"{0}\\\" | makemv vuln delim=\\\", \\\" | mvexpand vuln | appendcols [| makeresults | eval RC=\\\"{1}\\\" | makemv RC delim=\\\", \\\" | mvexpand RC ] | outputlookup huntvuln.csv\"\"\"\n\n # parameter list for template variable replacement\n parameters = [\n \"filtered-data:Entity_Type_Filter:condition_2:ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.entity.name\",\n \"filtered-data:Entity_Type_Filter:condition_2:ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.count\",\n ]\n\n phantom.format(container=container, template=template, parameters=parameters, name=\"format_related_vuln_lookup\")\n\n build_vuln_lookup(container=container)\n\n return",
- "callback_code": "",
- "callback_start": 1,
- "callsback": false,
- "connected_to_start": true,
- "connection_name": "ip intelligence",
- "connection_type": "action",
- "custom_callback": "",
- "custom_code": "",
- "custom_join": "",
- "custom_name": "format related vuln lookup",
- "description": "Build a Splunk query to turn a list of related entities from Recorded Future into a lookup table that can be used for threat hunting across any sourcetype or data model",
- "format": "format",
- "has_custom": false,
- "has_custom_block": false,
- "has_custom_callback": false,
- "has_custom_join": false,
- "id": "2fc7308a-1d54-48f2-8d63-ab8e71a5c933",
- "inPorts": [
- "in"
- ],
- "join_code": "",
- "join_optional": [],
- "join_start": 1,
- "line_end": 392,
- "line_start": 375,
- "message": "Configuring now",
- "name": "format",
- "notes": "Build a Splunk query to turn a list of related entities from Recorded Future into a lookup table that can be used for threat hunting across any sourcetype or data model",
- "number": 6,
- "order": 16,
- "outPorts": [
- "out-1"
- ],
- "parameters": [
- {
- "position": 0,
- "type": "",
- "value": "filtered-data:Entity_Type_Filter:condition_2:ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.entity.name"
- },
- {
- "position": 1,
- "type": "",
- "value": "filtered-data:Entity_Type_Filter:condition_2:ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.count"
- }
- ],
- "ports": {
- "groups": {
- "in": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "left"
- }
- },
- "position": {
- "name": "left"
- }
- },
- "out": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "right"
- }
- },
- "position": {
- "name": "right"
- }
- }
- }
- },
- "position": {
- "x": 860,
- "y": 140
- },
- "previous_function": "",
- "previous_name": "format_related_vuln_lookup",
- "show_number": true,
- "size": {
- "height": 100,
- "width": 180
- },
- "state": "format",
- "status": "",
- "template": "| makeresults | eval vuln=\"{0}\" | makemv vuln delim=\", \" | mvexpand vuln | appendcols [| makeresults | eval RC=\"{1}\" | makemv RC delim=\", \" | mvexpand RC ] | outputlookup huntvuln.csv",
- "title": "format",
- "type": "coa.Format",
- "warn": false,
- "z": 298
- },
- {
- "active": false,
- "angle": 0,
- "attrs": {
- ".background": {
- "fill": "#000000",
- "stroke": "#5C6773"
- },
- ".color-band": {
- "fill": "#3C444D"
- },
- ".format": {
- "text": "format related domain lo..."
- },
- ".inPorts>.port-in": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".inPorts>.port-in>.port-body": {
- "port": {
- "id": "in",
- "type": "in"
- }
- },
- ".message": {
- "opacity": 0,
- "text": "Configuring now"
- },
- ".outPorts>.port-out-1": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".outPorts>.port-out-1>.port-body": {
- "port": {
- "id": "out-1",
- "type": "out"
- }
- },
- ".title": {
- "text": "format"
- },
- "g.code image": {
- "opacity": 1
- },
- "g.delete": {
- "display": "none"
- },
- "g.error": {
- "opacity": 0
- },
- "g.error image": {
- "xlink:href": "/inc/coa/img/block_icon_warn.svg"
- },
- "g.notes": {
- "display": "block"
- },
- "g.notes image": {
- "opacity": 1,
- "xlink:href": "/inc/coa/img/block_icon_note_dark_on.svg"
- }
- },
- "block_code": "def format_related_domain_lookup(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):\n phantom.debug('format_related_domain_lookup() called')\n \n template = \"\"\"| makeresults | eval domain=\\\"{0}\\\" | makemv domain delim=\\\", \\\" | mvexpand domain | appendcols [| makeresults | eval RC=\\\"{1}\\\" | makemv RC delim=\\\", \\\" | mvexpand RC ] | outputlookup huntdomain.csv\"\"\"\n\n # parameter list for template variable replacement\n parameters = [\n \"filtered-data:Entity_Type_Filter:condition_4:ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.entity.name\",\n \"filtered-data:Entity_Type_Filter:condition_4:ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.count\",\n ]\n\n phantom.format(container=container, template=template, parameters=parameters, name=\"format_related_domain_lookup\")\n\n build_domain_lookup(container=container)\n\n return",
- "callback_code": "",
- "callback_start": 1,
- "callsback": false,
- "connected_to_start": true,
- "connection_name": "ip intelligence",
- "connection_type": "action",
- "custom_callback": "",
- "custom_code": "",
- "custom_join": "",
- "custom_name": "format related domain lookup",
- "description": "Build a Splunk query to turn a list of related entities from Recorded Future into a lookup table that can be used for threat hunting across any sourcetype or data model",
- "format": "format",
- "has_custom": false,
- "has_custom_block": false,
- "has_custom_callback": false,
- "has_custom_join": false,
- "id": "a8a36be4-700d-45bb-a10f-ebe21cba0d62",
- "inPorts": [
- "in"
- ],
- "join_code": "",
- "join_optional": [],
- "join_start": 1,
- "line_end": 302,
- "line_start": 285,
- "message": "Configuring now",
- "name": "format",
- "notes": "Build a Splunk query to turn a list of related entities from Recorded Future into a lookup table that can be used for threat hunting across any sourcetype or data model",
- "number": 4,
- "order": 12,
- "outPorts": [
- "out-1"
- ],
- "parameters": [
- {
- "position": 0,
- "type": "",
- "value": "filtered-data:Entity_Type_Filter:condition_4:ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.entity.name"
- },
- {
- "position": 1,
- "type": "",
- "value": "filtered-data:Entity_Type_Filter:condition_4:ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.count"
- }
- ],
- "ports": {
- "groups": {
- "in": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "left"
- }
- },
- "position": {
- "name": "left"
- }
- },
- "out": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "right"
- }
- },
- "position": {
- "name": "right"
- }
- }
- }
- },
- "position": {
- "x": 860,
- "y": -140
- },
- "previous_function": "",
- "previous_name": "format_related_domain_lookup",
- "show_number": true,
- "size": {
- "height": 100,
- "width": 180
- },
- "state": "format",
- "status": "",
- "template": "| makeresults | eval domain=\"{0}\" | makemv domain delim=\", \" | mvexpand domain | appendcols [| makeresults | eval RC=\"{1}\" | makemv RC delim=\", \" | mvexpand RC ] | outputlookup huntdomain.csv",
- "title": "format",
- "type": "coa.Format",
- "warn": false,
- "z": 299
- },
- {
- "action": "run query",
- "action_type": "investigate",
- "active": false,
- "active_keys": {},
- "active_values": {
- "display": "",
- "query": "format_1:formatted_data"
- },
- "angle": 0,
- "app": "Splunk",
- "appid": "91883aa8-9c81-470b-97a1-5d8f7995f560",
- "approver": "",
- "assets": [
- {
- "action": "run query",
- "actions": [
- "test connectivity",
- "get host events",
- "on poll",
- "run query",
- "update event",
- "post data"
- ],
- "active": true,
- "app_name": "Splunk",
- "app_version": "1.3.23",
- "appid": "91883aa8-9c81-470b-97a1-5d8f7995f560",
- "asset_name": "splunk.example.com",
- "config_type": "asset",
- "count": 0,
- "fields": {
- "command": "",
- "display": "",
- "parse_only": "",
- "query": "format_related_ip_lookup:formatted_data"
- },
- "has_app": true,
- "id": 11,
- "loaded": false,
- "missing": false,
- "name": "splunk",
- "output": [
- {
- "data_path": "action_result.status",
- "data_type": "string",
- "example_values": [
- "success",
- "failed"
- ]
- },
- {
- "data_path": "action_result.parameter.command",
- "data_type": "string",
- "example_values": [
- "savedsearch"
- ]
- },
- {
- "data_path": "action_result.parameter.display",
- "data_type": "string"
- },
- {
- "data_path": "action_result.parameter.parse_only",
- "data_type": "boolean",
- "example_values": [
- true,
- false
- ]
- },
- {
- "contains": [
- "splunk query"
- ],
- "data_path": "action_result.parameter.query",
- "data_type": "string",
- "example_values": [
- "\"Send to Phantom\""
- ]
- },
- {
- "data_path": "action_result.data.*._bkt",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._cd",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._indextime",
- "data_type": "string"
- },
- {
- "column_name": "Raw",
- "column_order": 2,
- "data_path": "action_result.data.*._raw",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._serial",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._si",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._sourcetype",
- "data_type": "string"
- },
- {
- "column_name": "Time",
- "column_order": 1,
- "data_path": "action_result.data.*._time",
- "data_type": "string"
- },
- {
- "column_name": "Host",
- "column_order": 0,
- "contains": [
- "host name"
- ],
- "data_path": "action_result.data.*.host",
- "data_type": "string",
- "example_values": [
- "10.1.67.187:8088"
- ]
- },
- {
- "data_path": "action_result.data.*.index",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*.linecount",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*.source",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*.sourcetype",
- "data_type": "string"
- },
- {
- "contains": [
- "host name"
- ],
- "data_path": "action_result.data.*.splunk_server",
- "data_type": "string"
- },
- {
- "data_path": "action_result.summary.total_events",
- "data_type": "numeric",
- "example_values": [
- 2
- ]
- },
- {
- "data_path": "action_result.message",
- "data_type": "string",
- "example_values": [
- "Total events: 2"
- ]
- },
- {
- "data_path": "summary.total_objects",
- "data_type": "numeric",
- "example_values": [
- 1
- ]
- },
- {
- "data_path": "summary.total_objects_successful",
- "data_type": "numeric",
- "example_values": [
- 1
- ]
- }
- ],
- "parameters": {
- "display": {
- "data_type": "string",
- "default": null,
- "description": "Display fields (comma separated)",
- "key": "display",
- "order": 1,
- "primary": false,
- "required": false
- },
- "query": {
- "contains": [
- "splunk query"
- ],
- "data_type": "string",
- "default": null,
- "description": "Query to run (in Splunk search language)",
- "key": "query",
- "order": 0,
- "primary": true,
- "required": true
- }
- },
- "product_name": "Splunk Enterprise",
- "product_vendor": "Splunk Inc.",
- "targets": "11",
- "type": "siem"
- }
- ],
- "attrs": {
- ".action": {
- "text": "build ip lookup"
- },
- ".background": {
- "fill": "#000000",
- "stroke": "#5C6773"
- },
- ".color-band": {
- "fill": "#3C444D"
- },
- ".inPorts>.port-in": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".inPorts>.port-in>.port-body": {
- "port": {
- "id": "in",
- "type": "in"
- }
- },
- ".message": {
- "opacity": 0,
- "ref-x": 5,
- "ref-y": 105,
- "text": "Configuring now"
- },
- ".outPorts>.port-out": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".outPorts>.port-out>.port-body": {
- "port": {
- "id": "out",
- "type": "out"
- }
- },
- ".title": {
- "text": "Investigate"
- },
- "g.approver image": {
- "opacity": 1
- },
- "g.code image": {
- "opacity": 1
- },
- "g.delete": {
- "display": "none"
- },
- "g.error": {
- "opacity": 0
- },
- "g.error image": {
- "xlink:href": "/inc/coa/img/block_icon_warn.svg"
- },
- "g.icon image": {
- "xlink:href": "/inc/coa/img/block_icon_investigate.svg"
- },
- "g.notes": {
- "display": "block"
- },
- "g.notes image": {
- "opacity": 1,
- "xlink:href": "/inc/coa/img/block_icon_note_dark_on.svg"
- },
- "g.timer image": {
- "opacity": 1
- }
- },
- "block_code": "def build_ip_lookup(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):\n phantom.debug('build_ip_lookup() called')\n \n #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))\n \n # collect data for 'build_ip_lookup' call\n formatted_data_1 = phantom.get_format_data(name='format_related_ip_lookup')\n\n parameters = []\n \n # build parameters list for 'build_ip_lookup' call\n parameters.append({\n 'query': formatted_data_1,\n 'command': \"\",\n 'display': \"\",\n 'parse_only': \"\",\n })\n\n phantom.act(action=\"run query\", parameters=parameters, assets=['splunk'], callback=search_splunk_for_ips, name=\"build_ip_lookup\")\n\n return",
- "callback_code": "",
- "callback_start": 97,
- "callsback": true,
- "color": "",
- "connected_to_start": true,
- "connection_name": "ip intelligence",
- "connection_type": "action",
- "custom_callback": "",
- "custom_code": "",
- "custom_join": "",
- "custom_name": "build ip lookup",
- "delay": 0,
- "description": "Run the Splunk query that creates the lookup file",
- "has_custom": false,
- "has_custom_block": false,
- "has_custom_callback": false,
- "has_custom_join": false,
- "id": "f3a05260-dbbc-45da-9e59-644f83693e30",
- "inPorts": [
- "in"
- ],
- "join_code": "",
- "join_optional": [],
- "join_start": 1,
- "line_end": 82,
- "line_start": 60,
- "message": "Configuring now",
- "name": "run query",
- "notes": "Run the Splunk query that creates the lookup file",
- "number": 2,
- "order": 4,
- "outPorts": [
- "out"
- ],
- "ports": {
- "groups": {
- "in": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "left"
- }
- },
- "position": {
- "name": "left"
- }
- },
- "out": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "right"
- }
- },
- "position": {
- "name": "right"
- }
- }
- }
- },
- "position": {
- "x": 1100,
- "y": -280
- },
- "previous_function": "",
- "previous_name": "build_ip_lookup",
- "required_params": {
- "query": true
- },
- "reviewer": "",
- "show_number": true,
- "size": {
- "height": 100,
- "width": 180
- },
- "state": "app_action_assets",
- "status": "",
- "title": "Investigate",
- "type": "coa.Action",
- "warn": false,
- "z": 306
- },
- {
- "action": "run query",
- "action_type": "investigate",
- "active": false,
- "active_keys": {},
- "active_values": {
- "display": "",
- "query": "format_related_domain_lookup:formatted_data"
- },
- "angle": 0,
- "app": "Splunk",
- "appid": "91883aa8-9c81-470b-97a1-5d8f7995f560",
- "approver": "",
- "assets": [
- {
- "action": "run query",
- "actions": [
- "test connectivity",
- "get host events",
- "on poll",
- "run query",
- "update event",
- "post data"
- ],
- "active": true,
- "app_name": "Splunk",
- "app_version": "1.3.23",
- "appid": "91883aa8-9c81-470b-97a1-5d8f7995f560",
- "asset_name": "splunk.example.com",
- "config_type": "asset",
- "count": 0,
- "fields": {
- "command": "",
- "display": "",
- "parse_only": "",
- "query": "format_related_domain_lookup:formatted_data"
- },
- "has_app": true,
- "id": 11,
- "loaded": false,
- "missing": false,
- "name": "splunk",
- "output": [
- {
- "data_path": "action_result.status",
- "data_type": "string",
- "example_values": [
- "success",
- "failed"
- ]
- },
- {
- "data_path": "action_result.parameter.command",
- "data_type": "string",
- "example_values": [
- "savedsearch"
- ]
- },
- {
- "data_path": "action_result.parameter.display",
- "data_type": "string"
- },
- {
- "data_path": "action_result.parameter.parse_only",
- "data_type": "boolean",
- "example_values": [
- true,
- false
- ]
- },
- {
- "contains": [
- "splunk query"
- ],
- "data_path": "action_result.parameter.query",
- "data_type": "string",
- "example_values": [
- "\"Send to Phantom\""
- ]
- },
- {
- "data_path": "action_result.data.*._bkt",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._cd",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._indextime",
- "data_type": "string"
- },
- {
- "column_name": "Raw",
- "column_order": 2,
- "data_path": "action_result.data.*._raw",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._serial",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._si",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._sourcetype",
- "data_type": "string"
- },
- {
- "column_name": "Time",
- "column_order": 1,
- "data_path": "action_result.data.*._time",
- "data_type": "string"
- },
- {
- "column_name": "Host",
- "column_order": 0,
- "contains": [
- "host name"
- ],
- "data_path": "action_result.data.*.host",
- "data_type": "string",
- "example_values": [
- "10.1.67.187:8088"
- ]
- },
- {
- "data_path": "action_result.data.*.index",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*.linecount",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*.source",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*.sourcetype",
- "data_type": "string"
- },
- {
- "contains": [
- "host name"
- ],
- "data_path": "action_result.data.*.splunk_server",
- "data_type": "string"
- },
- {
- "data_path": "action_result.summary.total_events",
- "data_type": "numeric",
- "example_values": [
- 2
- ]
- },
- {
- "data_path": "action_result.message",
- "data_type": "string",
- "example_values": [
- "Total events: 2"
- ]
- },
- {
- "data_path": "summary.total_objects",
- "data_type": "numeric",
- "example_values": [
- 1
- ]
- },
- {
- "data_path": "summary.total_objects_successful",
- "data_type": "numeric",
- "example_values": [
- 1
- ]
- }
- ],
- "parameters": {
- "display": {
- "data_type": "string",
- "default": null,
- "description": "Display fields (comma separated)",
- "key": "display",
- "order": 1,
- "primary": false,
- "required": false
- },
- "query": {
- "contains": [
- "splunk query"
- ],
- "data_type": "string",
- "default": null,
- "description": "Query to run (in Splunk search language)",
- "key": "query",
- "order": 0,
- "primary": true,
- "required": true
- }
- },
- "product_name": "Splunk Enterprise",
- "product_vendor": "Splunk Inc.",
- "targets": "11",
- "type": "siem"
- }
- ],
- "attrs": {
- ".action": {
- "text": "build domain lookup"
- },
- ".background": {
- "fill": "#000000",
- "stroke": "#5C6773"
- },
- ".color-band": {
- "fill": "#3C444D"
- },
- ".inPorts>.port-in": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".inPorts>.port-in>.port-body": {
- "port": {
- "id": "in",
- "type": "in"
- }
- },
- ".message": {
- "opacity": 0,
- "ref-x": 5,
- "ref-y": 105,
- "text": "Configuring now"
- },
- ".outPorts>.port-out": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".outPorts>.port-out>.port-body": {
- "port": {
- "id": "out",
- "type": "out"
- }
- },
- ".title": {
- "text": "Investigate"
- },
- "g.approver image": {
- "opacity": 1
- },
- "g.code image": {
- "opacity": 1
- },
- "g.delete": {
- "display": "none"
- },
- "g.error": {
- "opacity": 0
- },
- "g.error image": {
- "xlink:href": "/inc/coa/img/block_icon_warn.svg"
- },
- "g.icon image": {
- "xlink:href": "/inc/coa/img/block_icon_investigate.svg"
- },
- "g.notes": {
- "display": "block"
- },
- "g.notes image": {
- "opacity": 1,
- "xlink:href": "/inc/coa/img/block_icon_note_dark_on.svg"
- },
- "g.timer image": {
- "opacity": 1
- }
- },
- "block_code": "def build_domain_lookup(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):\n phantom.debug('build_domain_lookup() called')\n \n #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))\n \n # collect data for 'build_domain_lookup' call\n formatted_data_1 = phantom.get_format_data(name='format_related_domain_lookup')\n\n parameters = []\n \n # build parameters list for 'build_domain_lookup' call\n parameters.append({\n 'query': formatted_data_1,\n 'command': \"\",\n 'display': \"\",\n 'parse_only': \"\",\n })\n\n phantom.act(action=\"run query\", parameters=parameters, assets=['splunk'], callback=search_splunk_for_domains, name=\"build_domain_lookup\")\n\n return",
- "callback_code": "",
- "callback_start": 1,
- "callsback": true,
- "color": "",
- "connected_to_start": true,
- "connection_name": "ip intelligence",
- "connection_type": "action",
- "custom_callback": "",
- "custom_code": "",
- "custom_join": "",
- "custom_name": "build domain lookup",
- "delay": 0,
- "description": "Run the Splunk query that creates the lookup file",
- "has_custom": false,
- "has_custom_block": false,
- "has_custom_callback": false,
- "has_custom_join": false,
- "id": "c121d149-c163-4140-bf66-bc31a20e99ad",
- "inPorts": [
- "in"
- ],
- "join_code": "",
- "join_optional": [],
- "join_start": 1,
- "line_end": 327,
- "line_start": 305,
- "message": "Configuring now",
- "name": "run query",
- "notes": "Run the Splunk query that creates the lookup file",
- "number": 4,
- "order": 13,
- "outPorts": [
- "out"
- ],
- "ports": {
- "groups": {
- "in": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "left"
- }
- },
- "position": {
- "name": "left"
- }
- },
- "out": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "right"
- }
- },
- "position": {
- "name": "right"
- }
- }
- }
- },
- "position": {
- "x": 1100,
- "y": -140
- },
- "previous_function": "",
- "previous_name": "build_domain_lookup",
- "required_params": {
- "query": true
- },
- "reviewer": "",
- "show_number": true,
- "size": {
- "height": 100,
- "width": 180
- },
- "state": "app_action_assets",
- "status": "",
- "title": "Investigate",
- "type": "coa.Action",
- "warn": false,
- "z": 307
- },
- {
- "action": "run query",
- "action_type": "investigate",
- "active": false,
- "active_keys": {},
- "active_values": {
- "display": "",
- "query": "format_5:formatted_data"
- },
- "angle": 0,
- "app": "Splunk",
- "appid": "91883aa8-9c81-470b-97a1-5d8f7995f560",
- "approver": "",
- "assets": [
- {
- "action": "run query",
- "actions": [
- "test connectivity",
- "get host events",
- "on poll",
- "run query",
- "update event",
- "post data"
- ],
- "active": true,
- "app_name": "Splunk",
- "app_version": "1.3.23",
- "appid": "91883aa8-9c81-470b-97a1-5d8f7995f560",
- "asset_name": "splunk.example.com",
- "config_type": "asset",
- "count": 0,
- "fields": {
- "command": "",
- "display": "",
- "parse_only": "",
- "query": "format_related_hash_lookup:formatted_data"
- },
- "has_app": true,
- "id": 11,
- "loaded": false,
- "missing": false,
- "name": "splunk",
- "output": [
- {
- "data_path": "action_result.status",
- "data_type": "string",
- "example_values": [
- "success",
- "failed"
- ]
- },
- {
- "data_path": "action_result.parameter.command",
- "data_type": "string",
- "example_values": [
- "savedsearch"
- ]
- },
- {
- "data_path": "action_result.parameter.display",
- "data_type": "string"
- },
- {
- "data_path": "action_result.parameter.parse_only",
- "data_type": "boolean",
- "example_values": [
- true,
- false
- ]
- },
- {
- "contains": [
- "splunk query"
- ],
- "data_path": "action_result.parameter.query",
- "data_type": "string",
- "example_values": [
- "\"Send to Phantom\""
- ]
- },
- {
- "data_path": "action_result.data.*._bkt",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._cd",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._indextime",
- "data_type": "string"
- },
- {
- "column_name": "Raw",
- "column_order": 2,
- "data_path": "action_result.data.*._raw",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._serial",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._si",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._sourcetype",
- "data_type": "string"
- },
- {
- "column_name": "Time",
- "column_order": 1,
- "data_path": "action_result.data.*._time",
- "data_type": "string"
- },
- {
- "column_name": "Host",
- "column_order": 0,
- "contains": [
- "host name"
- ],
- "data_path": "action_result.data.*.host",
- "data_type": "string",
- "example_values": [
- "10.1.67.187:8088"
- ]
- },
- {
- "data_path": "action_result.data.*.index",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*.linecount",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*.source",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*.sourcetype",
- "data_type": "string"
- },
- {
- "contains": [
- "host name"
- ],
- "data_path": "action_result.data.*.splunk_server",
- "data_type": "string"
- },
- {
- "data_path": "action_result.summary.total_events",
- "data_type": "numeric",
- "example_values": [
- 2
- ]
- },
- {
- "data_path": "action_result.message",
- "data_type": "string",
- "example_values": [
- "Total events: 2"
- ]
- },
- {
- "data_path": "summary.total_objects",
- "data_type": "numeric",
- "example_values": [
- 1
- ]
- },
- {
- "data_path": "summary.total_objects_successful",
- "data_type": "numeric",
- "example_values": [
- 1
- ]
- }
- ],
- "parameters": {
- "display": {
- "data_type": "string",
- "default": null,
- "description": "Display fields (comma separated)",
- "key": "display",
- "order": 1,
- "primary": false,
- "required": false
- },
- "query": {
- "contains": [
- "splunk query"
- ],
- "data_type": "string",
- "default": null,
- "description": "Query to run (in Splunk search language)",
- "key": "query",
- "order": 0,
- "primary": true,
- "required": true
- }
- },
- "product_name": "Splunk Enterprise",
- "product_vendor": "Splunk Inc.",
- "targets": "11",
- "type": "siem"
- }
- ],
- "attrs": {
- ".action": {
- "text": "build hash lookup"
- },
- ".background": {
- "fill": "#000000",
- "stroke": "#5C6773"
- },
- ".color-band": {
- "fill": "#3C444D"
- },
- ".inPorts>.port-in": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".inPorts>.port-in>.port-body": {
- "port": {
- "id": "in",
- "type": "in"
- }
- },
- ".message": {
- "opacity": 0,
- "ref-x": 5,
- "ref-y": 105,
- "text": "Configuring now"
- },
- ".outPorts>.port-out": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".outPorts>.port-out>.port-body": {
- "port": {
- "id": "out",
- "type": "out"
- }
- },
- ".title": {
- "text": "Investigate"
- },
- "g.approver image": {
- "opacity": 1
- },
- "g.code image": {
- "opacity": 1
- },
- "g.delete": {
- "display": "none"
- },
- "g.error": {
- "opacity": 0
- },
- "g.error image": {
- "xlink:href": "/inc/coa/img/block_icon_warn.svg"
- },
- "g.icon image": {
- "xlink:href": "/inc/coa/img/block_icon_investigate.svg"
- },
- "g.notes": {
- "display": "block"
- },
- "g.notes image": {
- "opacity": 1,
- "xlink:href": "/inc/coa/img/block_icon_note_dark_on.svg"
- },
- "g.timer image": {
- "opacity": 1
- }
- },
- "block_code": "def build_hash_lookup(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):\n phantom.debug('build_hash_lookup() called')\n \n #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))\n \n # collect data for 'build_hash_lookup' call\n formatted_data_1 = phantom.get_format_data(name='format_related_hash_lookup')\n\n parameters = []\n \n # build parameters list for 'build_hash_lookup' call\n parameters.append({\n 'query': formatted_data_1,\n 'command': \"\",\n 'display': \"\",\n 'parse_only': \"\",\n })\n\n phantom.act(action=\"run query\", parameters=parameters, assets=['splunk'], callback=search_splunk_for_files, name=\"build_hash_lookup\")\n\n return",
- "callback_code": "",
- "callback_start": 1,
- "callsback": true,
- "color": "",
- "connected_to_start": true,
- "connection_name": "ip intelligence",
- "connection_type": "action",
- "custom_callback": "",
- "custom_code": "",
- "custom_join": "",
- "custom_name": "build hash lookup",
- "delay": 0,
- "description": "Run the Splunk query that creates the lookup file",
- "has_custom": false,
- "has_custom_block": false,
- "has_custom_callback": false,
- "has_custom_join": false,
- "id": "c5e8d349-03a6-41ad-9162-68f9db1a7486",
- "inPorts": [
- "in"
- ],
- "join_code": "",
- "join_optional": [],
- "join_start": 1,
- "line_end": 372,
- "line_start": 350,
- "message": "Configuring now",
- "name": "run query",
- "notes": "Run the Splunk query that creates the lookup file",
- "number": 5,
- "order": 15,
- "outPorts": [
- "out"
- ],
- "ports": {
- "groups": {
- "in": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "left"
- }
- },
- "position": {
- "name": "left"
- }
- },
- "out": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "right"
- }
- },
- "position": {
- "name": "right"
- }
- }
- }
- },
- "position": {
- "x": 1100,
- "y": 0
- },
- "previous_function": "",
- "previous_name": "build_hash_lookup",
- "required_params": {
- "query": true
- },
- "reviewer": "",
- "show_number": true,
- "size": {
- "height": 100,
- "width": 180
- },
- "state": "app_action_assets",
- "status": "",
- "title": "Investigate",
- "type": "coa.Action",
- "warn": false,
- "z": 308
- },
- {
- "action": "run query",
- "action_type": "investigate",
- "active": false,
- "active_keys": {},
- "active_values": {
- "display": "",
- "query": "format_related_vuln_lookup:formatted_data"
- },
- "angle": 0,
- "app": "Splunk",
- "appid": "91883aa8-9c81-470b-97a1-5d8f7995f560",
- "approver": "",
- "assets": [
- {
- "action": "run query",
- "actions": [
- "test connectivity",
- "get host events",
- "on poll",
- "run query",
- "update event",
- "post data"
- ],
- "active": true,
- "app_name": "Splunk",
- "app_version": "1.3.23",
- "appid": "91883aa8-9c81-470b-97a1-5d8f7995f560",
- "asset_name": "splunk.example.com",
- "config_type": "asset",
- "count": 0,
- "fields": {
- "command": "",
- "display": "",
- "parse_only": "",
- "query": "format_related_vuln_lookup:formatted_data"
- },
- "has_app": true,
- "id": 11,
- "loaded": false,
- "missing": false,
- "name": "splunk",
- "output": [
- {
- "data_path": "action_result.status",
- "data_type": "string",
- "example_values": [
- "success",
- "failed"
- ]
- },
- {
- "data_path": "action_result.parameter.command",
- "data_type": "string",
- "example_values": [
- "savedsearch"
- ]
- },
- {
- "data_path": "action_result.parameter.display",
- "data_type": "string"
- },
- {
- "data_path": "action_result.parameter.parse_only",
- "data_type": "boolean",
- "example_values": [
- true,
- false
- ]
- },
- {
- "contains": [
- "splunk query"
- ],
- "data_path": "action_result.parameter.query",
- "data_type": "string",
- "example_values": [
- "\"Send to Phantom\""
- ]
- },
- {
- "data_path": "action_result.data.*._bkt",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._cd",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._indextime",
- "data_type": "string"
- },
- {
- "column_name": "Raw",
- "column_order": 2,
- "data_path": "action_result.data.*._raw",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._serial",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._si",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._sourcetype",
- "data_type": "string"
- },
- {
- "column_name": "Time",
- "column_order": 1,
- "data_path": "action_result.data.*._time",
- "data_type": "string"
- },
- {
- "column_name": "Host",
- "column_order": 0,
- "contains": [
- "host name"
- ],
- "data_path": "action_result.data.*.host",
- "data_type": "string",
- "example_values": [
- "10.1.67.187:8088"
- ]
- },
- {
- "data_path": "action_result.data.*.index",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*.linecount",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*.source",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*.sourcetype",
- "data_type": "string"
- },
- {
- "contains": [
- "host name"
- ],
- "data_path": "action_result.data.*.splunk_server",
- "data_type": "string"
- },
- {
- "data_path": "action_result.summary.total_events",
- "data_type": "numeric",
- "example_values": [
- 2
- ]
- },
- {
- "data_path": "action_result.message",
- "data_type": "string",
- "example_values": [
- "Total events: 2"
- ]
- },
- {
- "data_path": "summary.total_objects",
- "data_type": "numeric",
- "example_values": [
- 1
- ]
- },
- {
- "data_path": "summary.total_objects_successful",
- "data_type": "numeric",
- "example_values": [
- 1
- ]
- }
- ],
- "parameters": {
- "display": {
- "data_type": "string",
- "default": null,
- "description": "Display fields (comma separated)",
- "key": "display",
- "order": 1,
- "primary": false,
- "required": false
- },
- "query": {
- "contains": [
- "splunk query"
- ],
- "data_type": "string",
- "default": null,
- "description": "Query to run (in Splunk search language)",
- "key": "query",
- "order": 0,
- "primary": true,
- "required": true
- }
- },
- "product_name": "Splunk Enterprise",
- "product_vendor": "Splunk Inc.",
- "targets": "11",
- "type": "siem"
- }
- ],
- "attrs": {
- ".action": {
- "text": "build vuln lookup"
- },
- ".background": {
- "fill": "#000000",
- "stroke": "#5C6773"
- },
- ".color-band": {
- "fill": "#3C444D"
- },
- ".inPorts>.port-in": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".inPorts>.port-in>.port-body": {
- "port": {
- "id": "in",
- "type": "in"
- }
- },
- ".message": {
- "opacity": 0,
- "ref-x": 5,
- "ref-y": 105,
- "text": "Configuring now"
- },
- ".outPorts>.port-out": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".outPorts>.port-out>.port-body": {
- "port": {
- "id": "out",
- "type": "out"
- }
- },
- ".title": {
- "text": "Investigate"
- },
- "g.approver image": {
- "opacity": 1
- },
- "g.code image": {
- "opacity": 1
- },
- "g.delete": {
- "display": "none"
- },
- "g.error": {
- "opacity": 0
- },
- "g.error image": {
- "xlink:href": "/inc/coa/img/block_icon_warn.svg"
- },
- "g.icon image": {
- "xlink:href": "/inc/coa/img/block_icon_investigate.svg"
- },
- "g.notes": {
- "display": "block"
- },
- "g.notes image": {
- "opacity": 1,
- "xlink:href": "/inc/coa/img/block_icon_note_dark_on.svg"
- },
- "g.timer image": {
- "opacity": 1
- }
- },
- "block_code": "def build_vuln_lookup(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):\n phantom.debug('build_vuln_lookup() called')\n \n #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))\n \n # collect data for 'build_vuln_lookup' call\n formatted_data_1 = phantom.get_format_data(name='format_related_vuln_lookup')\n\n parameters = []\n \n # build parameters list for 'build_vuln_lookup' call\n parameters.append({\n 'query': formatted_data_1,\n 'command': \"\",\n 'display': \"\",\n 'parse_only': \"\",\n })\n\n phantom.act(action=\"run query\", parameters=parameters, assets=['splunk'], callback=search_splunk_for_vulns, name=\"build_vuln_lookup\")\n\n return",
- "callback_code": "",
- "callback_start": 1,
- "callsback": true,
- "color": "",
- "connected_to_start": true,
- "connection_name": "ip intelligence",
- "connection_type": "action",
- "custom_callback": "",
- "custom_code": "",
- "custom_join": "",
- "custom_name": "build vuln lookup",
- "delay": 0,
- "description": "Run the Splunk query that creates the lookup file",
- "has_custom": false,
- "has_custom_block": false,
- "has_custom_callback": false,
- "has_custom_join": false,
- "id": "bab7c570-8780-408c-a520-b56a5587964b",
- "inPorts": [
- "in"
- ],
- "join_code": "",
- "join_optional": [],
- "join_start": 1,
- "line_end": 417,
- "line_start": 395,
- "message": "Configuring now",
- "name": "run query",
- "notes": "Run the Splunk query that creates the lookup file",
- "number": 6,
- "order": 17,
- "outPorts": [
- "out"
- ],
- "ports": {
- "groups": {
- "in": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "left"
- }
- },
- "position": {
- "name": "left"
- }
- },
- "out": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "right"
- }
- },
- "position": {
- "name": "right"
- }
- }
- }
- },
- "position": {
- "x": 1100,
- "y": 140
- },
- "previous_function": "",
- "previous_name": "build_vuln_lookup",
- "required_params": {
- "query": true
- },
- "reviewer": "",
- "show_number": true,
- "size": {
- "height": 100,
- "width": 180
- },
- "state": "app_action_assets",
- "status": "",
- "title": "Investigate",
- "type": "coa.Action",
- "warn": false,
- "z": 309
- },
- {
- "attrs": {
- ".connection": {
- "stroke": "#818D99",
- "stroke-width": 2
- },
- ".marker-target": {
- "d": "M 10 0 L 0 5 L 10 10 z",
- "fill": "#818D99",
- "stroke": "#818D99"
- }
- },
- "connector": {
- "args": {
- "radius": 5
- },
- "name": "rounded"
- },
- "endDirections": [
- "left"
- ],
- "id": "6b414d3b-ace2-4825-a891-f7276816af5b",
- "router": {
- "name": "metro"
- },
- "source": {
- "id": "4a326ccb-068c-44cb-807b-8d61e39d7fa0",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(2) > g:nth-child(1) > circle:nth-child(1)"
- },
- "startDirections": [
- "right"
- ],
- "target": {
- "id": "168d14e9-de64-4a76-8cb9-5488d711f22e",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(1) > g:nth-child(1) > circle:nth-child(1)"
- },
- "type": "link",
- "z": 334
- },
- {
- "active": false,
- "angle": 0,
- "attrs": {
- ".background": {
- "fill": "#000000",
- "stroke": "#637282",
- "transform": "rotate(45 30 70)"
- },
- ".inPorts>.port-0>.port-body": {
- "port": {
- "id": "in",
- "type": "in"
- }
- },
- ".number": {
- "text": 1
- },
- ".outPorts>.port-0": {
- "port": {
- "id": "out-1",
- "type": "out"
- },
- "ref-x": 83,
- "ref-y": 40
- },
- ".outPorts>.port-0>.port-body": {
- "port": {
- "id": "out-1",
- "type": "out"
- }
- },
- "g.delete": {
- "display": "none"
- },
- "g.error": {
- "opacity": 0
- },
- "g.error image": {
- "xlink:href": "/inc/coa/img/block_icon_warn.svg"
- },
- "g.notes": {
- "display": "block"
- },
- "g.notes image": {
- "opacity": 1,
- "xlink:href": "/inc/coa/img/block_icon_note_dark_on.svg"
- }
- },
- "block_code": "def risk_score_threshold(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):\n phantom.debug('risk_score_threshold() called')\n\n # check for 'if' condition 1\n matched = phantom.decision(\n container=container,\n action_results=results,\n conditions=[\n [\"ip_reputation_1:action_result.data.*.risk.score\", \">=\", 90],\n ])\n\n # call connected blocks if condition 1 matched\n if matched:\n ip_intelligence_1(action=action, success=success, container=container, results=results, handle=handle, custom_function=custom_function)\n return\n\n return",
- "callback_code": "",
- "callback_start": 1,
- "callsback": false,
- "connected_to_start": true,
- "connection_name": "ip reputation",
- "connection_type": "action",
- "custom_callback": "",
- "custom_code": "",
- "custom_join": "",
- "custom_name": "risk_score_threshold",
- "description": "Proceed if the risk score is higher than a certain threshold",
- "hasElse": false,
- "has_custom": false,
- "has_custom_block": false,
- "has_custom_callback": false,
- "has_custom_join": false,
- "id": "9a2f421f-4963-4326-a188-895a92cb08ee",
- "inPorts": [
- "in"
- ],
- "join_code": "",
- "join_optional": [],
- "join_start": 1,
- "line_end": 37,
- "line_start": 19,
- "name": "decision",
- "notes": "Proceed if the risk score is higher than a certain threshold",
- "number": 1,
- "order": 2,
- "outPorts": [
- "out-1"
- ],
- "outputs": [
- {
- "conditions": [
- {
- "comparison": ">=",
- "data_type": "",
- "param": "ip_reputation_1:action_result.data.*.risk.score",
- "value": "90"
- }
- ],
- "display": "If",
- "logic": "and",
- "type": "if"
- }
- ],
- "ports": {
- "groups": {
- "in": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "left"
- }
- },
- "position": {
- "name": "left"
- }
- },
- "out": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "right"
- }
- },
- "position": {
- "name": "right"
- }
- }
- }
- },
- "position": {
- "x": 340,
- "y": -60
- },
- "previous_function": "",
- "previous_name": "risk_score_threshold",
- "show_number": true,
- "size": {
- "height": 82,
- "width": 82
- },
- "state": "decision",
- "status": "",
- "type": "coa.Decision",
- "warn": "",
- "z": 335
- },
- {
- "attrs": {
- ".connection": {
- "stroke": "#818D99",
- "stroke-width": 2
- },
- ".marker-target": {
- "d": "M 10 0 L 0 5 L 10 10 z",
- "fill": "#818D99",
- "stroke": "#818D99"
- }
- },
- "connector": {
- "args": {
- "radius": 5
- },
- "name": "rounded"
- },
- "endDirections": [
- "left"
- ],
- "id": "84b30ec6-3f8b-4c42-a943-53b05e185f8c",
- "router": {
- "name": "metro"
- },
- "source": {
- "id": "9a2f421f-4963-4326-a188-895a92cb08ee",
- "port": "out-1",
- "selector": "g:nth-child(1) > g:nth-child(2) > g:nth-child(1) > circle:nth-child(1)"
- },
- "startDirections": [
- "right"
- ],
- "target": {
- "id": "8c84ebd6-735f-4014-88e1-8feffde0dcaa",
- "port": null,
- "selector": "g:nth-child(1) > g:nth-child(1) > g:nth-child(1) > circle:nth-child(1)"
- },
- "type": "link",
- "z": 336
- },
- {
- "action": "run query",
- "action_type": "investigate",
- "active": false,
- "active_keys": {},
- "active_values": {
- "display": "",
- "query": "sourcetype=pan:t* ((earliest=-1d latest=now)) |eval IP=dest_ip | lookup huntip.csv IP OUTPUT RC | search RC>10"
- },
- "angle": 0,
- "app": "Splunk",
- "appid": "91883aa8-9c81-470b-97a1-5d8f7995f560",
- "approver": "",
- "assets": [
- {
- "action": "run query",
- "actions": [
- "test connectivity",
- "get host events",
- "on poll",
- "run query",
- "update event",
- "post data"
- ],
- "active": true,
- "app_name": "Splunk",
- "app_version": "1.3.23",
- "appid": "91883aa8-9c81-470b-97a1-5d8f7995f560",
- "asset_name": "splunk.example.com",
- "config_type": "asset",
- "count": 0,
- "fields": {
- "command": "",
- "display": "",
- "parse_only": "",
- "query": "sourcetype=pan:t* ((earliest=-1d latest=now)) |eval IP=dest_ip | lookup huntip.csv IP OUTPUT RC | search RC>10"
- },
- "has_app": true,
- "id": 11,
- "loaded": false,
- "missing": false,
- "name": "splunk",
- "output": [
- {
- "data_path": "action_result.status",
- "data_type": "string",
- "example_values": [
- "success",
- "failed"
- ]
- },
- {
- "data_path": "action_result.parameter.command",
- "data_type": "string",
- "example_values": [
- "savedsearch"
- ]
- },
- {
- "data_path": "action_result.parameter.display",
- "data_type": "string"
- },
- {
- "data_path": "action_result.parameter.parse_only",
- "data_type": "boolean",
- "example_values": [
- true,
- false
- ]
- },
- {
- "contains": [
- "splunk query"
- ],
- "data_path": "action_result.parameter.query",
- "data_type": "string",
- "example_values": [
- "\"Send to Phantom\""
- ]
- },
- {
- "data_path": "action_result.data.*._bkt",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._cd",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._indextime",
- "data_type": "string"
- },
- {
- "column_name": "Raw",
- "column_order": 2,
- "data_path": "action_result.data.*._raw",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._serial",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._si",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._sourcetype",
- "data_type": "string"
- },
- {
- "column_name": "Time",
- "column_order": 1,
- "data_path": "action_result.data.*._time",
- "data_type": "string"
- },
- {
- "column_name": "Host",
- "column_order": 0,
- "contains": [
- "host name"
- ],
- "data_path": "action_result.data.*.host",
- "data_type": "string",
- "example_values": [
- "10.1.67.187:8088"
- ]
- },
- {
- "data_path": "action_result.data.*.index",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*.linecount",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*.source",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*.sourcetype",
- "data_type": "string"
- },
- {
- "contains": [
- "host name"
- ],
- "data_path": "action_result.data.*.splunk_server",
- "data_type": "string"
- },
- {
- "data_path": "action_result.summary.total_events",
- "data_type": "numeric",
- "example_values": [
- 2
- ]
- },
- {
- "data_path": "action_result.message",
- "data_type": "string",
- "example_values": [
- "Total events: 2"
- ]
- },
- {
- "data_path": "summary.total_objects",
- "data_type": "numeric",
- "example_values": [
- 1
- ]
- },
- {
- "data_path": "summary.total_objects_successful",
- "data_type": "numeric",
- "example_values": [
- 1
- ]
- }
- ],
- "parameters": {
- "display": {
- "data_type": "string",
- "default": null,
- "description": "Display fields (comma separated)",
- "key": "display",
- "order": 1,
- "primary": false,
- "required": false
- },
- "query": {
- "contains": [
- "splunk query"
- ],
- "data_type": "string",
- "default": null,
- "description": "Query to run (in Splunk search language)",
- "key": "query",
- "order": 0,
- "primary": true,
- "required": true
- }
- },
- "product_name": "Splunk Enterprise",
- "product_vendor": "Splunk Inc.",
- "targets": "11",
- "type": "siem"
- }
- ],
- "attrs": {
- ".action": {
- "text": "search splunk for ips"
- },
- ".background": {
- "fill": "#000000",
- "stroke": "#5C6773"
- },
- ".color-band": {
- "fill": "#3C444D"
- },
- ".inPorts>.port-in": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".inPorts>.port-in>.port-body": {
- "port": {
- "id": "in",
- "type": "in"
- }
- },
- ".message": {
- "opacity": 0,
- "ref-x": 5,
- "ref-y": 105,
- "text": "Configuring now"
- },
- ".outPorts>.port-out": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".outPorts>.port-out>.port-body": {
- "port": {
- "id": "out",
- "type": "out"
- }
- },
- ".title": {
- "text": "Investigate"
- },
- "g.approver image": {
- "opacity": 1
- },
- "g.code image": {
- "opacity": 1
- },
- "g.delete": {
- "display": "none"
- },
- "g.error": {
- "opacity": 0
- },
- "g.error image": {
- "xlink:href": "/inc/coa/img/block_icon_warn.svg"
- },
- "g.icon image": {
- "xlink:href": "/inc/coa/img/block_icon_investigate.svg"
- },
- "g.notes": {
- "display": "block"
- },
- "g.notes image": {
- "opacity": 1,
- "xlink:href": "/inc/coa/img/block_icon_note_dark_on.svg"
- },
- "g.timer image": {
- "opacity": 1
- }
- },
- "block_code": "def search_splunk_for_ips(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):\n phantom.debug('search_splunk_for_ips() called')\n \n #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))\n \n # collect data for 'search_splunk_for_ips' call\n\n parameters = []\n \n # build parameters list for 'search_splunk_for_ips' call\n parameters.append({\n 'query': \"sourcetype=pan:t* ((earliest=-1d latest=now)) |eval IP=dest_ip | lookup huntip.csv IP OUTPUT RC | search RC>10\",\n 'command': \"\",\n 'display': \"\",\n 'parse_only': \"\",\n })\n\n phantom.act(action=\"run query\", parameters=parameters, assets=['splunk'], callback=search_splunk_for_ips_callback, name=\"search_splunk_for_ips\", parent_action=action)\n\n return",
- "callback_code": "def search_splunk_for_ips_callback(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None):\n phantom.debug('search_splunk_for_ips_callback() called')\n \n join_Send_email_if_related_entities_are_found(action=action, success=success, container=container, results=results, handle=handle, custom_function=custom_function)\n recorded_future_threat_hunting_block_ip(action=action, success=success, container=container, results=results, handle=handle, custom_function=custom_function)\n\n return",
- "callback_start": 106,
- "callsback": true,
- "color": "",
- "connected_to_start": true,
- "connection_name": "build ip lookup",
- "connection_type": "action",
- "custom_callback": "",
- "custom_code": "",
- "custom_join": "",
- "custom_name": "search splunk for ips",
- "delay": 0,
- "description": "Search Palo Alto Networks firewall logs for any events with threat-related ip addresses in the dest_ip field",
- "has_custom": false,
- "has_custom_block": false,
- "has_custom_callback": false,
- "has_custom_join": false,
- "id": "4a326ccb-068c-44cb-807b-8d61e39d7fa0",
- "inPorts": [
- "in"
- ],
- "join_code": "",
- "join_optional": [],
- "join_start": 1,
- "line_end": 114,
- "line_start": 85,
- "message": "Configuring now",
- "name": "run query",
- "notes": "Search Palo Alto Networks firewall logs for any events with threat-related ip addresses in the dest_ip field",
- "number": 3,
- "order": 5,
- "outPorts": [
- "out"
- ],
- "ports": {
- "groups": {
- "in": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "left"
- }
- },
- "position": {
- "name": "left"
- }
- },
- "out": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "right"
- }
- },
- "position": {
- "name": "right"
- }
- }
- }
- },
- "position": {
- "x": 1340,
- "y": -280
- },
- "previous_function": "",
- "previous_name": "search_splunk_for_ips",
- "required_params": {
- "query": true
- },
- "reviewer": "",
- "show_number": true,
- "size": {
- "height": 100,
- "width": 180
- },
- "state": "app_action_assets",
- "status": "",
- "title": "Investigate",
- "type": "coa.Action",
- "warn": false,
- "z": 356
- },
- {
- "action": "run query",
- "action_type": "investigate",
- "active": false,
- "active_keys": {},
- "active_values": {
- "display": "",
- "query": "index=main sourcetype=symantec:ep:risk:file ((earliest=-1d latest=now)) |eval hash=file_hash | lookup hunthash.csv hash OUTPUT RC | search RC>10"
- },
- "angle": 0,
- "app": "Splunk",
- "appid": "91883aa8-9c81-470b-97a1-5d8f7995f560",
- "approver": "",
- "assets": [
- {
- "action": "run query",
- "actions": [
- "test connectivity",
- "get host events",
- "on poll",
- "run query",
- "update event",
- "post data"
- ],
- "active": true,
- "app_name": "Splunk",
- "app_version": "1.3.23",
- "appid": "91883aa8-9c81-470b-97a1-5d8f7995f560",
- "asset_name": "splunk.example.com",
- "config_type": "asset",
- "count": 0,
- "fields": {
- "command": "",
- "display": "",
- "parse_only": "",
- "query": "index=main sourcetype=symantec:ep:risk:file ((earliest=-1d latest=now)) |eval hash=file_hash | lookup hunthash.csv hash OUTPUT RC | search RC>10"
- },
- "has_app": true,
- "id": 11,
- "loaded": false,
- "missing": false,
- "name": "splunk",
- "output": [
- {
- "data_path": "action_result.status",
- "data_type": "string",
- "example_values": [
- "success",
- "failed"
- ]
- },
- {
- "data_path": "action_result.parameter.command",
- "data_type": "string",
- "example_values": [
- "savedsearch"
- ]
- },
- {
- "data_path": "action_result.parameter.display",
- "data_type": "string"
- },
- {
- "data_path": "action_result.parameter.parse_only",
- "data_type": "boolean",
- "example_values": [
- true,
- false
- ]
- },
- {
- "contains": [
- "splunk query"
- ],
- "data_path": "action_result.parameter.query",
- "data_type": "string",
- "example_values": [
- "\"Send to Phantom\""
- ]
- },
- {
- "data_path": "action_result.data.*._bkt",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._cd",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._indextime",
- "data_type": "string"
- },
- {
- "column_name": "Raw",
- "column_order": 2,
- "data_path": "action_result.data.*._raw",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._serial",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._si",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._sourcetype",
- "data_type": "string"
- },
- {
- "column_name": "Time",
- "column_order": 1,
- "data_path": "action_result.data.*._time",
- "data_type": "string"
- },
- {
- "column_name": "Host",
- "column_order": 0,
- "contains": [
- "host name"
- ],
- "data_path": "action_result.data.*.host",
- "data_type": "string",
- "example_values": [
- "10.1.67.187:8088"
- ]
- },
- {
- "data_path": "action_result.data.*.index",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*.linecount",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*.source",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*.sourcetype",
- "data_type": "string"
- },
- {
- "contains": [
- "host name"
- ],
- "data_path": "action_result.data.*.splunk_server",
- "data_type": "string"
- },
- {
- "data_path": "action_result.summary.total_events",
- "data_type": "numeric",
- "example_values": [
- 2
- ]
- },
- {
- "data_path": "action_result.message",
- "data_type": "string",
- "example_values": [
- "Total events: 2"
- ]
- },
- {
- "data_path": "summary.total_objects",
- "data_type": "numeric",
- "example_values": [
- 1
- ]
- },
- {
- "data_path": "summary.total_objects_successful",
- "data_type": "numeric",
- "example_values": [
- 1
- ]
- }
- ],
- "parameters": {
- "display": {
- "data_type": "string",
- "default": null,
- "description": "Display fields (comma separated)",
- "key": "display",
- "order": 1,
- "primary": false,
- "required": false
- },
- "query": {
- "contains": [
- "splunk query"
- ],
- "data_type": "string",
- "default": null,
- "description": "Query to run (in Splunk search language)",
- "key": "query",
- "order": 0,
- "primary": true,
- "required": true
- }
- },
- "product_name": "Splunk Enterprise",
- "product_vendor": "Splunk Inc.",
- "targets": "11",
- "type": "siem"
- }
- ],
- "attrs": {
- ".action": {
- "text": "search splunk for files"
- },
- ".background": {
- "fill": "#000000",
- "stroke": "#5C6773"
- },
- ".color-band": {
- "fill": "#3C444D"
- },
- ".inPorts>.port-in": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".inPorts>.port-in>.port-body": {
- "port": {
- "id": "in",
- "type": "in"
- }
- },
- ".message": {
- "opacity": 0,
- "ref-x": 5,
- "ref-y": 105,
- "text": "Configuring now"
- },
- ".outPorts>.port-out": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".outPorts>.port-out>.port-body": {
- "port": {
- "id": "out",
- "type": "out"
- }
- },
- ".title": {
- "text": "Investigate"
- },
- "g.approver image": {
- "opacity": 1
- },
- "g.code image": {
- "opacity": 1
- },
- "g.delete": {
- "display": "none"
- },
- "g.error": {
- "opacity": 0
- },
- "g.error image": {
- "xlink:href": "/inc/coa/img/block_icon_warn.svg"
- },
- "g.icon image": {
- "xlink:href": "/inc/coa/img/block_icon_investigate.svg"
- },
- "g.notes": {
- "display": "block"
- },
- "g.notes image": {
- "opacity": 1,
- "xlink:href": "/inc/coa/img/block_icon_note_dark_on.svg"
- },
- "g.timer image": {
- "opacity": 1
- }
- },
- "block_code": "def search_splunk_for_files(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):\n phantom.debug('search_splunk_for_files() called')\n \n #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))\n \n # collect data for 'search_splunk_for_files' call\n\n parameters = []\n \n # build parameters list for 'search_splunk_for_files' call\n parameters.append({\n 'query': \"index=main sourcetype=symantec:ep:risk:file ((earliest=-1d latest=now)) |eval hash=file_hash | lookup hunthash.csv hash OUTPUT RC | search RC>10\",\n 'command': \"\",\n 'display': \"\",\n 'parse_only': \"\",\n })\n\n phantom.act(action=\"run query\", parameters=parameters, assets=['splunk'], callback=join_Send_email_if_related_entities_are_found, name=\"search_splunk_for_files\", parent_action=action)\n\n return",
- "callback_code": "",
- "callback_start": 1,
- "callsback": true,
- "color": "",
- "connected_to_start": true,
- "connection_name": "build hash lookup",
- "connection_type": "action",
- "custom_callback": "",
- "custom_code": "",
- "custom_join": "",
- "custom_name": "search splunk for files",
- "delay": 0,
- "description": "Search Symantec Endpoint Protection logs for sightings of threat-related file hashes",
- "has_custom": false,
- "has_custom_block": false,
- "has_custom_callback": false,
- "has_custom_join": false,
- "id": "9a6151b0-b266-4c62-931d-bbaf3b943ebe",
- "inPorts": [
- "in"
- ],
- "join_code": "",
- "join_optional": [],
- "join_start": 1,
- "line_end": 465,
- "line_start": 444,
- "message": "Configuring now",
- "name": "run query",
- "notes": "Search Symantec Endpoint Protection logs for sightings of threat-related file hashes",
- "number": 8,
- "order": 19,
- "outPorts": [
- "out"
- ],
- "ports": {
- "groups": {
- "in": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "left"
- }
- },
- "position": {
- "name": "left"
- }
- },
- "out": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "right"
- }
- },
- "position": {
- "name": "right"
- }
- }
- }
- },
- "position": {
- "x": 1340,
- "y": 0
- },
- "previous_function": "",
- "previous_name": "search_splunk_for_files",
- "required_params": {
- "query": true
- },
- "reviewer": "",
- "show_number": true,
- "size": {
- "height": 100,
- "width": 180
- },
- "state": "app_action_assets",
- "status": "",
- "title": "Investigate",
- "type": "coa.Action",
- "warn": false,
- "z": 361
- },
- {
- "action": "run query",
- "action_type": "investigate",
- "active": false,
- "active_keys": {},
- "active_values": {
- "display": "",
- "query": "index=main sourcetype=\"tenable:sc:vuln\" ((earliest=-7d latest=now)) |eval vuln=cve | lookup huntvuln.csv vuln OUTPUT RC | search RC>10"
- },
- "angle": 0,
- "app": "Splunk",
- "appid": "91883aa8-9c81-470b-97a1-5d8f7995f560",
- "approver": "",
- "assets": [
- {
- "action": "run query",
- "actions": [
- "test connectivity",
- "get host events",
- "on poll",
- "run query",
- "update event",
- "post data"
- ],
- "active": true,
- "app_name": "Splunk",
- "app_version": "1.3.23",
- "appid": "91883aa8-9c81-470b-97a1-5d8f7995f560",
- "asset_name": "splunk.example.com",
- "config_type": "asset",
- "count": 0,
- "fields": {
- "command": "",
- "display": "",
- "parse_only": "",
- "query": "index=main sourcetype=\"tenable:sc:vuln\" ((earliest=-7d latest=now)) |eval vuln=cve | lookup huntvuln.csv vuln OUTPUT RC | search RC>10"
- },
- "has_app": true,
- "id": 11,
- "loaded": false,
- "missing": false,
- "name": "splunk",
- "output": [
- {
- "data_path": "action_result.status",
- "data_type": "string",
- "example_values": [
- "success",
- "failed"
- ]
- },
- {
- "data_path": "action_result.parameter.command",
- "data_type": "string",
- "example_values": [
- "savedsearch"
- ]
- },
- {
- "data_path": "action_result.parameter.display",
- "data_type": "string"
- },
- {
- "data_path": "action_result.parameter.parse_only",
- "data_type": "boolean",
- "example_values": [
- true,
- false
- ]
- },
- {
- "contains": [
- "splunk query"
- ],
- "data_path": "action_result.parameter.query",
- "data_type": "string",
- "example_values": [
- "\"Send to Phantom\""
- ]
- },
- {
- "data_path": "action_result.data.*._bkt",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._cd",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._indextime",
- "data_type": "string"
- },
- {
- "column_name": "Raw",
- "column_order": 2,
- "data_path": "action_result.data.*._raw",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._serial",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._si",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._sourcetype",
- "data_type": "string"
- },
- {
- "column_name": "Time",
- "column_order": 1,
- "data_path": "action_result.data.*._time",
- "data_type": "string"
- },
- {
- "column_name": "Host",
- "column_order": 0,
- "contains": [
- "host name"
- ],
- "data_path": "action_result.data.*.host",
- "data_type": "string",
- "example_values": [
- "10.1.67.187:8088"
- ]
- },
- {
- "data_path": "action_result.data.*.index",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*.linecount",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*.source",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*.sourcetype",
- "data_type": "string"
- },
- {
- "contains": [
- "host name"
- ],
- "data_path": "action_result.data.*.splunk_server",
- "data_type": "string"
- },
- {
- "data_path": "action_result.summary.total_events",
- "data_type": "numeric",
- "example_values": [
- 2
- ]
- },
- {
- "data_path": "action_result.message",
- "data_type": "string",
- "example_values": [
- "Total events: 2"
- ]
- },
- {
- "data_path": "summary.total_objects",
- "data_type": "numeric",
- "example_values": [
- 1
- ]
- },
- {
- "data_path": "summary.total_objects_successful",
- "data_type": "numeric",
- "example_values": [
- 1
- ]
- }
- ],
- "parameters": {
- "display": {
- "data_type": "string",
- "default": null,
- "description": "Display fields (comma separated)",
- "key": "display",
- "order": 1,
- "primary": false,
- "required": false
- },
- "query": {
- "contains": [
- "splunk query"
- ],
- "data_type": "string",
- "default": null,
- "description": "Query to run (in Splunk search language)",
- "key": "query",
- "order": 0,
- "primary": true,
- "required": true
- }
- },
- "product_name": "Splunk Enterprise",
- "product_vendor": "Splunk Inc.",
- "targets": "11",
- "type": "siem"
- }
- ],
- "attrs": {
- ".action": {
- "text": "search splunk for vulns"
- },
- ".background": {
- "fill": "#000000",
- "stroke": "#5C6773"
- },
- ".color-band": {
- "fill": "#3C444D"
- },
- ".inPorts>.port-in": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".inPorts>.port-in>.port-body": {
- "port": {
- "id": "in",
- "type": "in"
- }
- },
- ".message": {
- "opacity": 0,
- "ref-x": 5,
- "ref-y": 105,
- "text": "Configuring now"
- },
- ".outPorts>.port-out": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".outPorts>.port-out>.port-body": {
- "port": {
- "id": "out",
- "type": "out"
- }
- },
- ".title": {
- "text": "Investigate"
- },
- "g.approver image": {
- "opacity": 1
- },
- "g.code image": {
- "opacity": 1
- },
- "g.delete": {
- "display": "none"
- },
- "g.error": {
- "opacity": 0
- },
- "g.error image": {
- "xlink:href": "/inc/coa/img/block_icon_warn.svg"
- },
- "g.icon image": {
- "xlink:href": "/inc/coa/img/block_icon_investigate.svg"
- },
- "g.notes": {
- "display": "block"
- },
- "g.notes image": {
- "opacity": 1,
- "xlink:href": "/inc/coa/img/block_icon_note_dark_on.svg"
- },
- "g.timer image": {
- "opacity": 1
- }
- },
- "block_code": "def search_splunk_for_vulns(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):\n phantom.debug('search_splunk_for_vulns() called')\n \n #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))\n \n # collect data for 'search_splunk_for_vulns' call\n\n parameters = []\n \n # build parameters list for 'search_splunk_for_vulns' call\n parameters.append({\n 'query': \"index=main sourcetype=\\\"tenable:sc:vuln\\\" ((earliest=-7d latest=now)) |eval vuln=cve | lookup huntvuln.csv vuln OUTPUT RC | search RC>10\",\n 'command': \"\",\n 'display': \"\",\n 'parse_only': \"\",\n })\n\n phantom.act(action=\"run query\", parameters=parameters, assets=['splunk'], callback=join_Send_email_if_related_entities_are_found, name=\"search_splunk_for_vulns\", parent_action=action)\n\n return",
- "callback_code": "",
- "callback_start": 1,
- "callsback": true,
- "color": "",
- "connected_to_start": true,
- "connection_name": "build vuln lookup",
- "connection_type": "action",
- "custom_callback": "",
- "custom_code": "",
- "custom_join": "",
- "custom_name": "search splunk for vulns",
- "delay": 0,
- "description": "Search Tenable vulnerability scanning logs for any vulnerabilities related to the initial IP addresses",
- "has_custom": false,
- "has_custom_block": false,
- "has_custom_callback": false,
- "has_custom_join": false,
- "id": "2581c9e7-6a6c-488d-bff2-720a5e906763",
- "inPorts": [
- "in"
- ],
- "join_code": "",
- "join_optional": [],
- "join_start": 1,
- "line_end": 489,
- "line_start": 468,
- "message": "Configuring now",
- "name": "run query",
- "notes": "Search Tenable vulnerability scanning logs for any vulnerabilities related to the initial IP addresses",
- "number": 9,
- "order": 20,
- "outPorts": [
- "out"
- ],
- "ports": {
- "groups": {
- "in": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "left"
- }
- },
- "position": {
- "name": "left"
- }
- },
- "out": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "right"
- }
- },
- "position": {
- "name": "right"
- }
- }
- }
- },
- "position": {
- "x": 1340,
- "y": 140
- },
- "previous_function": "",
- "previous_name": "search_splunk_for_vulns",
- "required_params": {
- "query": true
- },
- "reviewer": "",
- "show_number": true,
- "size": {
- "height": 100,
- "width": 180
- },
- "state": "app_action_assets",
- "status": "",
- "title": "Investigate",
- "type": "coa.Action",
- "warn": false,
- "z": 362
- },
- {
- "active": false,
- "angle": 0,
- "approver": "admin",
- "attrs": {
- ".background": {
- "fill": "#000000",
- "stroke": "#5C6773"
- },
- ".inPorts>.port-in": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".inPorts>.port-in>.port-body": {
- "port": {
- "id": "in",
- "type": "in"
- }
- },
- ".number": {
- "text": 1
- },
- ".outPorts>.port-out": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".outPorts>.port-out>.port-body": {
- "port": {
- "id": "out",
- "type": "out"
- }
- },
- "g.delete": {
- "display": "none"
- },
- "g.error": {
- "opacity": 0
- },
- "g.error image": {
- "xlink:href": "/inc/coa/img/block_icon_warn.svg"
- },
- "g.notes": {
- "display": "block"
- },
- "g.notes image": {
- "opacity": 1,
- "xlink:href": "/inc/coa/img/block_icon_note_dark_on.svg"
- }
- },
- "block_code": "def recorded_future_threat_hunting_block_ip(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):\n phantom.debug('recorded_future_threat_hunting_block_ip() called')\n \n # set user and message variables for phantom.prompt call\n user = \"admin\"\n message = \"\"\"Do you want to add the following IP(s) to the block IP block list:\n{0}\"\"\"\n\n # parameter list for template variable replacement\n parameters = [\n \"search_splunk_for_ips:action_result.data.*.IP\",\n ]\n\n #responses:\n response_types = [\n {\n \"prompt\": \"\",\n \"options\": {\n \"type\": \"list\",\n \"choices\": [\n \"Yes\",\n \"No\",\n ]\n },\n },\n ]\n\n phantom.prompt2(container=container, user=user, message=message, respond_in_mins=30, name=\"recorded_future_threat_hunting_block_ip\", parameters=parameters, response_types=response_types, callback=check_prompt)\n\n return",
- "callback_code": "",
- "callback_start": 1,
- "callsback": true,
- "connected_to_start": true,
- "connection_name": "search splunk for ips",
- "connection_type": "action",
- "custom_callback": "",
- "custom_code": "",
- "custom_join": "",
- "custom_name": "recorded_future_threat_hunting_block_ip",
- "description": "Ask an analyst whether the discovered related IP addresses should be blocked",
- "has_custom": false,
- "has_custom_block": false,
- "has_custom_callback": false,
- "has_custom_join": false,
- "id": "168d14e9-de64-4a76-8cb9-5488d711f22e",
- "inPorts": [
- "in"
- ],
- "join_code": "",
- "join_optional": [],
- "join_start": 1,
- "line_end": 148,
- "line_start": 117,
- "message": "Do you want to add the following IP(s) to the block IP block list:\n{0}",
- "name": "prompt",
- "notes": "Ask an analyst whether the discovered related IP addresses should be blocked",
- "number": 1,
- "order": 6,
- "outPorts": [
- "out"
- ],
- "parameters": [
- {
- "position": 0,
- "type": "",
- "value": "search_splunk_for_ips:action_result.data.*.IP"
- }
- ],
- "ports": {
- "groups": {
- "in": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "left"
- }
- },
- "position": {
- "name": "left"
- }
- },
- "out": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "right"
- }
- },
- "position": {
- "name": "right"
- }
- }
- }
- },
- "position": {
- "x": 1580,
- "y": -280
- },
- "previous_function": "",
- "previous_name": "recorded_future_threat_hunting_block_ip",
- "respond_in": "30",
- "response_key": "Yes/No",
- "response_options": [
- "Yes",
- "No"
- ],
- "response_type": "list",
- "responses": [
- {
- "response_key": "Yes/No",
- "response_options": [
- "Yes",
- "No"
- ],
- "response_prompt": "",
- "response_type": "list"
- }
- ],
- "show_number": true,
- "size": {
- "height": 80,
- "width": 80
- },
- "state": "prompt",
- "status": "",
- "type": "coa.Prompt",
- "warn": false,
- "z": 369
- },
- {
- "active": false,
- "angle": 0,
- "attrs": {
- ".background": {
- "fill": "#000000",
- "stroke": "#637282",
- "transform": "rotate(45 30 70)"
- },
- ".inPorts>.port-0>.port-body": {
- "port": {
- "id": "in",
- "type": "in"
- }
- },
- ".number": {
- "text": 3
- },
- ".outPorts>.port-0": {
- "port": {
- "id": "out-1",
- "type": "out"
- },
- "ref-x": 83,
- "ref-y": 40
- },
- ".outPorts>.port-0>.port-body": {
- "port": {
- "id": "out-1",
- "type": "out"
- }
- },
- "g.delete": {
- "display": "none"
- },
- "g.error": {
- "opacity": 0
- },
- "g.error image": {
- "xlink:href": "/inc/coa/img/block_icon_warn.svg"
- },
- "g.notes": {
- "display": "block"
- },
- "g.notes image": {
- "opacity": 1,
- "xlink:href": "/inc/coa/img/block_icon_note_dark_on.svg"
- }
- },
- "block_code": "def Send_email_if_related_entities_are_found(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):\n phantom.debug('Send_email_if_related_entities_are_found() called')\n\n # check for 'if' condition 1\n matched = phantom.decision(\n container=container,\n action_results=results,\n conditions=[\n [\"search_splunk_for_ips:action_result.data.*.RC\", \">\", 0],\n [\"search_splunk_for_domains:action_result.data.*.RC\", \">\", 0],\n [\"search_splunk_for_files:action_result.data.*.RC\", \">\", 0],\n [\"search_splunk_for_vulns:action_result.data.*.Rc\", \">\", 0],\n ],\n logical_operator='or')\n\n # call connected blocks if condition 1 matched\n if matched:\n format_email(action=action, success=success, container=container, results=results, handle=handle, custom_function=custom_function)\n return\n\n return",
- "callback_code": "",
- "callback_start": 1,
- "callsback": false,
- "connected_to_start": true,
- "connection_name": "search splunk for ips, search splunk for domains, search splunk for files, search splunk for vulns",
- "connection_type": "action",
- "custom_callback": "",
- "custom_code": "",
- "custom_join": "",
- "custom_name": "Send email if related entities are found",
- "description": "If any of the Splunk searches had any results, send an email to an analyst",
- "hasElse": false,
- "has_custom": false,
- "has_custom_block": false,
- "has_custom_callback": false,
- "has_custom_join": false,
- "id": "c0301f30-04f3-4248-9f5a-52a62e8fbecc",
- "inPorts": [
- "in"
- ],
- "join_code": "def join_Send_email_if_related_entities_are_found(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None):\n phantom.debug('join_Send_email_if_related_entities_are_found() called')\n\n # check if all connected incoming playbooks, actions, or custom functions are done i.e. have succeeded or failed\n if phantom.completed(action_names=['search_splunk_for_ips', 'search_splunk_for_domains', 'search_splunk_for_files', 'search_splunk_for_vulns']):\n \n # call connected block \"Send_email_if_related_entities_are_found\"\n Send_email_if_related_entities_are_found(container=container, handle=handle)\n \n return",
- "join_optional": [],
- "join_start": 208,
- "line_end": 219,
- "line_start": 186,
- "name": "decision",
- "notes": "If any of the Splunk searches had any results, send an email to an analyst",
- "number": 3,
- "order": 9,
- "outPorts": [
- "out-1"
- ],
- "outputs": [
- {
- "conditions": [
- {
- "comparison": ">",
- "data_type": "",
- "param": "search_splunk_for_ips:action_result.data.*.RC",
- "value": "0"
- },
- {
- "comparison": ">",
- "data_type": "",
- "param": "search_splunk_for_domains:action_result.data.*.RC",
- "value": "0"
- },
- {
- "comparison": ">",
- "data_type": "",
- "param": "search_splunk_for_files:action_result.data.*.RC",
- "value": "0"
- },
- {
- "comparison": ">",
- "data_type": "",
- "param": "search_splunk_for_vulns:action_result.data.*.Rc",
- "value": "0"
- }
- ],
- "display": "If",
- "logic": "or",
- "type": "if"
- }
- ],
- "ports": {
- "groups": {
- "in": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "left"
- }
- },
- "position": {
- "name": "left"
- }
- },
- "out": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "right"
- }
- },
- "position": {
- "name": "right"
- }
- }
- }
- },
- "position": {
- "x": 1580,
- "y": -140
- },
- "previous_function": "",
- "previous_name": "Send_email_if_related_entities_are_found",
- "show_number": true,
- "size": {
- "height": 82,
- "width": 82
- },
- "state": "decision",
- "status": "",
- "type": "coa.Decision",
- "warn": "",
- "z": 370
- },
- {
- "active": false,
- "angle": 0,
- "attrs": {
- ".background": {
- "fill": "#000000",
- "stroke": "#5C6773"
- },
- ".color-band": {
- "fill": "#3C444D"
- },
- ".format": {
- "text": "format email"
- },
- ".inPorts>.port-in": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".inPorts>.port-in>.port-body": {
- "port": {
- "id": "in",
- "type": "in"
- }
- },
- ".message": {
- "opacity": 0,
- "text": "Configuring now"
- },
- ".outPorts>.port-out-1": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".outPorts>.port-out-1>.port-body": {
- "port": {
- "id": "out-1",
- "type": "out"
- }
- },
- ".title": {
- "text": "format"
- },
- "g.code image": {
- "opacity": 1
- },
- "g.delete": {
- "display": "none"
- },
- "g.error": {
- "opacity": 0
- },
- "g.error image": {
- "xlink:href": "/inc/coa/img/block_icon_warn.svg"
- },
- "g.notes": {
- "display": "block"
- },
- "g.notes image": {
- "opacity": 1,
- "xlink:href": "/inc/coa/img/block_icon_note_dark_on.svg"
- }
- },
- "block_code": "def format_email(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):\n phantom.debug('format_email() called')\n \n template = \"\"\"The potentially malicious destination IP {0} with a Risk Score of {1} was identified and process by the Phantom playbook \\\"recorded_future_threat_hunting\\\".\n\nAdditional searches performed against various logs showed that the following related entities occurring in > 10 relations have been found in recent events:\n\nIP addresses: {2}\ndomain names: {3}\nfile hashes: {4}\nvulnerability identifiers: {5}\n\nMore details are available in Phantom: {6}\"\"\"\n\n # parameter list for template variable replacement\n parameters = [\n \"ip_intelligence_1:action_result.parameter.ip\",\n \"ip_intelligence_1:action_result.data.*.risk.score\",\n \"search_splunk_for_ips:action_result.data.*.IP\",\n \"search_splunk_for_domains:action_result.data.*.domain\",\n \"search_splunk_for_files:action_result.data.*.hash\",\n \"search_splunk_for_vulns:action_result.data.*.vuln\",\n \"container:url\",\n ]\n\n phantom.format(container=container, template=template, parameters=parameters, name=\"format_email\")\n\n send_email_1(container=container)\n\n return",
- "callback_code": "",
- "callback_start": 1,
- "callsback": false,
- "connected_to_start": true,
- "connection_name": "search splunk for ips, search splunk for domains, search splunk for files, search splunk for vulns",
- "connection_type": "action",
- "custom_callback": "",
- "custom_code": "",
- "custom_join": "",
- "custom_name": "format email",
- "description": "Include the intelligence context and Splunk results in the email and link to the event in Phantom for the rest of the detail",
- "format": "format",
- "has_custom": false,
- "has_custom_block": false,
- "has_custom_callback": false,
- "has_custom_join": false,
- "id": "f4638aa4-0b35-4b81-ba9c-21bf905d70ad",
- "inPorts": [
- "in"
- ],
- "join_code": "",
- "join_optional": [],
- "join_start": 1,
- "line_end": 253,
- "line_start": 222,
- "message": "Configuring now",
- "name": "format",
- "notes": "Include the intelligence context and Splunk results in the email and link to the event in Phantom for the rest of the detail",
- "number": 3,
- "order": 10,
- "outPorts": [
- "out-1"
- ],
- "parameters": [
- {
- "position": 0,
- "type": "",
- "value": "ip_intelligence_1:action_result.parameter.ip"
- },
- {
- "position": 1,
- "type": "",
- "value": "ip_intelligence_1:action_result.data.*.risk.score"
- },
- {
- "position": 2,
- "type": "",
- "value": "search_splunk_for_ips:action_result.data.*.IP"
- },
- {
- "position": 3,
- "type": "",
- "value": "search_splunk_for_domains:action_result.data.*.domain"
- },
- {
- "position": 4,
- "type": "",
- "value": "search_splunk_for_files:action_result.data.*.hash"
- },
- {
- "position": 5,
- "type": "",
- "value": "search_splunk_for_vulns:action_result.data.*.vuln"
- },
- {
- "position": 6,
- "type": "",
- "value": "container:url"
- }
- ],
- "ports": {
- "groups": {
- "in": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "left"
- }
- },
- "position": {
- "name": "left"
- }
- },
- "out": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "right"
- }
- },
- "position": {
- "name": "right"
- }
- }
- }
- },
- "position": {
- "x": 1720,
- "y": -140
- },
- "previous_function": "",
- "previous_name": "format_email",
- "show_number": true,
- "size": {
- "height": 100,
- "width": 180
- },
- "state": "format",
- "status": "",
- "template": "The potentially malicious destination IP {0} with a Risk Score of {1} was identified and process by the Phantom playbook \"recorded_future_threat_hunting\".\n\nAdditional searches performed against various logs showed that the following related entities occurring in > 10 relations have been found in recent events:\n\nIP addresses: {2}\ndomain names: {3}\nfile hashes: {4}\nvulnerability identifiers: {5}\n\nMore details are available in Phantom: {6}",
- "title": "format",
- "type": "coa.Format",
- "warn": false,
- "z": 372
- },
- {
- "active": false,
- "angle": 0,
- "attrs": {
- ".background": {
- "fill": "#000000",
- "stroke": "#637282",
- "transform": "rotate(45 30 70)"
- },
- ".inPorts>.port-0>.port-body": {
- "port": {
- "id": "in",
- "type": "in"
- }
- },
- ".number": {
- "text": 2
- },
- ".outPorts>.port-0": {
- "port": {
- "id": "out-1",
- "type": "out"
- },
- "ref-x": 83,
- "ref-y": 40
- },
- ".outPorts>.port-0>.port-body": {
- "port": {
- "id": "out-1",
- "type": "out"
- }
- },
- "g.delete": {
- "display": "none"
- },
- "g.error": {
- "opacity": 0
- },
- "g.error image": {
- "xlink:href": "/inc/coa/img/block_icon_warn.svg"
- },
- "g.notes": {
- "display": "block"
- },
- "g.notes image": {
- "opacity": 1,
- "xlink:href": "/inc/coa/img/block_icon_note_dark_on.svg"
- }
- },
- "block_code": "def check_prompt(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):\n phantom.debug('check_prompt() called')\n\n # check for 'if' condition 1\n matched = phantom.decision(\n container=container,\n action_results=results,\n conditions=[\n [\"recorded_future_threat_hunting_block_ip:action_result.summary.response\", \"==\", \"Yes\"],\n ])\n\n # call connected blocks if condition 1 matched\n if matched:\n add_ip_to_block_list(action=action, success=success, container=container, results=results, handle=handle, custom_function=custom_function)\n return\n\n return",
- "callback_code": "",
- "callback_start": 1,
- "callsback": false,
- "connected_to_start": true,
- "connection_name": "recorded_future_threat_hunting_block_ip",
- "connection_type": "action",
- "custom_callback": "",
- "custom_code": "",
- "custom_join": "",
- "custom_name": "check_prompt",
- "description": "Only proceed if the analyst approved the prompt",
- "hasElse": false,
- "has_custom": false,
- "has_custom_block": false,
- "has_custom_callback": false,
- "has_custom_join": false,
- "id": "ad2d40e7-adc6-488e-95bf-6dc68b3111ee",
- "inPorts": [
- "in"
- ],
- "join_code": "",
- "join_optional": [],
- "join_start": 1,
- "line_end": 169,
- "line_start": 151,
- "name": "decision",
- "notes": "Only proceed if the analyst approved the prompt",
- "number": 2,
- "order": 7,
- "outPorts": [
- "out-1"
],
- "outputs": [
+ "type": "action"
+ },
+ "errors": {},
+ "id": "2",
+ "type": "action",
+ "x": 1060,
+ "y": 460
+ },
+ "20": {
+ "data": {
+ "advanced": {
+ "join": []
+ },
+ "conditions": [
{
- "conditions": [
+ "comparisons": [
{
- "comparison": "==",
- "data_type": "",
- "param": "recorded_future_threat_hunting_block_ip:action_result.summary.response",
+ "conditionIndex": 0,
+ "op": "==",
+ "param": "recorded_future_threat_hunting_block_ip:action_result.summary.responses.0",
"value": "Yes"
}
],
+ "conditionIndex": 0,
"display": "If",
"logic": "and",
"type": "if"
}
],
- "ports": {
- "groups": {
- "in": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "left"
- }
- },
- "position": {
- "name": "left"
- }
- },
- "out": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "right"
- }
- },
- "position": {
- "name": "right"
- }
- }
- }
- },
- "position": {
- "x": 1720,
- "y": -280
- },
- "previous_function": "",
- "previous_name": "check_prompt",
- "show_number": true,
- "size": {
- "height": 82,
- "width": 82
- },
- "state": "decision",
- "status": "",
- "type": "coa.Decision",
- "warn": "",
- "z": 374
+ "functionId": 2,
+ "functionName": "decision_2",
+ "id": "20",
+ "type": "decision"
},
- {
- "active": false,
- "angle": 0,
- "api": "add list",
- "attrs": {
- ".api": {
- "text": "add ip to block list"
- },
- ".background": {
- "fill": "#000000",
- "stroke": "#5C6773"
- },
- ".color-band": {
- "fill": "#3C444D"
- },
- ".inPorts>.port-in": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".inPorts>.port-in>.port-body": {
- "port": {
- "id": "in",
- "type": "in"
- }
- },
- ".message": {
- "opacity": 0,
- "ref-x": 5,
- "ref-y": 105,
- "text": "Configuring now"
- },
- ".outPorts>.port-out": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".outPorts>.port-out>.port-body": {
- "port": {
- "id": "out",
- "type": "out"
- }
- },
- ".title": {
- "text": "API"
- },
- "g.code image": {
- "opacity": 1
- },
- "g.delete": {
- "display": "none"
- },
- "g.error": {
- "opacity": 0
- },
- "g.error image": {
- "xlink:href": "/inc/coa/img/block_icon_warn.svg"
- },
- "g.notes": {
- "display": "block"
- },
- "g.notes code": {
- "opacity": 1,
- "xlink:href": "/inc/coa/img/block_icon_code_dark_off.svg"
- },
- "g.notes image": {
- "opacity": 1,
- "xlink:href": "/inc/coa/img/block_icon_note_dark_on.svg"
- }
- },
- "block_code": "def add_ip_to_block_list(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):\n phantom.debug('add_ip_to_block_list() called')\n\n results_data_1 = phantom.collect2(container=container, datapath=['search_splunk_for_ips:action_result.data.*.IP'], action_results=results)\n\n results_item_1_0 = [item[0] for item in results_data_1]\n\n phantom.add_list(\"IP Block List\", results_item_1_0)\n\n return",
- "callback_code": "",
- "callback_start": 1,
- "callsback": false,
- "color": "",
- "configured": [
- {
- "addListData": "search_splunk_for_ips:action_result.data.*.IP",
- "addListList": "IP Block List",
- "key": "add-list"
- }
- ],
- "connected_to_start": true,
- "connection_name": "recorded_future_threat_hunting_block_ip",
- "connection_type": "action",
- "custom_callback": "",
- "custom_code": "",
- "custom_join": "",
- "custom_name": "add ip to block list",
- "description": "Add the IP address to a Phantom custom list, which can be tracked as a REST-accessible external block list by a firewall",
- "has_custom": false,
- "has_custom_block": false,
- "has_custom_callback": false,
- "has_custom_join": false,
- "id": "98eaf55d-cfa9-4f15-bb6c-70a009cb10ef",
- "inPorts": [
- "in"
- ],
- "join_code": "",
- "join_optional": [],
- "join_start": 1,
- "line_end": 183,
- "line_start": 172,
- "message": "Configuring now",
- "name": "add list",
- "notes": "Add the IP address to a Phantom custom list, which can be tracked as a REST-accessible external block list by a firewall",
- "number": 3,
- "order": 8,
- "outPorts": [
- "out"
- ],
- "ports": {
- "groups": {
- "in": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "left"
- }
- },
- "position": {
- "name": "left"
- }
- },
- "out": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "right"
- }
+ "errors": {},
+ "id": "20",
+ "type": "decision",
+ "x": 520,
+ "y": 1484.5
+ },
+ "21": {
+ "data": {
+ "advanced": {
+ "customName": "add ip to block list",
+ "customNameId": 0,
+ "description": "Add the IP address to a Phantom custom list, which can be tracked as a REST-accessible external block list by a firewall",
+ "join": [],
+ "note": "Add the IP address to a Phantom custom list, which can be tracked as a REST-accessible external block list by a firewall"
+ },
+ "functionId": 1,
+ "functionName": "add_ip_to_block_list",
+ "id": "21",
+ "selectMore": false,
+ "tab": "apis",
+ "type": "utility",
+ "utilities": {
+ "add_list": {
+ "description": "",
+ "fields": [
+ {
+ "choices": "lists",
+ "description": "",
+ "label": "list",
+ "name": "list_name",
+ "placeholder": "Select a list",
+ "renderType": "combobox",
+ "required": true
},
- "position": {
- "name": "right"
+ {
+ "description": "",
+ "label": "data",
+ "name": "values",
+ "placeholder": "Enter data",
+ "renderType": "datapath",
+ "required": true
}
- }
+ ],
+ "label": "add to list",
+ "name": "add_list"
}
},
- "position": {
- "x": 1860,
- "y": -280
- },
- "previous_function": "",
- "previous_name": "add_ip_to_block_list",
- "show_number": false,
- "size": {
- "height": 100,
- "width": 180
- },
- "state": "api",
- "status": "",
- "title": "API",
- "type": "coa.API",
- "warn": false,
- "z": 375
+ "utilityType": "api",
+ "values": {
+ "add_list": {
+ "list_name": "IP Block List",
+ "values": "search_splunk_for_ips:action_result.data.*.Name"
+ }
+ }
},
- {
- "action": "run query",
- "action_type": "investigate",
- "active": false,
- "active_keys": {},
- "active_values": {
- "display": "",
- "query": "sourcetype=pan:threat ((earliest=-1d latest=now)) |eval domain=dest_hostname | lookup huntdomain.csv domain OUTPUT RC | search RC>10"
- },
- "angle": 0,
- "app": "Splunk",
- "appid": "91883aa8-9c81-470b-97a1-5d8f7995f560",
- "approver": "",
- "assets": [
+ "errors": {},
+ "id": "21",
+ "type": "utility",
+ "x": 440,
+ "y": 1644.5
+ },
+ "22": {
+ "data": {
+ "advanced": {
+ "customName": "format email",
+ "customNameId": 0,
+ "description": "Include the intelligence context and Splunk results in the email and link to the event in Phantom for the rest of the detail",
+ "join": [],
+ "note": "Include the intelligence context and Splunk results in the email and link to the event in Phantom for the rest of the detail"
+ },
+ "functionId": 6,
+ "functionName": "format_email",
+ "id": "22",
+ "parameters": [
+ "ip_intelligence_1:action_result.parameter.ip",
+ "ip_intelligence_1:action_result.data.*.risk.score",
+ "search_splunk_for_ips:action_result.data.*.Name",
+ "search_splunk_for_domains:action_result",
+ "search_splunk_for_files:action_result.data.*.Name",
+ "search_splunk_for_vulns:action_result.data.*.Name",
+ "container:url",
+ "ip_intelligence_1:action_result.data.*.recordedfutureLinks.entities.other.*.name",
+ "ip_intelligence_1:action_result.data.*.recordedfutureLinks.entities.ip.*.name",
+ "ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.entity.name",
+ "ip_intelligence_1:action_result.data.*.intelCard",
+ "ip_intelligence_1:action_result.data.*.location.location.city",
+ "ip_intelligence_1:action_result.data.*.location.location.country",
+ "ip_intelligence_1:action_result.data.*.location.location.continent"
+ ],
+ "template": "The potentially malicious destination IP {0} with a Risk Score of {1} was identified and processed by the Phantom playbook \"recorded_future_threat_hunting_conf\". \n\nThe IP is located in {11}, {12}, {13}\n\nAdditional searches performed against various logs showed that the following linked entities have been found in recent events:\n\nIP addresses: \n{2}\n\ndomain names: \n{3}\n\nfile hashes: \n{4}\n\nvulnerability identifiers: \n{5}\n\nRecorded Future Intelligence has also linked this IP to the following additional Entities:\n{7}\n\nMore details are available in Phantom: {6}\n\nMore details are available in Recorded Future: {10}",
+ "type": "format"
+ },
+ "errors": {},
+ "id": "22",
+ "type": "format",
+ "x": 960,
+ "y": 1360
+ },
+ "23": {
+ "data": {
+ "advanced": {
+ "customName": "send email if related entities are found",
+ "customNameId": 0,
+ "description": "If any of the Splunk searches had any results, send an email to an analyst",
+ "join": [],
+ "note": "If any of the Splunk searches had any results, send an email to an analyst"
+ },
+ "conditions": [
{
- "action": "run query",
- "actions": [
- "test connectivity",
- "get host events",
- "on poll",
- "run query",
- "update event",
- "post data"
- ],
- "active": true,
- "app_name": "Splunk",
- "app_version": "1.3.23",
- "appid": "91883aa8-9c81-470b-97a1-5d8f7995f560",
- "asset_name": "splunk.example.com",
- "config_type": "asset",
- "count": 0,
- "fields": {
- "command": "",
- "display": "",
- "parse_only": "",
- "query": "sourcetype=pan:threat ((earliest=-1d latest=now)) |eval domain=dest_hostname | lookup huntdomain.csv domain OUTPUT RC | search RC>10"
- },
- "has_app": true,
- "id": 11,
- "loaded": false,
- "missing": false,
- "name": "splunk",
- "output": [
- {
- "data_path": "action_result.status",
- "data_type": "string",
- "example_values": [
- "success",
- "failed"
- ]
- },
- {
- "data_path": "action_result.parameter.command",
- "data_type": "string",
- "example_values": [
- "savedsearch"
- ]
- },
- {
- "data_path": "action_result.parameter.display",
- "data_type": "string"
- },
- {
- "data_path": "action_result.parameter.parse_only",
- "data_type": "boolean",
- "example_values": [
- true,
- false
- ]
- },
- {
- "contains": [
- "splunk query"
- ],
- "data_path": "action_result.parameter.query",
- "data_type": "string",
- "example_values": [
- "\"Send to Phantom\""
- ]
- },
- {
- "data_path": "action_result.data.*._bkt",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*._cd",
- "data_type": "string"
- },
+ "comparisons": [
{
- "data_path": "action_result.data.*._indextime",
- "data_type": "string"
+ "conditionIndex": 0,
+ "op": ">",
+ "param": "search_splunk_for_ips:action_result.data.*.RF_Risk_Score",
+ "value": "64"
},
{
- "column_name": "Raw",
- "column_order": 2,
- "data_path": "action_result.data.*._raw",
- "data_type": "string"
+ "op": ">",
+ "param": "search_splunk_for_domains:action_result.data.*.RF_Risk_Score",
+ "value": "64"
},
{
- "data_path": "action_result.data.*._serial",
- "data_type": "string"
+ "op": ">",
+ "param": "search_splunk_for_files:action_result",
+ "value": "64"
},
{
- "data_path": "action_result.data.*._si",
- "data_type": "string"
+ "op": ">",
+ "param": "search_splunk_for_vulns:action_result.data.*.RF_Risk_Score",
+ "value": "64"
},
{
- "data_path": "action_result.data.*._sourcetype",
- "data_type": "string"
- },
- {
- "column_name": "Time",
- "column_order": 1,
- "data_path": "action_result.data.*._time",
- "data_type": "string"
- },
- {
- "column_name": "Host",
- "column_order": 0,
- "contains": [
- "host name"
- ],
- "data_path": "action_result.data.*.host",
- "data_type": "string",
- "example_values": [
- "10.1.67.187:8088"
- ]
- },
- {
- "data_path": "action_result.data.*.index",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*.linecount",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*.source",
- "data_type": "string"
- },
- {
- "data_path": "action_result.data.*.sourcetype",
- "data_type": "string"
- },
- {
- "contains": [
- "host name"
- ],
- "data_path": "action_result.data.*.splunk_server",
- "data_type": "string"
- },
- {
- "data_path": "action_result.summary.total_events",
- "data_type": "numeric",
- "example_values": [
- 2
- ]
- },
- {
- "data_path": "action_result.message",
- "data_type": "string",
- "example_values": [
- "Total events: 2"
- ]
- },
- {
- "data_path": "summary.total_objects",
- "data_type": "numeric",
- "example_values": [
- 1
- ]
- },
- {
- "data_path": "summary.total_objects_successful",
- "data_type": "numeric",
- "example_values": [
- 1
- ]
+ "op": ">",
+ "param": "search_splunk_for_urls:action_result.data.*.RF_Risk_Score",
+ "value": "64"
}
],
- "parameters": {
- "display": {
- "data_type": "string",
- "default": null,
- "description": "Display fields (comma separated)",
- "key": "display",
- "order": 1,
- "primary": false,
- "required": false
- },
- "query": {
- "contains": [
- "splunk query"
- ],
- "data_type": "string",
- "default": null,
- "description": "Query to run (in Splunk search language)",
- "key": "query",
- "order": 0,
- "primary": true,
- "required": true
- }
- },
- "product_name": "Splunk Enterprise",
- "product_vendor": "Splunk Inc.",
- "targets": "11",
- "type": "siem"
- }
- ],
- "attrs": {
- ".action": {
- "text": "search splunk for domai..."
- },
- ".background": {
- "fill": "#000000",
- "stroke": "#5C6773"
- },
- ".color-band": {
- "fill": "#3C444D"
- },
- ".inPorts>.port-in": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".inPorts>.port-in>.port-body": {
- "port": {
- "id": "in",
- "type": "in"
- }
- },
- ".message": {
- "opacity": 0,
- "ref-x": 5,
- "ref-y": 105,
- "text": "Configuring now"
- },
- ".outPorts>.port-out": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".outPorts>.port-out>.port-body": {
- "port": {
- "id": "out",
- "type": "out"
- }
- },
- ".title": {
- "text": "Investigate"
- },
- "g.approver image": {
- "opacity": 1
- },
- "g.code image": {
- "opacity": 1
- },
- "g.delete": {
- "display": "none"
- },
- "g.error": {
- "opacity": 0
- },
- "g.error image": {
- "xlink:href": "/inc/coa/img/block_icon_warn.svg"
- },
- "g.icon image": {
- "xlink:href": "/inc/coa/img/block_icon_investigate.svg"
- },
- "g.notes": {
- "display": "block"
- },
- "g.notes image": {
- "opacity": 1,
- "xlink:href": "/inc/coa/img/block_icon_note_dark_on.svg"
- },
- "g.timer image": {
- "opacity": 1
+ "conditionIndex": 0,
+ "display": "If",
+ "logic": "or",
+ "type": "if"
}
- },
- "block_code": "def search_splunk_for_domains(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):\n phantom.debug('search_splunk_for_domains() called')\n \n #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))\n \n # collect data for 'search_splunk_for_domains' call\n\n parameters = []\n \n # build parameters list for 'search_splunk_for_domains' call\n parameters.append({\n 'query': \"sourcetype=pan:threat ((earliest=-1d latest=now)) |eval domain=dest_hostname | lookup huntdomain.csv domain OUTPUT RC | search RC>10\",\n 'command': \"\",\n 'display': \"\",\n 'parse_only': \"\",\n })\n\n phantom.act(action=\"run query\", parameters=parameters, assets=['splunk'], callback=join_Send_email_if_related_entities_are_found, name=\"search_splunk_for_domains\", parent_action=action)\n\n return",
- "callback_code": "",
- "callback_start": 1,
- "callsback": true,
- "color": "",
- "connected_to_start": true,
- "connection_name": "build domain lookup",
- "connection_type": "action",
- "custom_callback": "",
- "custom_code": "",
- "custom_join": "",
- "custom_name": "search splunk for domains",
- "delay": 0,
- "description": "Search Palo Alto Networks threat logs for any events with threat-related domain names in the dest_hostname field",
- "has_custom": false,
- "has_custom_block": false,
- "has_custom_callback": false,
- "has_custom_join": false,
- "id": "27474fdc-e2a7-4347-a1ed-57a84fb43d10",
- "inPorts": [
- "in"
],
- "join_code": "",
- "join_optional": [],
- "join_start": 1,
- "line_end": 441,
- "line_start": 420,
- "message": "Configuring now",
- "name": "run query",
- "notes": "Search Palo Alto Networks threat logs for any events with threat-related domain names in the dest_hostname field",
- "number": 7,
- "order": 18,
- "outPorts": [
- "out"
- ],
- "ports": {
- "groups": {
- "in": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "left"
- }
- },
- "position": {
- "name": "left"
- }
- },
- "out": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "right"
- }
- },
- "position": {
- "name": "right"
- }
- }
- }
- },
- "position": {
- "x": 1340,
- "y": -140
- },
- "previous_function": "",
- "previous_name": "search_splunk_for_domains",
- "required_params": {
- "query": true
- },
- "reviewer": "",
- "show_number": true,
- "size": {
- "height": 100,
- "width": 180
- },
- "state": "app_action_assets",
- "status": "",
- "title": "Investigate",
- "type": "coa.Action",
- "warn": false,
- "z": 376
+ "functionId": 3,
+ "functionName": "send_email_if_related_entities_are_found",
+ "id": "23",
+ "type": "decision"
},
- {
+ "errors": {},
+ "id": "23",
+ "type": "decision",
+ "x": 1040,
+ "y": 1500
+ },
+ "25": {
+ "data": {
"action": "send email",
- "action_type": "generic",
- "active": false,
- "active_keys": {},
- "active_values": {
- "attachments": "",
- "bcc": "",
+ "actionType": "generic",
+ "advanced": {
+ "customName": "send email",
+ "customNameId": 0,
+ "description": "Send the formatted email to a hard-coded recipient",
+ "join": [],
+ "note": "Send the formatted email to a hard-coded recipient"
+ },
+ "connector": "SMTP",
+ "connectorConfigs": [
+ "email"
+ ],
+ "connectorId": "45bb6f37-4478-499b-b4a3-51ecfa62b78c",
+ "connectorVersion": "v1",
+ "functionId": 1,
+ "functionName": "send_email",
+ "id": "25",
+ "parameters": {
"body": "format_email:formatted_data",
- "cc": "",
- "from": "sender@example.com",
- "headers": "",
"subject": "Malicous IP with related entities found in Splunk",
- "to": "recipient@example.com"
+ "to": "placeholder"
},
- "angle": 0,
- "app": "SMTP",
- "appid": "45bb6f37-4478-499b-b4a3-51ecfa62b78c",
- "approver": "",
- "assets": [
+ "requiredParameters": [
{
- "action": "send email",
- "actions": [
- "test connectivity",
- "send email"
- ],
- "active": true,
- "app_name": "SMTP",
- "app_version": "1.2.49",
- "appid": "45bb6f37-4478-499b-b4a3-51ecfa62b78c",
- "asset_name": "defaultmail",
- "config_type": "asset",
- "count": 0,
- "fields": {
- "attachments": "",
- "bcc": "",
- "body": "format_email:formatted_data",
- "cc": "",
- "from": "sender@example.com",
- "headers": "",
- "subject": "Malicous IP with related entities found in Splunk",
- "to": "recipient@example.com"
- },
- "has_app": true,
- "id": 10,
- "loaded": false,
- "missing": false,
- "name": "smtp",
- "output": [
- {
- "column_name": "Status",
- "column_order": 0,
- "data_path": "action_result.status",
- "data_type": "string"
- },
- {
- "contains": [
- "vault id"
- ],
- "data_path": "action_result.parameter.attachments",
- "data_type": "string"
- },
- {
- "contains": [
- "email"
- ],
- "data_path": "action_result.parameter.bcc",
- "data_type": "string"
- },
- {
- "data_path": "action_result.parameter.body",
- "data_type": "string"
+ "data_type": "string",
+ "field": "to"
+ },
+ {
+ "data_type": "string",
+ "field": "body"
+ }
+ ],
+ "tab": "byConnector",
+ "type": "action"
+ },
+ "errors": {},
+ "id": "25",
+ "type": "action",
+ "x": 780,
+ "y": 1660
+ },
+ "26": {
+ "data": {
+ "advanced": {
+ "join": [],
+ "refreshNotableData": true
+ },
+ "functionId": 2,
+ "functionName": "set_severity_add_note_2",
+ "id": "26",
+ "selectMore": false,
+ "tab": "apis",
+ "type": "utility",
+ "utilities": {
+ "add_note": {
+ "description": "",
+ "fields": [
+ {
+ "description": "",
+ "label": "title",
+ "name": "title",
+ "placeholder": "Enter a note title",
+ "renderType": "datapath",
+ "required": false
},
{
- "contains": [
- "email"
- ],
- "data_path": "action_result.parameter.cc",
- "data_type": "string"
+ "description": "",
+ "label": "content",
+ "name": "content",
+ "placeholder": "Enter the note content",
+ "renderType": "datapath",
+ "required": false
},
{
- "contains": [
- "email"
+ "choices": [
+ "markdown",
+ "html"
],
- "data_path": "action_result.parameter.from",
- "data_type": "string"
- },
- {
- "data_path": "action_result.parameter.headers",
- "data_type": "string"
- },
- {
- "data_path": "action_result.parameter.subject",
- "data_type": "string"
+ "default": "markdown",
+ "description": "",
+ "label": "note format",
+ "name": "note_format",
+ "placeholder": "Enter the note content",
+ "renderType": "dropdown",
+ "required": false
},
{
- "contains": [
- "email"
- ],
- "data_path": "action_result.parameter.to",
- "data_type": "string"
+ "hidden": true,
+ "name": "container",
+ "required": false
},
{
- "data_path": "action_result.data",
- "data_type": "string"
+ "default": "general",
+ "hidden": true,
+ "name": "note_type",
+ "required": false
},
{
- "data_path": "action_result.summary",
- "data_type": "string"
+ "hidden": true,
+ "name": "author",
+ "required": false
},
{
- "column_name": "Message",
- "column_order": 1,
- "data_path": "action_result.message",
- "data_type": "string"
+ "hidden": true,
+ "name": "event_id",
+ "required": false
},
{
- "data_path": "summary.total_objects",
- "data_type": "numeric"
+ "hidden": true,
+ "name": "task_id",
+ "required": false
},
{
- "data_path": "summary.total_objects_successful",
- "data_type": "numeric"
+ "hidden": true,
+ "name": "trace",
+ "required": false
}
],
- "parameters": {
- "attachments": {
- "allow_list": true,
- "contains": [
- "vault id"
- ],
- "data_type": "string",
- "default": null,
- "description": "Vault IDs of files to attach",
- "key": "attachments",
- "order": 6,
- "required": false,
- "verbose": "Each file that is required to be attached, needs to be in the vault. Multiple file vault ids can be specified as comma separated."
- },
- "bcc": {
- "allow_list": true,
- "contains": [
- "email"
- ],
- "data_type": "string",
- "default": null,
- "description": "List of recipients email addresses to include on bcc line",
- "key": "bcc",
- "order": 3,
- "required": false
- },
- "body": {
- "data_type": "string",
- "default": null,
- "description": "Message body",
- "key": "body",
- "order": 5,
+ "label": "add note",
+ "name": "add_note"
+ },
+ "set_severity": {
+ "description": "",
+ "fields": [
+ {
+ "choices": "notableSeverity",
+ "description": "",
+ "label": "severity",
+ "name": "severity",
+ "placeholder": "Select severity",
+ "renderType": "dropdown",
"required": true
},
- "cc": {
- "allow_list": true,
- "contains": [
- "email"
- ],
- "data_type": "string",
- "default": null,
- "description": "List of recipients email addresses to include on cc line",
- "key": "cc",
- "order": 2,
- "required": false
- },
- "from": {
- "contains": [
- "email"
- ],
- "data_type": "string",
- "default": null,
- "description": "From field",
- "key": "from",
- "order": 0,
- "required": false
- },
- "headers": {
- "data_type": "string",
- "default": null,
- "description": "Custom email headers (formatted as JSON)",
- "key": "headers",
- "order": 7,
- "required": false
- },
- "subject": {
- "data_type": "string",
- "default": null,
- "description": "Message Subject",
- "key": "subject",
- "order": 4,
+ {
+ "hidden": true,
+ "name": "container",
"required": false
- },
- "to": {
- "allow_list": true,
- "contains": [
- "email"
- ],
- "data_type": "string",
- "default": null,
- "description": "List of recipients email addresses",
- "key": "to",
- "order": 1,
- "primary": true,
- "required": true
}
- },
- "product_name": "SMTP",
- "product_vendor": "Generic",
- "targets": "10",
- "type": "email"
+ ],
+ "label": "set severity",
+ "name": "set_severity",
+ "refreshNotableData": true
+ }
+ },
+ "utilityType": "api",
+ "values": {
+ "add_note": {
+ "_internal": [
+ "container",
+ "note_type",
+ "author",
+ "event_id",
+ "task_id",
+ "trace"
+ ],
+ "content": "format_email:formatted_data",
+ "note_format": "markdown",
+ "note_type": "general",
+ "title": "Recorded Future Intelligence"
+ },
+ "set_severity": {
+ "_internal": [
+ "container"
+ ],
+ "severity": "high"
}
- ],
- "attrs": {
- ".action": {
- "text": "send email"
- },
- ".background": {
- "fill": "#000000",
- "stroke": "#5C6773"
- },
- ".color-band": {
- "fill": "#3C444D"
- },
- ".inPorts>.port-in": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".inPorts>.port-in>.port-body": {
- "port": {
- "id": "in",
- "type": "in"
- }
- },
- ".message": {
- "opacity": 0,
- "ref-x": 5,
- "ref-y": 105,
- "text": "Configuring now"
- },
- ".outPorts>.port-out": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".outPorts>.port-out>.port-body": {
- "port": {
- "id": "out",
- "type": "out"
- }
- },
- ".title": {
- "text": "Generic"
- },
- "g.approver image": {
- "opacity": 1
- },
- "g.code image": {
- "opacity": 1
- },
- "g.delete": {
- "display": "none"
- },
- "g.error": {
- "opacity": 0
- },
- "g.error image": {
- "xlink:href": "/inc/coa/img/block_icon_warn.svg"
- },
- "g.icon image": {
- "xlink:href": "/inc/coa/img/block_icon_generic.svg"
- },
- "g.notes": {
- "display": "block"
- },
- "g.notes image": {
- "opacity": 1,
- "xlink:href": "/inc/coa/img/block_icon_note_dark_on.svg"
- },
- "g.timer image": {
- "opacity": 1
+ }
+ },
+ "errors": {},
+ "id": "26",
+ "type": "utility",
+ "x": 1260,
+ "y": 1660
+ },
+ "3": {
+ "data": {
+ "advanced": {
+ "description": "Proceed if the risk score is higher than a certain threshold",
+ "join": [],
+ "note": "Proceed if the risk score is higher than a certain threshold"
+ },
+ "conditions": [
+ {
+ "comparisons": [
+ {
+ "conditionIndex": 0,
+ "op": ">=",
+ "param": "ip_intelligence_1:action_result.data.*.risk.score",
+ "value": "90"
+ }
+ ],
+ "conditionIndex": 0,
+ "display": "If",
+ "logic": "and",
+ "type": "if"
}
- },
- "block_code": "def send_email_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):\n phantom.debug('send_email_1() called')\n \n #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))\n \n # collect data for 'send_email_1' call\n formatted_data_1 = phantom.get_format_data(name='format_email')\n\n parameters = []\n \n # build parameters list for 'send_email_1' call\n parameters.append({\n 'cc': \"\",\n 'to': \"recipient@example.com\",\n 'bcc': \"\",\n 'body': formatted_data_1,\n 'from': \"sender@example.com\",\n 'headers': \"\",\n 'subject': \"Malicous IP with related entities found in Splunk\",\n 'attachments': \"\",\n })\n\n phantom.act(action=\"send email\", parameters=parameters, assets=['smtp'], name=\"send_email_1\")\n\n return",
- "callback_code": "",
- "callback_start": 1,
- "callsback": true,
- "color": "",
- "connected_to_start": true,
- "connection_name": "search splunk for ips, search splunk for domains, search splunk for files, search splunk for vulns",
- "connection_type": "action",
- "custom_callback": "",
- "custom_code": "",
- "custom_join": "",
- "custom_name": "",
- "delay": 0,
- "description": "Send the formatted email to a hard-coded recipient",
- "has_custom": false,
- "has_custom_block": false,
- "has_custom_callback": false,
- "has_custom_join": false,
- "id": "6789cc3c-fa14-455f-a49f-a3077b1f483c",
- "inPorts": [
- "in"
],
- "join_code": "",
- "join_optional": [],
- "join_start": 1,
- "line_end": 282,
- "line_start": 256,
- "message": "Configuring now",
- "name": "send email",
- "notes": "Send the formatted email to a hard-coded recipient",
- "number": 1,
- "order": 11,
- "outPorts": [
- "out"
+ "functionId": 1,
+ "functionName": "decision_1",
+ "id": "3",
+ "type": "decision"
+ },
+ "errors": {},
+ "id": "3",
+ "type": "decision",
+ "x": 1140,
+ "y": 580
+ },
+ "4": {
+ "data": {
+ "advanced": {
+ "customName": "format linked ip lookup",
+ "customNameId": 0,
+ "description": "Build a Splunk query to turn a list of linked entities from Recorded Future into a lookup table that can be used for threat hunting across any sourcetype or data model",
+ "join": [],
+ "note": "Build a Splunk query to turn a list of linked entities from Recorded Future into a lookup table that can be used for threat hunting across any sourcetype or data model"
+ },
+ "functionId": 1,
+ "functionName": "format_linked_ip_lookup",
+ "id": "4",
+ "parameters": [
+ "ip_intelligence_1:action_result.data.*.recordedfutureLinks.entities.ip.*.name",
+ "ip_intelligence_1:action_result.data.*.recordedfutureLinks.entities.ip.*.score"
],
- "ports": {
- "groups": {
- "in": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "left"
- }
- },
- "position": {
- "name": "left"
- }
- },
- "out": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "right"
- }
- },
- "position": {
- "name": "right"
- }
- }
- }
- },
- "position": {
- "x": 1960,
- "y": -140
- },
- "previous_function": "",
- "previous_name": "send_email_1",
- "required_params": {
- "body": true,
- "to": true
- },
- "reviewer": "",
- "show_number": false,
- "size": {
- "height": 100,
- "width": 180
- },
- "state": "app_action_assets",
- "status": "",
- "title": "Generic",
- "type": "coa.Action",
- "warn": false,
- "z": 377
+ "template": "| eval Name=\"{0}\" | makemv Name delim=\", \" | mvexpand Name | appendcols [| makeresults | eval RF_Risk_Score=\"{1}\" | makemv RF_Risk_Score delim=\", \" | mvexpand RF_Risk_Score ] | outputlookup huntip.csv",
+ "type": "format"
},
- {
- "active": false,
- "angle": 0,
- "attrs": {
- ".background": {
- "fill": "#000000",
- "stroke": "#5C6773"
- },
- ".color-band": {
- "fill": "#3C444D"
- },
- ".format": {
- "text": "format related hash look..."
- },
- ".inPorts>.port-in": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".inPorts>.port-in>.port-body": {
- "port": {
- "id": "in",
- "type": "in"
- }
- },
- ".message": {
- "opacity": 0,
- "text": "Configuring now"
- },
- ".outPorts>.port-out-1": {
- "ref": ".background",
- "ref-x": 0.5
- },
- ".outPorts>.port-out-1>.port-body": {
- "port": {
- "id": "out-1",
- "type": "out"
- }
- },
- ".title": {
- "text": "format"
- },
- "g.code image": {
- "opacity": 1
- },
- "g.delete": {
- "display": "none"
- },
- "g.error": {
- "opacity": 0
- },
- "g.error image": {
- "xlink:href": "/inc/coa/img/block_icon_warn.svg"
- },
- "g.notes": {
- "display": "block"
- },
- "g.notes image": {
- "opacity": 1,
- "xlink:href": "/inc/coa/img/block_icon_note_dark_on.svg"
- }
- },
- "block_code": "def format_related_hash_lookup(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):\n phantom.debug('format_related_hash_lookup() called')\n \n template = \"\"\"| makeresults | eval hash=\\\"{0}\\\" | makemv hash delim=\\\", \\\" | mvexpand hash | appendcols [| makeresults | eval RC=\\\"{1}\\\" | makemv RC delim=\\\", \\\" | mvexpand RC ] | outputlookup hunthash.csv\"\"\"\n\n # parameter list for template variable replacement\n parameters = [\n \"filtered-data:Entity_Type_Filter:condition_1:ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.entity.name\",\n \"filtered-data:Entity_Type_Filter:condition_1:ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.count\",\n ]\n\n phantom.format(container=container, template=template, parameters=parameters, name=\"format_related_hash_lookup\")\n\n build_hash_lookup(container=container)\n\n return",
- "callback_code": "",
- "callback_start": 1,
- "callsback": false,
- "connected_to_start": true,
- "connection_name": "ip intelligence",
- "connection_type": "action",
- "custom_callback": "",
- "custom_code": "",
- "custom_join": "",
- "custom_name": "format related hash lookup",
- "description": "Build a Splunk query to turn a list of related entities from Recorded Future into a lookup table that can be used for threat hunting across any sourcetype or data model",
- "format": "format",
- "has_custom": false,
- "has_custom_block": false,
- "has_custom_callback": false,
- "has_custom_join": false,
- "id": "f1d8c308-f8af-4466-9397-cfde303f21ac",
- "inPorts": [
- "in"
+ "errors": {},
+ "id": "4",
+ "type": "format",
+ "x": 440,
+ "y": 760
+ },
+ "5": {
+ "data": {
+ "advanced": {
+ "customName": "format linked domain lookup",
+ "customNameId": 0,
+ "description": "Build a Splunk query to turn a list of linked entities from Recorded Future into a lookup table that can be used for threat hunting across any sourcetype or data model",
+ "join": [],
+ "note": "Build a Splunk query to turn a list of linked entities from Recorded Future into a lookup table that can be used for threat hunting across any sourcetype or data model"
+ },
+ "functionId": 2,
+ "functionName": "format_linked_domain_lookup",
+ "id": "5",
+ "parameters": [
+ "ip_intelligence_1:action_result.data.*.recordedfutureLinks.entities.domain.*.name",
+ "ip_intelligence_1:action_result.data.*.recordedfutureLinks.entities.domain.*.score"
],
- "join_code": "",
- "join_optional": [],
- "join_start": 1,
- "line_end": 347,
- "line_start": 330,
- "message": "Configuring now",
- "name": "format",
- "notes": "Build a Splunk query to turn a list of related entities from Recorded Future into a lookup table that can be used for threat hunting across any sourcetype or data model",
- "number": 5,
- "order": 14,
- "outPorts": [
- "out-1"
+ "template": "| eval Name=\"{0}\" | makemv Name delim=\", \" | mvexpand Name | appendcols [| makeresults | eval RF_Risk_Score=\"{1}\" | makemv RF_Risk_Score delim=\", \" | mvexpand RF_Risk_Score ] | outputlookup huntdomain.csv",
+ "type": "format"
+ },
+ "errors": {},
+ "id": "5",
+ "type": "format",
+ "x": 740,
+ "y": 780
+ },
+ "6": {
+ "data": {
+ "advanced": {
+ "customName": "format linked files lookup",
+ "customNameId": 0,
+ "description": "Build a Splunk query to turn a list of linked entities from Recorded Future into a lookup table that can be used for threat hunting across any sourcetype or data model",
+ "join": [],
+ "note": "Build a Splunk query to turn a list of linked entities from Recorded Future into a lookup table that can be used for threat hunting across any sourcetype or data model"
+ },
+ "functionId": 3,
+ "functionName": "format_linked_files_lookup",
+ "id": "6",
+ "parameters": [
+ "ip_intelligence_1:action_result.data.*.recordedfutureLinks.entities.file.*.name",
+ "ip_intelligence_1:action_result.data.*.recordedfutureLinks.entities.file.*.score"
+ ],
+ "template": "| eval Name=\"{0}\" | makemv Name delim=\", \" | mvexpand Name | appendcols [| makeresults | eval RF_Risk_Score=\"{1}\" | makemv RF_Risk_Score delim=\", \" | mvexpand RF_Risk_Score ] | outputlookup huntfile.csv",
+ "type": "format"
+ },
+ "errors": {},
+ "id": "6",
+ "type": "format",
+ "x": 1060,
+ "y": 860
+ },
+ "7": {
+ "data": {
+ "advanced": {
+ "customName": "format linked vuln lookup",
+ "customNameId": 0,
+ "description": "Build a Splunk query to turn a list of linked entities from Recorded Future into a lookup table that can be used for threat hunting across any sourcetype or data model",
+ "join": [],
+ "note": "Build a Splunk query to turn a list of linked entities from Recorded Future into a lookup table that can be used for threat hunting across any sourcetype or data model"
+ },
+ "functionId": 4,
+ "functionName": "format_linked_vuln_lookup",
+ "id": "7",
+ "parameters": [
+ "ip_intelligence_1:action_result.data.*.recordedfutureLinks.entities.vulnerability.*.name",
+ "ip_intelligence_1:action_result.data.*.recordedfutureLinks.entities.vulnerability.*.score"
],
+ "template": "| eval Name=\"{0}\" | makemv Name delim=\", \" | mvexpand Name | appendcols [| makeresults | eval RF_Risk_Score=\"{1}\" | makemv RF_Risk_Score delim=\", \" | mvexpand RF_Risk_Score ] | outputlookup huntvuln.csv",
+ "type": "format"
+ },
+ "errors": {},
+ "id": "7",
+ "type": "format",
+ "x": 1380,
+ "y": 780
+ },
+ "8": {
+ "data": {
+ "advanced": {
+ "customName": "format linked url lookup",
+ "customNameId": 0,
+ "description": "Build a Splunk query to turn a list of linked entities from Recorded Future into a lookup table that can be used for threat hunting across any sourcetype or data model",
+ "join": [],
+ "note": "Build a Splunk query to turn a list of linked entities from Recorded Future into a lookup table that can be used for threat hunting across any sourcetype or data model"
+ },
+ "functionId": 5,
+ "functionName": "format_linked_url_lookup",
+ "id": "8",
"parameters": [
+ "ip_intelligence_1:action_result.data.*.recordedfutureLinks.entities.url.*.name",
+ "ip_intelligence_1:action_result.data.*.recordedfutureLinks.entities.url.*.score"
+ ],
+ "template": "| eval Name=\"{0}\" | makemv Name delim=\", \" | mvexpand Name | appendcols [| makeresults | eval RF_Risk_Score=\"{1}\" | makemv RF_Risk_Score delim=\", \" | mvexpand RF_Risk_Score ] | outputlookup hunturl.csv",
+ "type": "format"
+ },
+ "errors": {},
+ "id": "8",
+ "type": "format",
+ "x": 1680,
+ "y": 760
+ },
+ "9": {
+ "data": {
+ "action": "run query",
+ "actionType": "investigate",
+ "advanced": {
+ "customName": "build ip lookup",
+ "customNameId": 0,
+ "description": "Run the Splunk query that creates the lookup file",
+ "join": [],
+ "note": "Run the Splunk query that creates the lookup file"
+ },
+ "connector": "Splunk",
+ "connectorConfigs": [
+ "splunk"
+ ],
+ "connectorId": "91883aa8-9c81-470b-97a1-5d8f7995f560",
+ "connectorVersion": "v1",
+ "functionId": 1,
+ "functionName": "build_ip_lookup",
+ "id": "9",
+ "parameters": {
+ "command": "| makeresults",
+ "query": "format_linked_ip_lookup:formatted_data"
+ },
+ "requiredParameters": [
{
- "position": 0,
- "type": "",
- "value": "filtered-data:Entity_Type_Filter:condition_1:ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.entity.name"
+ "data_type": "string",
+ "field": "query"
},
{
- "position": 1,
- "type": "",
- "value": "filtered-data:Entity_Type_Filter:condition_1:ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.count"
+ "data_type": "string",
+ "default": "search",
+ "field": "command"
}
],
- "ports": {
- "groups": {
- "in": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "left"
- }
- },
- "position": {
- "name": "left"
- }
- },
- "out": {
- "attrs": {
- ".port-body": {
- "fill": "#fff",
- "magnet": true,
- "r": 10,
- "stroke": "#000"
- },
- ".port-label": {
- "fill": "#000"
- }
- },
- "label": {
- "position": {
- "args": {
- "y": 10
- },
- "name": "right"
- }
- },
- "position": {
- "name": "right"
- }
- }
- }
- },
- "position": {
- "x": 860,
- "y": 0
- },
- "previous_function": "",
- "previous_name": "format_related_hash_lookup",
- "show_number": true,
- "size": {
- "height": 100,
- "width": 180
- },
- "state": "format",
- "status": "",
- "template": "| makeresults | eval hash=\"{0}\" | makemv hash delim=\", \" | mvexpand hash | appendcols [| makeresults | eval RC=\"{1}\" | makemv RC delim=\", \" | mvexpand RC ] | outputlookup hunthash.csv",
- "title": "format",
- "type": "coa.Format",
- "warn": false,
- "z": 378
- }
- ]
+ "type": "action"
+ },
+ "errors": {},
+ "id": "9",
+ "type": "action",
+ "x": 440,
+ "y": 980
+ }
},
- "notes": "This playbook uses the following Apps:\n - Recorded Future (ip reputation, ip intelligence) [asset name = recorded_future] - gather threat information and related entities associated with an IP address\n - Splunk (run query) [asset name = splunk] - build lookup files and query events\n - SMTP (send email) [asset name = smtp_gmail] - send an email\n\nDeployment Notes:\n - This playbook should be spawned manually or through high fidelity correlation searches\n - The initial indicator used is an IP address, but this could be adapted to other types of indicators\n - The email sender and recipient address are hard-coded and must be changed\n - The \"admin\" user should be replaced in the prompt to refer to a user or role that should be involved\n - The Splunk searches that create lookups can probably be reused, but the \"search splunk for x\" searches will probably need to be adapted or replaced to fit available data models or data sources in the target environment\n - Adding an IP to a block list allows firewalls such as Palo Alto Networks NGFW to query the Phantom REST API and use the list as an external block list"
+ "notes": "This playbook uses the following Apps:\n - Recorded Future (ip intelligence) [asset name = recordedfuture] - gather threat information and linked entities associated with an IP address\n - Splunk (run query) [asset name = splunkes_hunt] - build lookup files and query events\n - SMTP (send email) [asset name = smtp] - send an email\n\nDeployment Notes:\n - This playbook should be spawned manually or through high fidelity correlation searches\n - The initial indicator used is an IP address, but this could be adapted to other types of indicators\n - The email sender and recipient address are hard-coded and must be changed\n - The \"admin\" user should be replaced in the prompt to refer to a user or role that should be involved\n - The Splunk searches that create lookups can probably be reused, but the \"search splunk for x\" searches will probably need to be adapted or replaced to fit available data models or data sources in the target environment\n - Adding an IP to a block list allows firewalls such as Palo Alto Networks NGFW to query the Phantom REST API and use the list as an external block list"
},
+ "input_spec": null,
+ "output_spec": null,
+ "playbook_type": "automation",
"python_version": "3",
- "schema": 4,
- "version": "4.10.0.40961"
+ "schema": "5.0.8",
+ "version": "5.3.4.95226"
},
- "create_time": "2021-01-25T22:24:42.873094+00:00",
+ "create_time": "2022-10-24T18:06:10.346594+00:00",
"draft_mode": false,
"labels": [
- "events"
+ "*"
],
- "tags": [],
- "misc": {
- "apps_list": [
- "Recorded Future",
- "Splunk",
- "SMTP"
- ]
- }
+ "tags": []
}
\ No newline at end of file
diff --git a/recorded_future_threat_hunting.png b/recorded_future_threat_hunting.png
index 6f7671ad..bb97661b 100644
Binary files a/recorded_future_threat_hunting.png and b/recorded_future_threat_hunting.png differ
diff --git a/recorded_future_threat_hunting.py b/recorded_future_threat_hunting.py
index 2c58faed..faccae89 100644
--- a/recorded_future_threat_hunting.py
+++ b/recorded_future_threat_hunting.py
@@ -1,603 +1,851 @@
"""
-Starting with a single IP address, this playbook gathers a list of related IP addresses, domain names, file hashes, and vulnerability CVE's from Recorded Future. Then Splunk is used to build threat hunting lookup tables and search across multiple data sources for events containing the related entities. Finally, IP addresses are blocked if approved by an analyst and an email is sent to notify a responder if more than 10 of a certain kind of entity are matched at once.
+Starting with a single IP address, this playbook gathers a list of linked IP addresses, domain names, file hashes, urls, and vulnerability CVE's from Recorded Future. Then Splunk is used to build threat hunting lookup tables and search across multiple data sources for events containing the linked entities. Finally, IP addresses are blocked if approved by an analyst and an email is sent to notify a responder of the activity.
"""
+
import phantom.rules as phantom
import json
from datetime import datetime, timedelta
+
+
+@phantom.playbook_block()
def on_start(container):
phantom.debug('on_start() called')
-
- # call 'ip_reputation_1' block
- ip_reputation_1(container=container)
+
+ # call 'ip_intelligence_1' block
+ ip_intelligence_1(container=container)
return
-"""
-Proceed if the risk score is higher than a certain threshold
-"""
-def risk_score_threshold(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
- phantom.debug('risk_score_threshold() called')
+@phantom.playbook_block()
+def ip_intelligence_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("ip_intelligence_1() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ ################################################################################
+ # Query for the full context about the IP address and related entities from Recorded
+ # Future
+ ################################################################################
+
+ container_artifact_data = phantom.collect2(container=container, datapath=["artifact:*.cef.destinationAddress","artifact:*.id"])
+
+ parameters = []
+
+ # build parameters list for 'ip_intelligence_1' call
+ for container_artifact_item in container_artifact_data:
+ if container_artifact_item[0] is not None:
+ parameters.append({
+ "ip": container_artifact_item[0],
+ "context": {'artifact_id': container_artifact_item[1]},
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("ip intelligence", parameters=parameters, name="ip_intelligence_1", assets=["recorded future "], callback=decision_1)
+
+ 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")
+
+ ################################################################################
+ # Proceed if the risk score is higher than a certain threshold
+ ################################################################################
# check for 'if' condition 1
- matched = phantom.decision(
+ found_match_1 = phantom.decision(
container=container,
- action_results=results,
conditions=[
- ["ip_reputation_1:action_result.data.*.risk.score", ">=", 90],
+ ["ip_intelligence_1:action_result.data.*.risk.score", ">=", 90]
])
# call connected blocks if condition 1 matched
- if matched:
- ip_intelligence_1(action=action, success=success, container=container, results=results, handle=handle, custom_function=custom_function)
+ if found_match_1:
+ format_linked_ip_lookup(action=action, success=success, container=container, results=results, handle=handle)
+ format_linked_domain_lookup(action=action, success=success, container=container, results=results, handle=handle)
+ format_linked_files_lookup(action=action, success=success, container=container, results=results, handle=handle)
+ format_linked_vuln_lookup(action=action, success=success, container=container, results=results, handle=handle)
+ format_linked_url_lookup(action=action, success=success, container=container, results=results, handle=handle)
return
return
-"""
-Build a Splunk query to turn a list of related entities from Recorded Future into a lookup table that can be used for threat hunting across any sourcetype or data model
-"""
-def format_related_ip_lookup(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
- phantom.debug('format_related_ip_lookup() called')
-
- template = """| makeresults | eval IP=\"{0}\" | makemv IP delim=\", \" | mvexpand IP | appendcols [| makeresults | eval RC=\"{1}\" | makemv RC delim=\", \" | mvexpand RC ] | outputlookup huntip.csv"""
+
+@phantom.playbook_block()
+def format_linked_ip_lookup(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("format_linked_ip_lookup() called")
+
+ ################################################################################
+ # Build a Splunk query to turn a list of linked entities from Recorded Future
+ # into a lookup table that can be used for threat hunting across any sourcetype
+ # or data model
+ ################################################################################
+
+ template = """| eval Name=\"{0}\" | makemv Name delim=\", \" | mvexpand Name | appendcols [| makeresults | eval RF_Risk_Score=\"{1}\" | makemv RF_Risk_Score delim=\", \" | mvexpand RF_Risk_Score ] | outputlookup huntip.csv"""
# parameter list for template variable replacement
parameters = [
- "filtered-data:Entity_Type_Filter:condition_3:ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.entity.name",
- "filtered-data:Entity_Type_Filter:condition_3:ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.count",
+ "ip_intelligence_1:action_result.data.*.recordedfutureLinks.entities.ip.*.name",
+ "ip_intelligence_1:action_result.data.*.recordedfutureLinks.entities.ip.*.score"
]
- phantom.format(container=container, template=template, parameters=parameters, name="format_related_ip_lookup")
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.format(container=container, template=template, parameters=parameters, name="format_linked_ip_lookup")
build_ip_lookup(container=container)
return
-"""
-Run the Splunk query that creates the lookup file
-"""
-def build_ip_lookup(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
- phantom.debug('build_ip_lookup() called')
-
- #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
-
- # collect data for 'build_ip_lookup' call
- formatted_data_1 = phantom.get_format_data(name='format_related_ip_lookup')
- parameters = []
-
- # build parameters list for 'build_ip_lookup' call
- parameters.append({
- 'query': formatted_data_1,
- 'command': "",
- 'display': "",
- 'parse_only': "",
- })
+@phantom.playbook_block()
+def format_linked_domain_lookup(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("format_linked_domain_lookup() called")
- phantom.act(action="run query", parameters=parameters, assets=['splunk'], callback=search_splunk_for_ips, name="build_ip_lookup")
+ ################################################################################
+ # Build a Splunk query to turn a list of linked entities from Recorded Future
+ # into a lookup table that can be used for threat hunting across any sourcetype
+ # or data model
+ ################################################################################
- return
+ template = """| eval Name=\"{0}\" | makemv Name delim=\", \" | mvexpand Name | appendcols [| makeresults | eval RF_Risk_Score=\"{1}\" | makemv RF_Risk_Score delim=\", \" | mvexpand RF_Risk_Score ] | outputlookup huntdomain.csv"""
-"""
-Search Palo Alto Networks firewall logs for any events with threat-related ip addresses in the dest_ip field
-"""
-def search_splunk_for_ips(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
- phantom.debug('search_splunk_for_ips() called')
-
- #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
-
- # collect data for 'search_splunk_for_ips' call
+ # parameter list for template variable replacement
+ parameters = [
+ "ip_intelligence_1:action_result.data.*.recordedfutureLinks.entities.domain.*.name",
+ "ip_intelligence_1:action_result.data.*.recordedfutureLinks.entities.domain.*.score"
+ ]
- parameters = []
-
- # build parameters list for 'search_splunk_for_ips' call
- parameters.append({
- 'query': "sourcetype=pan:t* ((earliest=-1d latest=now)) |eval IP=dest_ip | lookup huntip.csv IP OUTPUT RC | search RC>10",
- 'command': "",
- 'display': "",
- 'parse_only': "",
- })
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
- phantom.act(action="run query", parameters=parameters, assets=['splunk'], callback=search_splunk_for_ips_callback, name="search_splunk_for_ips", parent_action=action)
+ # Write your custom code here...
- return
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
-def search_splunk_for_ips_callback(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None):
- phantom.debug('search_splunk_for_ips_callback() called')
-
- join_Send_email_if_related_entities_are_found(action=action, success=success, container=container, results=results, handle=handle, custom_function=custom_function)
- recorded_future_threat_hunting_block_ip(action=action, success=success, container=container, results=results, handle=handle, custom_function=custom_function)
+ phantom.format(container=container, template=template, parameters=parameters, name="format_linked_domain_lookup")
+
+ build_domain_lookup(container=container)
return
-"""
-Ask an analyst whether the discovered related IP addresses should be blocked
-"""
-def recorded_future_threat_hunting_block_ip(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
- phantom.debug('recorded_future_threat_hunting_block_ip() called')
-
- # set user and message variables for phantom.prompt call
- user = "admin"
- message = """Do you want to add the following IP(s) to the block IP block list:
-{0}"""
+
+@phantom.playbook_block()
+def format_linked_files_lookup(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("format_linked_files_lookup() called")
+
+ ################################################################################
+ # Build a Splunk query to turn a list of linked entities from Recorded Future
+ # into a lookup table that can be used for threat hunting across any sourcetype
+ # or data model
+ ################################################################################
+
+ template = """| eval Name=\"{0}\" | makemv Name delim=\", \" | mvexpand Name | appendcols [| makeresults | eval RF_Risk_Score=\"{1}\" | makemv RF_Risk_Score delim=\", \" | mvexpand RF_Risk_Score ] | outputlookup huntfile.csv"""
# parameter list for template variable replacement
parameters = [
- "search_splunk_for_ips:action_result.data.*.IP",
- ]
-
- #responses:
- response_types = [
- {
- "prompt": "",
- "options": {
- "type": "list",
- "choices": [
- "Yes",
- "No",
- ]
- },
- },
+ "ip_intelligence_1:action_result.data.*.recordedfutureLinks.entities.file.*.name",
+ "ip_intelligence_1:action_result.data.*.recordedfutureLinks.entities.file.*.score"
]
- phantom.prompt2(container=container, user=user, message=message, respond_in_mins=30, name="recorded_future_threat_hunting_block_ip", parameters=parameters, response_types=response_types, callback=check_prompt)
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
- return
+ # Write your custom code here...
-"""
-Only proceed if the analyst approved the prompt
-"""
-def check_prompt(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
- phantom.debug('check_prompt() called')
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
- # check for 'if' condition 1
- matched = phantom.decision(
- container=container,
- action_results=results,
- conditions=[
- ["recorded_future_threat_hunting_block_ip:action_result.summary.response", "==", "Yes"],
- ])
+ phantom.format(container=container, template=template, parameters=parameters, name="format_linked_files_lookup")
- # call connected blocks if condition 1 matched
- if matched:
- add_ip_to_block_list(action=action, success=success, container=container, results=results, handle=handle, custom_function=custom_function)
- return
+ build_file_lookup(container=container)
return
-"""
-Add the IP address to a Phantom custom list, which can be tracked as a REST-accessible external block list by a firewall
-"""
-def add_ip_to_block_list(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
- phantom.debug('add_ip_to_block_list() called')
- results_data_1 = phantom.collect2(container=container, datapath=['search_splunk_for_ips:action_result.data.*.IP'], action_results=results)
+@phantom.playbook_block()
+def format_linked_vuln_lookup(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("format_linked_vuln_lookup() called")
- results_item_1_0 = [item[0] for item in results_data_1]
+ ################################################################################
+ # Build a Splunk query to turn a list of linked entities from Recorded Future
+ # into a lookup table that can be used for threat hunting across any sourcetype
+ # or data model
+ ################################################################################
- phantom.add_list("IP Block List", results_item_1_0)
+ template = """| eval Name=\"{0}\" | makemv Name delim=\", \" | mvexpand Name | appendcols [| makeresults | eval RF_Risk_Score=\"{1}\" | makemv RF_Risk_Score delim=\", \" | mvexpand RF_Risk_Score ] | outputlookup huntvuln.csv"""
- return
+ # parameter list for template variable replacement
+ parameters = [
+ "ip_intelligence_1:action_result.data.*.recordedfutureLinks.entities.vulnerability.*.name",
+ "ip_intelligence_1:action_result.data.*.recordedfutureLinks.entities.vulnerability.*.score"
+ ]
-"""
-If any of the Splunk searches had any results, send an email to an analyst
-"""
-def Send_email_if_related_entities_are_found(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
- phantom.debug('Send_email_if_related_entities_are_found() called')
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
- # check for 'if' condition 1
- matched = phantom.decision(
- container=container,
- action_results=results,
- conditions=[
- ["search_splunk_for_ips:action_result.data.*.RC", ">", 0],
- ["search_splunk_for_domains:action_result.data.*.RC", ">", 0],
- ["search_splunk_for_files:action_result.data.*.RC", ">", 0],
- ["search_splunk_for_vulns:action_result.data.*.Rc", ">", 0],
- ],
- logical_operator='or')
+ # Write your custom code here...
- # call connected blocks if condition 1 matched
- if matched:
- format_email(action=action, success=success, container=container, results=results, handle=handle, custom_function=custom_function)
- return
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
- return
+ phantom.format(container=container, template=template, parameters=parameters, name="format_linked_vuln_lookup")
-def join_Send_email_if_related_entities_are_found(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None):
- phantom.debug('join_Send_email_if_related_entities_are_found() called')
+ build_vuln_lookup(container=container)
- # check if all connected incoming playbooks, actions, or custom functions are done i.e. have succeeded or failed
- if phantom.completed(action_names=['search_splunk_for_ips', 'search_splunk_for_domains', 'search_splunk_for_files', 'search_splunk_for_vulns']):
-
- # call connected block "Send_email_if_related_entities_are_found"
- Send_email_if_related_entities_are_found(container=container, handle=handle)
-
return
-"""
-Include the intelligence context and Splunk results in the email and link to the event in Phantom for the rest of the detail
-"""
-def format_email(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
- phantom.debug('format_email() called')
-
- template = """The potentially malicious destination IP {0} with a Risk Score of {1} was identified and process by the Phantom playbook \"recorded_future_threat_hunting\".
-Additional searches performed against various logs showed that the following related entities occurring in > 10 relations have been found in recent events:
+@phantom.playbook_block()
+def format_linked_url_lookup(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("format_linked_url_lookup() called")
-IP addresses: {2}
-domain names: {3}
-file hashes: {4}
-vulnerability identifiers: {5}
+ ################################################################################
+ # Build a Splunk query to turn a list of linked entities from Recorded Future
+ # into a lookup table that can be used for threat hunting across any sourcetype
+ # or data model
+ ################################################################################
-More details are available in Phantom: {6}"""
+ template = """| eval Name=\"{0}\" | makemv Name delim=\", \" | mvexpand Name | appendcols [| makeresults | eval RF_Risk_Score=\"{1}\" | makemv RF_Risk_Score delim=\", \" | mvexpand RF_Risk_Score ] | outputlookup hunturl.csv"""
# parameter list for template variable replacement
parameters = [
- "ip_intelligence_1:action_result.parameter.ip",
- "ip_intelligence_1:action_result.data.*.risk.score",
- "search_splunk_for_ips:action_result.data.*.IP",
- "search_splunk_for_domains:action_result.data.*.domain",
- "search_splunk_for_files:action_result.data.*.hash",
- "search_splunk_for_vulns:action_result.data.*.vuln",
- "container:url",
+ "ip_intelligence_1:action_result.data.*.recordedfutureLinks.entities.url.*.name",
+ "ip_intelligence_1:action_result.data.*.recordedfutureLinks.entities.url.*.score"
]
- phantom.format(container=container, template=template, parameters=parameters, name="format_email")
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
- send_email_1(container=container)
+ phantom.format(container=container, template=template, parameters=parameters, name="format_linked_url_lookup")
+
+ build_url_lookup(container=container)
return
-"""
-Send the formatted email to a hard-coded recipient
-"""
-def send_email_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
- phantom.debug('send_email_1() called')
-
- #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
-
- # collect data for 'send_email_1' call
- formatted_data_1 = phantom.get_format_data(name='format_email')
- parameters = []
-
- # build parameters list for 'send_email_1' call
- parameters.append({
- 'cc': "",
- 'to': "recipient@example.com",
- 'bcc': "",
- 'body': formatted_data_1,
- 'from': "sender@example.com",
- 'headers': "",
- 'subject': "Malicous IP with related entities found in Splunk",
- 'attachments': "",
- })
+@phantom.playbook_block()
+def build_ip_lookup(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("build_ip_lookup() called")
- phantom.act(action="send email", parameters=parameters, assets=['smtp'], name="send_email_1")
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
- return
+ ################################################################################
+ # Run the Splunk query that creates the lookup file
+ ################################################################################
-"""
-Build a Splunk query to turn a list of related entities from Recorded Future into a lookup table that can be used for threat hunting across any sourcetype or data model
-"""
-def format_related_domain_lookup(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
- phantom.debug('format_related_domain_lookup() called')
-
- template = """| makeresults | eval domain=\"{0}\" | makemv domain delim=\", \" | mvexpand domain | appendcols [| makeresults | eval RC=\"{1}\" | makemv RC delim=\", \" | mvexpand RC ] | outputlookup huntdomain.csv"""
+ format_linked_ip_lookup = phantom.get_format_data(name="format_linked_ip_lookup")
- # parameter list for template variable replacement
- parameters = [
- "filtered-data:Entity_Type_Filter:condition_4:ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.entity.name",
- "filtered-data:Entity_Type_Filter:condition_4:ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.count",
- ]
+ parameters = []
- phantom.format(container=container, template=template, parameters=parameters, name="format_related_domain_lookup")
+ if format_linked_ip_lookup is not None:
+ parameters.append({
+ "query": format_linked_ip_lookup,
+ "command": "| makeresults",
+ })
- build_domain_lookup(container=container)
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("run query", parameters=parameters, name="build_ip_lookup", assets=["splunk"], callback=search_splunk_for_ips)
return
-"""
-Run the Splunk query that creates the lookup file
-"""
+
+@phantom.playbook_block()
def build_domain_lookup(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
- phantom.debug('build_domain_lookup() called')
-
- #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
-
- # collect data for 'build_domain_lookup' call
- formatted_data_1 = phantom.get_format_data(name='format_related_domain_lookup')
+ phantom.debug("build_domain_lookup() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ ################################################################################
+ # Run the Splunk query that creates the lookup file
+ ################################################################################
+
+ format_linked_domain_lookup = phantom.get_format_data(name="format_linked_domain_lookup")
parameters = []
-
- # build parameters list for 'build_domain_lookup' call
- parameters.append({
- 'query': formatted_data_1,
- 'command': "",
- 'display': "",
- 'parse_only': "",
- })
- phantom.act(action="run query", parameters=parameters, assets=['splunk'], callback=search_splunk_for_domains, name="build_domain_lookup")
+ if format_linked_domain_lookup is not None:
+ parameters.append({
+ "query": format_linked_domain_lookup,
+ "command": "| makeresults",
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("run query", parameters=parameters, name="build_domain_lookup", assets=["splunk"], callback=search_splunk_for_domains)
return
-"""
-Build a Splunk query to turn a list of related entities from Recorded Future into a lookup table that can be used for threat hunting across any sourcetype or data model
-"""
-def format_related_hash_lookup(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
- phantom.debug('format_related_hash_lookup() called')
-
- template = """| makeresults | eval hash=\"{0}\" | makemv hash delim=\", \" | mvexpand hash | appendcols [| makeresults | eval RC=\"{1}\" | makemv RC delim=\", \" | mvexpand RC ] | outputlookup hunthash.csv"""
- # parameter list for template variable replacement
- parameters = [
- "filtered-data:Entity_Type_Filter:condition_1:ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.entity.name",
- "filtered-data:Entity_Type_Filter:condition_1:ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.count",
- ]
+@phantom.playbook_block()
+def build_file_lookup(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("build_file_lookup() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ ################################################################################
+ # Run the Splunk query that creates the lookup file
+ ################################################################################
+
+ format_linked_files_lookup = phantom.get_format_data(name="format_linked_files_lookup")
+
+ parameters = []
+
+ if format_linked_files_lookup is not None:
+ parameters.append({
+ "query": format_linked_files_lookup,
+ "command": "| makeresults",
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
- phantom.format(container=container, template=template, parameters=parameters, name="format_related_hash_lookup")
+ # Write your custom code here...
- build_hash_lookup(container=container)
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("run query", parameters=parameters, name="build_file_lookup", assets=["splunk"], callback=search_splunk_for_files)
return
-"""
-Run the Splunk query that creates the lookup file
-"""
-def build_hash_lookup(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
- phantom.debug('build_hash_lookup() called')
-
- #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
-
- # collect data for 'build_hash_lookup' call
- formatted_data_1 = phantom.get_format_data(name='format_related_hash_lookup')
+
+@phantom.playbook_block()
+def build_vuln_lookup(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("build_vuln_lookup() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ ################################################################################
+ # Run the Splunk query that creates the lookup file
+ ################################################################################
+
+ format_linked_vuln_lookup = phantom.get_format_data(name="format_linked_vuln_lookup")
parameters = []
-
- # build parameters list for 'build_hash_lookup' call
- parameters.append({
- 'query': formatted_data_1,
- 'command': "",
- 'display': "",
- 'parse_only': "",
- })
- phantom.act(action="run query", parameters=parameters, assets=['splunk'], callback=search_splunk_for_files, name="build_hash_lookup")
+ if format_linked_vuln_lookup is not None:
+ parameters.append({
+ "query": format_linked_vuln_lookup,
+ "command": "| makeresults",
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("run query", parameters=parameters, name="build_vuln_lookup", assets=["splunk"], callback=search_splunk_for_vulns)
return
-"""
-Build a Splunk query to turn a list of related entities from Recorded Future into a lookup table that can be used for threat hunting across any sourcetype or data model
-"""
-def format_related_vuln_lookup(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
- phantom.debug('format_related_vuln_lookup() called')
-
- template = """| makeresults | eval vuln=\"{0}\" | makemv vuln delim=\", \" | mvexpand vuln | appendcols [| makeresults | eval RC=\"{1}\" | makemv RC delim=\", \" | mvexpand RC ] | outputlookup huntvuln.csv"""
- # parameter list for template variable replacement
- parameters = [
- "filtered-data:Entity_Type_Filter:condition_2:ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.entity.name",
- "filtered-data:Entity_Type_Filter:condition_2:ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.count",
- ]
+@phantom.playbook_block()
+def build_url_lookup(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("build_url_lookup() called")
- phantom.format(container=container, template=template, parameters=parameters, name="format_related_vuln_lookup")
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
- build_vuln_lookup(container=container)
+ ################################################################################
+ # Run the Splunk query that creates the lookup file
+ ################################################################################
+
+ format_linked_url_lookup = phantom.get_format_data(name="format_linked_url_lookup")
+
+ parameters = []
+
+ if format_linked_url_lookup is not None:
+ parameters.append({
+ "query": format_linked_url_lookup,
+ "command": "| makeresults",
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("run query", parameters=parameters, name="build_url_lookup", assets=["splunk"], callback=search_splunk_for_urls)
return
-"""
-Run the Splunk query that creates the lookup file
-"""
-def build_vuln_lookup(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
- phantom.debug('build_vuln_lookup() called')
-
- #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
-
- # collect data for 'build_vuln_lookup' call
- formatted_data_1 = phantom.get_format_data(name='format_related_vuln_lookup')
+
+@phantom.playbook_block()
+def search_splunk_for_ips(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("search_splunk_for_ips() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ ################################################################################
+ # Search Palo Alto Networks firewall logs for any events with threat-related ip
+ # addresses in the dest_ip field
+ ################################################################################
parameters = []
-
- # build parameters list for 'build_vuln_lookup' call
+
parameters.append({
- 'query': formatted_data_1,
- 'command': "",
- 'display': "",
- 'parse_only': "",
+ "query": "sourcetype=\"netscreen:firewall\" ((earliest=-24h latest=now)) |eval Name=dest_ip | lookup huntip.csv Name OUTPUT RF_Risk_Score | search RF_Risk_Score>24",
+ "command": "search",
})
- phantom.act(action="run query", parameters=parameters, assets=['splunk'], callback=search_splunk_for_vulns, name="build_vuln_lookup")
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("run query", parameters=parameters, name="search_splunk_for_ips", assets=["splunk"], callback=search_splunk_for_ips_callback)
return
-"""
-Search Palo Alto Networks threat logs for any events with threat-related domain names in the dest_hostname field
-"""
-def search_splunk_for_domains(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
- phantom.debug('search_splunk_for_domains() called')
-
- #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+@phantom.playbook_block()
+def search_splunk_for_ips_callback(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("search_splunk_for_ips_callback() called")
+
- # collect data for 'search_splunk_for_domains' call
+ recorded_future_threat_hunting_block_ip(action=action, success=success, container=container, results=results, handle=handle, filtered_artifacts=filtered_artifacts, filtered_results=filtered_results)
+ join_format_email(action=action, success=success, container=container, results=results, handle=handle, filtered_artifacts=filtered_artifacts, filtered_results=filtered_results)
+
+
+ return
+
+
+@phantom.playbook_block()
+def search_splunk_for_domains(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("search_splunk_for_domains() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ ################################################################################
+ # Search Palo Alto Networks threat logs for any events with threat-related domain
+ # names in the dest_hostname field
+ ################################################################################
parameters = []
-
- # build parameters list for 'search_splunk_for_domains' call
+
parameters.append({
- 'query': "sourcetype=pan:threat ((earliest=-1d latest=now)) |eval domain=dest_hostname | lookup huntdomain.csv domain OUTPUT RC | search RC>10",
- 'command': "",
- 'display': "",
- 'parse_only': "",
+ "query": "sourcetype=\"netscreen:firewall\" ((earliest=-24h latest=now)) |eval Name=dest_ip | lookup huntip.csv Name OUTPUT RF_Risk_Score | search RF_Risk_Score>24",
+ "command": "search",
})
- phantom.act(action="run query", parameters=parameters, assets=['splunk'], callback=join_Send_email_if_related_entities_are_found, name="search_splunk_for_domains", parent_action=action)
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("run query", parameters=parameters, name="search_splunk_for_domains", assets=["splunk"], callback=join_format_email)
return
-"""
-Search Symantec Endpoint Protection logs for sightings of threat-related file hashes
-"""
+
+@phantom.playbook_block()
def search_splunk_for_files(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
- phantom.debug('search_splunk_for_files() called')
-
- #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
-
- # collect data for 'search_splunk_for_files' call
+ phantom.debug("search_splunk_for_files() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ ################################################################################
+ # Search Symantec Endpoint Protection logs for sightings of threat-related file
+ # hashes
+ ################################################################################
parameters = []
-
- # build parameters list for 'search_splunk_for_files' call
+
parameters.append({
- 'query': "index=main sourcetype=symantec:ep:risk:file ((earliest=-1d latest=now)) |eval hash=file_hash | lookup hunthash.csv hash OUTPUT RC | search RC>10",
- 'command': "",
- 'display': "",
- 'parse_only': "",
+ "query": "index=main sourcetype=symantec:ep:risk:file ((earliest=-1d latest=now)) |eval Name=file_hash | lookup huntfile.csv Name OUTPUT RF_Risk_Score | search RF_Risk_Score>24",
+ "command": "search",
})
- phantom.act(action="run query", parameters=parameters, assets=['splunk'], callback=join_Send_email_if_related_entities_are_found, name="search_splunk_for_files", parent_action=action)
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("run query", parameters=parameters, name="search_splunk_for_files", assets=["splunk"], callback=join_format_email)
return
-"""
-Search Tenable vulnerability scanning logs for any vulnerabilities related to the initial IP addresses
-"""
+
+@phantom.playbook_block()
def search_splunk_for_vulns(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
- phantom.debug('search_splunk_for_vulns() called')
-
- #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
-
- # collect data for 'search_splunk_for_vulns' call
+ phantom.debug("search_splunk_for_vulns() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ ################################################################################
+ # Search Tenable vulnerability scanning logs for any vulnerabilities related to
+ # the initial IP addresses
+ ################################################################################
parameters = []
-
- # build parameters list for 'search_splunk_for_vulns' call
+
parameters.append({
- 'query': "index=main sourcetype=\"tenable:sc:vuln\" ((earliest=-7d latest=now)) |eval vuln=cve | lookup huntvuln.csv vuln OUTPUT RC | search RC>10",
- 'command': "",
- 'display': "",
- 'parse_only': "",
+ "query": "index=main sourcetype=\"tenable:sc:vuln\" ((earliest=-7d latest=now)) |eval Name=cve | lookup huntvuln.csv Name OUTPUT RF_Risk_Score | search RF_Risk_Score>24",
+ "command": "search",
})
- phantom.act(action="run query", parameters=parameters, assets=['splunk'], callback=join_Send_email_if_related_entities_are_found, name="search_splunk_for_vulns", parent_action=action)
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("run query", parameters=parameters, name="search_splunk_for_vulns", assets=["splunk"], callback=join_format_email)
return
-"""
-Query for the full context about the IP address and related entities from Recorded Future
-"""
-def ip_intelligence_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
- phantom.debug('ip_intelligence_1() called')
-
- #phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
-
- # collect data for 'ip_intelligence_1' call
- container_data = phantom.collect2(container=container, datapath=['artifact:*.cef.destinationAddress', 'artifact:*.id'])
+
+@phantom.playbook_block()
+def search_splunk_for_urls(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("search_splunk_for_urls() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ ################################################################################
+ # Search Squid Proxy logs for any URLs related to the initial IP addresses
+ ################################################################################
parameters = []
-
- # build parameters list for 'ip_intelligence_1' call
- for container_item in container_data:
- if container_item[0]:
- parameters.append({
- 'ip': container_item[0],
- # context (artifact id) is added to associate results with the artifact
- 'context': {'artifact_id': container_item[1]},
- })
- phantom.act(action="ip intelligence", parameters=parameters, assets=['recorded_future'], callback=Entity_Type_Filter, name="ip_intelligence_1")
+ parameters.append({
+ "query": "index=main sourcetype=\"squid:access\" ((earliest=-24h latest=now)) |eval Name=url | lookup hunturl.csv Name OUTPUT RF_Risk_Score | search RF_Risk_Score>24",
+ "command": "search",
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("run query", parameters=parameters, name="search_splunk_for_urls", assets=["splunk"], callback=join_format_email)
return
-"""
-Filter four common entity types into different Splunk searches
-"""
-def Entity_Type_Filter(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
- phantom.debug('Entity_Type_Filter() called')
- # collect filtered artifact ids for 'if' condition 1
- matched_artifacts_1, matched_results_1 = phantom.condition(
- container=container,
- action_results=results,
- conditions=[
- ["ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.entity.type", "==", "Hash"],
- ],
- name="Entity_Type_Filter:condition_1")
+@phantom.playbook_block()
+def recorded_future_threat_hunting_block_ip(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("recorded_future_threat_hunting_block_ip() called")
- # call connected blocks if filtered artifacts or results
- if matched_artifacts_1 or matched_results_1:
- format_related_hash_lookup(action=action, success=success, container=container, results=results, handle=handle, custom_function=custom_function, filtered_artifacts=matched_artifacts_1, filtered_results=matched_results_1)
+ ################################################################################
+ # Ask an analyst whether the discovered related IP addresses should be blocked
+ ################################################################################
- # collect filtered artifact ids for 'if' condition 2
- matched_artifacts_2, matched_results_2 = phantom.condition(
- container=container,
- action_results=results,
- conditions=[
- ["ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.entity.type", "==", "CyberVulnerability"],
- ],
- name="Entity_Type_Filter:condition_2")
+ # set user and message variables for phantom.prompt call
+
+ user = "admin"
+ message = """Do you want to add the following IP(s) to the block IP block list:\n{0}"""
+
+ # parameter list for template variable replacement
+ parameters = [
+ "search_splunk_for_ips:action_result.data.*.IP"
+ ]
+
+ # responses
+ response_types = [
+ {
+ "prompt": "Block IPs?",
+ "options": {
+ "type": "list",
+ "choices": [
+ "Yes",
+ "No"
+ ],
+ },
+ }
+ ]
- # call connected blocks if filtered artifacts or results
- if matched_artifacts_2 or matched_results_2:
- format_related_vuln_lookup(action=action, success=success, container=container, results=results, handle=handle, custom_function=custom_function, filtered_artifacts=matched_artifacts_2, filtered_results=matched_results_2)
+ phantom.prompt2(container=container, user=user, message=message, respond_in_mins=30, name="recorded_future_threat_hunting_block_ip", parameters=parameters, response_types=response_types, callback=decision_2)
- # collect filtered artifact ids for 'if' condition 3
- matched_artifacts_3, matched_results_3 = phantom.condition(
+ return
+
+
+@phantom.playbook_block()
+def decision_2(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("decision_2() called")
+
+ # check for 'if' condition 1
+ found_match_1 = phantom.decision(
container=container,
- action_results=results,
conditions=[
- ["ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.entity.type", "==", "IpAddress"],
- ],
- name="Entity_Type_Filter:condition_3")
+ ["recorded_future_threat_hunting_block_ip:action_result.summary.responses.0", "==", "Yes"]
+ ])
+
+ # call connected blocks if condition 1 matched
+ if found_match_1:
+ add_ip_to_block_list(action=action, success=success, container=container, results=results, handle=handle)
+ return
+
+ return
+
- # call connected blocks if filtered artifacts or results
- if matched_artifacts_3 or matched_results_3:
- format_related_ip_lookup(action=action, success=success, container=container, results=results, handle=handle, custom_function=custom_function, filtered_artifacts=matched_artifacts_3, filtered_results=matched_results_3)
+@phantom.playbook_block()
+def add_ip_to_block_list(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("add_ip_to_block_list() called")
+
+ ################################################################################
+ # Add the IP address to a Phantom custom list, which can be tracked as a REST-accessible
+ # external block list by a firewall
+ ################################################################################
+
+ search_splunk_for_ips_result_data = phantom.collect2(container=container, datapath=["search_splunk_for_ips:action_result.data.*.Name"], action_results=results)
+
+ search_splunk_for_ips_result_item_0 = [item[0] for item in search_splunk_for_ips_result_data]
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.add_list(list_name="IP Block List", values=search_splunk_for_ips_result_item_0)
+
+ return
+
+
+@phantom.playbook_block()
+def join_format_email(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("join_format_email() called")
- # collect filtered artifact ids for 'if' condition 4
- matched_artifacts_4, matched_results_4 = phantom.condition(
+ if phantom.completed(action_names=["search_splunk_for_ips", "search_splunk_for_domains", "search_splunk_for_files", "search_splunk_for_vulns", "search_splunk_for_urls"]):
+ # call connected block "format_email"
+ format_email(container=container, handle=handle)
+
+ return
+
+
+@phantom.playbook_block()
+def format_email(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("format_email() called")
+
+ ################################################################################
+ # Include the intelligence context and Splunk results in the email and link to
+ # the event in Phantom for the rest of the detail
+ ################################################################################
+
+ template = """The potentially malicious destination IP {0} with a Risk Score of {1} was identified and processed by the Phantom playbook \"recorded_future_threat_hunting_conf\". \n\nThe IP is located in {11}, {12}, {13}\n\nAdditional searches performed against various logs showed that the following linked entities have been found in recent events:\n\nIP addresses: \n{2}\n\ndomain names: \n{3}\n\nfile hashes: \n{4}\n\nvulnerability identifiers: \n{5}\n\nRecorded Future Intelligence has also linked this IP to the following additional Entities:\n{7}\n\nMore details are available in Phantom: {6}\n\nMore details are available in Recorded Future: {10}"""
+
+ # parameter list for template variable replacement
+ parameters = [
+ "ip_intelligence_1:action_result.parameter.ip",
+ "ip_intelligence_1:action_result.data.*.risk.score",
+ "search_splunk_for_ips:action_result.data.*.Name",
+ "search_splunk_for_domains:action_result",
+ "search_splunk_for_files:action_result.data.*.Name",
+ "search_splunk_for_vulns:action_result.data.*.Name",
+ "container:url",
+ "ip_intelligence_1:action_result.data.*.recordedfutureLinks.entities.other.*.name",
+ "ip_intelligence_1:action_result.data.*.recordedfutureLinks.entities.ip.*.name",
+ "ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.entity.name",
+ "ip_intelligence_1:action_result.data.*.intelCard",
+ "ip_intelligence_1:action_result.data.*.location.location.city",
+ "ip_intelligence_1:action_result.data.*.location.location.country",
+ "ip_intelligence_1:action_result.data.*.location.location.continent"
+ ]
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.format(container=container, template=template, parameters=parameters, name="format_email")
+
+ send_email_if_related_entities_are_found(container=container)
+
+ return
+
+
+@phantom.playbook_block()
+def send_email_if_related_entities_are_found(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("send_email_if_related_entities_are_found() called")
+
+ ################################################################################
+ # If any of the Splunk searches had any results, send an email to an analyst
+ ################################################################################
+
+ # check for 'if' condition 1
+ found_match_1 = phantom.decision(
container=container,
- action_results=results,
+ logical_operator="or",
conditions=[
- ["ip_intelligence_1:action_result.data.*.relatedEntities.*.entities.*.entity.type", "==", "InternetDomainName"],
- ],
- name="Entity_Type_Filter:condition_4")
+ ["search_splunk_for_ips:action_result.data.*.RF_Risk_Score", ">", 64],
+ ["search_splunk_for_domains:action_result.data.*.RF_Risk_Score", ">", 64],
+ ["search_splunk_for_files:action_result", ">", 64],
+ ["search_splunk_for_vulns:action_result.data.*.RF_Risk_Score", ">", 64],
+ ["search_splunk_for_urls:action_result.data.*.RF_Risk_Score", ">", 64]
+ ])
- # call connected blocks if filtered artifacts or results
- if matched_artifacts_4 or matched_results_4:
- format_related_domain_lookup(action=action, success=success, container=container, results=results, handle=handle, custom_function=custom_function, filtered_artifacts=matched_artifacts_4, filtered_results=matched_results_4)
+ # call connected blocks if condition 1 matched
+ if found_match_1:
+ send_email(action=action, success=success, container=container, results=results, handle=handle)
+ set_severity_add_note_2(action=action, success=success, container=container, results=results, handle=handle)
+ return
return
-"""
-Query for the risk score from Recorded Future
-"""
-def ip_reputation_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
- phantom.debug('ip_reputation_1() called')
- # collect data for 'ip_reputation_1' call
- container_data = phantom.collect2(container=container, datapath=['artifact:*.cef.destinationAddress', 'artifact:*.id'])
+@phantom.playbook_block()
+def send_email(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("send_email() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ ################################################################################
+ # Send the formatted email to a hard-coded recipient
+ ################################################################################
+
+ format_email = phantom.get_format_data(name="format_email")
parameters = []
-
- # build parameters list for 'ip_reputation_1' call
- for container_item in container_data:
- if container_item[0]:
- parameters.append({
- 'ip': container_item[0],
- # context (artifact id) is added to associate results with the artifact
- 'context': {'artifact_id': container_item[1]},
- })
- phantom.act(action="ip reputation", parameters=parameters, assets=['recorded_future'], callback=risk_score_threshold, name="ip_reputation_1")
+ if format_email is not None:
+ parameters.append({
+ "subject": "Malicous IP with related entities found in Splunk",
+ "body": format_email,
+ "to": "placeholder",
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("send email", parameters=parameters, name="send_email", assets=["email"])
+
+ return
+
+
+@phantom.playbook_block()
+def set_severity_add_note_2(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("set_severity_add_note_2() called")
+
+ format_email = phantom.get_format_data(name="format_email")
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.set_severity(container=container, severity="high")
+ phantom.add_note(container=container, content=format_email, note_format="markdown", note_type="general", title="Recorded Future Intelligence")
+
+ container = phantom.get_container(container.get('id', None))
return
+
+@phantom.playbook_block()
def on_finish(container, summary):
- phantom.debug('on_finish() called')
+ phantom.debug("on_finish() called")
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
# This function is called after all actions are completed.
# summary of all the action and/or all details of actions
# can be collected here.
@@ -609,4 +857,8 @@ def on_finish(container, summary):
# action_results = phantom.get_action_results(action_run_id=action_result['action_run_id'], result_data=False, flatten=False)
# phantom.debug(action_results)
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
return
\ No newline at end of file
diff --git a/recorded_future_typosquat_handling.json b/recorded_future_typosquat_handling.json
new file mode 100644
index 00000000..8b05e0bb
--- /dev/null
+++ b/recorded_future_typosquat_handling.json
@@ -0,0 +1,481 @@
+{
+ "blockly": false,
+ "blockly_xml": "",
+ "category": "Uncategorized",
+ "coa": {
+ "data": {
+ "description": "This playbook responds to Recorded Future monitoring of potential typosquatting domain alerts. The domain is filtered from the artifacts and enriched several times via Whois, Censys, Urlscan, DNS, and Recorded Future's Intelligence.\n\nThis playbook runs on the assumption that the typosquatting alert rule ID has been configured in the Recorded Future app's asset 'on-poll' field.",
+ "edges": [
+ {
+ "id": "port_0_to_port_8",
+ "sourceNode": "0",
+ "sourcePort": "0_out",
+ "targetNode": "8",
+ "targetPort": "8_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 0
+ }
+ ],
+ "id": "port_8_to_port_15",
+ "sourceNode": "8",
+ "sourcePort": "8_out",
+ "targetNode": "15",
+ "targetPort": "15_in"
+ },
+ {
+ "id": "port_15_to_port_16",
+ "sourceNode": "15",
+ "sourcePort": "15_out",
+ "targetNode": "16",
+ "targetPort": "16_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 0
+ }
+ ],
+ "id": "port_16_to_port_17",
+ "sourceNode": "16",
+ "sourcePort": "16_out",
+ "targetNode": "17",
+ "targetPort": "17_in"
+ },
+ {
+ "id": "port_15_to_port_20",
+ "sourceNode": "15",
+ "sourcePort": "15_out",
+ "targetNode": "20",
+ "targetPort": "20_in"
+ },
+ {
+ "id": "port_20_to_port_21",
+ "sourceNode": "20",
+ "sourcePort": "20_out",
+ "targetNode": "21",
+ "targetPort": "21_in"
+ },
+ {
+ "id": "port_21_to_port_22",
+ "sourceNode": "21",
+ "sourcePort": "21_out",
+ "targetNode": "22",
+ "targetPort": "22_in"
+ },
+ {
+ "id": "port_19_to_port_1",
+ "sourceNode": "19",
+ "sourcePort": "19_out",
+ "targetNode": "1",
+ "targetPort": "1_in"
+ },
+ {
+ "id": "port_24_to_port_1",
+ "sourceNode": "24",
+ "sourcePort": "24_out",
+ "targetNode": "1",
+ "targetPort": "1_in"
+ },
+ {
+ "id": "port_22_to_port_24",
+ "sourceNode": "22",
+ "sourcePort": "22_out",
+ "targetNode": "24",
+ "targetPort": "24_in"
+ },
+ {
+ "id": "port_17_to_port_19",
+ "sourceNode": "17",
+ "sourcePort": "17_out",
+ "targetNode": "19",
+ "targetPort": "19_in"
+ }
+ ],
+ "hash": "74a9cb5fd25438ae5e535a1180a97000411620c4",
+ "nodes": {
+ "0": {
+ "data": {
+ "advanced": {
+ "join": []
+ },
+ "functionName": "on_start",
+ "id": "0",
+ "type": "start"
+ },
+ "errors": {},
+ "id": "0",
+ "type": "start",
+ "x": 1940,
+ "y": 880
+ },
+ "1": {
+ "data": {
+ "advanced": {
+ "join": []
+ },
+ "functionId": 1,
+ "functionName": "on_finish",
+ "id": "1",
+ "type": "end"
+ },
+ "errors": {},
+ "id": "1",
+ "type": "end",
+ "userCode": "\n # This function is called after all actions are completed.\n # summary of all the action and/or all details of actions\n # can be collected here.\n\n # summary_json = phantom.get_summary()\n # if 'result' in summary_json:\n # for action_result in summary_json['result']:\n # if 'action_run_id' in action_result:\n # action_results = phantom.get_action_results(action_run_id=action_result['action_run_id'], result_data=False, flatten=False)\n # phantom.debug(action_results)\n\n",
+ "x": 1960,
+ "y": 1680
+ },
+ "15": {
+ "data": {
+ "action": "lookup domain",
+ "actionType": "investigate",
+ "advanced": {
+ "join": []
+ },
+ "connector": "DNS",
+ "connectorConfigs": [
+ "dns"
+ ],
+ "connectorId": "876ab991-313e-48e7-bccd-e8c9650c239c",
+ "connectorVersion": "v1",
+ "functionId": 2,
+ "functionName": "lookup_domain_2",
+ "id": "15",
+ "parameters": {
+ "domain": "filtered-data:filter_2:condition_1:artifact:*.cef.domain",
+ "type": "A"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "default": "",
+ "field": "domain"
+ }
+ ],
+ "type": "action"
+ },
+ "errors": {},
+ "id": "15",
+ "type": "action",
+ "x": 1920,
+ "y": 1140
+ },
+ "16": {
+ "data": {
+ "advanced": {
+ "customName": "Filter domain",
+ "customNameId": 0,
+ "join": []
+ },
+ "conditions": [
+ {
+ "comparisons": [
+ {
+ "conditionIndex": 0,
+ "op": "!=",
+ "param": "lookup_domain_2:action_result.summary.record_info",
+ "value": ""
+ }
+ ],
+ "conditionIndex": 0,
+ "logic": "and"
+ }
+ ],
+ "functionId": 3,
+ "functionName": "filter_domain",
+ "id": "16",
+ "type": "filter"
+ },
+ "errors": {},
+ "id": "16",
+ "type": "filter",
+ "x": 1740,
+ "y": 1260
+ },
+ "17": {
+ "data": {
+ "action": "whois ip",
+ "actionType": "investigate",
+ "advanced": {
+ "join": []
+ },
+ "connector": "WHOIS",
+ "connectorConfigs": [
+ "whois"
+ ],
+ "connectorId": "e6723c2e-06ef-415a-8098-62c46c1cb71f",
+ "connectorVersion": "v1",
+ "functionId": 1,
+ "functionName": "whois_ip_1",
+ "id": "17",
+ "parameters": {
+ "ip": "filtered-data:filter_domain:condition_1:lookup_domain_2:action_result.summary.record_info"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "default": "",
+ "field": "ip"
+ }
+ ],
+ "type": "action"
+ },
+ "errors": {},
+ "id": "17",
+ "type": "action",
+ "x": 1680,
+ "y": 1420
+ },
+ "19": {
+ "data": {
+ "action": "ip intelligence",
+ "actionType": "investigate",
+ "advanced": {
+ "customName": "Recorded Future IP Intelligence",
+ "customNameId": 0,
+ "join": []
+ },
+ "connector": "Recorded Future",
+ "connectorConfigs": [
+ "recorded future"
+ ],
+ "connectorId": "6efe0e1b-76ac-4ffd-8fa0-ac58fd6efd77",
+ "connectorVersion": "v1",
+ "functionId": 1,
+ "functionName": "recorded_future_ip_intelligence",
+ "id": "19",
+ "parameters": {
+ "ip": "filtered-data:filter_domain:condition_1:lookup_domain_2:action_result.summary.record_info"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "default": "",
+ "field": "ip"
+ }
+ ],
+ "type": "action"
+ },
+ "errors": {},
+ "id": "19",
+ "type": "action",
+ "x": 1680,
+ "y": 1540
+ },
+ "20": {
+ "data": {
+ "action": "whois domain",
+ "actionType": "investigate",
+ "advanced": {
+ "join": []
+ },
+ "connector": "WHOIS",
+ "connectorConfigs": [
+ "whois"
+ ],
+ "connectorId": "e6723c2e-06ef-415a-8098-62c46c1cb71f",
+ "connectorVersion": "v1",
+ "functionId": 2,
+ "functionName": "whois_domain_2",
+ "id": "20",
+ "parameters": {
+ "domain": "filtered-data:filter_2:condition_1:artifact:*.cef.domain"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "default": "",
+ "field": "domain"
+ }
+ ],
+ "type": "action"
+ },
+ "errors": {},
+ "id": "20",
+ "type": "action",
+ "x": 2180,
+ "y": 1260
+ },
+ "21": {
+ "data": {
+ "action": "query certificate",
+ "actionType": "investigate",
+ "advanced": {
+ "customName": "Censys Query Certificate",
+ "customNameId": 0,
+ "join": []
+ },
+ "connector": "Censys",
+ "connectorConfigs": [
+ "censys"
+ ],
+ "connectorId": "97C8DF6F-C870-4482-B6CA-B6C31745FBAB",
+ "connectorVersion": "v1",
+ "functionId": 2,
+ "functionName": "censys_query_certificate",
+ "id": "21",
+ "parameters": {
+ "limit": 200,
+ "query": "filtered-data:filter_2:condition_1:artifact:*.cef.domain"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "numeric",
+ "default": 200,
+ "field": "limit"
+ },
+ {
+ "data_type": "string",
+ "default": "",
+ "field": "query"
+ }
+ ],
+ "type": "action"
+ },
+ "errors": {},
+ "id": "21",
+ "type": "action",
+ "x": 2180,
+ "y": 1340
+ },
+ "22": {
+ "data": {
+ "action": "detonate url",
+ "actionType": "investigate",
+ "advanced": {
+ "customName": "Urlscan Detonate URL",
+ "customNameId": 0,
+ "join": []
+ },
+ "connector": "urlscan.io",
+ "connectorConfigs": [
+ "urlscan"
+ ],
+ "connectorId": "c46c00cd-7231-4dd3-8d8e-02b9fa0e14a2",
+ "connectorVersion": "v1",
+ "functionId": 1,
+ "functionName": "urlscan_detonate_url",
+ "id": "22",
+ "parameters": {
+ "get_result": true,
+ "url": "filtered-data:filter_2:condition_1:artifact:*.cef.domain"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "default": "",
+ "field": "url"
+ },
+ {
+ "data_type": "boolean",
+ "default": true,
+ "field": "get_result"
+ }
+ ],
+ "type": "action"
+ },
+ "errors": {},
+ "id": "22",
+ "type": "action",
+ "x": 2180,
+ "y": 1440
+ },
+ "24": {
+ "data": {
+ "action": "domain intelligence",
+ "actionType": "investigate",
+ "advanced": {
+ "customName": "Recorded Future Domain Intelligence",
+ "customNameId": 0,
+ "join": []
+ },
+ "connector": "Recorded Future",
+ "connectorConfigs": [
+ "recorded future"
+ ],
+ "connectorId": "6efe0e1b-76ac-4ffd-8fa0-ac58fd6efd77",
+ "connectorVersion": "v1",
+ "functionId": 2,
+ "functionName": "recorded_future_domain_intelligence",
+ "id": "24",
+ "parameters": {
+ "domain": "filtered-data:filter_2:condition_1:artifact:*.cef.domain"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "default": "",
+ "field": "domain"
+ }
+ ],
+ "type": "action"
+ },
+ "errors": {},
+ "id": "24",
+ "type": "action",
+ "x": 2180,
+ "y": 1540
+ },
+ "8": {
+ "data": {
+ "advanced": {
+ "join": [],
+ "scope": "all"
+ },
+ "conditions": [
+ {
+ "comparisons": [
+ {
+ "conditionIndex": 0,
+ "op": "in",
+ "param": "DOMAIN",
+ "value": "artifact:*.name"
+ },
+ {
+ "conditionIndex": 0,
+ "op": "==",
+ "param": "artifact:*.cef.title",
+ "value": "Certificate Registration"
+ },
+ {
+ "conditionIndex": 0,
+ "op": "!=",
+ "param": "artifact:*.cef.domain",
+ "value": ""
+ }
+ ],
+ "conditionIndex": 0,
+ "logic": "and"
+ }
+ ],
+ "functionId": 2,
+ "functionName": "filter_2",
+ "id": "8",
+ "type": "filter"
+ },
+ "errors": {},
+ "id": "8",
+ "type": "filter",
+ "x": 1980,
+ "y": 980
+ }
+ },
+ "notes": ""
+ },
+ "input_spec": null,
+ "output_spec": null,
+ "playbook_type": "automation",
+ "python_version": "3",
+ "schema": "5.0.8",
+ "version": "5.3.4.95226"
+ },
+ "create_time": "2022-09-15T19:40:10.411260+00:00",
+ "draft_mode": false,
+ "labels": [
+ "typosquat"
+ ],
+ "tags": []
+}
\ No newline at end of file
diff --git a/recorded_future_typosquat_handling.png b/recorded_future_typosquat_handling.png
new file mode 100644
index 00000000..8b548edd
Binary files /dev/null and b/recorded_future_typosquat_handling.png differ
diff --git a/recorded_future_typosquat_handling.py b/recorded_future_typosquat_handling.py
new file mode 100644
index 00000000..07fccca7
--- /dev/null
+++ b/recorded_future_typosquat_handling.py
@@ -0,0 +1,329 @@
+"""
+This playbook responds to Recorded Future monitoring of potential typosquatting domain alerts. The domain is filtered from the artifacts and enriched several times via Whois, Censys, Urlscan, DNS, and Recorded Future's Intelligence.\n\nThis playbook runs on the assumption that the typosquatting alert rule ID has been configured in the Recorded Future app's asset 'on-poll' field.
+"""
+
+
+import phantom.rules as phantom
+import json
+from datetime import datetime, timedelta
+
+
+@phantom.playbook_block()
+def on_start(container):
+ phantom.debug('on_start() called')
+
+ # call 'filter_2' block
+ filter_2(container=container)
+
+ return
+
+@phantom.playbook_block()
+def filter_2(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("filter_2() called")
+
+ # collect filtered artifact ids and results for 'if' condition 1
+ matched_artifacts_1, matched_results_1 = phantom.condition(
+ container=container,
+ logical_operator="and",
+ conditions=[
+ ["DOMAIN", "in", "artifact:*.name"],
+ ["artifact:*.cef.title", "==", "Certificate Registration"],
+ ["artifact:*.cef.domain", "!=", ""]
+ ],
+ name="filter_2:condition_1",
+ scope="all")
+
+ # call connected blocks if filtered artifacts or results
+ if matched_artifacts_1 or matched_results_1:
+ lookup_domain_2(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 lookup_domain_2(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("lookup_domain_2() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ filtered_artifact_0_data_filter_2 = phantom.collect2(container=container, datapath=["filtered-data:filter_2:condition_1:artifact:*.cef.domain","filtered-data:filter_2:condition_1:artifact:*.id"])
+
+ parameters = []
+
+ # build parameters list for 'lookup_domain_2' call
+ for filtered_artifact_0_item_filter_2 in filtered_artifact_0_data_filter_2:
+ if filtered_artifact_0_item_filter_2[0] is not None:
+ parameters.append({
+ "type": "A",
+ "domain": filtered_artifact_0_item_filter_2[0],
+ "context": {'artifact_id': filtered_artifact_0_item_filter_2[1]},
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("lookup domain", parameters=parameters, name="lookup_domain_2", assets=["dns"], callback=lookup_domain_2_callback)
+
+ return
+
+
+@phantom.playbook_block()
+def lookup_domain_2_callback(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("lookup_domain_2_callback() called")
+
+
+ filter_domain(action=action, success=success, container=container, results=results, handle=handle, filtered_artifacts=filtered_artifacts, filtered_results=filtered_results)
+ whois_domain_2(action=action, success=success, container=container, results=results, handle=handle, filtered_artifacts=filtered_artifacts, filtered_results=filtered_results)
+
+
+ return
+
+
+@phantom.playbook_block()
+def filter_domain(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("filter_domain() called")
+
+ # collect filtered artifact ids and results for 'if' condition 1
+ matched_artifacts_1, matched_results_1 = phantom.condition(
+ container=container,
+ conditions=[
+ ["lookup_domain_2:action_result.summary.record_info", "!=", ""]
+ ],
+ name="filter_domain:condition_1")
+
+ # call connected blocks if filtered artifacts or results
+ if matched_artifacts_1 or matched_results_1:
+ whois_ip_1(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 whois_ip_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("whois_ip_1() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ filtered_result_0_data_filter_domain = phantom.collect2(container=container, datapath=["filtered-data:filter_domain:condition_1:lookup_domain_2:action_result.summary.record_info"])
+
+ parameters = []
+
+ # build parameters list for 'whois_ip_1' call
+ for filtered_result_0_item_filter_domain in filtered_result_0_data_filter_domain:
+ if filtered_result_0_item_filter_domain[0] is not None:
+ parameters.append({
+ "ip": filtered_result_0_item_filter_domain[0],
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("whois ip", parameters=parameters, name="whois_ip_1", assets=["whois"], callback=recorded_future_ip_intelligence)
+
+ return
+
+
+@phantom.playbook_block()
+def recorded_future_ip_intelligence(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("recorded_future_ip_intelligence() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ filtered_result_0_data_filter_domain = phantom.collect2(container=container, datapath=["filtered-data:filter_domain:condition_1:lookup_domain_2:action_result.summary.record_info"])
+
+ parameters = []
+
+ # build parameters list for 'recorded_future_ip_intelligence' call
+ for filtered_result_0_item_filter_domain in filtered_result_0_data_filter_domain:
+ if filtered_result_0_item_filter_domain[0] is not None:
+ parameters.append({
+ "ip": filtered_result_0_item_filter_domain[0],
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("ip intelligence", parameters=parameters, name="recorded_future_ip_intelligence", assets=["recorded future"])
+
+ return
+
+
+@phantom.playbook_block()
+def whois_domain_2(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("whois_domain_2() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ filtered_artifact_0_data_filter_2 = phantom.collect2(container=container, datapath=["filtered-data:filter_2:condition_1:artifact:*.cef.domain","filtered-data:filter_2:condition_1:artifact:*.id"])
+
+ parameters = []
+
+ # build parameters list for 'whois_domain_2' call
+ for filtered_artifact_0_item_filter_2 in filtered_artifact_0_data_filter_2:
+ if filtered_artifact_0_item_filter_2[0] is not None:
+ parameters.append({
+ "domain": filtered_artifact_0_item_filter_2[0],
+ "context": {'artifact_id': filtered_artifact_0_item_filter_2[1]},
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("whois domain", parameters=parameters, name="whois_domain_2", assets=["whois"], callback=censys_query_certificate)
+
+ return
+
+
+@phantom.playbook_block()
+def censys_query_certificate(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("censys_query_certificate() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ filtered_artifact_0_data_filter_2 = phantom.collect2(container=container, datapath=["filtered-data:filter_2:condition_1:artifact:*.cef.domain","filtered-data:filter_2:condition_1:artifact:*.id"])
+
+ parameters = []
+
+ # build parameters list for 'censys_query_certificate' call
+ for filtered_artifact_0_item_filter_2 in filtered_artifact_0_data_filter_2:
+ if filtered_artifact_0_item_filter_2[0] is not None:
+ parameters.append({
+ "limit": 200,
+ "query": filtered_artifact_0_item_filter_2[0],
+ "context": {'artifact_id': filtered_artifact_0_item_filter_2[1]},
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("query certificate", parameters=parameters, name="censys_query_certificate", assets=["censys"], callback=urlscan_detonate_url)
+
+ return
+
+
+@phantom.playbook_block()
+def urlscan_detonate_url(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("urlscan_detonate_url() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ filtered_artifact_0_data_filter_2 = phantom.collect2(container=container, datapath=["filtered-data:filter_2:condition_1:artifact:*.cef.domain","filtered-data:filter_2:condition_1:artifact:*.id"])
+
+ parameters = []
+
+ # build parameters list for 'urlscan_detonate_url' call
+ for filtered_artifact_0_item_filter_2 in filtered_artifact_0_data_filter_2:
+ if filtered_artifact_0_item_filter_2[0] is not None:
+ parameters.append({
+ "url": filtered_artifact_0_item_filter_2[0],
+ "get_result": True,
+ "context": {'artifact_id': filtered_artifact_0_item_filter_2[1]},
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("detonate url", parameters=parameters, name="urlscan_detonate_url", assets=["urlscan"], callback=recorded_future_domain_intelligence)
+
+ return
+
+
+@phantom.playbook_block()
+def recorded_future_domain_intelligence(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("recorded_future_domain_intelligence() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ filtered_artifact_0_data_filter_2 = phantom.collect2(container=container, datapath=["filtered-data:filter_2:condition_1:artifact:*.cef.domain","filtered-data:filter_2:condition_1:artifact:*.id"])
+
+ parameters = []
+
+ # build parameters list for 'recorded_future_domain_intelligence' call
+ for filtered_artifact_0_item_filter_2 in filtered_artifact_0_data_filter_2:
+ if filtered_artifact_0_item_filter_2[0] is not None:
+ parameters.append({
+ "domain": filtered_artifact_0_item_filter_2[0],
+ "context": {'artifact_id': filtered_artifact_0_item_filter_2[1]},
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("domain intelligence", parameters=parameters, name="recorded_future_domain_intelligence", assets=["recorded future"])
+
+ return
+
+
+@phantom.playbook_block()
+def on_finish(container, summary):
+ phantom.debug("on_finish() called")
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # This function is called after all actions are completed.
+ # summary of all the action and/or all details of actions
+ # can be collected here.
+
+ # summary_json = phantom.get_summary()
+ # if 'result' in summary_json:
+ # for action_result in summary_json['result']:
+ # if 'action_run_id' in action_result:
+ # action_results = phantom.get_action_results(action_run_id=action_result['action_run_id'], result_data=False, flatten=False)
+ # phantom.debug(action_results)
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ return
\ No newline at end of file
diff --git a/recorded_future_vulnerability_alert_handling.json b/recorded_future_vulnerability_alert_handling.json
new file mode 100644
index 00000000..95f5d106
--- /dev/null
+++ b/recorded_future_vulnerability_alert_handling.json
@@ -0,0 +1,613 @@
+{
+ "blockly": false,
+ "blockly_xml": "",
+ "category": "Uncategorized",
+ "coa": {
+ "data": {
+ "description": "This playbook will run on 'vulnerability' labeled containers which will include Recorded Future's New Critical or Pre NVD Vulnerabilities, alert.\n\nThe mentioned CVE's are converted to a list and passed into a Splunk search. Assuming vulnerability scan results exist in Splunk, if a match is found, the associated CVE and IP address of the affected machine will be returned into Splunk SOAR.",
+ "edges": [
+ {
+ "id": "port_0_to_port_2",
+ "sourceNode": "0",
+ "sourcePort": "0_out",
+ "targetNode": "2",
+ "targetPort": "2_in"
+ },
+ {
+ "id": "port_6_to_port_10",
+ "sourceNode": "6",
+ "sourcePort": "6_out",
+ "targetNode": "10",
+ "targetPort": "10_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 0
+ }
+ ],
+ "id": "port_2_to_port_6",
+ "sourceNode": "2",
+ "sourcePort": "2_out",
+ "targetNode": "6",
+ "targetPort": "6_in"
+ },
+ {
+ "id": "port_14_to_port_13",
+ "sourceNode": "14",
+ "sourcePort": "14_out",
+ "targetNode": "13",
+ "targetPort": "13_in"
+ },
+ {
+ "id": "port_15_to_port_14",
+ "sourceNode": "15",
+ "sourcePort": "15_out",
+ "targetNode": "14",
+ "targetPort": "14_in"
+ },
+ {
+ "id": "port_13_to_port_1",
+ "sourceNode": "13",
+ "sourcePort": "13_out",
+ "targetNode": "1",
+ "targetPort": "1_in"
+ },
+ {
+ "id": "port_10_to_port_18",
+ "sourceNode": "10",
+ "sourcePort": "10_out",
+ "targetNode": "18",
+ "targetPort": "18_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 0
+ }
+ ],
+ "id": "port_18_to_port_15",
+ "sourceNode": "18",
+ "sourcePort": "18_out",
+ "targetNode": "15",
+ "targetPort": "15_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 0
+ }
+ ],
+ "id": "port_18_to_port_17",
+ "sourceNode": "18",
+ "sourcePort": "18_out",
+ "targetNode": "17",
+ "targetPort": "17_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 1
+ }
+ ],
+ "id": "port_18_to_port_19",
+ "sourceNode": "18",
+ "sourcePort": "18_out",
+ "targetNode": "19",
+ "targetPort": "19_in"
+ },
+ {
+ "id": "port_19_to_port_1",
+ "sourceNode": "19",
+ "sourcePort": "19_out",
+ "targetNode": "1",
+ "targetPort": "1_in"
+ }
+ ],
+ "hash": "239f69f0dd09c6dd142f50733c50a531da6351e8",
+ "nodes": {
+ "0": {
+ "data": {
+ "advanced": {
+ "join": []
+ },
+ "functionName": "on_start",
+ "id": "0",
+ "type": "start"
+ },
+ "errors": {},
+ "id": "0",
+ "type": "start",
+ "x": 1000,
+ "y": 399.9999999999999
+ },
+ "1": {
+ "data": {
+ "advanced": {
+ "join": []
+ },
+ "functionId": 1,
+ "functionName": "on_finish",
+ "id": "1",
+ "type": "end"
+ },
+ "errors": {},
+ "id": "1",
+ "type": "end",
+ "userCode": "\n # This function is called after all actions are completed.\n # summary of all the action and/or all details of actions\n # can be collected here.\n\n # summary_json = phantom.get_summary()\n # if 'result' in summary_json:\n # for action_result in summary_json['result']:\n # if 'action_run_id' in action_result:\n # action_results = phantom.get_action_results(action_run_id=action_result['action_run_id'], result_data=False, flatten=False)\n # phantom.debug(action_results)\n\n",
+ "x": 1000,
+ "y": 1520
+ },
+ "10": {
+ "customCode": null,
+ "data": {
+ "action": "run query",
+ "actionType": "investigate",
+ "advanced": {
+ "customName": "Query Scan Results",
+ "customNameId": 0,
+ "join": [],
+ "note": "Query Splunk for vulnerability scan results. You will need to modify the index and sourcetype fields to suit your environment."
+ },
+ "connector": "Splunk",
+ "connectorConfigs": [
+ "splunk"
+ ],
+ "connectorId": "91883aa8-9c81-470b-97a1-5d8f7995f560",
+ "connectorVersion": "v1",
+ "functionId": 1,
+ "functionName": "query_scan_results",
+ "id": "10",
+ "parameters": {
+ "command": "",
+ "query": {
+ "functionId": 1,
+ "parameters": [
+ "deduplicated_cves:custom_function:cve"
+ ],
+ "template": "| makeresults \n| eval cve=\"{0}\" \n| makemv cve delim=\", \"\n| mvexpand cve \n| join type=inner cve\n [ search index=main sourcetype=\"tenable:sc:vuln\" earliest=-7d@d]"
+ }
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "field": "query"
+ },
+ {
+ "data_type": "string",
+ "default": "search",
+ "field": "command"
+ }
+ ],
+ "type": "action"
+ },
+ "errors": {},
+ "id": "10",
+ "type": "action",
+ "userCode": null,
+ "x": 980,
+ "y": 780
+ },
+ "13": {
+ "data": {
+ "advanced": {
+ "join": [],
+ "note": "Add a comment with the formatted Splunk Results. This can be modified into an email to inform the vulnerability team or into a ticket for ServiceNow or Jira."
+ },
+ "functionId": 3,
+ "functionName": "add_comment_3",
+ "id": "13",
+ "selectMore": false,
+ "tab": "apis",
+ "type": "utility",
+ "utilities": {
+ "comment": {
+ "description": "",
+ "fields": [
+ {
+ "description": "",
+ "label": "comment",
+ "name": "comment",
+ "placeholder": "Enter a comment",
+ "renderType": "datapath",
+ "required": true
+ },
+ {
+ "hidden": true,
+ "name": "container",
+ "required": false
+ },
+ {
+ "hidden": true,
+ "name": "author",
+ "required": false
+ },
+ {
+ "hidden": true,
+ "name": "trace",
+ "required": false
+ }
+ ],
+ "label": "add comment",
+ "name": "comment"
+ }
+ },
+ "utilityType": "api",
+ "values": {
+ "comment": {
+ "_internal": [
+ "container",
+ "author",
+ "trace"
+ ],
+ "comment": "format_splunk_results:formatted_data"
+ }
+ }
+ },
+ "errors": {},
+ "id": "13",
+ "type": "utility",
+ "x": 980,
+ "y": 1360
+ },
+ "14": {
+ "data": {
+ "advanced": {
+ "customName": "Format Splunk Results",
+ "customNameId": 0,
+ "join": [],
+ "note": "Format the affected host and the CVE. Customize further for additional information."
+ },
+ "functionId": 1,
+ "functionName": "format_splunk_results",
+ "id": "14",
+ "parameters": [
+ "query_scan_results:action_result.data.*.dnsName",
+ "query_scan_results:action_result.data.*.cve",
+ "container:name"
+ ],
+ "template": "List of affected devices from {2}:\n%%\n{0} is impacted by {1}\n%%",
+ "type": "format"
+ },
+ "errors": {},
+ "id": "14",
+ "type": "format",
+ "x": 980,
+ "y": 1220
+ },
+ "15": {
+ "data": {
+ "action": "vulnerability intelligence",
+ "actionType": "investigate",
+ "advanced": {
+ "join": [],
+ "note": "Run a Recorded Future vulnerability lookup for each returned CVE."
+ },
+ "connector": "Recorded Future",
+ "connectorConfigs": [
+ "recorded future "
+ ],
+ "connectorId": "6efe0e1b-76ac-4ffd-8fa0-ac58fd6efd77",
+ "connectorVersion": "v1",
+ "functionId": 1,
+ "functionName": "vulnerability_intelligence_1",
+ "id": "15",
+ "parameters": {
+ "vulnerability": "query_scan_results:action_result.data.*.cve"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "field": "vulnerability"
+ }
+ ],
+ "type": "action"
+ },
+ "errors": {},
+ "id": "15",
+ "type": "action",
+ "x": 980,
+ "y": 1080
+ },
+ "17": {
+ "data": {
+ "advanced": {
+ "customName": "Pin Findings",
+ "customNameId": 0,
+ "join": [],
+ "note": "Custom code to individually pin each scan result finding."
+ },
+ "functionId": 2,
+ "functionName": "pin_findings",
+ "id": "17",
+ "inputParameters": [
+ "query_scan_results:action_result.data.*.dnsName",
+ "query_scan_results:action_result.data.*.cve"
+ ],
+ "outputVariables": [],
+ "type": "code"
+ },
+ "errors": {},
+ "id": "17",
+ "type": "code",
+ "userCode": " for hostname, vulnerability in zip(query_scan_results_result_item_0, query_scan_results_result_item_1):\n phantom.pin(container=container, data=hostname, message=vulnerability, pin_style=\"red\", pin_type=\"card\")\n\n",
+ "x": 580,
+ "y": 1100
+ },
+ "18": {
+ "data": {
+ "advanced": {
+ "join": [],
+ "note": "Continue if results are found."
+ },
+ "conditions": [
+ {
+ "comparisons": [
+ {
+ "conditionIndex": 0,
+ "op": ">",
+ "param": "query_scan_results:action_result.summary.total_events",
+ "value": "0"
+ }
+ ],
+ "conditionIndex": 0,
+ "display": "If",
+ "logic": "and",
+ "type": "if"
+ },
+ {
+ "comparisons": [
+ {
+ "op": "==",
+ "param": "",
+ "value": ""
+ }
+ ],
+ "conditionIndex": 1,
+ "display": "Else",
+ "logic": "and",
+ "type": "else"
+ }
+ ],
+ "functionId": 1,
+ "functionName": "decision_1",
+ "id": "18",
+ "type": "decision"
+ },
+ "errors": {},
+ "id": "18",
+ "type": "decision",
+ "x": 1060,
+ "y": 900
+ },
+ "19": {
+ "data": {
+ "advanced": {
+ "join": [],
+ "note": "No findings. Close container/alert.",
+ "refreshNotableData": true
+ },
+ "functionId": 5,
+ "functionName": "pin_set_status_5",
+ "id": "19",
+ "selectMore": false,
+ "tab": "apis",
+ "type": "utility",
+ "utilities": {
+ "pin": {
+ "description": "",
+ "fields": [
+ {
+ "description": "",
+ "label": "message",
+ "name": "message",
+ "placeholder": "Enter a message",
+ "renderType": "datapath",
+ "required": false
+ },
+ {
+ "description": "",
+ "label": "data",
+ "name": "data",
+ "placeholder": "Enter a value",
+ "renderType": "datapath",
+ "required": false
+ },
+ {
+ "choices": [
+ "card",
+ "data"
+ ],
+ "description": "",
+ "label": "pin type",
+ "name": "pin_type",
+ "placeholder": "Select pin type",
+ "renderType": "dropdown",
+ "required": false
+ },
+ {
+ "choices": [
+ "grey",
+ "blue",
+ "red"
+ ],
+ "description": "",
+ "label": "pin color",
+ "name": "pin_style",
+ "placeholder": "Select pin color",
+ "renderType": "dropdown",
+ "required": false
+ },
+ {
+ "description": "",
+ "label": "name",
+ "name": "name",
+ "placeholder": "Use a named pin",
+ "renderType": "input",
+ "required": false
+ },
+ {
+ "hidden": true,
+ "name": "container",
+ "required": false
+ },
+ {
+ "hidden": true,
+ "name": "author",
+ "required": false
+ },
+ {
+ "hidden": true,
+ "name": "truncate",
+ "required": false
+ },
+ {
+ "hidden": true,
+ "name": "trace",
+ "required": false
+ }
+ ],
+ "label": "pin",
+ "name": "pin"
+ },
+ "set_status": {
+ "description": "",
+ "fields": [
+ {
+ "choices": "notableStatus",
+ "description": "",
+ "label": "status",
+ "name": "status",
+ "placeholder": "Select status",
+ "renderType": "dropdown",
+ "required": true
+ },
+ {
+ "hidden": true,
+ "name": "container",
+ "required": false
+ },
+ {
+ "hidden": true,
+ "name": "trace",
+ "required": false
+ }
+ ],
+ "label": "set status",
+ "name": "set_status",
+ "refreshNotableData": true
+ }
+ },
+ "utilityType": "api",
+ "values": {
+ "pin": {
+ "_internal": [
+ "container",
+ "author",
+ "truncate",
+ "trace"
+ ],
+ "data": "deduplicated_cves:custom_function:cve",
+ "message": "No findings in Splunk for the vulnerabilities:",
+ "name": null,
+ "pin_style": "blue",
+ "pin_type": "card"
+ },
+ "set_status": {
+ "_internal": [
+ "container",
+ "trace"
+ ],
+ "status": "closed"
+ }
+ }
+ },
+ "errors": {},
+ "id": "19",
+ "type": "utility",
+ "x": 1440,
+ "y": 1080
+ },
+ "2": {
+ "data": {
+ "advanced": {
+ "customName": "FIlter CVEs",
+ "customNameId": 0,
+ "description": "",
+ "join": [],
+ "note": "Filter CYBERVULNERABILITY artifacts for CVE's"
+ },
+ "conditions": [
+ {
+ "comparisons": [
+ {
+ "conditionIndex": 0,
+ "op": "in",
+ "param": "CYBERVULNERABILITY",
+ "value": "artifact:*.name"
+ },
+ {
+ "conditionIndex": 0,
+ "op": "!=",
+ "param": "artifact:*.cef.cyberVulnerability",
+ "value": ""
+ }
+ ],
+ "conditionIndex": 0,
+ "logic": "and"
+ }
+ ],
+ "functionId": 1,
+ "functionName": "filter_cves",
+ "id": "2",
+ "type": "filter"
+ },
+ "errors": {},
+ "id": "2",
+ "type": "filter",
+ "x": 1040,
+ "y": 500
+ },
+ "6": {
+ "data": {
+ "advanced": {
+ "customName": "Deduplicated CVEs",
+ "customNameId": 0,
+ "join": [],
+ "note": "Deduplicate any CVE's that are included in the same Recorded Future alert."
+ },
+ "functionId": 1,
+ "functionName": "deduplicated_cves",
+ "id": "6",
+ "inputParameters": [
+ "filtered-data:filter_cves:condition_1:artifact:*.cef.cyberVulnerability"
+ ],
+ "outputVariables": [
+ "cve"
+ ],
+ "type": "code"
+ },
+ "errors": {},
+ "id": "6",
+ "type": "code",
+ "userCode": "\n cve_list = filtered_artifact_0__cef_cybervulnerability\n cve_list = list(set(cve_list))\n phantom.debug(cve_list)\n deduplicated_cves__cve = cve_list\n\n",
+ "x": 980,
+ "y": 660
+ }
+ },
+ "notes": ""
+ },
+ "input_spec": null,
+ "output_spec": null,
+ "playbook_type": "automation",
+ "python_version": "3",
+ "schema": "5.0.8",
+ "version": "5.3.4.95226"
+ },
+ "create_time": "2022-10-05T15:09:32.639904+00:00",
+ "draft_mode": false,
+ "labels": [
+ "*"
+ ],
+ "tags": []
+}
\ No newline at end of file
diff --git a/recorded_future_vulnerability_alert_handling.png b/recorded_future_vulnerability_alert_handling.png
new file mode 100644
index 00000000..72e78813
Binary files /dev/null and b/recorded_future_vulnerability_alert_handling.png differ
diff --git a/recorded_future_vulnerability_alert_handling.py b/recorded_future_vulnerability_alert_handling.py
new file mode 100644
index 00000000..1fc2bed7
--- /dev/null
+++ b/recorded_future_vulnerability_alert_handling.py
@@ -0,0 +1,283 @@
+"""
+This playbook will run on 'vulnerability' labeled containers which will include Recorded Future's New Critical or Pre NVD Vulnerabilities, alert.\n\nThe mentioned CVE's are converted to a list and passed into a Splunk search. Assuming vulnerability scan results exist in Splunk, if a match is found, the associated CVE and IP address of the affected machine will be returned into Splunk SOAR.
+"""
+
+
+import phantom.rules as phantom
+import json
+from datetime import datetime, timedelta
+
+
+@phantom.playbook_block()
+def on_start(container):
+ phantom.debug('on_start() called')
+
+ # call 'filter_cves' block
+ filter_cves(container=container)
+
+ return
+
+@phantom.playbook_block()
+def filter_cves(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("filter_cves() called")
+
+ # collect filtered artifact ids and results for 'if' condition 1
+ matched_artifacts_1, matched_results_1 = phantom.condition(
+ container=container,
+ logical_operator="and",
+ conditions=[
+ ["CYBERVULNERABILITY", "in", "artifact:*.name"],
+ ["artifact:*.cef.cyberVulnerability", "!=", ""]
+ ],
+ name="filter_cves:condition_1")
+
+ # call connected blocks if filtered artifacts or results
+ if matched_artifacts_1 or matched_results_1:
+ deduplicated_cves(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 deduplicated_cves(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("deduplicated_cves() called")
+
+ filtered_artifact_0_data_filter_cves = phantom.collect2(container=container, datapath=["filtered-data:filter_cves:condition_1:artifact:*.cef.cyberVulnerability"])
+
+ filtered_artifact_0__cef_cybervulnerability = [item[0] for item in filtered_artifact_0_data_filter_cves]
+
+ deduplicated_cves__cve = None
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ cve_list = filtered_artifact_0__cef_cybervulnerability
+ cve_list = list(set(cve_list))
+ phantom.debug(cve_list)
+ deduplicated_cves__cve = cve_list
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.save_run_data(key="deduplicated_cves:cve", value=json.dumps(deduplicated_cves__cve))
+
+ query_scan_results(container=container)
+
+ return
+
+
+@phantom.playbook_block()
+def query_scan_results(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("query_scan_results() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ query_formatted_string = phantom.format(
+ container=container,
+ template="""| makeresults \n| eval cve=\"{0}\" \n| makemv cve delim=\", \"\n| mvexpand cve \n| join type=inner cve\n [ search index=main sourcetype=\"tenable:sc:vuln\" earliest=-7d@d]""",
+ parameters=[
+ "deduplicated_cves:custom_function:cve"
+ ])
+
+ parameters = []
+
+ if query_formatted_string is not None:
+ parameters.append({
+ "query": query_formatted_string,
+ "command": "",
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("run query", parameters=parameters, name="query_scan_results", assets=["splunk"], callback=decision_1)
+
+ return
+
+
+@phantom.playbook_block()
+def add_comment_3(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("add_comment_3() called")
+
+ format_splunk_results = phantom.get_format_data(name="format_splunk_results")
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.comment(container=container, comment=format_splunk_results)
+
+ return
+
+
+@phantom.playbook_block()
+def format_splunk_results(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("format_splunk_results() called")
+
+ template = """List of affected devices from {2}:\n%%\n{0} is impacted by {1}\n%%"""
+
+ # parameter list for template variable replacement
+ parameters = [
+ "query_scan_results:action_result.data.*.dnsName",
+ "query_scan_results:action_result.data.*.cve",
+ "container:name"
+ ]
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.format(container=container, template=template, parameters=parameters, name="format_splunk_results")
+
+ add_comment_3(container=container)
+
+ return
+
+
+@phantom.playbook_block()
+def vulnerability_intelligence_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("vulnerability_intelligence_1() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ query_scan_results_result_data = phantom.collect2(container=container, datapath=["query_scan_results:action_result.data.*.cve","query_scan_results:action_result.parameter.context.artifact_id"], action_results=results)
+
+ parameters = []
+
+ # build parameters list for 'vulnerability_intelligence_1' call
+ for query_scan_results_result_item in query_scan_results_result_data:
+ if query_scan_results_result_item[0] is not None:
+ parameters.append({
+ "vulnerability": query_scan_results_result_item[0],
+ "context": {'artifact_id': query_scan_results_result_item[1]},
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("vulnerability intelligence", parameters=parameters, name="vulnerability_intelligence_1", assets=["recorded future "], callback=format_splunk_results)
+
+ return
+
+
+@phantom.playbook_block()
+def pin_findings(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("pin_findings() called")
+
+ query_scan_results_result_data = phantom.collect2(container=container, datapath=["query_scan_results:action_result.data.*.dnsName","query_scan_results:action_result.data.*.cve"], action_results=results)
+
+ query_scan_results_result_item_0 = [item[0] for item in query_scan_results_result_data]
+ query_scan_results_result_item_1 = [item[1] for item in query_scan_results_result_data]
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+ for hostname, vulnerability in zip(query_scan_results_result_item_0, query_scan_results_result_item_1):
+ phantom.pin(container=container, data=hostname, message=vulnerability, pin_style="red", pin_type="card")
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ 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")
+
+ # check for 'if' condition 1
+ found_match_1 = phantom.decision(
+ container=container,
+ conditions=[
+ ["query_scan_results:action_result.summary.total_events", ">", 0]
+ ])
+
+ # call connected blocks if condition 1 matched
+ if found_match_1:
+ vulnerability_intelligence_1(action=action, success=success, container=container, results=results, handle=handle)
+ pin_findings(action=action, success=success, container=container, results=results, handle=handle)
+ return
+
+ # check for 'else' condition 2
+ pin_set_status_5(action=action, success=success, container=container, results=results, handle=handle)
+
+ return
+
+
+@phantom.playbook_block()
+def pin_set_status_5(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("pin_set_status_5() called")
+
+ deduplicated_cves__cve = json.loads(phantom.get_run_data(key="deduplicated_cves:cve"))
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.pin(container=container, data=deduplicated_cves__cve, message="No findings in Splunk for the vulnerabilities:", pin_style="blue", pin_type="card")
+ phantom.set_status(container=container, status="closed")
+
+ container = phantom.get_container(container.get('id', None))
+
+ return
+
+
+@phantom.playbook_block()
+def on_finish(container, summary):
+ phantom.debug("on_finish() called")
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # This function is called after all actions are completed.
+ # summary of all the action and/or all details of actions
+ # can be collected here.
+
+ # summary_json = phantom.get_summary()
+ # if 'result' in summary_json:
+ # for action_result in summary_json['result']:
+ # if 'action_run_id' in action_result:
+ # action_results = phantom.get_action_results(action_run_id=action_result['action_run_id'], result_data=False, flatten=False)
+ # phantom.debug(action_results)
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ return
\ No newline at end of file
diff --git a/recordedfuture_phishing_sandbox.json b/recordedfuture_phishing_sandbox.json
new file mode 100644
index 00000000..9e0acbc8
--- /dev/null
+++ b/recordedfuture_phishing_sandbox.json
@@ -0,0 +1,899 @@
+{
+ "blockly": false,
+ "blockly_xml": "",
+ "category": "Uncategorized",
+ "coa": {
+ "data": {
+ "description": "This playbook is designed to run on containers created from the EWS for Office 365 app's polling feature that monitors an email inbox, ingests emails, and creates artifacts based on those emails.\n\nThis playbook will extract files from the vault and create artifacts for each one. Then, the playbook will submit each file to Recorded Future's sandbox for analysis. \n\nThe same will be done for URLs for any artifact that contains a cef field of requestURL.\n\nThe results will be brought back into a container for analysis.",
+ "edges": [
+ {
+ "id": "port_4_to_port_9",
+ "sourceNode": "4",
+ "sourcePort": "4_out",
+ "targetNode": "9",
+ "targetPort": "9_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 0
+ }
+ ],
+ "id": "port_9_to_port_2",
+ "sourceNode": "9",
+ "sourcePort": "9_out",
+ "targetNode": "2",
+ "targetPort": "2_in"
+ },
+ {
+ "id": "port_0_to_port_4",
+ "sourceNode": "0",
+ "sourcePort": "0_out",
+ "targetNode": "4",
+ "targetPort": "4_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 0
+ }
+ ],
+ "id": "port_23_to_port_24",
+ "sourceNode": "23",
+ "sourcePort": "23_out",
+ "targetNode": "24",
+ "targetPort": "24_in"
+ },
+ {
+ "id": "port_24_to_port_1",
+ "sourceNode": "24",
+ "sourcePort": "24_out",
+ "targetNode": "1",
+ "targetPort": "1_in"
+ },
+ {
+ "id": "port_2_to_port_28",
+ "sourceNode": "2",
+ "sourcePort": "2_out",
+ "targetNode": "28",
+ "targetPort": "28_in"
+ },
+ {
+ "id": "port_28_to_port_23",
+ "sourceNode": "28",
+ "sourcePort": "28_out",
+ "targetNode": "23",
+ "targetPort": "23_in"
+ },
+ {
+ "id": "port_0_to_port_29",
+ "sourceNode": "0",
+ "sourcePort": "0_out",
+ "targetNode": "29",
+ "targetPort": "29_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 0
+ }
+ ],
+ "id": "port_29_to_port_30",
+ "sourceNode": "29",
+ "sourcePort": "29_out",
+ "targetNode": "30",
+ "targetPort": "30_in"
+ },
+ {
+ "id": "port_30_to_port_31",
+ "sourceNode": "30",
+ "sourcePort": "30_out",
+ "targetNode": "31",
+ "targetPort": "31_in"
+ },
+ {
+ "id": "port_31_to_port_32",
+ "sourceNode": "31",
+ "sourcePort": "31_out",
+ "targetNode": "32",
+ "targetPort": "32_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 0
+ }
+ ],
+ "id": "port_32_to_port_33",
+ "sourceNode": "32",
+ "sourcePort": "32_out",
+ "targetNode": "33",
+ "targetPort": "33_in"
+ },
+ {
+ "id": "port_33_to_port_1",
+ "sourceNode": "33",
+ "sourcePort": "33_out",
+ "targetNode": "1",
+ "targetPort": "1_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 1
+ }
+ ],
+ "id": "port_32_to_port_34",
+ "sourceNode": "32",
+ "sourcePort": "32_out",
+ "targetNode": "34",
+ "targetPort": "34_in"
+ },
+ {
+ "id": "port_34_to_port_1",
+ "sourceNode": "34",
+ "sourcePort": "34_out",
+ "targetNode": "1",
+ "targetPort": "1_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 1
+ }
+ ],
+ "id": "port_23_to_port_35",
+ "sourceNode": "23",
+ "sourcePort": "23_out",
+ "targetNode": "35",
+ "targetPort": "35_in"
+ },
+ {
+ "id": "port_35_to_port_36",
+ "sourceNode": "35",
+ "sourcePort": "35_out",
+ "targetNode": "36",
+ "targetPort": "36_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 0
+ }
+ ],
+ "id": "port_36_to_port_37",
+ "sourceNode": "36",
+ "sourcePort": "36_out",
+ "targetNode": "37",
+ "targetPort": "37_in"
+ },
+ {
+ "id": "port_37_to_port_1",
+ "sourceNode": "37",
+ "sourcePort": "37_out",
+ "targetNode": "1",
+ "targetPort": "1_in"
+ },
+ {
+ "conditions": [
+ {
+ "index": 1
+ }
+ ],
+ "id": "port_36_to_port_38",
+ "sourceNode": "36",
+ "sourcePort": "36_out",
+ "targetNode": "38",
+ "targetPort": "38_in"
+ },
+ {
+ "id": "port_38_to_port_1",
+ "sourceNode": "38",
+ "sourcePort": "38_out",
+ "targetNode": "1",
+ "targetPort": "1_in"
+ }
+ ],
+ "hash": "76a0141fa396f80da0aeceb3489edb05bf992035",
+ "nodes": {
+ "0": {
+ "data": {
+ "advanced": {
+ "join": []
+ },
+ "functionName": "on_start",
+ "id": "0",
+ "type": "start"
+ },
+ "errors": {},
+ "id": "0",
+ "type": "start",
+ "x": 1100,
+ "y": 420
+ },
+ "1": {
+ "data": {
+ "advanced": {
+ "join": []
+ },
+ "functionId": 1,
+ "functionName": "on_finish",
+ "id": "1",
+ "type": "end"
+ },
+ "errors": {},
+ "id": "1",
+ "type": "end",
+ "userCode": "\n # This function is called after all actions are completed.\n # summary of all the action and/or all details of actions\n # can be collected here.\n\n # summary_json = phantom.get_summary()\n # if 'result' in summary_json:\n # for action_result in summary_json['result']:\n # if 'action_run_id' in action_result:\n # action_results = phantom.get_action_results(action_run_id=action_result['action_run_id'], result_data=False, flatten=False)\n # phantom.debug(action_results)\n\n",
+ "x": 1160,
+ "y": 1780
+ },
+ "2": {
+ "data": {
+ "action": "detonate file",
+ "actionType": "investigate",
+ "advanced": {
+ "delayTime": 0,
+ "join": [],
+ "note": "Submit each file to the Recorded Future sandbox.",
+ "scope": "all"
+ },
+ "connector": "Recorded Future Sandbox",
+ "connectorConfigs": [
+ "rf sandbox"
+ ],
+ "connectorId": "1d05afb4-5201-4cfd-9c76-ed6d9d808241",
+ "connectorVersion": "v1",
+ "functionId": 1,
+ "functionName": "detonate_file_1",
+ "id": "2",
+ "parameters": {
+ "file_name": "filtered-data:filter_file_artifacts:condition_1:artifact:*.cef.fileName",
+ "vault_id": "filtered-data:filter_file_artifacts:condition_1:artifact:*.cef.vaultId"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "field": "vault_id"
+ },
+ {
+ "data_type": "string",
+ "field": "file_name"
+ }
+ ],
+ "type": "action"
+ },
+ "errors": {},
+ "id": "2",
+ "type": "action",
+ "x": 900,
+ "y": 880
+ },
+ "23": {
+ "customCode": null,
+ "data": {
+ "advanced": {
+ "join": [],
+ "notRequiredJoins": [
+ "get_status_2"
+ ],
+ "note": "Check if submission has finished processing.",
+ "scope": "all"
+ },
+ "conditions": [
+ {
+ "comparisons": [
+ {
+ "conditionIndex": 0,
+ "op": "==",
+ "param": "get_status_1:action_result.data.*.status",
+ "value": "reported"
+ }
+ ],
+ "conditionIndex": 0,
+ "display": "If",
+ "logic": "and",
+ "type": "if"
+ },
+ {
+ "comparisons": [
+ {
+ "conditionIndex": 1,
+ "op": "==",
+ "param": "",
+ "value": ""
+ }
+ ],
+ "conditionIndex": 1,
+ "display": "Else",
+ "logic": "and",
+ "type": "else"
+ }
+ ],
+ "functionId": 5,
+ "functionName": "decision_5",
+ "id": "23",
+ "type": "decision"
+ },
+ "errors": {},
+ "id": "23",
+ "type": "decision",
+ "userCode": null,
+ "x": 980,
+ "y": 1160
+ },
+ "24": {
+ "data": {
+ "action": "fetch report",
+ "actionType": "investigate",
+ "advanced": {
+ "customName": "fetch file report",
+ "customNameId": 0,
+ "join": [],
+ "note": "Fetch the sandbox report."
+ },
+ "connector": "Recorded Future Sandbox",
+ "connectorConfigs": [
+ "rf sandbox"
+ ],
+ "connectorId": "1d05afb4-5201-4cfd-9c76-ed6d9d808241",
+ "connectorVersion": "v1",
+ "functionId": 1,
+ "functionName": "fetch_file_report",
+ "id": "24",
+ "parameters": {
+ "analysis_id": "get_status_1:action_result.data.*.analysis_id"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "field": "analysis_id"
+ }
+ ],
+ "type": "action"
+ },
+ "errors": {},
+ "id": "24",
+ "type": "action",
+ "x": 900,
+ "y": 1340
+ },
+ "28": {
+ "data": {
+ "action": "get status",
+ "actionType": "investigate",
+ "advanced": {
+ "delayTime": 4,
+ "join": [],
+ "note": "Get the status of the file submission after waiting for 4 minutes."
+ },
+ "connector": "Recorded Future Sandbox",
+ "connectorConfigs": [
+ "rf sandbox"
+ ],
+ "connectorId": "1d05afb4-5201-4cfd-9c76-ed6d9d808241",
+ "connectorVersion": "v1",
+ "functionId": 1,
+ "functionName": "get_status_1",
+ "id": "28",
+ "parameters": {
+ "analysis_id": "detonate_file_1:action_result.data.*.analysis_id"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "field": "analysis_id"
+ }
+ ],
+ "type": "action"
+ },
+ "errors": {},
+ "id": "28",
+ "type": "action",
+ "x": 900,
+ "y": 1020
+ },
+ "29": {
+ "data": {
+ "advanced": {
+ "customName": "Filter URLs",
+ "customNameId": 0,
+ "join": [],
+ "note": "Filter artifacts for any requestURLs; commonly found in Email Artifacts."
+ },
+ "conditions": [
+ {
+ "comparisons": [
+ {
+ "conditionIndex": 0,
+ "op": "!=",
+ "param": "artifact:*.cef.requestURL",
+ "value": ""
+ }
+ ],
+ "conditionIndex": 0,
+ "logic": "and"
+ }
+ ],
+ "functionId": 1,
+ "functionName": "filter_urls",
+ "id": "29",
+ "type": "filter"
+ },
+ "errors": {},
+ "id": "29",
+ "type": "filter",
+ "x": 1280,
+ "y": 560
+ },
+ "30": {
+ "data": {
+ "action": "detonate url",
+ "actionType": "investigate",
+ "advanced": {
+ "join": [],
+ "note": "Detonate any URLs found in the Email Artifact."
+ },
+ "connector": "Recorded Future Sandbox",
+ "connectorConfigs": [
+ "rf sandbox"
+ ],
+ "connectorId": "1d05afb4-5201-4cfd-9c76-ed6d9d808241",
+ "connectorVersion": "v1",
+ "functionId": 1,
+ "functionName": "detonate_url_1",
+ "id": "30",
+ "parameters": {
+ "kind": "url",
+ "url": "filtered-data:filter_urls:condition_1:artifact:*.cef.requestURL"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "field": "url"
+ },
+ {
+ "data_type": "string",
+ "default": "url",
+ "field": "kind"
+ }
+ ],
+ "type": "action"
+ },
+ "errors": {},
+ "id": "30",
+ "type": "action",
+ "x": 1220,
+ "y": 780
+ },
+ "31": {
+ "data": {
+ "action": "get status",
+ "actionType": "investigate",
+ "advanced": {
+ "delayTime": 4,
+ "join": [],
+ "note": "Get the status of the URL submission after waiting for 4 minutes."
+ },
+ "connector": "Recorded Future Sandbox",
+ "connectorConfigs": [
+ "rf sandbox"
+ ],
+ "connectorId": "1d05afb4-5201-4cfd-9c76-ed6d9d808241",
+ "connectorVersion": "v1",
+ "functionId": 2,
+ "functionName": "get_status_2",
+ "id": "31",
+ "parameters": {
+ "analysis_id": "detonate_url_1:action_result.data.*.analysis_id"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "field": "analysis_id"
+ }
+ ],
+ "type": "action"
+ },
+ "errors": {},
+ "id": "31",
+ "type": "action",
+ "x": 1220,
+ "y": 920
+ },
+ "32": {
+ "data": {
+ "advanced": {
+ "description": "",
+ "join": [],
+ "note": "Check if submission has finished processing."
+ },
+ "conditions": [
+ {
+ "comparisons": [
+ {
+ "conditionIndex": 0,
+ "op": "==",
+ "param": "get_status_2:action_result.data.*.status",
+ "value": "reported"
+ }
+ ],
+ "conditionIndex": 0,
+ "display": "If",
+ "logic": "and",
+ "type": "if"
+ },
+ {
+ "comparisons": [
+ {
+ "op": "==",
+ "param": "",
+ "value": ""
+ }
+ ],
+ "conditionIndex": 1,
+ "display": "Else",
+ "logic": "and",
+ "type": "else"
+ }
+ ],
+ "functionId": 1,
+ "functionName": "decision_1",
+ "id": "32",
+ "type": "decision"
+ },
+ "errors": {},
+ "id": "32",
+ "type": "decision",
+ "x": 1300,
+ "y": 1100
+ },
+ "33": {
+ "data": {
+ "action": "fetch report",
+ "actionType": "investigate",
+ "advanced": {
+ "customName": "fetch URL report",
+ "customNameId": 0,
+ "join": [],
+ "note": "Fetch the sandbox report."
+ },
+ "connector": "Recorded Future Sandbox",
+ "connectorConfigs": [
+ "rf sandbox"
+ ],
+ "connectorId": "1d05afb4-5201-4cfd-9c76-ed6d9d808241",
+ "connectorVersion": "v1",
+ "functionId": 2,
+ "functionName": "fetch_url_report",
+ "id": "33",
+ "parameters": {
+ "analysis_id": "get_status_2:action_result.data.*.analysis_id"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "field": "analysis_id"
+ }
+ ],
+ "type": "action"
+ },
+ "errors": {},
+ "id": "33",
+ "type": "action",
+ "x": 1220,
+ "y": 1340
+ },
+ "34": {
+ "data": {
+ "advanced": {
+ "join": [],
+ "note": "Comment: Fetched the submission too early."
+ },
+ "functionId": 1,
+ "functionName": "add_comment_1",
+ "id": "34",
+ "selectMore": false,
+ "tab": "apis",
+ "type": "utility",
+ "utilities": {
+ "comment": {
+ "description": "",
+ "fields": [
+ {
+ "description": "",
+ "label": "comment",
+ "name": "comment",
+ "placeholder": "Enter a comment",
+ "renderType": "datapath",
+ "required": true
+ },
+ {
+ "hidden": true,
+ "name": "container",
+ "required": false
+ },
+ {
+ "hidden": true,
+ "name": "author",
+ "required": false
+ },
+ {
+ "hidden": true,
+ "name": "trace",
+ "required": false
+ }
+ ],
+ "label": "add comment",
+ "name": "comment"
+ }
+ },
+ "utilityType": "api",
+ "values": {
+ "comment": {
+ "_internal": [
+ "container",
+ "author",
+ "trace"
+ ],
+ "comment": "The report was fetched before completion. Increase the delay timer and try again. "
+ }
+ }
+ },
+ "errors": {},
+ "id": "34",
+ "type": "utility",
+ "x": 1500,
+ "y": 1340
+ },
+ "35": {
+ "data": {
+ "action": "get status",
+ "actionType": "investigate",
+ "advanced": {
+ "join": [],
+ "note": "Get the status of the file submission after waiting for 4 minutes a second time in case of larger file."
+ },
+ "connector": "Recorded Future Sandbox",
+ "connectorConfigs": [
+ "rf sandbox"
+ ],
+ "connectorId": "1d05afb4-5201-4cfd-9c76-ed6d9d808241",
+ "connectorVersion": "v1",
+ "functionId": 3,
+ "functionName": "get_status_3",
+ "id": "35",
+ "parameters": {
+ "analysis_id": "detonate_file_1:action_result.data.*.analysis_id"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "field": "analysis_id"
+ }
+ ],
+ "type": "action"
+ },
+ "errors": {},
+ "id": "35",
+ "type": "action",
+ "x": 540,
+ "y": 1340
+ },
+ "36": {
+ "data": {
+ "advanced": {
+ "join": [],
+ "note": "Check if submission has finished processing."
+ },
+ "conditions": [
+ {
+ "comparisons": [
+ {
+ "conditionIndex": 0,
+ "op": "==",
+ "param": "get_status_3:action_result.data.*.status",
+ "value": "reported"
+ }
+ ],
+ "conditionIndex": 0,
+ "display": "If",
+ "logic": "and",
+ "type": "if"
+ },
+ {
+ "comparisons": [
+ {
+ "op": "==",
+ "param": "",
+ "value": ""
+ }
+ ],
+ "conditionIndex": 1,
+ "display": "Else",
+ "logic": "and",
+ "type": "else"
+ }
+ ],
+ "functionId": 2,
+ "functionName": "decision_2",
+ "id": "36",
+ "type": "decision"
+ },
+ "errors": {},
+ "id": "36",
+ "type": "decision",
+ "x": 620,
+ "y": 1460
+ },
+ "37": {
+ "data": {
+ "action": "fetch report",
+ "actionType": "investigate",
+ "advanced": {
+ "join": [],
+ "note": "Fetch the sandbox report."
+ },
+ "connector": "Recorded Future Sandbox",
+ "connectorConfigs": [
+ "rf sandbox"
+ ],
+ "connectorId": "1d05afb4-5201-4cfd-9c76-ed6d9d808241",
+ "connectorVersion": "v1",
+ "functionId": 3,
+ "functionName": "fetch_report_3",
+ "id": "37",
+ "parameters": {
+ "analysis_id": "get_status_3:action_result.data.*.analysis_id"
+ },
+ "requiredParameters": [
+ {
+ "data_type": "string",
+ "field": "analysis_id"
+ }
+ ],
+ "type": "action"
+ },
+ "errors": {},
+ "id": "37",
+ "type": "action",
+ "x": 540,
+ "y": 1620
+ },
+ "38": {
+ "data": {
+ "advanced": {
+ "join": [],
+ "note": "Comment: Fetched the submission too early."
+ },
+ "functionId": 2,
+ "functionName": "add_comment_2",
+ "id": "38",
+ "selectMore": false,
+ "tab": "apis",
+ "type": "utility",
+ "utilities": {
+ "comment": {
+ "description": "",
+ "fields": [
+ {
+ "description": "",
+ "label": "comment",
+ "name": "comment",
+ "placeholder": "Enter a comment",
+ "renderType": "datapath",
+ "required": true
+ },
+ {
+ "hidden": true,
+ "name": "container",
+ "required": false
+ },
+ {
+ "hidden": true,
+ "name": "author",
+ "required": false
+ },
+ {
+ "hidden": true,
+ "name": "trace",
+ "required": false
+ }
+ ],
+ "label": "add comment",
+ "name": "comment"
+ }
+ },
+ "utilityType": "api",
+ "values": {
+ "comment": {
+ "_internal": [
+ "container",
+ "author",
+ "trace"
+ ],
+ "comment": "The file report was fetched before completion. Increase the delay timer and try again. "
+ }
+ }
+ },
+ "errors": {},
+ "id": "38",
+ "type": "utility",
+ "x": 260,
+ "y": 1620
+ },
+ "4": {
+ "data": {
+ "advanced": {
+ "customName": "Get files from vault",
+ "customNameId": 0,
+ "join": [],
+ "note": "Checks the vault for files and creates artfiacts for each one."
+ },
+ "functionId": 1,
+ "functionName": "get_files_from_vault",
+ "id": "4",
+ "inputParameters": [
+ "container:id"
+ ],
+ "outputVariables": [],
+ "type": "code"
+ },
+ "errors": {},
+ "id": "4",
+ "type": "code",
+ "userCode": "\n phantom.debug('phantom.vault_info start')\n\n success, message, info = phantom.vault_info(\n container_id=id_value\n )\n\n for item in info:\n raw = {}\n cef = {}\n cef['vaultId'] = item['vault_id']\n cef['fileName'] = item['name']\n cef['fileHashSha256'] = item['metadata']['sha256']\n phantom.debug(cef)\n \n success, message, artifact_id = phantom.add_artifact(\n container=container, raw_data=raw, cef_data=cef, label='event',\n name='file', severity='high',\n identifier=None,\n artifact_type='file')\n phantom.debug('artifact added as id:'+str(artifact_id))\n\n",
+ "x": 900,
+ "y": 560
+ },
+ "9": {
+ "data": {
+ "advanced": {
+ "customName": "Filter file artifacts",
+ "customNameId": 0,
+ "join": [],
+ "note": "Filter the file artifacts.",
+ "scope": "all"
+ },
+ "conditions": [
+ {
+ "comparisons": [
+ {
+ "conditionIndex": 0,
+ "op": "==",
+ "param": "artifact:*.name",
+ "value": "file"
+ }
+ ],
+ "conditionIndex": 0,
+ "logic": "and"
+ }
+ ],
+ "functionId": 2,
+ "functionName": "filter_file_artifacts",
+ "id": "9",
+ "type": "filter"
+ },
+ "errors": {},
+ "id": "9",
+ "type": "filter",
+ "x": 960,
+ "y": 700
+ }
+ },
+ "notes": "You may need to modify the delay timer for the 'get-status' actions. Currently. it delays 4 minutes on each check."
+ },
+ "input_spec": null,
+ "output_spec": null,
+ "playbook_type": "automation",
+ "python_version": "3",
+ "schema": "5.0.8",
+ "version": "5.3.4.95226"
+ },
+ "create_time": "2022-10-26T12:07:28.609756+00:00",
+ "draft_mode": false,
+ "labels": [
+ "*"
+ ],
+ "tags": []
+}
\ No newline at end of file
diff --git a/recordedfuture_phishing_sandbox.png b/recordedfuture_phishing_sandbox.png
new file mode 100644
index 00000000..aa1b0cd6
Binary files /dev/null and b/recordedfuture_phishing_sandbox.png differ
diff --git a/recordedfuture_phishing_sandbox.py b/recordedfuture_phishing_sandbox.py
new file mode 100644
index 00000000..ced02d9e
--- /dev/null
+++ b/recordedfuture_phishing_sandbox.py
@@ -0,0 +1,499 @@
+"""
+This playbook is designed to run on containers created from the EWS for Office 365 app's polling feature that monitors an email inbox, ingests emails, and creates artifacts based on those emails.\n\nThis playbook will extract files from the vault and create artifacts for each one. Then, the playbook will submit each file to Recorded Future's sandbox for analysis. \n\nThe same will be done for URLs for any artifact that contains a cef field of requestURL.\n\nThe results will be brought back into a container for analysis.
+"""
+
+
+import phantom.rules as phantom
+import json
+from datetime import datetime, timedelta
+
+
+@phantom.playbook_block()
+def on_start(container):
+ phantom.debug('on_start() called')
+
+ # call 'get_files_from_vault' block
+ get_files_from_vault(container=container)
+ # call 'filter_urls' block
+ filter_urls(container=container)
+
+ return
+
+@phantom.playbook_block()
+def detonate_file_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("detonate_file_1() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ filtered_artifact_0_data_filter_file_artifacts = phantom.collect2(container=container, datapath=["filtered-data:filter_file_artifacts:condition_1:artifact:*.cef.vaultId","filtered-data:filter_file_artifacts:condition_1:artifact:*.cef.fileName","filtered-data:filter_file_artifacts:condition_1:artifact:*.id"], scope="all")
+
+ parameters = []
+
+ # build parameters list for 'detonate_file_1' call
+ for filtered_artifact_0_item_filter_file_artifacts in filtered_artifact_0_data_filter_file_artifacts:
+ if filtered_artifact_0_item_filter_file_artifacts[0] is not None and filtered_artifact_0_item_filter_file_artifacts[1] is not None:
+ parameters.append({
+ "vault_id": filtered_artifact_0_item_filter_file_artifacts[0],
+ "file_name": filtered_artifact_0_item_filter_file_artifacts[1],
+ "context": {'artifact_id': filtered_artifact_0_item_filter_file_artifacts[2]},
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("detonate file", parameters=parameters, name="detonate_file_1", assets=["rf sandbox"], callback=get_status_1)
+
+ return
+
+
+@phantom.playbook_block()
+def get_files_from_vault(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("get_files_from_vault() called")
+
+ id_value = container.get("id", None)
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ phantom.debug('phantom.vault_info start')
+
+ success, message, info = phantom.vault_info(
+ container_id=id_value
+ )
+
+ for item in info:
+ raw = {}
+ cef = {}
+ cef['vaultId'] = item['vault_id']
+ cef['fileName'] = item['name']
+ cef['fileHashSha256'] = item['metadata']['sha256']
+ phantom.debug(cef)
+
+ success, message, artifact_id = phantom.add_artifact(
+ container=container, raw_data=raw, cef_data=cef, label='event',
+ name='file', severity='high',
+ identifier=None,
+ artifact_type='file')
+ phantom.debug('artifact added as id:'+str(artifact_id))
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ filter_file_artifacts(container=container)
+
+ return
+
+
+@phantom.playbook_block()
+def filter_file_artifacts(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("filter_file_artifacts() called")
+
+ # collect filtered artifact ids and results for 'if' condition 1
+ matched_artifacts_1, matched_results_1 = phantom.condition(
+ container=container,
+ conditions=[
+ ["artifact:*.name", "==", "file"]
+ ],
+ name="filter_file_artifacts:condition_1",
+ scope="all")
+
+ # call connected blocks if filtered artifacts or results
+ if matched_artifacts_1 or matched_results_1:
+ detonate_file_1(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 decision_5(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("decision_5() called")
+
+ # check for 'if' condition 1
+ found_match_1 = phantom.decision(
+ container=container,
+ conditions=[
+ ["get_status_1:action_result.data.*.status", "==", "reported"]
+ ],
+ scope="all")
+
+ # call connected blocks if condition 1 matched
+ if found_match_1:
+ fetch_file_report(action=action, success=success, container=container, results=results, handle=handle)
+ return
+
+ # check for 'else' condition 2
+ get_status_3(action=action, success=success, container=container, results=results, handle=handle)
+
+ return
+
+
+@phantom.playbook_block()
+def fetch_file_report(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("fetch_file_report() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ get_status_1_result_data = phantom.collect2(container=container, datapath=["get_status_1:action_result.data.*.analysis_id","get_status_1:action_result.parameter.context.artifact_id"], action_results=results)
+
+ parameters = []
+
+ # build parameters list for 'fetch_file_report' call
+ for get_status_1_result_item in get_status_1_result_data:
+ if get_status_1_result_item[0] is not None:
+ parameters.append({
+ "analysis_id": get_status_1_result_item[0],
+ "context": {'artifact_id': get_status_1_result_item[1]},
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("fetch report", parameters=parameters, name="fetch_file_report", assets=["rf sandbox"])
+
+ return
+
+
+@phantom.playbook_block()
+def get_status_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("get_status_1() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ detonate_file_1_result_data = phantom.collect2(container=container, datapath=["detonate_file_1:action_result.data.*.analysis_id","detonate_file_1:action_result.parameter.context.artifact_id"], action_results=results)
+
+ parameters = []
+
+ # build parameters list for 'get_status_1' call
+ for detonate_file_1_result_item in detonate_file_1_result_data:
+ if detonate_file_1_result_item[0] is not None:
+ parameters.append({
+ "analysis_id": detonate_file_1_result_item[0],
+ "context": {'artifact_id': detonate_file_1_result_item[1]},
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ # calculate start time using delay of 4 minutes
+ start_time = datetime.now() + timedelta(minutes=4)
+ phantom.act("get status", parameters=parameters, name="get_status_1", start_time=start_time, assets=["rf sandbox"], callback=decision_5)
+
+ return
+
+
+@phantom.playbook_block()
+def filter_urls(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("filter_urls() called")
+
+ # collect filtered artifact ids and results for 'if' condition 1
+ matched_artifacts_1, matched_results_1 = phantom.condition(
+ container=container,
+ conditions=[
+ ["artifact:*.cef.requestURL", "!=", ""]
+ ],
+ name="filter_urls:condition_1")
+
+ # call connected blocks if filtered artifacts or results
+ if matched_artifacts_1 or matched_results_1:
+ detonate_url_1(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 detonate_url_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("detonate_url_1() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ filtered_artifact_0_data_filter_urls = phantom.collect2(container=container, datapath=["filtered-data:filter_urls:condition_1:artifact:*.cef.requestURL","filtered-data:filter_urls:condition_1:artifact:*.id"])
+
+ parameters = []
+
+ # build parameters list for 'detonate_url_1' call
+ for filtered_artifact_0_item_filter_urls in filtered_artifact_0_data_filter_urls:
+ if filtered_artifact_0_item_filter_urls[0] is not None:
+ parameters.append({
+ "url": filtered_artifact_0_item_filter_urls[0],
+ "kind": "url",
+ "context": {'artifact_id': filtered_artifact_0_item_filter_urls[1]},
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("detonate url", parameters=parameters, name="detonate_url_1", assets=["rf sandbox"], callback=get_status_2)
+
+ return
+
+
+@phantom.playbook_block()
+def get_status_2(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("get_status_2() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ detonate_url_1_result_data = phantom.collect2(container=container, datapath=["detonate_url_1:action_result.data.*.analysis_id","detonate_url_1:action_result.parameter.context.artifact_id"], action_results=results)
+
+ parameters = []
+
+ # build parameters list for 'get_status_2' call
+ for detonate_url_1_result_item in detonate_url_1_result_data:
+ if detonate_url_1_result_item[0] is not None:
+ parameters.append({
+ "analysis_id": detonate_url_1_result_item[0],
+ "context": {'artifact_id': detonate_url_1_result_item[1]},
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ # calculate start time using delay of 4 minutes
+ start_time = datetime.now() + timedelta(minutes=4)
+ phantom.act("get status", parameters=parameters, name="get_status_2", start_time=start_time, assets=["rf sandbox"], callback=decision_1)
+
+ 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")
+
+ # check for 'if' condition 1
+ found_match_1 = phantom.decision(
+ container=container,
+ conditions=[
+ ["get_status_2:action_result.data.*.status", "==", "reported"]
+ ])
+
+ # call connected blocks if condition 1 matched
+ if found_match_1:
+ fetch_url_report(action=action, success=success, container=container, results=results, handle=handle)
+ return
+
+ # check for 'else' condition 2
+ add_comment_1(action=action, success=success, container=container, results=results, handle=handle)
+
+ return
+
+
+@phantom.playbook_block()
+def fetch_url_report(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("fetch_url_report() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ get_status_2_result_data = phantom.collect2(container=container, datapath=["get_status_2:action_result.data.*.analysis_id","get_status_2:action_result.parameter.context.artifact_id"], action_results=results)
+
+ parameters = []
+
+ # build parameters list for 'fetch_url_report' call
+ for get_status_2_result_item in get_status_2_result_data:
+ if get_status_2_result_item[0] is not None:
+ parameters.append({
+ "analysis_id": get_status_2_result_item[0],
+ "context": {'artifact_id': get_status_2_result_item[1]},
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("fetch report", parameters=parameters, name="fetch_url_report", assets=["rf sandbox"])
+
+ return
+
+
+@phantom.playbook_block()
+def add_comment_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("add_comment_1() called")
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.comment(container=container, comment="The report was fetched before completion. Increase the delay timer and try again. ")
+
+ return
+
+
+@phantom.playbook_block()
+def get_status_3(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("get_status_3() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ detonate_file_1_result_data = phantom.collect2(container=container, datapath=["detonate_file_1:action_result.data.*.analysis_id","detonate_file_1:action_result.parameter.context.artifact_id"], action_results=results)
+
+ parameters = []
+
+ # build parameters list for 'get_status_3' call
+ for detonate_file_1_result_item in detonate_file_1_result_data:
+ if detonate_file_1_result_item[0] is not None:
+ parameters.append({
+ "analysis_id": detonate_file_1_result_item[0],
+ "context": {'artifact_id': detonate_file_1_result_item[1]},
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("get status", parameters=parameters, name="get_status_3", assets=["rf sandbox"], callback=decision_2)
+
+ return
+
+
+@phantom.playbook_block()
+def decision_2(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("decision_2() called")
+
+ # check for 'if' condition 1
+ found_match_1 = phantom.decision(
+ container=container,
+ conditions=[
+ ["get_status_3:action_result.data.*.status", "==", "reported"]
+ ])
+
+ # call connected blocks if condition 1 matched
+ if found_match_1:
+ fetch_report_3(action=action, success=success, container=container, results=results, handle=handle)
+ return
+
+ # check for 'else' condition 2
+ add_comment_2(action=action, success=success, container=container, results=results, handle=handle)
+
+ return
+
+
+@phantom.playbook_block()
+def fetch_report_3(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("fetch_report_3() called")
+
+ # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
+
+ get_status_3_result_data = phantom.collect2(container=container, datapath=["get_status_3:action_result.data.*.analysis_id","get_status_3:action_result.parameter.context.artifact_id"], action_results=results)
+
+ parameters = []
+
+ # build parameters list for 'fetch_report_3' call
+ for get_status_3_result_item in get_status_3_result_data:
+ if get_status_3_result_item[0] is not None:
+ parameters.append({
+ "analysis_id": get_status_3_result_item[0],
+ "context": {'artifact_id': get_status_3_result_item[1]},
+ })
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.act("fetch report", parameters=parameters, name="fetch_report_3", assets=["rf sandbox"])
+
+ return
+
+
+@phantom.playbook_block()
+def add_comment_2(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
+ phantom.debug("add_comment_2() called")
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # Write your custom code here...
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ phantom.comment(container=container, comment="The file report was fetched before completion. Increase the delay timer and try again. ")
+
+ return
+
+
+@phantom.playbook_block()
+def on_finish(container, summary):
+ phantom.debug("on_finish() called")
+
+ ################################################################################
+ ## Custom Code Start
+ ################################################################################
+
+ # This function is called after all actions are completed.
+ # summary of all the action and/or all details of actions
+ # can be collected here.
+
+ # summary_json = phantom.get_summary()
+ # if 'result' in summary_json:
+ # for action_result in summary_json['result']:
+ # if 'action_run_id' in action_result:
+ # action_results = phantom.get_action_results(action_run_id=action_result['action_run_id'], result_data=False, flatten=False)
+ # phantom.debug(action_results)
+
+ ################################################################################
+ ## Custom Code End
+ ################################################################################
+
+ return
\ No newline at end of file