Khoa previously wrote about monitoring AD Group Membership changes using his Powershell script which can be found here.
In this article we will be setting up a Logstash filter that will look for Event Ids that match the Security Group Management logs generated by your Domain Controller for long term storage. This will allow us to look back through historical data and see when groups were created, deleted, and whether users were added/removed.
These are the Event ID’s that we’re interested in which can be found in this MS Technet article
ID | Event Message |
4727 | A security-enabled global group was created |
4728 | A member was added to a security-enabled global group |
4729 | A member was removed from a security-enabled global group |
4730 | A security-enabled global group was deleted |
4731 | A security-enabled local group was created |
4732 | A member was added to a security-enabled local group |
4733 | A member was removed from a security-enabled local group |
4734 | A security-enabled local group was deleted |
4735 | A security-enabled local group was changed |
4737 | A security-enabled global group was changed |
4754 | A security-enabled universal group was created |
4755 | A security-enabled universal group was changed |
4756 | A member was added to a security-enabled universal group |
4757 | A member was removed from a security-enabled universal group |
4758 | A security-enabled universal group was deleted |
4764 | A group’s type was changed |
Note: These events might not be setup to be audited by your Domain Controller, so ensure you are selecting the ones you are interested in.
Knowing these Event ID’s is great; however, it’s difficult just seeing the Event ID’s as they get generated, and having to look at each individual log to see the raw message which tells us what kind of event that is. This is time-consuming; therefore, let’s make it simpler by adding the following to your logstash configuration.
Logstash Config:
# Active Directory - Security Group Management filter { if "winlogbeat" in [tags] and [event_id] == 4727 { mutate { add_field => { "short_message" => "A security-enabled global group was created" } } } else if [event_id] == 4728 { mutate { add_field => { "short_message" => "A member was added to a security-enabled global group" } } } else if [event_id] == 4729 { mutate { add_field => { "short_message" => "A member was removed from a security-enabled global group" } } } else if [event_id] == 4730 { mutate { add_field => { "short_message" => "A security-enabled global group was deleted" } } } else if [event_id] == 4731 { mutate { add_field => { "short_message" => "A security-enabled local group was created" } } } else if [event_id] == 4732 { mutate { add_field => { "short_message" => "A member was added to a security-enabled local group" } } } else if [event_id] == 4733 { mutate { add_field => { "short_message" => "A member was removed from a security-enabled local group" } } } else if [event_id] == 4734 { mutate { add_field => { "short_message" => "A security-enabled local group was deleted" } } } else if [event_id] == 4735 { mutate { add_field => { "short_message" => "A security-enabled local group was changed" } } } else if [event_id] == 4737 { mutate { add_field => { "short_message" => "A security-enabled global group was changed" } } } else if [event_id] == 4754 { mutate { add_field => { "short_message" => "A security-enabled universal group was created" } } } else if [event_id] == 4755 { mutate { add_field => { "short_message" => "A security-enabled universal group was changed" } } } else if [event_id] == 4756 { mutate { add_field => { "short_message" => "A member was added to a security-enabled universal group" } } } else if [event_id] == 4757 { mutate { add_field => { "short_message" => "A member was removed from a security-enabled universal group" } } } else if [event_id] == 4758 { mutate { add_field => { "short_message" => "A security-enabled universal group was deleted" } } } else if [event_id] == 4764 { mutate { add_field => { "short_message" => "A group's type was changed" } } } }
Here’s a full Logstash config that includes these changes:
input { beats { port => 7510 tags => [ "winlogbeat" ] } } # Active Directory - Security Group Management filter { if "winlogbeat" in [tags] and [log_name] == "Security" and [event_id] == 4727 { mutate { add_field => { "short_message" => "A security-enabled global group was created" } } } else if [event_id] == 4728 { mutate { add_field => { "short_message" => "A member was added to a security-enabled global group" } } } else if [event_id] == 4729 { mutate { add_field => { "short_message" => "A member was removed from a security-enabled global group" } } } else if [event_id] == 4730 { mutate { add_field => { "short_message" => "A security-enabled global group was deleted" } } } else if [event_id] == 4731 { mutate { add_field => { "short_message" => "A security-enabled local group was created" } } } else if [event_id] == 4732 { mutate { add_field => { "short_message" => "A member was added to a security-enabled local group" } } } else if [event_id] == 4733 { mutate { add_field => { "short_message" => "A member was removed from a security-enabled local group" } } } else if [event_id] == 4734 { mutate { add_field => { "short_message" => "A security-enabled local group was deleted" } } } else if [event_id] == 4735 { mutate { add_field => { "short_message" => "A security-enabled local group was changed" } } } else if [event_id] == 4737 { mutate { add_field => { "short_message" => "A security-enabled global group was changed" } } } else if [event_id] == 4754 { mutate { add_field => { "short_message" => "A security-enabled universal group was created" } } } else if [event_id] == 4755 { mutate { add_field => { "short_message" => "A security-enabled universal group was changed" } } } else if [event_id] == 4756 { mutate { add_field => { "short_message" => "A member was added to a security-enabled universal group" } } } else if [event_id] == 4757 { mutate { add_field => { "short_message" => "A member was removed from a security-enabled universal group" } } } else if [event_id] == 4758 { mutate { add_field => { "short_message" => "A security-enabled universal group was deleted" } } } else if [event_id] == 4764 { mutate { add_field => { "short_message" => "A group's type was changed" } } } } output { elasticsearch { hosts => ["http://elasticsearchserver:9200"] index => "logstash-winlogbeat-%{+xxxx.ww}" } }
So what changed?
Now anytime a group membership activity is changed, the message will be parsed through logstash and based on the event ID, a short_message field will added which will indicate the type of action that occurred.
Here’s some example of the changes we can see.
- A Security Group was created
- A user was added or removed from that particular group
At the end you may create a Dashboard that displays the Event IDs that you might be interested in:
You may search by specific Usernames (Such as your Domain admins, and see who has made any changes).
Here’s the Raw logs along with the field names which will help in creating your Dashboard in Kibana.
Active directory is great, and leveraging Windows Event Forwarder + ELK is a great free alternative to purchasing an vendor-provided application; however, you do have to spend some time setting it up.
Since you read this far, I’ll show you how to create a simple visualization in Kibana to filter these Security Group Management events generated in your environment.
In Kibana
- Navigate to Visualization
- Create New Visualization
- Select “Data Table”
- Select your Index
- On the search bar paste the following query:
event_id: 4727 OR event_id: 4728 OR event_id: 4729 OR event_id: 4730 OR event_id: 4731 OR event_id: 4732 OR event_id: 4733 OR event_id: 4734 OR event_id: 4735 OR event_id: 4737 OR event_id: 4754 OR event_id: 4755 OR event_id: 4756 OR event_id: 4757 OR event_id: 4758 OR event_id: 4764
- Click on Add Metrics:
Aggregation: Terms
Field: Event_id
- Add Metrics again
Aggregation: Terms
Field: short_message.keyword
- Click on the Search button to see your visualization generated. Here’s an example of the past 24 hours and the events it found.
You may then create a dashboard and add other visualizations that you might find interesting.
Note: You will need to forward your windows event logs using Winlogbeat so that your field names match the ones shown in this article. I wrote an article on setting that up in your endpoint which may be accessed here.
Here’s some useful fields to start off with:
event_data.SubjectUserName = The individual that made the changes (e.g. Domain Admin)
event_data.SamAccountName = The Group that was modified (e.g. SuperSecretGroup)
event_data.MemberName = The Individual that was added/removed to a group. (e.g. CN=Pablo Delgado,OU=Users,DC=SuperSecret,DC=com)
I hope this helps out, the next article I will be focusing on other Active directory dashboards such as Account Failure/Lockouts/Account Creations, etc.
Thank you
Hi,
For some reason this isn’t adding the short_message field. Logstash is processing the eventlogs, I can see everything, just no short_message. Any ideas?
Thanks,
Andrew