mirror of
https://github.com/splunk/security_content
synced 2026-06-08 17:32:49 +00:00
Merge pull request #2669 from splunk/AWS_IAM_Account_Locking_Playbook
AWS_IAM_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 AWS IAM 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"
|
||||
},
|
||||
{
|
||||
"id": "port_6_to_port_1",
|
||||
"sourceNode": "6",
|
||||
"sourcePort": "6_out",
|
||||
"targetNode": "1",
|
||||
"targetPort": "1_in"
|
||||
},
|
||||
{
|
||||
"id": "port_3_to_port_7",
|
||||
"sourceNode": "3",
|
||||
"sourcePort": "3_out",
|
||||
"targetNode": "7",
|
||||
"targetPort": "7_in"
|
||||
},
|
||||
{
|
||||
"conditions": [
|
||||
{
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
"id": "port_2_to_port_3",
|
||||
"sourceNode": "2",
|
||||
"sourcePort": "2_out",
|
||||
"targetNode": "3",
|
||||
"targetPort": "3_in"
|
||||
},
|
||||
{
|
||||
"conditions": [
|
||||
{
|
||||
"index": 0
|
||||
}
|
||||
],
|
||||
"id": "port_7_to_port_6",
|
||||
"sourceNode": "7",
|
||||
"sourcePort": "7_out",
|
||||
"targetNode": "6",
|
||||
"targetPort": "6_in"
|
||||
}
|
||||
],
|
||||
"hash": "5cd799e95d456dc116881e04c82ec7bd2e783edc",
|
||||
"nodes": {
|
||||
"0": {
|
||||
"data": {
|
||||
"advanced": {
|
||||
"join": []
|
||||
},
|
||||
"functionName": "on_start",
|
||||
"id": "0",
|
||||
"type": "start"
|
||||
},
|
||||
"errors": {},
|
||||
"id": "0",
|
||||
"type": "start",
|
||||
"warnings": {},
|
||||
"x": 19.999999999999986,
|
||||
"y": -4.476419235288631e-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": "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",
|
||||
"value": ""
|
||||
}
|
||||
],
|
||||
"conditionIndex": 0,
|
||||
"customName": "username_filter",
|
||||
"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 user",
|
||||
"actionType": "contain",
|
||||
"advanced": {
|
||||
"customName": "disable user account",
|
||||
"customNameId": 0,
|
||||
"description": "Disable user account from filtered playbook inputs.",
|
||||
"join": [],
|
||||
"note": "Disable user account from filtered playbook inputs."
|
||||
},
|
||||
"connector": "AWS IAM",
|
||||
"connectorConfigs": [
|
||||
"aws_iam"
|
||||
],
|
||||
"connectorId": "7d06523f-d524-4dbd-befd-7f30f5492882",
|
||||
"connectorVersion": "v1",
|
||||
"functionId": 1,
|
||||
"functionName": "disable_user_account",
|
||||
"id": "3",
|
||||
"parameters": {
|
||||
"disable_access_keys": true,
|
||||
"username": "filtered-data:username_filter:condition_1:playbook_input:user"
|
||||
},
|
||||
"requiredParameters": [
|
||||
{
|
||||
"data_type": "string",
|
||||
"field": "username"
|
||||
},
|
||||
{
|
||||
"data_type": "boolean",
|
||||
"default": true,
|
||||
"field": "disable_access_keys"
|
||||
}
|
||||
],
|
||||
"type": "action"
|
||||
},
|
||||
"errors": {},
|
||||
"id": "3",
|
||||
"type": "action",
|
||||
"warnings": {},
|
||||
"x": 0,
|
||||
"y": 320
|
||||
},
|
||||
"6": {
|
||||
"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": 2,
|
||||
"functionName": "username_observables",
|
||||
"id": "6",
|
||||
"inputParameters": [
|
||||
"filtered-data:filter_disable_result:condition_1:disable_user_account:action_result.parameter.disable_access_keys",
|
||||
"filtered-data:filter_disable_result:condition_1:disable_user_account:action_result.parameter.username",
|
||||
"filtered-data:filter_disable_result:condition_1:disable_user_account:action_result.parameter.credentials",
|
||||
"filtered-data:filter_disable_result:condition_1:disable_user_account:action_result.data.*.RequestId",
|
||||
"filtered-data:filter_disable_result:condition_1:disable_user_account:action_result.message",
|
||||
"filtered-data:filter_disable_result:condition_1:disable_user_account:action_result.status"
|
||||
],
|
||||
"outputVariables": [
|
||||
"observable_array"
|
||||
],
|
||||
"type": "code"
|
||||
},
|
||||
"errors": {},
|
||||
"id": "6",
|
||||
"type": "code",
|
||||
"userCode": "\n # Write your custom code here...\n username_observables__observable_array = []\n \n for access_key, usrname, creds, req_id, msg, status in zip(filtered_result_0_parameter_disable_access_keys, filtered_result_0_parameter_username, filtered_result_0_parameter_credentials, filtered_result_0_data___requestid, filtered_result_0_message, filtered_result_0_status):\n user_acc_status = {\n \"type\": \"aws iam user name\",\n \"value\": usrname,\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": 680
|
||||
},
|
||||
"7": {
|
||||
"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": "disable_success",
|
||||
"logic": "and"
|
||||
}
|
||||
],
|
||||
"functionId": 2,
|
||||
"functionName": "filter_disable_result",
|
||||
"id": "7",
|
||||
"type": "filter"
|
||||
},
|
||||
"errors": {},
|
||||
"id": "7",
|
||||
"type": "filter",
|
||||
"warnings": {},
|
||||
"x": 60,
|
||||
"y": 500
|
||||
}
|
||||
},
|
||||
"notes": "Inputs: users\nInteractions: AWS IAM\nActions: Account Locking/Disabling\nOutputs: observables"
|
||||
},
|
||||
"input_spec": [
|
||||
{
|
||||
"contains": [
|
||||
"user name",
|
||||
"aws iam user name"
|
||||
],
|
||||
"description": "A user name provided for account locking - AWS IAM",
|
||||
"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:50:39.360247+00:00",
|
||||
"draft_mode": false,
|
||||
"labels": [
|
||||
"*"
|
||||
],
|
||||
"tags": [
|
||||
"user",
|
||||
"aws_iam",
|
||||
"disable_account",
|
||||
"D3-AL"
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 85 KiB |
@@ -0,0 +1,170 @@
|
||||
"""
|
||||
Accepts user name that needs to be disabled in AWS IAM 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="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.
|
||||
################################################################################
|
||||
|
||||
filtered_input_0_user = phantom.collect2(container=container, datapath=["filtered-data:username_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({
|
||||
"disable_access_keys": True,
|
||||
"username": 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=["aws_iam"], 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.disable_access_keys","filtered-data:filter_disable_result:condition_1:disable_user_account:action_result.parameter.username","filtered-data:filter_disable_result:condition_1:disable_user_account:action_result.parameter.credentials","filtered-data:filter_disable_result:condition_1:disable_user_account:action_result.data.*.RequestId","filtered-data:filter_disable_result:condition_1:disable_user_account:action_result.message","filtered-data:filter_disable_result:condition_1:disable_user_account:action_result.status"])
|
||||
|
||||
filtered_result_0_parameter_disable_access_keys = [item[0] for item in filtered_result_0_data_filter_disable_result]
|
||||
filtered_result_0_parameter_username = [item[1] for item in filtered_result_0_data_filter_disable_result]
|
||||
filtered_result_0_parameter_credentials = [item[2] for item in filtered_result_0_data_filter_disable_result]
|
||||
filtered_result_0_data___requestid = [item[3] for item in filtered_result_0_data_filter_disable_result]
|
||||
filtered_result_0_message = [item[4] for item in filtered_result_0_data_filter_disable_result]
|
||||
filtered_result_0_status = [item[5] 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 access_key, usrname, creds, req_id, msg, status in zip(filtered_result_0_parameter_disable_access_keys, filtered_result_0_parameter_username, filtered_result_0_parameter_credentials, filtered_result_0_data___requestid, filtered_result_0_message, filtered_result_0_status):
|
||||
user_acc_status = {
|
||||
"type": "aws iam user name",
|
||||
"value": usrname,
|
||||
"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: AWS IAM Account Locking
|
||||
id: f15e4ab7-b057-4225-86ae-c36ab78b50f2
|
||||
version: 1
|
||||
date: '2023-05-08'
|
||||
author: Teoderick Contreras, Splunk
|
||||
type: Investigation
|
||||
description: "Accepts user, to be disabled using AWS IAM connector. This playbook produces a normalized observables output for each user and device."
|
||||
playbook: AWS_IAM_Account_Locking
|
||||
how_to_implement: This input playbook requires the AWS IAM 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:
|
||||
- AWS IAM API
|
||||
tags:
|
||||
platform_tags:
|
||||
- user
|
||||
- aws_iam
|
||||
- D3-AL
|
||||
- disable_account
|
||||
playbook_type: Input
|
||||
vpe_type: Modern
|
||||
playbook_fields: []
|
||||
product:
|
||||
- Splunk SOAR
|
||||
Reference in New Issue
Block a user