Introduction
Active Directory is a prime target for attackers – and for most organizations something that’s considered the crown jewels. This is due to Active Directory still being the bread and butter for most organizations in regard to authentication and authorization.
When it comes to security, automation is your best friend and keeping a close eye on privileged group membership should be on top of your list.
This post will walk you through, how you can make sure no unwelcome objects make their way into privileged groups in on-premises AD, by leveraging Microsoft Sentinel and its option to run playbooks automated.
This breaks down to Microsoft Sentinel generating an alert, which triggers the associated Playbook, which triggers a Logic app, which triggers a Runbook in an Automation Account, which ultimately runs a PowerShell script on an on-premises server.
Big shout out to my colleague Christian Frohn Petersen who assisted in setting up the prerequisites for this solution. 🙂
Prerequisites
This paragraph is written by Christian Frohn Petersen.
A lot of the prerequisites are well explained in the official Microsoft documentation, so I’m only elaborating where necessary for the complete understanding. This section will cover following 3 prerequisites you need to have for this to work:
- Automation Account
- A hybrid worker group
- Domain joined Azure VM
Automation Account
An Automation Account is ultimately required in order to run the PowerShell script on the domain joined Windows server.
The detailed steps to create an Automation Account are explained here:
For your convenience, this is a screenshot of my Automation Account I created for the purpose. The Automation Account is called Sentinel-Worker:
Hybrid Worker Group
The Automation Account needs to be enabled as a Hybrid Runbook Worker. This will enable the runbooks within the Automation Account to run directly on an Azure VM. This VM in question is running Windows server and is joined to the on-premises Active Directory.
The documentation on this subject mentions an agent-based and an extension-based Hybrid Runbook Worker. I’m using the extension-based which is the recommended configuration, and the details on that is found here:
For your convenience, this is a screenshot of my Hybrid worker group I created for the purpose. The hybrid worker group is called Sentinel-Worker-Hybrid-Group:
Inside the Hybrid worker group, you will have the option Add your Azure VM. Below is a screenshot of mine. Note that this is indeed an Extension-based configuration:
Domain joined Azure VM
Browsing the VM on the Extensions + applications tab after adding it as a Hybrid Runbook Worker, you should verify that HybridWorkerExtension is automatically added (it can also be installed manually as well via the Add option).
On the server itself, this extension will be noted as a Dependency Agent when browsing Programs and Features:
Microsoft Sentinel
With the prerequisites in order and assuming that Microsoft Sentinel is in use already, we’re left with how to capture the changes made to the on-premises groups, generating alerts based off of that and ultimately run some PowerShell scripts automatically.
This paragraph assumes some knowledge with Microsoft Sentinel.
Data connectors
You need a data connector that essentially forwards the security logs of your Domain Controllers to Microsoft Sentinel.
Sentinel has 2 data connectors that can do that for you. I’m using the Security Events via Legacy Agent connector as shown below:
Analytics
Once logs are being sent from On-Premises to Microsoft Sentinel, you can start querying them and creating alerts using KQL.
If you’re interested in getting insights on additions to Domain Admins, following query can serve as a starting point:
- Event id 4728: A member was added to a security-enabled global group
- Event id 4732: A member was added to a security-enabled local group
- Event id 4756: A member was added to a security-enabled universal group
SecurityEvent | where EventID in ("4728", "4732", "4756") | where TargetAccount == "<DomainNetBiosName>\\Domain Admins"
Running the query in my end, gives me following output, as I added and removed accounts several times during my testing of this:
Automation Account Runbook
The Automation Account you created earlier contains the PowerShell scripts as a Runbook. Again, this is the PowerShell script which will run on the on-premises domain joined server, in order to remove and disable objects from the privileged groups.
Below is a screenshot the Runbooks from my AutomationAccount. The runbook of interest is Runbook-iAM-Compliance-Domain-Admins:
PowerShell
The PowerShell script I run with the Runbook above is located here on my GitHub repository: PowerShell/iAM-Compliance-Domain-Admins.ps1 at master · imabdk/PowerShell (github.com)
Use this script as inspiration, as it’s specifically tailored to my needs to leverage an extensionattribute in on-prem AD
The script requires RSAT on the server running the script (the VM in Azure). With RSAT comes the ActiveDirectory PowerShell module.
The script does following:
- Loops through each member of Domain Admins (or any other defined group)
- Queries a locked* down extensionAttribute to confirm if the AD object belongs to the membership of the group
- If the object is not expected to be a member of the group, the object is removed and disabled
- Queries a locked* down extensionAttribute to confirm if the AD object belongs to the membership of the group
- Loops through a locked* down OU, to find objects that is permitted to be a member of the group
- If an object which is permitted, but is not already a member of the group is found, the object is added back to the group
*Locked here means, that no regular user is able to view or write to the extensionattribute/OU. Not going into details on this, as this is considered sensitive.
The logic of the script is to 1) remove any objects which isn’t allowed to be a member 2) add back members that are allowed. This is done to counter that 1) any unwelcome objects are added and 2) all the existing members are removed by anyone with ill intentions.
Logic app
The Logic App, which is used as a playbook on the alert in Microsoft Sentinel, is the engine in automating all of this.
Below is a screenshot of the alert in my Sentinel workspace, more specifically the automated response that’s occurring once this alert is triggered. This translates into: Alert is created in Sentinel > then carry out these rules automatically.
Logic app designer
The logic app is inspired by this Playbooks/Block-OnPremADUser (github.com) which can be deployed via a Template. Scroll down to the bottom and use Deploy to Azure if you’re not familiar with designing logic apps.
In the following screenshot, the logic app is creating a job with the specified Automation Account, in the specified Hybrid Worker Group and ultimately running the Runbook containing the PowerShell script.
All the names used here should be familiar to you, as I mentioned them along the way:
If the job is run successfully, an email is being sent to relevant personel:
In Action
A new member is added to the Domain Admins group in on-premises Active Directory and a new alert is generated:
The playbook associated with the alert in Microsoft Sentinel is then being run, running the logic app, which is running the runbook in the Automation Account:
Final words
This solution admittedly consists of many moving parts and it’s very easy to get lost. I’m happy to assist with any issues or questions you may have while implementing this.
Enjoy 🙂
Hi Martin, Very interesting article, I assume that the Azure VM would need some sort of connection to the on-prem network. How can this be done? Adrian
Hello Adrian, that would require some work in your corporate firewall and a site-to-site VPN from Azure to your on-premises network, more or less extending your corporate LAN to Azure 🙂