mirror of
https://github.com/splunk/security_content
synced 2026-06-08 17:32:49 +00:00
Branch was auto-updated.
This commit is contained in:
@@ -0,0 +1,700 @@
|
||||
{
|
||||
"blockly": false,
|
||||
"blockly_xml": "<xml></xml>",
|
||||
"category": "Isolation",
|
||||
"coa": {
|
||||
"data": {
|
||||
"description": "Detects available indicators and routes them to dispatch url outbound traffic filtering playbooks. These playbooks will block the given urls. The output of the analysis will update any artifacts, tasks, and indicator tags.",
|
||||
"edges": [
|
||||
{
|
||||
"id": "port_0_to_port_3",
|
||||
"sourceNode": "0",
|
||||
"sourcePort": "0_out",
|
||||
"targetNode": "3",
|
||||
"targetPort": "3_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_6_to_port_5",
|
||||
"sourceNode": "6",
|
||||
"sourcePort": "6_out",
|
||||
"targetNode": "5",
|
||||
"targetPort": "5_in"
|
||||
},
|
||||
{
|
||||
"conditions": [
|
||||
{
|
||||
"index": 1
|
||||
}
|
||||
],
|
||||
"id": "port_3_to_port_7",
|
||||
"sourceNode": "3",
|
||||
"sourcePort": "3_out",
|
||||
"targetNode": "7",
|
||||
"targetPort": "7_in"
|
||||
},
|
||||
{
|
||||
"id": "port_5_to_port_8",
|
||||
"sourceNode": "5",
|
||||
"sourcePort": "5_out",
|
||||
"targetNode": "8",
|
||||
"targetPort": "8_in"
|
||||
},
|
||||
{
|
||||
"conditions": [
|
||||
{
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
"id": "port_8_to_port_13",
|
||||
"sourceNode": "8",
|
||||
"sourcePort": "8_out",
|
||||
"targetNode": "13",
|
||||
"targetPort": "13_in"
|
||||
},
|
||||
{
|
||||
"conditions": [
|
||||
{
|
||||
"index": 1
|
||||
}
|
||||
],
|
||||
"id": "port_8_to_port_9",
|
||||
"sourceNode": "8",
|
||||
"sourcePort": "8_out",
|
||||
"targetNode": "9",
|
||||
"targetPort": "9_in"
|
||||
},
|
||||
{
|
||||
"id": "port_12_to_port_1",
|
||||
"sourceNode": "12",
|
||||
"sourcePort": "12_out",
|
||||
"targetNode": "1",
|
||||
"targetPort": "1_in"
|
||||
},
|
||||
{
|
||||
"id": "port_13_to_port_14",
|
||||
"sourceNode": "13",
|
||||
"sourcePort": "13_out",
|
||||
"targetNode": "14",
|
||||
"targetPort": "14_in"
|
||||
},
|
||||
{
|
||||
"id": "port_14_to_port_12",
|
||||
"sourceNode": "14",
|
||||
"sourcePort": "14_out",
|
||||
"targetNode": "12",
|
||||
"targetPort": "12_in"
|
||||
}
|
||||
],
|
||||
"hash": "eed0927f579163be0a8a5756c72e1de1935a7840",
|
||||
"nodes": {
|
||||
"0": {
|
||||
"data": {
|
||||
"advanced": {
|
||||
"join": []
|
||||
},
|
||||
"functionName": "on_start",
|
||||
"id": "0",
|
||||
"type": "start"
|
||||
},
|
||||
"errors": {},
|
||||
"id": "0",
|
||||
"type": "start",
|
||||
"warnings": {},
|
||||
"x": 1000,
|
||||
"y": 179.9999999999999
|
||||
},
|
||||
"1": {
|
||||
"data": {
|
||||
"advanced": {
|
||||
"join": []
|
||||
},
|
||||
"functionName": "on_finish",
|
||||
"id": "1",
|
||||
"type": "end"
|
||||
},
|
||||
"errors": {},
|
||||
"id": "1",
|
||||
"type": "end",
|
||||
"warnings": {},
|
||||
"x": 1080,
|
||||
"y": 1320
|
||||
},
|
||||
"12": {
|
||||
"data": {
|
||||
"advanced": {
|
||||
"customName": "update isolation task",
|
||||
"customNameId": 0,
|
||||
"join": []
|
||||
},
|
||||
"customFunction": {
|
||||
"draftMode": false,
|
||||
"name": "workbook_task_update",
|
||||
"repoName": "community"
|
||||
},
|
||||
"functionId": 5,
|
||||
"functionName": "update_isolation_task",
|
||||
"id": "12",
|
||||
"selectMore": false,
|
||||
"type": "utility",
|
||||
"utilities": {
|
||||
"workbook_task_update": {
|
||||
"description": "Update a workbook task by task name or the task where the currently running playbook appears. Requires a task_name, container_id, and a note_title, note_content, owner, or status.",
|
||||
"fields": [
|
||||
{
|
||||
"dataTypes": [
|
||||
"*"
|
||||
],
|
||||
"description": "Name of a workbook task or keyword 'playbook' to update the task where the currently running playbook appears. (Required)",
|
||||
"inputType": "item",
|
||||
"label": "task_name",
|
||||
"name": "task_name",
|
||||
"placeholder": "my_task",
|
||||
"renderType": "datapath",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"dataTypes": [
|
||||
"*"
|
||||
],
|
||||
"description": "Note title. (Optional)",
|
||||
"inputType": "item",
|
||||
"label": "note_title",
|
||||
"name": "note_title",
|
||||
"placeholder": "My Title",
|
||||
"renderType": "datapath",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"dataTypes": [
|
||||
"*"
|
||||
],
|
||||
"description": "Note content. (Optional)",
|
||||
"inputType": "item",
|
||||
"label": "note_content",
|
||||
"name": "note_content",
|
||||
"placeholder": "My notes",
|
||||
"renderType": "datapath",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"dataTypes": [
|
||||
"*"
|
||||
],
|
||||
"description": "Accepts 'incomplete', 'in_progress, or 'complete'. (Optional)",
|
||||
"inputType": "item",
|
||||
"label": "status",
|
||||
"name": "status",
|
||||
"placeholder": "in_progress",
|
||||
"renderType": "datapath",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"dataTypes": [
|
||||
"*"
|
||||
],
|
||||
"description": "A user to assign as the task owner or keyword 'current\" to assign the task to the user that launched the playbook. (Optional)",
|
||||
"inputType": "item",
|
||||
"label": "owner",
|
||||
"name": "owner",
|
||||
"placeholder": "username",
|
||||
"renderType": "datapath",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"dataTypes": [
|
||||
"phantom container id"
|
||||
],
|
||||
"description": "The ID of a SOAR Container. (Required)",
|
||||
"inputType": "item",
|
||||
"label": "container",
|
||||
"name": "container",
|
||||
"placeholder": "container:id",
|
||||
"renderType": "datapath",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"label": "workbook_task_update",
|
||||
"name": "workbook_task_update"
|
||||
}
|
||||
},
|
||||
"utilityType": "custom_function",
|
||||
"values": {
|
||||
"workbook_task_update": {
|
||||
"container": "container:id",
|
||||
"note_content": "format_note:formatted_data",
|
||||
"note_title": "Dispatch URL Outbound Traffic Filtering Report",
|
||||
"owner": null,
|
||||
"status": "complete",
|
||||
"task_name": "playbook"
|
||||
}
|
||||
}
|
||||
},
|
||||
"errors": {},
|
||||
"id": "12",
|
||||
"type": "utility",
|
||||
"warnings": {},
|
||||
"x": 1060,
|
||||
"y": 1200
|
||||
},
|
||||
"13": {
|
||||
"data": {
|
||||
"advanced": {
|
||||
"customName": "tag indicators",
|
||||
"customNameId": 0,
|
||||
"join": []
|
||||
},
|
||||
"customFunction": {
|
||||
"draftMode": false,
|
||||
"name": "indicator_tag",
|
||||
"repoName": "community"
|
||||
},
|
||||
"functionId": 6,
|
||||
"functionName": "tag_indicators",
|
||||
"id": "13",
|
||||
"selectMore": false,
|
||||
"tab": "customFunctions",
|
||||
"type": "utility",
|
||||
"utilities": {
|
||||
"indicator_tag": {
|
||||
"description": "Tag an existing indicator record. Tags can be overwritten or appended.",
|
||||
"fields": [
|
||||
{
|
||||
"dataTypes": [
|
||||
"*"
|
||||
],
|
||||
"description": "Specifies the indicator which the tag will be added to. Supports a string indicator value or an indicator id.",
|
||||
"inputType": "item",
|
||||
"label": "indicator",
|
||||
"name": "indicator",
|
||||
"placeholder": "my_indicator",
|
||||
"renderType": "datapath",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"dataTypes": [
|
||||
"*"
|
||||
],
|
||||
"description": "Comma separated list of tags. Tags should only contain characters Aa-Zz, 0-9, '-', and '_'.",
|
||||
"inputType": "item",
|
||||
"label": "tags",
|
||||
"name": "tags",
|
||||
"placeholder": "tag1,tag2,...,tagk",
|
||||
"renderType": "datapath",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"dataTypes": [],
|
||||
"description": "Either True or False with default as False. If set to True, existing tags on the indicator record will be replaced by the provided input. If set to False, the new tags will be appended to the existing indicator tags.",
|
||||
"inputType": "item",
|
||||
"label": "overwrite",
|
||||
"name": "overwrite",
|
||||
"placeholder": "False",
|
||||
"renderType": "datapath",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"label": "indicator_tag",
|
||||
"name": "indicator_tag"
|
||||
}
|
||||
},
|
||||
"utilityType": "custom_function",
|
||||
"values": {
|
||||
"indicator_tag": {
|
||||
"indicator": "dispatch_url_outbound_traffic_filtering_playbooks:playbook_output:observable.value",
|
||||
"overwrite": null,
|
||||
"tags": "blocked"
|
||||
}
|
||||
}
|
||||
},
|
||||
"errors": {},
|
||||
"id": "13",
|
||||
"type": "utility",
|
||||
"warnings": {},
|
||||
"x": 1060,
|
||||
"y": 940
|
||||
},
|
||||
"14": {
|
||||
"data": {
|
||||
"advanced": {
|
||||
"customName": "format note",
|
||||
"customNameId": 0,
|
||||
"description": "Format a note that merges together normalized data. ",
|
||||
"join": [],
|
||||
"note": "Format a note that merges together normalized data. "
|
||||
},
|
||||
"functionId": 1,
|
||||
"functionName": "format_note",
|
||||
"id": "14",
|
||||
"parameters": [
|
||||
"dispatch_url_outbound_traffic_filtering_playbooks:playbook_output:observable.value",
|
||||
"dispatch_url_outbound_traffic_filtering_playbooks:playbook_output:observable.status",
|
||||
"dispatch_url_outbound_traffic_filtering_playbooks:playbook_output:observable.source"
|
||||
],
|
||||
"template": "Splunk SOAR blocked the following urls:\n\n| url | status | source |\n| --- | --- | --- |\n%%\n| {0} | {1} | {2} |\n%%\n",
|
||||
"type": "format"
|
||||
},
|
||||
"errors": {},
|
||||
"id": "14",
|
||||
"type": "format",
|
||||
"warnings": {},
|
||||
"x": 1060,
|
||||
"y": 1060
|
||||
},
|
||||
"3": {
|
||||
"data": {
|
||||
"advanced": {
|
||||
"customName": "artifact_exists",
|
||||
"customNameId": 0,
|
||||
"description": "Checks if a artifact exists",
|
||||
"join": [],
|
||||
"note": "Checks if a artifact exists"
|
||||
},
|
||||
"conditions": [
|
||||
{
|
||||
"comparisons": [
|
||||
{
|
||||
"conditionIndex": 0,
|
||||
"op": "!=",
|
||||
"param": "artifact:*.id",
|
||||
"value": "None"
|
||||
}
|
||||
],
|
||||
"conditionIndex": 0,
|
||||
"customName": "artifact exists",
|
||||
"display": "If",
|
||||
"logic": "and",
|
||||
"type": "if"
|
||||
},
|
||||
{
|
||||
"comparisons": [
|
||||
{
|
||||
"conditionIndex": 1,
|
||||
"op": "==",
|
||||
"param": "",
|
||||
"value": ""
|
||||
}
|
||||
],
|
||||
"conditionIndex": 1,
|
||||
"customName": "artifact does not exist",
|
||||
"display": "Else",
|
||||
"logic": "and",
|
||||
"type": "else"
|
||||
}
|
||||
],
|
||||
"functionId": 1,
|
||||
"functionName": "artifact_exists",
|
||||
"id": "3",
|
||||
"type": "decision"
|
||||
},
|
||||
"errors": {},
|
||||
"id": "3",
|
||||
"type": "decision",
|
||||
"warnings": {},
|
||||
"x": 1060,
|
||||
"y": 280
|
||||
},
|
||||
"5": {
|
||||
"data": {
|
||||
"advanced": {
|
||||
"customName": "dispatch url outbound traffic filtering playbooks",
|
||||
"customNameId": 0,
|
||||
"join": []
|
||||
},
|
||||
"functionId": 1,
|
||||
"functionName": "dispatch_url_outbound_traffic_filtering_playbooks",
|
||||
"id": "5",
|
||||
"inputs": {
|
||||
"artifact_ids_include": {
|
||||
"datapaths": [
|
||||
"filtered-data:filter_new_artifacts:condition_1:artifact:*.id"
|
||||
],
|
||||
"deduplicate": false
|
||||
},
|
||||
"indicator_tags_exclude": {
|
||||
"datapaths": [],
|
||||
"deduplicate": false
|
||||
},
|
||||
"indicator_tags_include": {
|
||||
"datapaths": [],
|
||||
"deduplicate": false
|
||||
},
|
||||
"playbook_repo": {
|
||||
"datapaths": [],
|
||||
"deduplicate": false
|
||||
},
|
||||
"playbook_tags": {
|
||||
"datapaths": [],
|
||||
"deduplicate": false
|
||||
}
|
||||
},
|
||||
"playbookName": "dispatch_input_playbooks",
|
||||
"playbookRepo": 1,
|
||||
"playbookRepoName": "community",
|
||||
"playbookType": "data",
|
||||
"synchronous": true,
|
||||
"type": "playbook"
|
||||
},
|
||||
"errors": {},
|
||||
"id": "5",
|
||||
"type": "playbook",
|
||||
"warnings": {},
|
||||
"x": 880,
|
||||
"y": 600
|
||||
},
|
||||
"6": {
|
||||
"data": {
|
||||
"advanced": {
|
||||
"customName": "filter_new_artifacts",
|
||||
"customNameId": 0,
|
||||
"description": "Only dispatch playbooks against new artifacts.",
|
||||
"join": [],
|
||||
"note": "Only dispatch playbooks against new artifacts."
|
||||
},
|
||||
"conditions": [
|
||||
{
|
||||
"comparisons": [
|
||||
{
|
||||
"conditionIndex": 0,
|
||||
"op": "!=",
|
||||
"param": "artifact:*.id",
|
||||
"value": "None"
|
||||
}
|
||||
],
|
||||
"conditionIndex": 0,
|
||||
"customName": "artifact exists",
|
||||
"logic": "and"
|
||||
}
|
||||
],
|
||||
"functionId": 3,
|
||||
"functionName": "filter_new_artifacts",
|
||||
"id": "6",
|
||||
"type": "filter"
|
||||
},
|
||||
"errors": {},
|
||||
"id": "6",
|
||||
"type": "filter",
|
||||
"warnings": {},
|
||||
"x": 940,
|
||||
"y": 420
|
||||
},
|
||||
"7": {
|
||||
"data": {
|
||||
"advanced": {
|
||||
"customName": "comment no new artifacts",
|
||||
"customNameId": 0,
|
||||
"description": "Add comment when no new artifacts exists.",
|
||||
"join": [],
|
||||
"note": "Add comment when no new artifacts exists."
|
||||
},
|
||||
"functionId": 1,
|
||||
"functionName": "comment_no_new_artifacts",
|
||||
"id": "7",
|
||||
"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": "No new artifacts found."
|
||||
}
|
||||
}
|
||||
},
|
||||
"errors": {},
|
||||
"id": "7",
|
||||
"type": "utility",
|
||||
"warnings": {},
|
||||
"x": 1140,
|
||||
"y": 420
|
||||
},
|
||||
"8": {
|
||||
"data": {
|
||||
"advanced": {
|
||||
"customName": "outputs decision",
|
||||
"customNameId": 0,
|
||||
"description": "Determine if outputs exist.",
|
||||
"join": [],
|
||||
"note": "Determine if outputs exist."
|
||||
},
|
||||
"conditions": [
|
||||
{
|
||||
"comparisons": [
|
||||
{
|
||||
"conditionIndex": 0,
|
||||
"op": "!=",
|
||||
"param": "dispatch_url_outbound_traffic_filtering_playbooks:playbook_output:observable",
|
||||
"value": "None"
|
||||
}
|
||||
],
|
||||
"conditionIndex": 0,
|
||||
"customName": "observable exists",
|
||||
"display": "If",
|
||||
"logic": "and",
|
||||
"type": "if"
|
||||
},
|
||||
{
|
||||
"comparisons": [
|
||||
{
|
||||
"conditionIndex": 1,
|
||||
"op": "==",
|
||||
"param": "",
|
||||
"value": ""
|
||||
}
|
||||
],
|
||||
"conditionIndex": 1,
|
||||
"customName": "observable does not exist",
|
||||
"display": "Else",
|
||||
"logic": "and",
|
||||
"type": "else"
|
||||
}
|
||||
],
|
||||
"functionId": 2,
|
||||
"functionName": "outputs_decision",
|
||||
"id": "8",
|
||||
"type": "decision"
|
||||
},
|
||||
"errors": {},
|
||||
"id": "8",
|
||||
"type": "decision",
|
||||
"warnings": {},
|
||||
"x": 960,
|
||||
"y": 760
|
||||
},
|
||||
"9": {
|
||||
"data": {
|
||||
"advanced": {
|
||||
"customName": "comment no observables",
|
||||
"customNameId": 0,
|
||||
"description": "Add comment when no observables were generated.",
|
||||
"join": [],
|
||||
"note": "Add comment when no observables were generated."
|
||||
},
|
||||
"functionId": 2,
|
||||
"functionName": "comment_no_observables",
|
||||
"id": "9",
|
||||
"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": "No observable data found from dispatched playbooks."
|
||||
}
|
||||
}
|
||||
},
|
||||
"errors": {},
|
||||
"id": "9",
|
||||
"type": "utility",
|
||||
"warnings": {},
|
||||
"x": 680,
|
||||
"y": 960
|
||||
}
|
||||
},
|
||||
"notes": "Outputs: \n- Concludes task\n- tags indicators"
|
||||
},
|
||||
"input_spec": null,
|
||||
"output_spec": null,
|
||||
"playbook_type": "automation",
|
||||
"python_version": "3",
|
||||
"schema": "5.0.9",
|
||||
"version": "6.0.0.114895"
|
||||
},
|
||||
"create_time": "2023-05-22T10:13:00.300558+00:00",
|
||||
"draft_mode": false,
|
||||
"labels": [
|
||||
"*"
|
||||
],
|
||||
"tags": [
|
||||
"D3-OTF"
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 92 KiB |
@@ -0,0 +1,285 @@
|
||||
"""
|
||||
Detects available indicators and routes them to dispatch url outbound traffic filtering playbooks. These playbooks will block the given urls. The output of the analysis will update any artifacts, tasks, and indicator tags.
|
||||
"""
|
||||
|
||||
|
||||
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 'artifact_exists' block
|
||||
artifact_exists(container=container)
|
||||
|
||||
return
|
||||
|
||||
@phantom.playbook_block()
|
||||
def artifact_exists(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
|
||||
phantom.debug("artifact_exists() called")
|
||||
|
||||
################################################################################
|
||||
# Checks if a artifact exists
|
||||
################################################################################
|
||||
|
||||
# check for 'if' condition 1
|
||||
found_match_1 = phantom.decision(
|
||||
container=container,
|
||||
conditions=[
|
||||
["artifact:*.id", "!=", None]
|
||||
])
|
||||
|
||||
# call connected blocks if condition 1 matched
|
||||
if found_match_1:
|
||||
filter_new_artifacts(action=action, success=success, container=container, results=results, handle=handle)
|
||||
return
|
||||
|
||||
# check for 'else' condition 2
|
||||
comment_no_new_artifacts(action=action, success=success, container=container, results=results, handle=handle)
|
||||
|
||||
return
|
||||
|
||||
|
||||
@phantom.playbook_block()
|
||||
def dispatch_url_outbound_traffic_filtering_playbooks(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
|
||||
phantom.debug("dispatch_url_outbound_traffic_filtering_playbooks() called")
|
||||
|
||||
filtered_artifact_0_data_filter_new_artifacts = phantom.collect2(container=container, datapath=["filtered-data:filter_new_artifacts:condition_1:artifact:*.id"])
|
||||
|
||||
filtered_artifact_0__id = [item[0] for item in filtered_artifact_0_data_filter_new_artifacts]
|
||||
|
||||
inputs = {
|
||||
"playbook_repo": [],
|
||||
"playbook_tags": [],
|
||||
"artifact_ids_include": filtered_artifact_0__id,
|
||||
"indicator_tags_exclude": [],
|
||||
"indicator_tags_include": [],
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## Custom Code Start
|
||||
################################################################################
|
||||
|
||||
# Write your custom code here...
|
||||
|
||||
################################################################################
|
||||
## Custom Code End
|
||||
################################################################################
|
||||
|
||||
# call playbook "community/dispatch_input_playbooks", returns the playbook_run_id
|
||||
playbook_run_id = phantom.playbook("community/dispatch_input_playbooks", container=container, name="dispatch_url_outbound_traffic_filtering_playbooks", callback=outputs_decision, inputs=inputs)
|
||||
|
||||
return
|
||||
|
||||
|
||||
@phantom.playbook_block()
|
||||
def filter_new_artifacts(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
|
||||
phantom.debug("filter_new_artifacts() called")
|
||||
|
||||
################################################################################
|
||||
# Only dispatch playbooks against new artifacts.
|
||||
################################################################################
|
||||
|
||||
# collect filtered artifact ids and results for 'if' condition 1
|
||||
matched_artifacts_1, matched_results_1 = phantom.condition(
|
||||
container=container,
|
||||
conditions=[
|
||||
["artifact:*.id", "!=", None]
|
||||
],
|
||||
name="filter_new_artifacts:condition_1")
|
||||
|
||||
# call connected blocks if filtered artifacts or results
|
||||
if matched_artifacts_1 or matched_results_1:
|
||||
dispatch_url_outbound_traffic_filtering_playbooks(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 comment_no_new_artifacts(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
|
||||
phantom.debug("comment_no_new_artifacts() called")
|
||||
|
||||
################################################################################
|
||||
# Add comment when no new artifacts exists.
|
||||
################################################################################
|
||||
|
||||
################################################################################
|
||||
## Custom Code Start
|
||||
################################################################################
|
||||
|
||||
# Write your custom code here...
|
||||
|
||||
################################################################################
|
||||
## Custom Code End
|
||||
################################################################################
|
||||
|
||||
phantom.comment(container=container, comment="No new artifacts found.")
|
||||
|
||||
return
|
||||
|
||||
|
||||
@phantom.playbook_block()
|
||||
def outputs_decision(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
|
||||
phantom.debug("outputs_decision() called")
|
||||
|
||||
################################################################################
|
||||
# Determine if outputs exist.
|
||||
################################################################################
|
||||
|
||||
# check for 'if' condition 1
|
||||
found_match_1 = phantom.decision(
|
||||
container=container,
|
||||
conditions=[
|
||||
["dispatch_url_outbound_traffic_filtering_playbooks:playbook_output:observable", "!=", None]
|
||||
])
|
||||
|
||||
# call connected blocks if condition 1 matched
|
||||
if found_match_1:
|
||||
tag_indicators(action=action, success=success, container=container, results=results, handle=handle)
|
||||
return
|
||||
|
||||
# check for 'else' condition 2
|
||||
comment_no_observables(action=action, success=success, container=container, results=results, handle=handle)
|
||||
|
||||
return
|
||||
|
||||
|
||||
@phantom.playbook_block()
|
||||
def comment_no_observables(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
|
||||
phantom.debug("comment_no_observables() called")
|
||||
|
||||
################################################################################
|
||||
# Add comment when no observables were generated.
|
||||
################################################################################
|
||||
|
||||
################################################################################
|
||||
## Custom Code Start
|
||||
################################################################################
|
||||
|
||||
# Write your custom code here...
|
||||
|
||||
################################################################################
|
||||
## Custom Code End
|
||||
################################################################################
|
||||
|
||||
phantom.comment(container=container, comment="No observable data found from dispatched playbooks.")
|
||||
|
||||
return
|
||||
|
||||
|
||||
@phantom.playbook_block()
|
||||
def update_isolation_task(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
|
||||
phantom.debug("update_isolation_task() called")
|
||||
|
||||
id_value = container.get("id", None)
|
||||
format_note = phantom.get_format_data(name="format_note")
|
||||
|
||||
parameters = []
|
||||
|
||||
parameters.append({
|
||||
"owner": None,
|
||||
"status": "complete",
|
||||
"container": id_value,
|
||||
"task_name": "playbook",
|
||||
"note_title": "Dispatch URL Outbound Traffic Filtering Report",
|
||||
"note_content": format_note,
|
||||
})
|
||||
|
||||
################################################################################
|
||||
## Custom Code Start
|
||||
################################################################################
|
||||
|
||||
# Write your custom code here...
|
||||
|
||||
################################################################################
|
||||
## Custom Code End
|
||||
################################################################################
|
||||
|
||||
phantom.custom_function(custom_function="community/workbook_task_update", parameters=parameters, name="update_isolation_task")
|
||||
|
||||
return
|
||||
|
||||
|
||||
@phantom.playbook_block()
|
||||
def tag_indicators(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
|
||||
phantom.debug("tag_indicators() called")
|
||||
|
||||
dispatch_url_outbound_traffic_filtering_playbooks_output_observable = phantom.collect2(container=container, datapath=["dispatch_url_outbound_traffic_filtering_playbooks:playbook_output:observable.value"])
|
||||
|
||||
parameters = []
|
||||
|
||||
# build parameters list for 'tag_indicators' call
|
||||
for dispatch_url_outbound_traffic_filtering_playbooks_output_observable_item in dispatch_url_outbound_traffic_filtering_playbooks_output_observable:
|
||||
parameters.append({
|
||||
"tags": "blocked",
|
||||
"indicator": dispatch_url_outbound_traffic_filtering_playbooks_output_observable_item[0],
|
||||
"overwrite": None,
|
||||
})
|
||||
|
||||
################################################################################
|
||||
## Custom Code Start
|
||||
################################################################################
|
||||
|
||||
# Write your custom code here...
|
||||
|
||||
################################################################################
|
||||
## Custom Code End
|
||||
################################################################################
|
||||
|
||||
phantom.custom_function(custom_function="community/indicator_tag", parameters=parameters, name="tag_indicators", callback=format_note)
|
||||
|
||||
return
|
||||
|
||||
|
||||
@phantom.playbook_block()
|
||||
def format_note(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
|
||||
phantom.debug("format_note() called")
|
||||
|
||||
################################################################################
|
||||
# Format a note that merges together normalized data.
|
||||
################################################################################
|
||||
|
||||
template = """Splunk SOAR blocked the following urls:\n\n| url | status | source |\n| --- | --- | --- |\n%%\n| {0} | {1} | {2} |\n%%\n"""
|
||||
|
||||
# parameter list for template variable replacement
|
||||
parameters = [
|
||||
"dispatch_url_outbound_traffic_filtering_playbooks:playbook_output:observable.value",
|
||||
"dispatch_url_outbound_traffic_filtering_playbooks:playbook_output:observable.status",
|
||||
"dispatch_url_outbound_traffic_filtering_playbooks:playbook_output:observable.source"
|
||||
]
|
||||
|
||||
################################################################################
|
||||
## Custom Code Start
|
||||
################################################################################
|
||||
|
||||
# Write your custom code here...
|
||||
|
||||
################################################################################
|
||||
## Custom Code End
|
||||
################################################################################
|
||||
|
||||
phantom.format(container=container, template=template, parameters=parameters, name="format_note")
|
||||
|
||||
update_isolation_task(container=container)
|
||||
|
||||
return
|
||||
|
||||
|
||||
@phantom.playbook_block()
|
||||
def on_finish(container, summary):
|
||||
phantom.debug("on_finish() called")
|
||||
|
||||
################################################################################
|
||||
## Custom Code Start
|
||||
################################################################################
|
||||
|
||||
# Write your custom code here...
|
||||
|
||||
################################################################################
|
||||
## Custom Code End
|
||||
################################################################################
|
||||
|
||||
return
|
||||
@@ -0,0 +1,19 @@
|
||||
name: URL Outbound Traffic Filtering Dispatch
|
||||
id: 83bbe505-4636-4f60-a37b-86f1234d8567
|
||||
version: 1
|
||||
date: '2023-05-22'
|
||||
author: Patrick Bareiss, Splunk
|
||||
type: Response
|
||||
description: Accepts a list of URLs and blocks them. Generates a global report and list of observables.
|
||||
playbook: URL_Outbound_Traffic_Filtering_Dispatch
|
||||
how_to_implement: This playbook looks for artifacts and then dispatches the community denylisting playbooks. This playbook takes the output of those playbooks and nicely formats them into notes and tags indicators with their results.
|
||||
references:
|
||||
- https://d3fend.mitre.org/technique/d3f:OutboundTrafficFiltering/
|
||||
app_list: []
|
||||
tags:
|
||||
platform_tags: []
|
||||
playbook_type: Automation
|
||||
vpe_type: Modern
|
||||
playbook_fields: []
|
||||
product:
|
||||
- Splunk SOAR
|
||||
Reference in New Issue
Block a user