How to automatically disable users in AWS Managed Microsoft AD based on GuardDuty findings

Organizations are facing an increasing number of security threats, especially in the form of compromised user accounts. Manually monitoring and acting on suspicious activities is not only time-consuming but also prone to human error. The lack of automated responses to security incidents can lead to disastrous consequences, such as data breaches and financial loss.

In this blog post, I show you how to detect suspicious events using Amazon GuardDuty and create an automation from those findings to disable user accounts in AWS Directory Service for Microsoft Active Directory.

This post addresses scenarios where, for example, you have a web server that uses a Microsoft Active Directory user account (service account) to access an application or database resources on other servers, and you want to automate disabling the user account if suspicious activity is detected.

I walk you through how to deploy Microsoft Active Directory in AWS Directory Services, set up GuardDuty to monitor Amazon Elastic Compute Cloud (Amazon EC2) instances, and configure Amazon EventBridge with AWS Step Functions to trigger AWS Systems Manager Run Command to obtain the username and disable the user in Active Directory.

Solution overview

In this example, shown in Figure 1, you deploy a test EC2 instance and enable GuardDuty runtime monitoring. Findings will trigger an EventBridge rule that executes a Step Functions state machine, which runs two Systems Manager Run Command documents that discover the username and disable that user using the directory administration EC2 instance.

Figure 1: Solution architecture

Figure 1: Solution architecture

GuardDuty

GuardDuty is an automated threat detection service that continuously monitors for suspicious activity and unauthorized behavior to protect your AWS accounts, workloads, and data stored in Amazon Simple Storage Service (Amazon S3).

To activate GuardDuty:

  1. Go to GuardDuty on the AWS Management Console.
    1. If you’re activating GuardDuty for the first time, under Try threat detection with GuardDuty, select All Features and then choose Get Started.
    2. If you’ve used GuardDuty before, select Runtime Monitoring and then choose Enable under Runtime Monitoring.
    Figure 2: GuardDuty Runtime Monitoring enabled with EC2 monitoring

    Figure 2: GuardDuty Runtime Monitoring enabled with EC2 monitoring

AWS Managed Microsoft AD

AWS Managed Microsoft AD provides a fully managed service for Microsoft Active Directory (AD) in the AWS Cloud. When you create your directory, AWS deploys two domain controllers in separate Availability Zones that are exclusively yours for high availability. For use cases that require even higher resilience and performance in a specific AWS Region or during specific hours, you can scale AWS Managed Microsoft AD by deploying additional domain controllers to meet your needs. These domain controllers can help load balance, increase overall performance, or provide additional nodes to protect against temporary availability issues. Using AWS Managed Microsoft AD, you can define the correct number of domain controllers for your directory based on your use case.

To deploy a new AWS Managed Microsoft AD:

  1. Go to the Directory Service console.
  2. Choose Set up directory and select AWS Managed Microsoft AD.
  3. Select Standard Edition and enter a Directory DNS name and password.
  4. Select a virtual private cloud (VPC), for this example use the Default VPC.
  5. Choose Create directory.

Directory administration EC2 instance

This directory administration EC2 instance will be used to control the Microsoft Active Directory using AWS Systems Manager.

To deploy the directory administration EC2 instance:

  1. If you have deployed a new directory, you might need to wait 20–45 minutes until the directory status is Active.
  2. Select the Directory ID.
  3. Choose Actions and select Launch directory Administration EC2 Instance, using the default options.

Alternatively, you can build your own Windows EC2 instances with a role that has the AmazonSSMManagedInstanceCore policy, join it to the Active Directory domain, and install Active Directory management tools.

To remotely connect to the directory administration EC2 instance:

  1. Go to the Systems Manager console.
  2. Open Fleet Manager from the navigation pane.
  3. Select the Node ID for the instance with the name ending managementInstance.
  4. Choose Node Actions (top right), select Connect, and then choose Connect with Remote Desktop.
  5. Enter the username admin and the directory password that you set earlier.

Create a test Active Directory user

You will use this test user account to sign in to an EC2 instance and initiate a command that simulates suspicious activity that results in this account being disabled.

To use the directory administration EC2 instance to create a test user on the Active Directory:

  1. From the management EC2 instance, open the start menu, select Windows Administrative Tools and then open Active Directory Users and Computers.
  2. Browse to your Domain, the Domain OU, and then the Users OU, right-click and choose New and then select User.
  3. Create a TestUser user, making sure that you don’t select Account is disabled.

Create a privileged domain service account

You will create this domain user account with delegated permissions to be used by Systems Manager Windows Service.

To use the directory administration EC2 instance to create a service account in AD:

  1. From the management EC2 instance, open the start menu, select Windows Administrative Tools, and then open Active Directory Users and Computers.
  2. Browse to your Domain, the Domain OU, and then the Users OU. Right-click and select New, and then select User
  3. Create an SSMService user, making sure that you don’t select Account is disabled.

To delegate permission to the service account in AD:

  1. Right-click on the Users OU and select Delegate Control.
  2. Choose Next on the Delegation of Control Wizard.
  3. Add the new service user you created earlier and choose Next.
  4. Select Create a custom task to delegate and choose Next.
  5. Select Only the following objects in the folder and select User Objects, then choose Next.
  6. Select General and Property-specific to show the permissions, select Read userAccountControl and Write userAccountControl (near the end of the list), then choose Next and Finish.

To add a service account to the local administrators group:

  1. From the management EC2 instance, open the start menu, select Windows Administrative Tools, and then open Computer Management.
  2. Browse to Local Users and Groups, then to Groups.
  3. Right-click on Administrators and select Properties.
  4. Choose Add to add the new service user you created earlier and choose OK.

Configure Systems Manager

Configure Systems Manager on the directory administration EC2 instance with permission to manage the Active Directory.

To configure Systems Manager:

  1. From the management EC2 instance from the Start Menu, select Windows Administrative Tools, and then open Services.
  2. Locate the Amazon SSM Agent, right-click, and select Properties.
  3. Select the Log On tab and select This account.
  4. Within This account enter the privileged domain username you created earlier followed by @ and then the domain name, for example SSMService@corp.example.com. Enter your password and choose OK.
    Figure 3: Microsoft Windows Services showing Systems Manager Agent settings

    Figure 3: Microsoft Windows Services showing Systems Manager Agent settings

  5. Choose OK on the This account has been granted Log On As A Service right and The new logon name will not take effect until you stop and restart the service popups.
  6. Right-click Amazon SSM Agent and select Restart.

Systems Manager Run Command

Run Command is a feature of Systems Manager that can remotely and securely manage the configuration of your managed nodes. You can use Run Command to automate common administrative tasks and perform one-time configuration changes at scale. You can use Run Command from the console, the AWS Command Line Interface (AWS CLI), AWS Tools for PowerShell, or the AWS SDKs. Run Command is offered at no additional cost.

To create a Run Command document with a PowerShell command to disable domain user accounts:

  1. Go to the AWS Systems Manager console.
  2. Select Documents under Change Management Tools.
  3. Choose Create document and select Command or Session.
  4. Enter a name, for example DisableADUser.
  5. Select document type Command.
  6. Select YAML and then enter the following code:
    ---
    schemaVersion: "2.2"
    description: "Disable AD Users"
    parameters:
      UserName:
        type: String
        description: "(Required) The username to disable."
    mainSteps:
    - action: "aws:runPowerShellScript"
      name: "DisableUser"
      inputs:
        runCommand:
        - "import-module activedirectory"
        - "$disableuser = get-aduser {{ UserName }} | select-object -ExpandProperty DistinguishedName"
        - "dsmod user $disableuser -disabled yes"
    
  7. Choose Create document.

To create a Run Command document with a bash command to find a username from a UserID:

  1. Follow steps 1–3 from the previous procedure.
  2. Enter a name, for example GetUsernameFromID.
  3. Select document type Command.
  4. Select YAML and then enter the following code:
    ---
    description: "Get Username from Linux"
    schemaVersion: "2.2"
    parameters:
      UserId:
        type: String
        description: "(Required) The User ID to find."
        default: "1000"
    mainSteps:
    - action: aws:runShellScript
      name: GetLinuxUsername
      precondition:
        StringEquals:
        - platformType
        - Linux
      inputs:
        timeoutSeconds: 7200
        runCommand:
          - "#!/bin/bash"
          - "#"
          - "UserName=$(id -nu {{ UserId }})"
          - "if [[ $UserName == *'@'* ]]; then"
          - "echo ${UserName%@*} "
          - "else if [[ $UserName == *'\'* ]]; then"
          - "echo $UserName | sed 's/.*\\//g'"
          - "fi"
          - "fi"
      outputs:
        - Name: output
          Selector: $.Payload.output
          Type: String
    
  5. Choose Create document.

Step Functions

Step Functions is a serverless orchestration service that you can use to coordinate multiple AWS services, microservices, and third-party integrations into business-critical applications. Step Functions is widely used for orchestrating complex workflows, such as loan processing, fraud detection, risk management, and compliance processes. By breaking down these processes into a series of steps, Step Functions provides a clear overview and control of the entire workflow. This helps make sure that it executes each stage correctly and in the right order. One of the critical aspects of using Step Functions in regulated industries is the importance of security and data protection.

By the end of this section, your state machine should have a sequential flow that starts with a choice that defaults to No UserID found and with the UserID present, includes the steps Find Username, Wait, Get Username, and Disable AD User. If it doesn’t, you can drag the actions into the correct order or change the next state associated with each action. Alternatively, copy this state machine definition JSON and import it directly into Step Functions.

To create a Step Functions state machine to execute the Systems Manager Run Commands:

  1. Go to the Step Functions console.
  2. Choose Get Started.
  3. Choose Create your own.
  4. Enter a name for the state machine, select Standard, and choose Continue.
  5. Select JSONPath as the state machine query language.
  6. From the navigation pane, search for and add the Pass action by dragging the action to the center window.
  7. Add the Systems Manager: SendCommand Action for Finding the Username using Run Command.
  8. Select the SendCommand, change the state name to Find Username, and then enter the following code into API Parameters on the right side of the screen.
    {
      "DocumentName": "GetUsernameFromID",
      "Parameters": {
        "UserId.$": "States.Array(States.JsonToString($.detail.service.runtimeDetails.process.euid))"
      },
      "Targets": [
        {
          "Key": "InstanceIds",
          "Values.$": "States.Array($.detail.resource.instanceDetails.instanceId)"
        }
      ]
    }
    
  9. With SendCommand selected, select the Input/Output tab, select Add original input to output using ResultPath, select Combine original input with result, and enter the following:
    $.RunCommand.State
    
  10. Add a Wait Action and set the number of seconds to wait before resuming the execution to 5 seconds.
  11. Add a Systems Manager: GetCommandInvocation action, which will get the Username value from Run Command and change the state name to Get Username, then enter the following API Parameters.
    {
      "CommandId.$": "$.RunCommand.State.Command.CommandId",
      "InstanceId.$": "$.detail.resource.instanceDetails.instanceId"
    }
    
  12. On the Input/Output tab, select Transform result with ResultSelector and enter the following:
    {
      "StandardOutputContent.$": "States.StringSplit($.StandardOutputContent,'n')"
    }
    
  13. Add a Systems Manager: SendCommand action which will disable the Active Directory user using Run Command. Change the state name to Disable AD User then enter the following API Parameters, changing the InstanceIds value to the ID of your Active Directory Management server.
    {
      "DocumentName": "DisableADUser",
      "Parameters": {
        "UserName.$": "$.StandardOutputContent"
      },
      "Targets": [
        {
          "Key": "InstanceIds",
          "Values": [
            "i-0b22a22eec53b9321"
          ]
        }
      ]
    }
    
  14. Add a Choice action, choose the pencil icon next to Rule #1, choose Edit conditions, enter the variable $.detail.service.runtimeDetails.process.euid, select operator is present, value true, leave Not as blank, and choose Save Conditions.
  15. Re-arrange the state machine layout to the same structure as displayed in Figure 4, with a sequential flow that starts with a choice that defaults to No UserID found and with the UserID present includes the steps Find Username, Wait, Get Username, and Disable AD User.
    Figure 4: Step Functions state machine structure

    Figure 4: Step Functions state machine structure

  16. Choose Create (top right) and then Confirm to create the step function state machine.

To add permissions to enable the State Machine to run System Manager commands:

  1. Within the newly created state machine, choose Config (top center).
  2. Choose View in IAM, under Permissions, Execution role.
  3. Choose Add permissions, Attach Polices (center right).
  4. Search for and select AmazonSSMAutomationRole and choose Add permission.

EventBridge

EventBridge helps developers build event-driven architectures (EDA) by connecting loosely coupled publishers and consumers using event routing, filtering, and transformation. To create an EventBridge rule that triggers the Systems Manger Run Command document you created earlier:

  1. Go to the Amazon EventBridge console and select Create rule with EventBridge Rule.
  2. Enter a name, for example GuardDutyDisableADuser.
  3. Select Rule with an event pattern and choose Next.
  4. Under the Event pattern JSON window, choose Edit pattern and enter the following:
    {
      "source": ["aws.guardduty"],
      "detail-type": ["GuardDuty Finding"]
    }
    
  5. Choose Next.
  6. Select AWS Service.
  7. Select Step Functions state machine as the target.
  8. Select the state machine you created earlier, for example MyStateMachine-A123456789.
  9. Choose Next twice and choose Create rule

Create a test EC2 instance

To generate alerts on GuardDuty, you create a domain joined Linux EC2 instance. For this example, you’ll use two separate EC2 instances so you can monitor for activity from each instance within GuardDuty and use EventBridge to create automations.

To create an AWS Identity and Access Management (IAM) role to permit the EC2 instance to join the AD:

  1. Go to the IAM console.
  2. Select Policies from the navigation pane.
  3. Choose Create policy (top right).
  4. Select Policy editor JSON, enter the following code and choose Next.
    {
    "Version": "2012-10-17",
    "Statement": [
    	{
    		"Effect": "Allow",
    		"Action": [
    			"secretsmanager:GetSecretValue",
    			"secretsmanager:DescribeSecret"
    			],
    		"Resource": "*"
    	}
    	]
    }
    
  5. Enter the Policy name, for example SecretsManagerGetSecrets, and choose Create policy.
  6. Select Roles from navigation pane.
  7. Choose Create role (top right).
  8. Select AWS service and choose EC2 from the service or use case selection, then choose Next.
  9. Search for and select the following policies and choose Next
    • AmazonSSMDirectoryServiceAccess
    • AmazonSSMManagedInstanceCore
    • SecretsManagerGetSecrets (created earlier)
  10. Enter the role name, for example EC2DomainJoin, and choose Create role.

To create a secret that will be used to store privileged credentials used to join EC2 instances to the domain:

  1. Go to the Secrets Manager console.
  2. Select Store a new secret.
  3. Select Other type of secret.
  4. Add the following keys with the corresponding value of a domain username and password that have permissions to join computers to the domain:
    1. awsSeamlessDomainUsername
    2. awsSeamlessDomainPassword
  5. Choose Next.
  6. Enter the following secret name, replacing <d-1234567890> with your directory ID.
    aws/directory-services/<d-1234567890>/seamless-domain-join
    
  7. Choose Next twice, then Store.

For more information more, see Seamlessly joining an Amazon EC2 Linux instance to your AWS Managed Microsoft AD Active Directory.

To create a domain joined EC2 instance for testing this GuardDuty automation:

  1. Go to the Amazon EC2 console.
  2. Select Instances from navigation pane.
  3. Choose Launch Instances.
  4. Select Amazon Linux AMI.
  5. Select an existing Key Pair or create a new key pair.
  6. Scroll to the bottom and select Advanced details.
  7. Within Domain join directory, select the domain
  8. Within IAM instance profile, select the EC2DomainJoin role that you created earlier.
  9. Choose Launch Instance.

Testing

To simulate a threat, use a GuardDuty test domain that GuardDuty will recognize as a command and control server.

  1. Go to the Amazon EC2 console.
  2. Choose Instances from the navigation pane.
  3. Select the test EC2 instance that you created earlier.
  4. Choose Connect, select the Session Manager tab, and choose Connect
  5. Authenticate with your test user by entering su followed by the test user with the domain name that you created earlier. For example su TestUser@example.com, then enter the password.
  6. Enter the command curl guarddutyc2activityb.com.
    • You will receive an error because the page won’t resolve, but GuardDuty will have detected suspicious events.
  7. Go to the GuardDuty console and select Findings from the navigation pane.
  8. Within 3–5 minutes, you should see a high severity finding for Backdoor:EC2/C&CActivity.B!DNS.

Note: You must archive the GuardDuty finding before re-running this test, because the EventBridge rule only runs once against a GuardDuty finding with the same details. To archive the finding, select the check box next to the Backdoor:EC2/C&CActivity.B!DNS finding, choose Actions (top right), and select Archive.

Figure 5: GuardDuty simulated findings

Figure 5: GuardDuty simulated findings

If you go back to Active Directory Users and Computers on the Directory Administration EC2 instance, you should see that the Test User is now disabled. You can enable the user by right-clicking on the user and selecting Enable Account.

Figure 6: Active Directory Users and Computers showing the disabled test use

Figure 6: Active Directory Users and Computers showing the disabled test use

Conclusion

In this post, you learned how to deploy AWS Managed AD, Systems Manager Run Command, EventBridge, Step Functions, and GuardDuty to monitor for suspicious events and disable the associated Active Directory user account.

You can expand this scenario by creating Run Command documents that reset Active Directory passwords, disable computer accounts, or Active Directory tasks supported by Microsoft PowerShell. Additionally, you can add steps within the Step Functions state machine to notify administrators through Amazon Simple Notification Service (Amazon SNS) or add additional checks with AWS Lambda.

Although this post uses AWS Managed Microsoft AD, the same functionality can be achieved with a manual deployment of Active Directory on Amazon EC2 or on-premises, either by using an EC2 instance joined to the Active Directory domain with the Active Directory administration tools installed or by installing Systems Manager agent onto a management server on-premises.

If you have feedback about this post, submit comments in the Comments section below. If you have questions about this post, start a new thread on AWS re:Post GuardDuty or contact AWS Support.

Tim Kingdon

Tim Kingdon

Tim is a Senior Partner Solutions Architect at AWS and has more than 25 years of experience in healthcare, financial, government, and defence industries. In his role, he provides strategic technical guidance to partners and helps drive their success through technical enablement initiatives.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top