Branch was auto-updated.

This commit is contained in:
srv-rr-gh-researchbt
2023-06-21 07:56:15 -07:00
committed by GitHub
4 changed files with 1004 additions and 0 deletions
@@ -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