Windows Event Forwarding & SACLs

Rich
6 min readAug 12, 2023

--

TL;DR how to get Windows Event Forwarding working, how to query & tweak SACLs, and how to query the logs on the Windows Event Collector.

Welcome to Part XI of our Back to the Basics Series!

Part I: NTDS.dit vs SAM

Part II: Ownership Matters

Part III: Recovering from a Crash

Part IV: Setting up a Simple Honeypot Account

Part V: Automating DC Deployment

Part VI: Sometimes it’s the dumbest thing

Part VII: Merry Christmas, macros, & Base64

Part VIII: Why old 0 Days make great teaching tools

Part IX: PowerShell & PS1s without PowerShell.exe

Part X: Ownership & so called “effective permissions”

Part XI: Windows Event Forwarding & SACLs

Part XII: Poorly planned honeypots & other Bad Ideas

Part XIII: Setting up a simple honey token

Part XIV: Smartcards and Pass-the-Hash

Part XV: Forwarding logs to Sentinel & basic alerts

Part XVI: Automating VM deployments in Hyper-V

Part XVII: Migrating the lab from ESXi to Hyper-V

Background

I had been meaning to setup Windows Event Forwarding and dive into SACLs ever since we ran Part IV of the Back to the Basics Series. An astute reader of that howto would have noticed that we only queried the logs on one DC in the honeypot’s trigger.

What if the event was generated on a different DC though?

This is where Windows Event Forwarding comes in. One can simply forward logs to a collector, and then either query them there or ship them to a SIEM.

Windows Event Forwarding

There were a few steps involved in getting this working, but nothing too daunting. There’s walkthroughs out there on Google, but we ended up having to put pieces from several different ones together to get a working solution.

We:

  • Stood up a member server named TestWEC
  • Created a GPO
  • Set SDDL via the GPO on log access
  • Put TestWEC in the Event Log Readers group via the GPO
  • Put TestWEC & NETWORK SERVICE in the Event Log Readers group in AD
  • Created a subscription on TestWEC and added the DCs and member servers to it

Details

Adam the Automator explains this part quite well here.

Run ‘wevtutil gl security’ and copy paste the SDDL in ChannelAccess:

O:BAG:SYD:(A;;0xf0005;;;SY)(A;;0x5;;;BA)(A;;0x1;;;S-1–5–32–573)

Copy/paste it to the GPO in

Computer Configuration\Policies\Administrative Templates\Windows Components\Event Log Service\Security\Configure log access

(S-1–5–32–573 is the well known SID for the Event Log Readers Group.)

Run Event Viewer on TestWEC, create a subscription, and if it’s ‘Collector Initiated’ then add the computers you want to collect from. One can also choose what logs they want to collect. I am only collecting the Security log for now.

Once the systems pull Group Policy you will start to see Forwarded Events populate.

Querying Forwarded Events

I have barely used Event Viewer for anything more than one offs like setting up forwarding. It’s too clunky, involves too much clicking, and just isn’t all that flexible. We want to look for specific events, say for example

  • What IP address a given user logged in from?
  • What time they logged in?
  • What DC processed the request?
#Get login details for a given user (Source IP, DC that handled the login, time, etc)

$Event = Get-WinEvent -Path "$env:SystemRoot\System32\Winevt\Logs\ForwardedEvents.evtx" | Where-Object {($_.Id -eq "4624") -and ($_.Message -like "*Mishky*")} | Select-Object -First 1 | Select-Object *

$Source_IP = $Example.Properties[18].Value
$DC = $Event.MachineName
$Time = $Event.TimeCreated

Write-Host "Mishky logged on from $Source_IP using $DC at $Time"

How do we pull the IP address from the Message property though?

How did we know it was 18? Simple, we borrowed Mishka’s idea from Part IV and brute forced it:

#Find the Properties number you are looking for via brute force :P

$x = 0
$z = 30
do
{
$x = $x + 1
$x
$Event.Properties[$x]
}
while ($x -lt $z)

Let’s make this interesting

So we can query logins regardless of the DC that handled them. Great, but not super interesting.

Here at test.local we have talked a lot about DACLs in AD, tweaking them, auditing them, and what ‘Dangerous Rights’ to look out for.

However there’s another ACL that we really never dove into before; the SACL (System Access Control List).

  • Some cyber courses teach that subjects act on objects.
  • However, bear in mind that in AD objects can absolutely act on other objects.
  • What actions they can take depend on the DACL.
  • What actions they took are logged according to the SACL.

Tweaking & querying SACLs

We’ll use the CEO account in the VIPs OU for this example.

To query a SACL on a given account:

(Get-Acl (Get-ADUser “CEO”).DistinguishedName -Audit).Audit

Here we are specifically auditing changes to attributes on the account made by anyone.

We’ll use the WriteProperty as an example:

#Set a new audit rule in a SACL, works :D
$object = (Get-ADUser "CEO").DistinguishedName
$subject = [Security.Principal.NTAccount]"Everyone"
$ObjectType_GUID = [system.guid]"00000000–0000–0000–0000–000000000000"
$InheritedObjectType_GUID = [system.guid]"00000000–0000–0000–0000–000000000000"
$acl = Get-Acl $object -Audit
$NewRule = New-Object System.DirectoryServices.ActiveDirectoryAuditRule($subject,"WriteProperty","Success",$ObjectType_GUID,"All",$InheritedObjectType_GUID)
$ACL.AddAuditRule($NewRule)
Set-Acl $object $acl

Putting it all together

Let’s change the CEO’s phone number and then query who changed it. Using any account that has privileges:

Set-ADUser CEO -OfficePhone “867–5309”

Then query the collected logs on TestWEC:

#Pull Event ID 5136; "a directory service object was modified"
$CEO_ChangesII = Get-WinEvent -Path "$env:SystemRoot\System32\Winevt\Logs\ForwardedEvents.evtx" | Where-Object {($_.Id -eq "5136")}

#Now just tease out the Properties[] value
$WhatChanged = $CEO_ChangesII.Properties[11].Value
$NewValue = $CEO_ChangesII.Properties[13].Value
$Target = $CEO_ChangesII.Properties[8].Value
$WhoDunnit = $CEO_ChangesII.Properties[3].Value
$DC = $CEO_ChangesII.MachineName
$Time = $CEO_ChangesII.TimeCreated

Write-Host "$WhoDunnit changed the $Target $WhatChanged to $NewValue at $Time using $DC"

Summary

There are guides out there on Google for setting up Windows Event Forwarding, Adam the Automator’s being the most helpful in our case. Adam the Automator is a rock star.

Information on querying forwarded events was a bit scarce though and information on how to query & tweak SACLs was almost nonexistent.

I’ll probably put together a cheatsheet later mapping ‘Dangerous Rights’ to the Event ID. Changing an attribute on the CEO’s account and then looking for Event ID 5136 was just an example. Some on Google suggested looking for Event ID 4738, but it fails to show changes to all attributes.

A future project is shipping these logs off to Azure and using Sentinel as a SIEM.

This was more about querying and tweaking SACLs and having something to look in the logs for. Changing a phone number isn’t a huge deal security wise, but it’s an introduction to auditing for things like changes to group memberships, who reset a password, etc.

References

Description of what SACLs are: https://learn.microsoft.com/en-us/windows/win32/secauthz/access-control-lists

Get-Acl: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.security/get-acl?view=powershell-7.3

Special identity groups: https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/understand-special-identities-groups#everyone

Tweaking SACLs in PowerShell: https://stackoverflow.com/questions/47017970/access-is-denied-when-enabling-auditing-rules-for-active-directory-schema-chan

Set-AuditRule script: https://github.com/OTRF/Set-AuditRule/blob/master/Set-AuditRule.ps1

ResetPassword ExtendedRight: https://learn.microsoft.com/en-us/windows/win32/adschema/r-user-force-change-password

Windows Even Forwarding: https://learn.microsoft.com/en-us/windows/security/threat-protection/use-windows-event-forwarding-to-assist-in-intrusion-detection

Configure Windows Event Collection: https://learn.microsoft.com/en-us/advanced-threat-analytics/configure-event-collection

How to set SACLs in NTFS via PowerShell:

https://medium.com/@cryps1s/detecting-windows-endpoint-compromise-with-sacls-cd748e10950#:~:text=An%20ACL%20can%20be%20one,access%20attempts%20to%20an%20object.

Howto setup WEF/WEC: https://www.youtube.com/watch?v=urRWkyzRI78

Event ID 4624 (account logon): https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventID=4624

Windows Event Forwarding: https://learn.microsoft.com/en-us/windows/security/threat-protection/use-windows-event-forwarding-to-assist-in-intrusion-detection

Example GPO for WEC: https://andys-tech.blog/2021/07/windows-event-collector-tutorial/

WEF & WEC walkthrough: https://adamtheautomator.com/windows-event-collector/

Well known SIDs: https://learn.microsoft.com/en-us/windows/win32/secauthz/well-known-sids

Event ID 4738 (only shows some attributes): https://learn.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4738

Event ID 5136 (show what changed): https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventid=5136

--

--

Rich

I work various IT jobs & like Windows domain security as a hobby. Most of what’s here is my notes from auditing or the lab.