mirror of
https://github.com/splunk/security_content
synced 2026-06-08 17:32:49 +00:00
Merge pull request #2672 from splunk/Azure_AD_Locking_Playbook
Azure_AD_Locking_Playbook
This commit is contained in:
@@ -0,0 +1,274 @@
|
||||
{
|
||||
"blockly": false,
|
||||
"blockly_xml": "<xml></xml>",
|
||||
"category": "Account Locking",
|
||||
"coa": {
|
||||
"data": {
|
||||
"description": "Accepts user name that needs to be disabled in Azure Active Directory. Generates an observable output based on the status of account locking or disabling.",
|
||||
"edges": [
|
||||
{
|
||||
"id": "port_0_to_port_2",
|
||||
"sourceNode": "0",
|
||||
"sourcePort": "0_out",
|
||||
"targetNode": "2",
|
||||
"targetPort": "2_in"
|
||||
},
|
||||
{
|
||||
"conditions": [
|
||||
{
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
"id": "port_2_to_port_3",
|
||||
"sourceNode": "2",
|
||||
"sourcePort": "2_out",
|
||||
"targetNode": "3",
|
||||
"targetPort": "3_in"
|
||||
},
|
||||
{
|
||||
"id": "port_4_to_port_1",
|
||||
"sourceNode": "4",
|
||||
"sourcePort": "4_out",
|
||||
"targetNode": "1",
|
||||
"targetPort": "1_in"
|
||||
},
|
||||
{
|
||||
"id": "port_3_to_port_5",
|
||||
"sourceNode": "3",
|
||||
"sourcePort": "3_out",
|
||||
"targetNode": "5",
|
||||
"targetPort": "5_in"
|
||||
},
|
||||
{
|
||||
"conditions": [
|
||||
{
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
"id": "port_5_to_port_4",
|
||||
"sourceNode": "5",
|
||||
"sourcePort": "5_out",
|
||||
"targetNode": "4",
|
||||
"targetPort": "4_in"
|
||||
}
|
||||
],
|
||||
"hash": "76828347e693a60201c3b9342e6f493ee5253566",
|
||||
"nodes": {
|
||||
"0": {
|
||||
"data": {
|
||||
"advanced": {
|
||||
"join": []
|
||||
},
|
||||
"functionName": "on_start",
|
||||
"id": "0",
|
||||
"type": "start"
|
||||
},
|
||||
"errors": {},
|
||||
"id": "0",
|
||||
"type": "start",
|
||||
"warnings": {},
|
||||
"x": 19.999999999999986,
|
||||
"y": -3.197442310920451e-13
|
||||
},
|
||||
"1": {
|
||||
"data": {
|
||||
"advanced": {
|
||||
"join": []
|
||||
},
|
||||
"functionName": "on_finish",
|
||||
"id": "1",
|
||||
"type": "end"
|
||||
},
|
||||
"errors": {},
|
||||
"id": "1",
|
||||
"type": "end",
|
||||
"warnings": {},
|
||||
"x": 19.999999999999986,
|
||||
"y": 860
|
||||
},
|
||||
"2": {
|
||||
"data": {
|
||||
"advanced": {
|
||||
"customName": "user name filter",
|
||||
"customNameId": 0,
|
||||
"description": "Filter user name inputs to route inputs to appropriate actions.",
|
||||
"join": [],
|
||||
"note": "Filter user name inputs to route inputs to appropriate actions."
|
||||
},
|
||||
"conditions": [
|
||||
{
|
||||
"comparisons": [
|
||||
{
|
||||
"conditionIndex": 0,
|
||||
"op": "!=",
|
||||
"param": "playbook_input:user",
|
||||
"value": ""
|
||||
}
|
||||
],
|
||||
"conditionIndex": 0,
|
||||
"customName": "user_name_check",
|
||||
"logic": "and"
|
||||
}
|
||||
],
|
||||
"functionId": 1,
|
||||
"functionName": "user_name_filter",
|
||||
"id": "2",
|
||||
"type": "filter"
|
||||
},
|
||||
"errors": {},
|
||||
"id": "2",
|
||||
"type": "filter",
|
||||
"warnings": {
|
||||
"config": [
|
||||
"Reconfigure invalid datapath."
|
||||
]
|
||||
},
|
||||
"x": 60,
|
||||
"y": 140
|
||||
},
|
||||
"3": {
|
||||
"data": {
|
||||
"action": "disable user",
|
||||
"actionType": "generic",
|
||||
"advanced": {
|
||||
"customName": "disable user account",
|
||||
"customNameId": 0,
|
||||
"description": "Disable the user attributes for filtered playbook inputs.",
|
||||
"join": [],
|
||||
"note": "Disable the user attributes for filtered playbook inputs."
|
||||
},
|
||||
"connector": "Azure AD Graph",
|
||||
"connectorConfigs": [
|
||||
"azure_ad_graph"
|
||||
],
|
||||
"connectorId": "c6d3b801-5c26-4abd-9e89-6d8007e2778f",
|
||||
"connectorVersion": "v1",
|
||||
"functionId": 1,
|
||||
"functionName": "disable_user_account",
|
||||
"id": "3",
|
||||
"parameters": {
|
||||
"user_id": "filtered-data:user_name_filter:condition_1:playbook_input:user"
|
||||
},
|
||||
"requiredParameters": [
|
||||
{
|
||||
"data_type": "string",
|
||||
"field": "user_id"
|
||||
}
|
||||
],
|
||||
"type": "action"
|
||||
},
|
||||
"errors": {},
|
||||
"id": "3",
|
||||
"type": "action",
|
||||
"warnings": {},
|
||||
"x": 0,
|
||||
"y": 320
|
||||
},
|
||||
"4": {
|
||||
"data": {
|
||||
"advanced": {
|
||||
"customName": "username observables",
|
||||
"customNameId": 0,
|
||||
"description": "Format a normalized output for each user.",
|
||||
"join": [],
|
||||
"note": "Format a normalized output for each user."
|
||||
},
|
||||
"functionId": 1,
|
||||
"functionName": "username_observables",
|
||||
"id": "4",
|
||||
"inputParameters": [
|
||||
"filtered-data:filter_disable_result:condition_1:disable_user_account:action_result.parameter.user_id",
|
||||
"filtered-data:filter_disable_result:condition_1:disable_user_account:action_result.status",
|
||||
"filtered-data:filter_disable_result:condition_1:disable_user_account:action_result.message"
|
||||
],
|
||||
"outputVariables": [
|
||||
"observable_array"
|
||||
],
|
||||
"type": "code"
|
||||
},
|
||||
"errors": {},
|
||||
"id": "4",
|
||||
"type": "code",
|
||||
"userCode": "\n # Write your custom code here...\n username_observables__observable_array = []\n \n for user_id, status, msg in zip(filtered_result_0_parameter_user_id, filtered_result_0_status, filtered_result_0_message):\n user_acc_status = {\n \"type\": \"Azure AD Account\",\n \"value\": user_id,\n \"message\": msg,\n \"status\": status\n }\n username_observables__observable_array.append(user_acc_status)\n #phantom.debug(username_observables__observable_array)\n",
|
||||
"warnings": {},
|
||||
"x": 0,
|
||||
"y": 680
|
||||
},
|
||||
"5": {
|
||||
"data": {
|
||||
"advanced": {
|
||||
"customName": "filter disable result",
|
||||
"customNameId": 0,
|
||||
"description": "filter check if the user is disabled successfully.",
|
||||
"join": [],
|
||||
"note": "filter check if the user is disabled successfully."
|
||||
},
|
||||
"conditions": [
|
||||
{
|
||||
"comparisons": [
|
||||
{
|
||||
"conditionIndex": 0,
|
||||
"op": "==",
|
||||
"param": "disable_user_account:action_result.status",
|
||||
"value": "success"
|
||||
}
|
||||
],
|
||||
"conditionIndex": 0,
|
||||
"customName": "disabled_success",
|
||||
"logic": "and"
|
||||
}
|
||||
],
|
||||
"functionId": 2,
|
||||
"functionName": "filter_disable_result",
|
||||
"id": "5",
|
||||
"type": "filter"
|
||||
},
|
||||
"errors": {},
|
||||
"id": "5",
|
||||
"type": "filter",
|
||||
"warnings": {},
|
||||
"x": 60,
|
||||
"y": 500
|
||||
}
|
||||
},
|
||||
"notes": "Inputs: users\nInteractions: Azure AD Graph\nActions: Account Locking/Disabling\nOutputs: observables"
|
||||
},
|
||||
"input_spec": [
|
||||
{
|
||||
"contains": [
|
||||
"user name",
|
||||
"azure user principal name"
|
||||
],
|
||||
"description": "A user name provided to be disable - Azure AD",
|
||||
"name": "user"
|
||||
}
|
||||
],
|
||||
"output_spec": [
|
||||
{
|
||||
"contains": [],
|
||||
"datapaths": [
|
||||
"username_observables:custom_function:observable_array"
|
||||
],
|
||||
"deduplicate": false,
|
||||
"description": "An array of observable dictionaries ",
|
||||
"metadata": {},
|
||||
"name": "observable"
|
||||
}
|
||||
],
|
||||
"playbook_type": "data",
|
||||
"python_version": "3",
|
||||
"schema": "5.0.9",
|
||||
"version": "6.0.0.114895"
|
||||
},
|
||||
"create_time": "2023-05-25T07:40:09.337037+00:00",
|
||||
"draft_mode": false,
|
||||
"labels": [
|
||||
"*"
|
||||
],
|
||||
"tags": [
|
||||
"user",
|
||||
"azure_ad_graph",
|
||||
"disable_account",
|
||||
"D3-AL"
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 90 KiB |
@@ -0,0 +1,165 @@
|
||||
"""
|
||||
Accepts user name that needs to be disabled in Azure Active Directory. Generates an observable output based on the status of account locking or disabling.
|
||||
"""
|
||||
|
||||
|
||||
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 'user_name_filter' block
|
||||
user_name_filter(container=container)
|
||||
|
||||
return
|
||||
|
||||
@phantom.playbook_block()
|
||||
def user_name_filter(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
|
||||
phantom.debug("user_name_filter() called")
|
||||
|
||||
################################################################################
|
||||
# Filter user name inputs to route inputs to appropriate actions.
|
||||
################################################################################
|
||||
|
||||
# collect filtered artifact ids and results for 'if' condition 1
|
||||
matched_artifacts_1, matched_results_1 = phantom.condition(
|
||||
container=container,
|
||||
conditions=[
|
||||
["playbook_input:user", "!=", ""]
|
||||
],
|
||||
name="user_name_filter:condition_1")
|
||||
|
||||
# call connected blocks if filtered artifacts or results
|
||||
if matched_artifacts_1 or matched_results_1:
|
||||
disable_user_account(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 disable_user_account(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
|
||||
phantom.debug("disable_user_account() called")
|
||||
|
||||
# phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED')))
|
||||
|
||||
################################################################################
|
||||
# Disable the user attributes for filtered playbook inputs.
|
||||
################################################################################
|
||||
|
||||
filtered_input_0_user = phantom.collect2(container=container, datapath=["filtered-data:user_name_filter:condition_1:playbook_input:user"])
|
||||
|
||||
parameters = []
|
||||
|
||||
# build parameters list for 'disable_user_account' call
|
||||
for filtered_input_0_user_item in filtered_input_0_user:
|
||||
if filtered_input_0_user_item[0] is not None:
|
||||
parameters.append({
|
||||
"user_id": filtered_input_0_user_item[0],
|
||||
})
|
||||
|
||||
################################################################################
|
||||
## Custom Code Start
|
||||
################################################################################
|
||||
|
||||
# Write your custom code here...
|
||||
|
||||
################################################################################
|
||||
## Custom Code End
|
||||
################################################################################
|
||||
|
||||
phantom.act("disable user", parameters=parameters, name="disable_user_account", assets=["azure_ad_graph"], callback=filter_disable_result)
|
||||
|
||||
return
|
||||
|
||||
|
||||
@phantom.playbook_block()
|
||||
def username_observables(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
|
||||
phantom.debug("username_observables() called")
|
||||
|
||||
################################################################################
|
||||
# Format a normalized output for each user.
|
||||
################################################################################
|
||||
|
||||
filtered_result_0_data_filter_disable_result = phantom.collect2(container=container, datapath=["filtered-data:filter_disable_result:condition_1:disable_user_account:action_result.parameter.user_id","filtered-data:filter_disable_result:condition_1:disable_user_account:action_result.status","filtered-data:filter_disable_result:condition_1:disable_user_account:action_result.message"])
|
||||
|
||||
filtered_result_0_parameter_user_id = [item[0] for item in filtered_result_0_data_filter_disable_result]
|
||||
filtered_result_0_status = [item[1] for item in filtered_result_0_data_filter_disable_result]
|
||||
filtered_result_0_message = [item[2] for item in filtered_result_0_data_filter_disable_result]
|
||||
|
||||
username_observables__observable_array = None
|
||||
|
||||
################################################################################
|
||||
## Custom Code Start
|
||||
################################################################################
|
||||
|
||||
# Write your custom code here...
|
||||
username_observables__observable_array = []
|
||||
|
||||
for user_id, status, msg in zip(filtered_result_0_parameter_user_id, filtered_result_0_status, filtered_result_0_message):
|
||||
user_acc_status = {
|
||||
"type": "Azure AD Account",
|
||||
"value": user_id,
|
||||
"message": msg,
|
||||
"status": status
|
||||
}
|
||||
username_observables__observable_array.append(user_acc_status)
|
||||
#phantom.debug(username_observables__observable_array)
|
||||
################################################################################
|
||||
## Custom Code End
|
||||
################################################################################
|
||||
|
||||
phantom.save_run_data(key="username_observables:observable_array", value=json.dumps(username_observables__observable_array))
|
||||
|
||||
return
|
||||
|
||||
|
||||
@phantom.playbook_block()
|
||||
def filter_disable_result(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
|
||||
phantom.debug("filter_disable_result() called")
|
||||
|
||||
################################################################################
|
||||
# filter check if the user is disabled successfully.
|
||||
################################################################################
|
||||
|
||||
# collect filtered artifact ids and results for 'if' condition 1
|
||||
matched_artifacts_1, matched_results_1 = phantom.condition(
|
||||
container=container,
|
||||
conditions=[
|
||||
["disable_user_account:action_result.status", "==", "success"]
|
||||
],
|
||||
name="filter_disable_result:condition_1")
|
||||
|
||||
# call connected blocks if filtered artifacts or results
|
||||
if matched_artifacts_1 or matched_results_1:
|
||||
username_observables(action=action, success=success, container=container, results=results, handle=handle, filtered_artifacts=matched_artifacts_1, filtered_results=matched_results_1)
|
||||
|
||||
return
|
||||
|
||||
|
||||
@phantom.playbook_block()
|
||||
def on_finish(container, summary):
|
||||
phantom.debug("on_finish() called")
|
||||
|
||||
username_observables__observable_array = json.loads(_ if (_ := phantom.get_run_data(key="username_observables:observable_array")) != "" else "null") # pylint: disable=used-before-assignment
|
||||
|
||||
output = {
|
||||
"observable": username_observables__observable_array,
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## Custom Code Start
|
||||
################################################################################
|
||||
|
||||
# Write your custom code here...
|
||||
|
||||
################################################################################
|
||||
## Custom Code End
|
||||
################################################################################
|
||||
|
||||
phantom.save_playbook_output_data(output=output)
|
||||
|
||||
return
|
||||
@@ -0,0 +1,24 @@
|
||||
name: Azure AD Locking Account
|
||||
id: c3c0157d-7da0-46cb-8b97-327ee92f591c
|
||||
version: 1
|
||||
date: '2023-05-08'
|
||||
author: Teoderick Contreras, Splunk
|
||||
type: Investigation
|
||||
description: "Accepts user, to be disabled using Azure AD Graph connector. This playbook produces a normalized observables output for each user and device."
|
||||
playbook: Azure_AD_Locking_Account
|
||||
how_to_implement: This input playbook requires the Azure AD Graph connector to be configured.
|
||||
It is designed to work in conjunction with the Dynamic Attribute Lookup playbook or other playbooks in the same style.
|
||||
references: []
|
||||
app_list:
|
||||
- Azure AD Graph API
|
||||
tags:
|
||||
platform_tags:
|
||||
- user
|
||||
- D3-AL
|
||||
- azure_ad_graph
|
||||
- disable_account
|
||||
playbook_type: Input
|
||||
vpe_type: Modern
|
||||
playbook_fields: []
|
||||
product:
|
||||
- Splunk SOAR
|
||||
Reference in New Issue
Block a user