mirror of
https://github.com/splunk/security_content
synced 2026-06-08 17:32:49 +00:00
ad_ldap_account_locking_playbook
This commit is contained in:
@@ -0,0 +1,283 @@
|
||||
{
|
||||
"blockly": false,
|
||||
"blockly_xml": "<xml></xml>",
|
||||
"category": "Account Locking",
|
||||
"coa": {
|
||||
"data": {
|
||||
"description": "Accepts user name that needs to be disabled in Microsoft LDAP 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": "9e264b4abd2e3c0730a58dd66c6ef88d9b2453af",
|
||||
"nodes": {
|
||||
"0": {
|
||||
"data": {
|
||||
"advanced": {
|
||||
"join": []
|
||||
},
|
||||
"functionName": "on_start",
|
||||
"id": "0",
|
||||
"type": "start"
|
||||
},
|
||||
"errors": {},
|
||||
"id": "0",
|
||||
"type": "start",
|
||||
"warnings": {},
|
||||
"x": 19.999999999999986,
|
||||
"y": -6.394884621840902e-14
|
||||
},
|
||||
"1": {
|
||||
"data": {
|
||||
"advanced": {
|
||||
"join": []
|
||||
},
|
||||
"functionName": "on_finish",
|
||||
"id": "1",
|
||||
"type": "end"
|
||||
},
|
||||
"errors": {},
|
||||
"id": "1",
|
||||
"type": "end",
|
||||
"warnings": {},
|
||||
"x": 19.999999999999986,
|
||||
"y": 864
|
||||
},
|
||||
"2": {
|
||||
"data": {
|
||||
"advanced": {
|
||||
"customName": "username 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_name",
|
||||
"value": ""
|
||||
}
|
||||
],
|
||||
"conditionIndex": 0,
|
||||
"customName": "filter_username_check",
|
||||
"logic": "and"
|
||||
}
|
||||
],
|
||||
"functionId": 1,
|
||||
"functionName": "username_filter",
|
||||
"id": "2",
|
||||
"type": "filter"
|
||||
},
|
||||
"errors": {},
|
||||
"id": "2",
|
||||
"type": "filter",
|
||||
"warnings": {
|
||||
"config": [
|
||||
"Reconfigure invalid datapath."
|
||||
]
|
||||
},
|
||||
"x": 60,
|
||||
"y": 140
|
||||
},
|
||||
"3": {
|
||||
"data": {
|
||||
"action": "disable account",
|
||||
"actionType": "generic",
|
||||
"advanced": {
|
||||
"customName": "disable user account",
|
||||
"customNameId": 0,
|
||||
"delayTime": 0,
|
||||
"description": "Disable user account from filtered playbook inputs.",
|
||||
"join": [],
|
||||
"note": "Disable user account from filtered playbook inputs."
|
||||
},
|
||||
"connector": "AD LDAP",
|
||||
"connectorConfigs": [
|
||||
"microsoft ad ldap"
|
||||
],
|
||||
"connectorId": "a5730e5d-a396-4695-92c2-35ff391aaf45",
|
||||
"connectorVersion": "v1",
|
||||
"functionId": 1,
|
||||
"functionName": "disable_user_account",
|
||||
"id": "3",
|
||||
"parameters": {
|
||||
"use_samaccountname": true,
|
||||
"user": "playbook_input:user_name"
|
||||
},
|
||||
"requiredParameters": [
|
||||
{
|
||||
"data_type": "string",
|
||||
"default": false,
|
||||
"field": "user"
|
||||
}
|
||||
],
|
||||
"type": "action"
|
||||
},
|
||||
"errors": {},
|
||||
"id": "3",
|
||||
"type": "action",
|
||||
"warnings": {
|
||||
"config": [
|
||||
"Reconfigure invalid datapath."
|
||||
]
|
||||
},
|
||||
"x": 0,
|
||||
"y": 328
|
||||
},
|
||||
"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": [
|
||||
"disable_user_account:action_result.parameter.user",
|
||||
"disable_user_account:action_result.parameter.use_samaccountname",
|
||||
"disable_user_account:action_result.data.*.user_dn",
|
||||
"disable_user_account:action_result.status",
|
||||
"disable_user_account:action_result.message",
|
||||
"disable_user_account:action_result.data.*.starting_status"
|
||||
],
|
||||
"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, sam_account, user_dn, status, msg, prev_status in zip(disable_user_account_parameter_user, disable_user_account_parameter_use_samaccountname, disable_user_account_result_item_2, disable_user_account_result_item_3, disable_user_account_result_message, disable_user_account_result_item_5):\n user_acc_status = {\n \"type\": \"Microsoft AD LDAP Account\",\n \"value\": user,\n \"previous_status\": prev_status,\n \"sam_account\": sam_account,\n \"user_dn\": user_dn,\n \"message\": msg,\n \"status\": status\n }\n \n username_observables__observable_array.append(user_acc_status)\n #phantom.debug(username_observables__observable_array)\n",
|
||||
"warnings": {},
|
||||
"x": 0,
|
||||
"y": 686
|
||||
},
|
||||
"5": {
|
||||
"data": {
|
||||
"advanced": {
|
||||
"customName": "filter disable account",
|
||||
"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_account",
|
||||
"id": "5",
|
||||
"type": "filter"
|
||||
},
|
||||
"errors": {},
|
||||
"id": "5",
|
||||
"type": "filter",
|
||||
"warnings": {},
|
||||
"x": 60,
|
||||
"y": 500
|
||||
}
|
||||
},
|
||||
"notes": "Inputs: users\nInteractions: Microsoft AD LDAP\nActions: Account Locking/Disabling\nOutputs: observables"
|
||||
},
|
||||
"input_spec": [
|
||||
{
|
||||
"contains": [
|
||||
"user name"
|
||||
],
|
||||
"description": "A user name provided to be disable - AD LDAP",
|
||||
"name": "user_name"
|
||||
}
|
||||
],
|
||||
"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-15T10:29:31.917563+00:00",
|
||||
"draft_mode": false,
|
||||
"labels": [
|
||||
"*"
|
||||
],
|
||||
"tags": [
|
||||
"user",
|
||||
"microsoft_ad_ldap",
|
||||
"disable_account",
|
||||
"D3-AL"
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 90 KiB |
@@ -0,0 +1,173 @@
|
||||
"""
|
||||
Accepts user name that needs to be disabled in Microsoft LDAP 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 'username_filter' block
|
||||
username_filter(container=container)
|
||||
|
||||
return
|
||||
|
||||
@phantom.playbook_block()
|
||||
def username_filter(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
|
||||
phantom.debug("username_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", "!=", ""]
|
||||
],
|
||||
name="username_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 user account from filtered playbook inputs.
|
||||
################################################################################
|
||||
|
||||
playbook_input_user_name = phantom.collect2(container=container, datapath=["playbook_input:user_name"])
|
||||
|
||||
parameters = []
|
||||
|
||||
# build parameters list for 'disable_user_account' call
|
||||
for playbook_input_user_name_item in playbook_input_user_name:
|
||||
if playbook_input_user_name_item[0] is not None:
|
||||
parameters.append({
|
||||
"user": playbook_input_user_name_item[0],
|
||||
"use_samaccountname": True,
|
||||
})
|
||||
|
||||
################################################################################
|
||||
## Custom Code Start
|
||||
################################################################################
|
||||
|
||||
# Write your custom code here...
|
||||
|
||||
################################################################################
|
||||
## Custom Code End
|
||||
################################################################################
|
||||
|
||||
phantom.act("disable account", parameters=parameters, name="disable_user_account", assets=["microsoft ad ldap"], callback=filter_disable_account)
|
||||
|
||||
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.
|
||||
################################################################################
|
||||
|
||||
disable_user_account_result_data = phantom.collect2(container=container, datapath=["disable_user_account:action_result.parameter.user","disable_user_account:action_result.parameter.use_samaccountname","disable_user_account:action_result.data.*.user_dn","disable_user_account:action_result.status","disable_user_account:action_result.message","disable_user_account:action_result.data.*.starting_status"], action_results=results)
|
||||
|
||||
disable_user_account_parameter_user = [item[0] for item in disable_user_account_result_data]
|
||||
disable_user_account_parameter_use_samaccountname = [item[1] for item in disable_user_account_result_data]
|
||||
disable_user_account_result_item_2 = [item[2] for item in disable_user_account_result_data]
|
||||
disable_user_account_result_item_3 = [item[3] for item in disable_user_account_result_data]
|
||||
disable_user_account_result_message = [item[4] for item in disable_user_account_result_data]
|
||||
disable_user_account_result_item_5 = [item[5] for item in disable_user_account_result_data]
|
||||
|
||||
username_observables__observable_array = None
|
||||
|
||||
################################################################################
|
||||
## Custom Code Start
|
||||
################################################################################
|
||||
|
||||
# Write your custom code here...
|
||||
username_observables__observable_array = []
|
||||
|
||||
for user, sam_account, user_dn, status, msg, prev_status in zip(disable_user_account_parameter_user, disable_user_account_parameter_use_samaccountname, disable_user_account_result_item_2, disable_user_account_result_item_3, disable_user_account_result_message, disable_user_account_result_item_5):
|
||||
user_acc_status = {
|
||||
"type": "Microsoft AD LDAP Account",
|
||||
"value": user,
|
||||
"previous_status": prev_status,
|
||||
"sam_account": sam_account,
|
||||
"user_dn": user_dn,
|
||||
"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_account(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs):
|
||||
phantom.debug("filter_disable_account() 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_account: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: AD LDAP Account Locking
|
||||
id: e6f96caf-610c-4ced-aa2c-ba9b19b89e1f
|
||||
version: 1
|
||||
date: '2023-05-08'
|
||||
author: Teoderick Contreras, Splunk
|
||||
type: Investigation
|
||||
description: "Accepts user, to be disabled using Microsoft AD LDAP connector. This playbook produces a normalized observables output for each user and device."
|
||||
playbook: AD_LDAP_Account_Locking
|
||||
how_to_implement: This input playbook requires the Microsoft AD LDAP 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:
|
||||
- AD LDAP API
|
||||
tags:
|
||||
platform_tags:
|
||||
- user
|
||||
- microsoft_ad_ldap
|
||||
- D3-AL
|
||||
- disable_account
|
||||
playbook_type: Input
|
||||
vpe_type: Modern
|
||||
playbook_fields: []
|
||||
product:
|
||||
- Splunk SOAR
|
||||
Reference in New Issue
Block a user