mirror of
https://github.com/splunk/security_content
synced 2026-06-08 17:32:49 +00:00
604 lines
32 KiB
JSON
604 lines
32 KiB
JSON
{
|
|
"blockly": false,
|
|
"blockly_xml": "<xml></xml>",
|
|
"category": "Related Tickets Search",
|
|
"coa": {
|
|
"data": {
|
|
"description": "Accepts a user or device and identifies if related tickets exists in a timeframe of last 30 days. Generates a global report and list of observables.",
|
|
"edges": [
|
|
{
|
|
"id": "port_6_to_port_8",
|
|
"sourceNode": "6",
|
|
"sourcePort": "6_out",
|
|
"targetNode": "8",
|
|
"targetPort": "8_in"
|
|
},
|
|
{
|
|
"id": "port_0_to_port_6",
|
|
"sourceNode": "0",
|
|
"sourcePort": "0_out",
|
|
"targetNode": "6",
|
|
"targetPort": "6_in"
|
|
},
|
|
{
|
|
"conditions": [
|
|
{
|
|
"index": 0
|
|
}
|
|
],
|
|
"id": "port_10_to_port_9",
|
|
"sourceNode": "10",
|
|
"sourcePort": "10_out",
|
|
"targetNode": "9",
|
|
"targetPort": "9_in"
|
|
},
|
|
{
|
|
"id": "port_8_to_port_17",
|
|
"sourceNode": "8",
|
|
"sourcePort": "8_out",
|
|
"targetNode": "17",
|
|
"targetPort": "17_in"
|
|
},
|
|
{
|
|
"id": "port_17_to_port_10",
|
|
"sourceNode": "17",
|
|
"sourcePort": "17_out",
|
|
"targetNode": "10",
|
|
"targetPort": "10_in"
|
|
},
|
|
{
|
|
"id": "port_9_to_port_19",
|
|
"sourceNode": "9",
|
|
"sourcePort": "9_out",
|
|
"targetNode": "19",
|
|
"targetPort": "19_in"
|
|
},
|
|
{
|
|
"id": "port_19_to_port_14",
|
|
"sourceNode": "19",
|
|
"sourcePort": "19_out",
|
|
"targetNode": "14",
|
|
"targetPort": "14_in"
|
|
},
|
|
{
|
|
"id": "port_14_to_port_16",
|
|
"sourceNode": "14",
|
|
"sourcePort": "14_out",
|
|
"targetNode": "16",
|
|
"targetPort": "16_in"
|
|
},
|
|
{
|
|
"id": "port_16_to_port_25",
|
|
"sourceNode": "16",
|
|
"sourcePort": "16_out",
|
|
"targetNode": "25",
|
|
"targetPort": "25_in"
|
|
},
|
|
{
|
|
"id": "port_25_to_port_1",
|
|
"sourceNode": "25",
|
|
"sourcePort": "25_out",
|
|
"targetNode": "1",
|
|
"targetPort": "1_in"
|
|
}
|
|
],
|
|
"hash": "0c56bc09507f0a442ed7f70f357f51ae6d3983fe",
|
|
"nodes": {
|
|
"0": {
|
|
"data": {
|
|
"advanced": {
|
|
"join": []
|
|
},
|
|
"functionName": "on_start",
|
|
"id": "0",
|
|
"type": "start"
|
|
},
|
|
"errors": {},
|
|
"id": "0",
|
|
"type": "start",
|
|
"warnings": {},
|
|
"x": 19.999999999999986,
|
|
"y": -1.9184653865522705e-13
|
|
},
|
|
"1": {
|
|
"data": {
|
|
"advanced": {
|
|
"join": []
|
|
},
|
|
"functionName": "on_finish",
|
|
"id": "1",
|
|
"type": "end"
|
|
},
|
|
"errors": {},
|
|
"id": "1",
|
|
"type": "end",
|
|
"warnings": {},
|
|
"x": 19.999999999999986,
|
|
"y": 1708
|
|
},
|
|
"10": {
|
|
"data": {
|
|
"advanced": {
|
|
"customName": "input filter",
|
|
"customNameId": 0,
|
|
"delimiter": ",",
|
|
"delimiter_enabled": true,
|
|
"description": "Creates a dataset without None values.",
|
|
"join": [],
|
|
"note": "Creates a dataset without None values."
|
|
},
|
|
"conditions": [
|
|
{
|
|
"comparisons": [
|
|
{
|
|
"conditionIndex": 0,
|
|
"op": "!=",
|
|
"param": "playbook_input:search_term",
|
|
"value": "None"
|
|
}
|
|
],
|
|
"conditionIndex": 0,
|
|
"customName": "search term exists",
|
|
"logic": "and"
|
|
}
|
|
],
|
|
"functionId": 1,
|
|
"functionName": "input_filter",
|
|
"id": "10",
|
|
"type": "filter"
|
|
},
|
|
"errors": {},
|
|
"id": "10",
|
|
"type": "filter",
|
|
"warnings": {},
|
|
"x": 60,
|
|
"y": 622
|
|
},
|
|
"14": {
|
|
"data": {
|
|
"advanced": {
|
|
"customName": "process results",
|
|
"customNameId": 0,
|
|
"description": "Iterates through the results of the run ticket query to link playbook input search term to their associated tickets.",
|
|
"join": [],
|
|
"note": "Iterates through the results of the run ticket query to link playbook input search term to their associated tickets."
|
|
},
|
|
"functionId": 3,
|
|
"functionName": "process_results",
|
|
"id": "14",
|
|
"inputParameters": [
|
|
"filtered-data:input_filter:condition_1:playbook_input:search_term",
|
|
"run_ticket_query:action_result.data",
|
|
"run_ticket_query:action_result.parameter.query_table"
|
|
],
|
|
"outputVariables": [
|
|
"output"
|
|
],
|
|
"type": "code"
|
|
},
|
|
"errors": {},
|
|
"id": "14",
|
|
"type": "code",
|
|
"userCode": " process_results__output = {}\n for search_term in filtered_input_0_search_term_values:\n process_results__output[search_term] = []\n for result, query_table in zip(run_ticket_query_result_item_0, run_ticket_query_parameter_query_table):\n if not isinstance(result, list):\n list_result = [result]\n else:\n list_result = result\n for result_item in list_result:\n result_item_values = [item.lower() for item in result_item.values() if isinstance(item, str)]\n match = False\n for string_value in result_item_values:\n if search_term.lower() in string_value:\n match = True\n break\n if match:\n process_results__output[search_term].append({**result_item, **{\"ticket_type\": query_table}})\n\n",
|
|
"warnings": {},
|
|
"x": 1.4210854715202004e-14,
|
|
"y": 1158
|
|
},
|
|
"16": {
|
|
"customCode": null,
|
|
"data": {
|
|
"advanced": {
|
|
"customName": "build output",
|
|
"customNameId": 0,
|
|
"description": "Extract relevant data and add them to an observable array.",
|
|
"join": [],
|
|
"note": "Extract relevant data and add them to an observable array."
|
|
},
|
|
"functionId": 5,
|
|
"functionName": "build_output",
|
|
"id": "16",
|
|
"inputParameters": [
|
|
"process_results:custom_function:output"
|
|
],
|
|
"outputVariables": [
|
|
"observable_array",
|
|
"name",
|
|
"number",
|
|
"message",
|
|
"start_time",
|
|
"end_time",
|
|
"assignee",
|
|
"creator_name",
|
|
"state",
|
|
"matched_fields",
|
|
"source_link",
|
|
"source"
|
|
],
|
|
"type": "code"
|
|
},
|
|
"errors": {},
|
|
"id": "16",
|
|
"type": "code",
|
|
"userCode": " import re \n \n build_output__observable_array = []\n build_output__name = []\n build_output__number = []\n build_output__message = []\n build_output__start_time = []\n build_output__end_time = []\n build_output__assignee = []\n build_output__creator_name = []\n build_output__state = []\n build_output__matched_fields = []\n build_output__source_link = []\n build_output__source = []\n \n def generate_ticket_link(sample_url, ticket_type, sys_id):\n extract_host = re.search(r\"https*:\\/\\/[^\\/]+\", sample_url).group(0)\n extract_host += f\"/nav_to.do?uri={ticket_type}.do?sys_id={sys_id}\"\n return extract_host\n \n for key in process_results__output.keys():\n \n for value in process_results__output[key]:\n assigned_to = None\n caller_id = None\n matched_fields = []\n if value.get(\"assigned_to\"):\n assigned_to = value[\"assigned_to\"][\"display_value\"]\n if value.get(\"caller_id\"):\n caller_id = value[\"caller_id\"][\"display_value\"]\n \n sample_link = None\n for k, v in value.items():\n # generate matched fields where the searched entity appears\n if isinstance(v, str) and key.lower() in v.lower():\n matched_fields.append(k)\n # search for any link sample:\n if isinstance(v, dict):\n sample_link = v.get('link')\n \n source_link = generate_ticket_link(sample_link, value['ticket_type'], value['sys_id'])\n observable_object = {\n \"value\": key,\n \"ticket\": {\n \"name\": value[\"short_description\"],\n \"id\": value[\"sys_id\"],\n \"number\": value[\"number\"],\n \"message\": json.dumps(value[\"description\"]),\n \"start_time\": value[\"sys_created_on\"],\n \"end_time\": value[\"closed_at\"],\n \"assigned_to\": assigned_to,\n \"creator_name\": caller_id,\n \"state\": value[\"state\"],\n \"notes\": [value[\"work_notes\"]],\n \"comments\": [value[\"comments\"]]\n },\n \"matched_fields\": matched_fields,\n \"source\": \"ServiceNow\",\n \"source_link\": source_link\n }\n build_output__observable_array.append(observable_object)\n build_output__name.append(value[\"short_description\"])\n build_output__number.append(value[\"number\"])\n build_output__message.append(json.dumps(value[\"description\"])) # eliminate new line issues\n build_output__start_time.append(value[\"sys_created_on\"])\n build_output__end_time.append(value[\"closed_at\"])\n build_output__assignee.append(assigned_to)\n build_output__creator_name.append(caller_id)\n build_output__state.append(value[\"state\"])\n build_output__matched_fields.append(matched_fields)\n build_output__source.append(\"ServiceNow\")\n build_output__source_link.append(source_link)\n #phantom.debug(observable_object)\n\n",
|
|
"warnings": {},
|
|
"x": 1.4210854715202004e-14,
|
|
"y": 1352
|
|
},
|
|
"17": {
|
|
"data": {
|
|
"advanced": {
|
|
"customName": "calculate earliest time",
|
|
"customNameId": 0,
|
|
"join": [],
|
|
"note": "Converts the container create time into a different datetime string compatible with ServiceNow."
|
|
},
|
|
"customFunction": {
|
|
"draftMode": false,
|
|
"name": "datetime_modify",
|
|
"repoName": "community"
|
|
},
|
|
"functionId": 2,
|
|
"functionName": "calculate_earliest_time",
|
|
"id": "17",
|
|
"loop": {
|
|
"enabled": false,
|
|
"exitAfterUnit": "m",
|
|
"exitAfterValue": 10,
|
|
"exitConditionEnabled": false,
|
|
"exitLoopAfter": 2,
|
|
"pauseUnit": "m",
|
|
"pauseValue": 2
|
|
},
|
|
"selectMore": false,
|
|
"type": "utility",
|
|
"utilities": {
|
|
"datetime_modify": {
|
|
"description": "Change a timestamp by adding or subtracting minutes, hours, or days.",
|
|
"fields": [
|
|
{
|
|
"dataTypes": [
|
|
""
|
|
],
|
|
"description": "The datetime to modify, which should be provided in a string format determined by input_format_string",
|
|
"inputType": "item",
|
|
"label": "input_datetime",
|
|
"name": "input_datetime",
|
|
"placeholder": "2020-06-27T14:53:08.219016Z",
|
|
"renderType": "datapath",
|
|
"required": false
|
|
},
|
|
{
|
|
"dataTypes": [],
|
|
"description": "The format string to use for the input according to the Python's datetime.strptime() formatting rules. If none is provided the default will be '%Y-%m-%dT%H:%M:%S.%fZ'. In addition to strptime() formats, the special format \"epoch\" can be used to accept unix epoch timestamps.",
|
|
"inputType": "item",
|
|
"label": "input_format_string",
|
|
"name": "input_format_string",
|
|
"placeholder": "%Y-%m-%dT%H:%M:%S.%fZ",
|
|
"renderType": "datapath",
|
|
"required": false
|
|
},
|
|
{
|
|
"dataTypes": [
|
|
""
|
|
],
|
|
"description": "Choose a unit to modify the date by, which must be either seconds, minutes, hours, or days. If none is provided the default will be 'minutes'",
|
|
"inputType": "item",
|
|
"label": "modification_unit",
|
|
"name": "modification_unit",
|
|
"placeholder": "minutes",
|
|
"renderType": "datapath",
|
|
"required": false
|
|
},
|
|
{
|
|
"dataTypes": [],
|
|
"description": "The number of seconds, minutes, hours, or days to add or subtract. Use a negative number such as -1.5 to subtract time. Defaults to zero.",
|
|
"inputType": "item",
|
|
"label": "amount_to_modify",
|
|
"name": "amount_to_modify",
|
|
"placeholder": "0",
|
|
"renderType": "datapath",
|
|
"required": false
|
|
},
|
|
{
|
|
"dataTypes": [],
|
|
"description": "The format string to use for the output according to the Python's datetime.strftime() formatting rules. If none is provided the default will be '%Y-%m-%dT%H:%M:%S.%fZ'.",
|
|
"inputType": "item",
|
|
"label": "output_format_string",
|
|
"name": "output_format_string",
|
|
"placeholder": "%Y-%m-%dT%H:%M:%S.%fZ",
|
|
"renderType": "datapath",
|
|
"required": false
|
|
}
|
|
],
|
|
"label": "datetime_modify",
|
|
"name": "datetime_modify"
|
|
}
|
|
},
|
|
"utilityType": "custom_function",
|
|
"values": {
|
|
"datetime_modify": {
|
|
"amount_to_modify": "-30",
|
|
"input_datetime": "container:create_time",
|
|
"input_format_string": "%Y-%m-%d %H:%M:%S.%f+00",
|
|
"modification_unit": "days",
|
|
"output_format_string": "'%Y-%m-%d','%H:%M:%S'"
|
|
}
|
|
}
|
|
},
|
|
"errors": {},
|
|
"id": "17",
|
|
"type": "utility",
|
|
"warnings": {},
|
|
"x": 1.4210854715202004e-14,
|
|
"y": 474
|
|
},
|
|
"19": {
|
|
"data": {
|
|
"action": "run query",
|
|
"actionType": "investigate",
|
|
"advanced": {
|
|
"customName": "run ticket query",
|
|
"customNameId": 0,
|
|
"description": "Perform a text search match within ServiceNow.",
|
|
"join": [],
|
|
"note": "Perform a text search match within ServiceNow."
|
|
},
|
|
"connector": "ServiceNow",
|
|
"connectorConfigs": [
|
|
"servicenow"
|
|
],
|
|
"connectorId": "a590c3bc-ca41-4a0e-b063-8066ca868794",
|
|
"connectorVersion": "v1",
|
|
"functionId": 3,
|
|
"functionName": "run_ticket_query",
|
|
"id": "19",
|
|
"loop": {
|
|
"enabled": false,
|
|
"exitAfterUnit": "m",
|
|
"exitAfterValue": 10,
|
|
"exitConditionEnabled": false,
|
|
"exitLoopAfter": 2,
|
|
"pauseUnit": "m",
|
|
"pauseValue": 2
|
|
},
|
|
"parameters": {
|
|
"max_results": "100",
|
|
"query": {
|
|
"functionId": 3,
|
|
"parameters": [
|
|
"space_delimiter_input:formatted_data",
|
|
"calculate_earliest_time:custom_function_result.data.datetime_string"
|
|
],
|
|
"template": "sysparm_query=active=true^IR_OR_QUERY={0}^opened_at>javascript:gs.dateGenerate({1})&sysparm_display_value=true \n\n"
|
|
},
|
|
"query_table": "convert_table_list:custom_function_result.data.output"
|
|
},
|
|
"requiredParameters": [
|
|
{
|
|
"data_type": "string",
|
|
"field": "query"
|
|
},
|
|
{
|
|
"data_type": "numeric",
|
|
"default": 100,
|
|
"field": "max_results"
|
|
},
|
|
{
|
|
"data_type": "string",
|
|
"field": "query_table"
|
|
}
|
|
],
|
|
"type": "action"
|
|
},
|
|
"errors": {},
|
|
"id": "19",
|
|
"type": "action",
|
|
"warnings": {},
|
|
"x": 0,
|
|
"y": 980
|
|
},
|
|
"25": {
|
|
"data": {
|
|
"advanced": {
|
|
"customName": "format report",
|
|
"customNameId": 0,
|
|
"description": "Format a summary table with the information gathered from the playbook.",
|
|
"join": [],
|
|
"note": "Format a summary table with the information gathered from the playbook."
|
|
},
|
|
"functionId": 3,
|
|
"functionName": "format_report",
|
|
"id": "25",
|
|
"parameters": [
|
|
"build_output:custom_function:name",
|
|
"build_output:custom_function:number",
|
|
"build_output:custom_function:message",
|
|
"build_output:custom_function:start_time",
|
|
"build_output:custom_function:end_time",
|
|
"build_output:custom_function:assignee",
|
|
"build_output:custom_function:creator_name",
|
|
"build_output:custom_function:state",
|
|
"build_output:custom_function:matched_fields",
|
|
"build_output:custom_function:source",
|
|
"build_output:custom_function:source_link"
|
|
],
|
|
"template": "SOAR retrieved tickets from Service Now. The table below shows a summary of the information gathered.\n\n| Name | Number | Message | Start Time | End Time | Assignee | Creator Name | State | Matched Fields | Source | Source Link |\n| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |\n%%\n| {0} | {1} | {2} | {3} | {4} | {5} | {6} | {7} | {8} | {9} | {10} |\n%%\n",
|
|
"type": "format"
|
|
},
|
|
"errors": {},
|
|
"id": "25",
|
|
"type": "format",
|
|
"warnings": {},
|
|
"x": 1.4210854715202004e-14,
|
|
"y": 1530
|
|
},
|
|
"6": {
|
|
"data": {
|
|
"advanced": {
|
|
"customName": "default table list",
|
|
"customNameId": 0,
|
|
"description": "Adjust the table list variable to change which tables should be searched.",
|
|
"join": [],
|
|
"note": "Adjust the table list variable to change which tables should be searched."
|
|
},
|
|
"functionId": 2,
|
|
"functionName": "default_table_list",
|
|
"id": "6",
|
|
"inputParameters": [],
|
|
"outputVariables": [
|
|
"output"
|
|
],
|
|
"type": "code"
|
|
},
|
|
"errors": {},
|
|
"id": "6",
|
|
"type": "code",
|
|
"userCode": " \n # Default tables list to find related tickets. Adjust as needed.\n default_table_list = [\n 'incident', \n 'change_request', \n 'change_task', \n 'problem',\n 'sc_request', \n 'sc_task', \n 'sc_req_item',\n ]\n default_table_list__output = default_table_list\n \n",
|
|
"warnings": {},
|
|
"x": 1.4210854715202004e-14,
|
|
"y": 148
|
|
},
|
|
"8": {
|
|
"data": {
|
|
"advanced": {
|
|
"customName": "convert table list",
|
|
"customNameId": 0,
|
|
"join": [],
|
|
"note": "Converts the table into a custom function result that is filterable downstream.",
|
|
"refreshNotableData": false
|
|
},
|
|
"customFunction": {
|
|
"draftMode": false,
|
|
"name": "list_demux",
|
|
"repoName": "community"
|
|
},
|
|
"functionId": 1,
|
|
"functionName": "convert_table_list",
|
|
"id": "8",
|
|
"loop": {
|
|
"enabled": false,
|
|
"exitAfterUnit": "m",
|
|
"exitAfterValue": 10,
|
|
"exitConditionEnabled": false,
|
|
"exitLoopAfter": 2,
|
|
"pauseUnit": "m",
|
|
"pauseValue": 2
|
|
},
|
|
"selectMore": false,
|
|
"type": "utility",
|
|
"utilities": {
|
|
"list_demux": {
|
|
"description": "Accepts a single list and converts it into multiple custom function output results. All output will be placed in the \"output\" datapath. Sub-items and sub-item variable names are dependent on the input.",
|
|
"fields": [
|
|
{
|
|
"dataTypes": [
|
|
"*"
|
|
],
|
|
"description": "A list of objects. Nested lists are not unpacked.",
|
|
"inputType": "item",
|
|
"label": "input_list",
|
|
"name": "input_list",
|
|
"placeholder": "[\"list_item_1\", \"list_item_2\", \"list_item_3\"]",
|
|
"renderType": "datapath",
|
|
"required": false
|
|
}
|
|
],
|
|
"label": "list_demux",
|
|
"name": "list_demux"
|
|
}
|
|
},
|
|
"utilityType": "custom_function",
|
|
"values": {
|
|
"list_demux": {
|
|
"input_list": "default_table_list:custom_function:output"
|
|
}
|
|
}
|
|
},
|
|
"errors": {},
|
|
"id": "8",
|
|
"type": "utility",
|
|
"userCode": "\n",
|
|
"warnings": {},
|
|
"x": 1.4210854715202004e-14,
|
|
"y": 326
|
|
},
|
|
"9": {
|
|
"data": {
|
|
"advanced": {
|
|
"customName": "space delimiter input",
|
|
"customNameId": 0,
|
|
"description": "Convert playbook input into space delimiter string for ServiceNow query.",
|
|
"drop_none": true,
|
|
"join": [],
|
|
"note": "Convert playbook input into space delimiter string for ServiceNow query.",
|
|
"separator": " "
|
|
},
|
|
"functionId": 1,
|
|
"functionName": "space_delimiter_input",
|
|
"id": "9",
|
|
"parameters": [
|
|
"filtered-data:input_filter:condition_1:playbook_input:search_term"
|
|
],
|
|
"template": "{0}\n",
|
|
"type": "format"
|
|
},
|
|
"errors": {},
|
|
"id": "9",
|
|
"type": "format",
|
|
"warnings": {},
|
|
"x": 1.4210854715202004e-14,
|
|
"y": 802
|
|
}
|
|
},
|
|
"notes": "Inputs: user, device\nInteractions: ServiceNow\nActions: run query\nOutputs: report, observables"
|
|
},
|
|
"input_spec": [
|
|
{
|
|
"contains": [
|
|
"user name",
|
|
"host name"
|
|
],
|
|
"description": "Find tickets in ServiceNow that have mentioned this search term..",
|
|
"name": "search_term"
|
|
}
|
|
],
|
|
"output_spec": [
|
|
{
|
|
"contains": [],
|
|
"datapaths": [
|
|
"build_output:custom_function:observable_array"
|
|
],
|
|
"deduplicate": false,
|
|
"description": "An array of observable dictionaries with value, type, score, score_id, and categories.",
|
|
"metadata": {},
|
|
"name": "observable"
|
|
},
|
|
{
|
|
"contains": [],
|
|
"datapaths": [
|
|
"format_report:formatted_data"
|
|
],
|
|
"deduplicate": false,
|
|
"description": "An array of reports. One report per reputation category.",
|
|
"metadata": {},
|
|
"name": "markdown_report"
|
|
}
|
|
],
|
|
"playbook_trigger": "artifact_created",
|
|
"playbook_type": "data",
|
|
"python_version": "3.13",
|
|
"schema": "5.0.15",
|
|
"version": "6.3.1.176"
|
|
},
|
|
"create_time": "2025-01-24T16:39:26.106708+00:00",
|
|
"draft_mode": false,
|
|
"labels": [
|
|
"*"
|
|
],
|
|
"tags": [
|
|
"user",
|
|
"device",
|
|
"ServiceNow",
|
|
"ticket"
|
|
]
|
|
} |