Track changes to sensitive groups with Advanced Hunting in Microsoft 365 Defender
Published Apr 06 2022 04:00 PM 29.1K Views
Iron Contributor

In my role working with Defender for Identity (MDI) customers, I'm often asked if MDI can help them answer questions about activities taking place within the environment. MDI does have a lot of information around the activities taking place in Active Directory and now combined with the power of Advanced Hunting in Microsoft 365 Defender, we can help customers answer some these questions with ease and efficiency.  

 

MDI tracks the changes made to Active Directory group memberships. These changes are recorded by MDI as an activity and are available in the Microsoft 365 Defender Advanced Hunting, IdentityDirectoryEvents. MDI records these changes from two different sources:

 

  1. Tracking changes made to an entity by the Active Directory Update Sequence Number (USN).  In the case of a group, MDI can see who has been added or removed from a group, but we don’t see the actor who made the change or which domain controller the change was made on.
  2. Tracking changes to a group, including who performed the action. MDI requires specific Windows events to be recorded on the domain controller.  For more information on the Windows events required by MDI, see https://docs.microsoft.com/en-us/defender-for-identity/configure-windows-event-collection.

In this blog we will show you how to build an Advanced Hunting query that captures group modification. Let’s start with a very basic script showing all the changes to a query that will show modifications to sensitive groups in your organization.

 

Step 1: Basic query that will show all group modifications.

The MDI group modification activities are in the “IdentityDirectoryEvents” table where ActionType equals “Group changed”

Here is a simple AH query you use to show you all the group changes in Active Directory.

 

 

 

 

 

IdentityDirectoryEvents 
| where Application == "Active Directory"
| where ActionType == "Group Membership changed"

 

 

 

 

 

Running this query yields the following result:

 

GersonLevitz_0-1649064568987.png

 

This shows some columns that are not relevant for the rest of our scenario, so we will use the “project” command to show only the columns of interest.

 

 

 

 

 

 

IdentityDirectoryEvents
| where Application == "Active Directory"
| where ActionType == "Group Membership changed"
| project Timestamp, ActionType, TargetAccountDisplayName, TargetAccountUpn, DestinationDeviceName, AccountName, AccountDomain, AdditionalFields

 

 

 

 

 

 

 

GersonLevitz_0-1649064708224.png

 

Step 2: Just show activities from Windows Events

As you can see there are some duplicate activities above. This is caused by MDI recording the group changes from two different sources.

  • Windows events
  • Active Directory sync changes via USN

The activities from the Windows events have more information such as which domain controller the change was initiated from and the user (actor) who performed the change. To simplify our query’s results, we want to exclude activities that are from Active Directory sync changes.

Additionally, we are going to use the “project” command again to show specific columns that are relevant here.

To include the activities from the Windows events only, run the following query:

 

 

 

 

 

 

 

IdentityDirectoryEvents
| where Application == "Active Directory"
| where ActionType == "Group Membership changed"
| where DestinationDeviceName != "" // Exclude activities coming from AD Sync changes. 
| project Timestamp, ActionType, TargetAccountDisplayName, TargetAccountUpn, DestinationDeviceName, AccountName, AccountDomain, AdditionalFields

 

 

 

 

 

 

 

GersonLevitz_1-1649064838159.png

 

Step 3: Group name and action type

The table is starting to take shape, but we are still missing some valuable pieces of information.

  • Group name that was modified
  • Whether the group change was an “Add” or a “Remove”

If you look closely, you can see a few lines that have no data for the TargetAccountDisplayName and TargetAccountUPN attributes. This is due to another group being added or removed to the queried group (group nesting).

To complete the missing data, we will be extracting it from the “AdditionalFields” column.  

 

 

 

 

 

 

 

IdentityDirectoryEvents
| where Application == "Active Directory"
| where ActionType == "Group Membership changed"
| where DestinationDeviceName != "" // Exclude activites coming AD Sync changes. 
| extend ToGroup = tostring(parse_json(AdditionalFields).["TO.GROUP"]) // Extracts the group name if action is add enity to a group.
| extend FromGroup = tostring(parse_json(AdditionalFields).["FROM.GROUP"]) // etracts the group name if action is remove entity from a group.
| extend Action = iff(isempty(ToGroup), "Remove", "Add") // calculates if the action is Remove or Add
| extend GroupModified = iff(isempty(ToGroup), FromGroup, ToGroup) // group name that the action was taken on 
| extend Target_Group = tostring(parse_json(AdditionalFields).["TARGET_OBJECT.GROUP"])
| project Timestamp, Action, GroupModified,  Target_Account = TargetAccountDisplayName, Target_UPN = TargetAccountUpn, Target_Group,  DC=DestinationDeviceName, Actor=AccountName, ActorDomain=AccountDomain, AdditionalFields
| sort by Timestamp desc 

 

 

 

 

 

 

GersonLevitz_0-1649064974705.png

The information is now presented in a more concise manner. You can now sort the data as needed and export the data to a CSV file.

 

Step 4: See changes for sensitive groups

You might not want to see every group change that has occurred, as some groups may have many changes but might not be of interest from a security standpoint, like an all company group, for example.

From a security standpoint, we want to focus on changes that have been made to “sensitive” groups. By default, MDI considers specific groups to be sensitive. You can see the list of groups that are by default sensitive here - https://docs.microsoft.com/en-us/defender-for-identity/manage-sensitive-honeytoken-accounts#sensitiv....

If you have nested other groups to one of these predefined groups or if you have manually tagged group as sensitive, you should add the group name to the list in the query below.

An array is created with the list of the default sensitive groups as defined by MDI.

We will then query to only show groups that have been modified based on the array defined. The new or changed lines in the query are highlighted to help you keep track of the query evolution:   

Note: If your operating system is in a different language than English validate the spelling of the group names. 

 

 

 

 

 

 

 

let SensitiveGroupName = pack_array(  // Declare Sensitive Group names. Add any groups that you manually tagged as sensitive
    'Account Operators',
    'Administrators',
    'Domain Admins', 
    'Backup Operators',
    'Domain Controllers',
    'Enterprise Admins',
    'Enterprise Read-only Domain Controllers',
    'Group Policy Creator Owners',
    'Incoming Forest Trust Builders',
    'Microsoft Exchange Servers',
    'Network Configuration Operators',
    'Microsoft Exchange Servers',
    'Print Operators',
    'Read-only Domain Controllers',
    'Replicator',
    'Schema Admins',
    'Server Operators'
);
IdentityDirectoryEvents
| where Application == "Active Directory"
| where ActionType == "Group Membership changed"
| where DestinationDeviceName != "" // Exclude activites coming AD Sync changes. 
| extend ToGroup = tostring(parse_json(AdditionalFields).["TO.GROUP"]) // Extracts the group name if action is add enity to a group.
| extend FromGroup = tostring(parse_json(AdditionalFields).["FROM.GROUP"]) // etracts the group name if action is remove entity from a group.
| extend Action = iff(isempty(ToGroup), "Remove", "Add") // calculates if the action is Remove or Add
| extend GroupModified = iff(isempty(ToGroup), FromGroup, ToGroup) // group name that the action was taken on
| extend Target_Group = tostring(parse_json(AdditionalFields).["TARGET_OBJECT.GROUP"])
| where GroupModified in~ (SensitiveGroupName)
| project Timestamp, Action, GroupModified,  Target_Account = TargetAccountDisplayName, Target_UPN = TargetAccountUpn, Target_Group,  DC=DestinationDeviceName, Actor=AccountName, ActorDomain=AccountDomain, AdditionalFields
| sort by Timestamp desc

 

 

 

 

 

 

GersonLevitz_1-1649065556856.png

 

We can now review all changes made to sensitive groups. Feel free to save this query, then customize it further to suit your organization’s needs.

 

If you find the query helpful, please leave a comment, or use the comment space to tell us what you’ve done to make this query even more powerful in your organization. Please let us know what areas you want to see us tackle next in Advanced Hunting. We can’t wait to hear your ideas.

 

 

 

 

2 Comments
Co-Authors
Version history
Last update:
‎Apr 07 2022 11:22 PM
Updated by: