Operator On The Wire
← Back to Knowledge Base
OOTW / Chapter IV - Active Directory / 04. Techniques / GPO

Response

GPO response starts by separating LDAP changes from SYSVOL changes. LDAP tells us which GPO object, link, ACL, WMI filter, or version changed. SYSVOL tells us what payload or configuration was delivered to clients.

High-value events

EventMeaningFocus
5136Directory object modifiedgroupPolicyContainer, gPLink, gPOptions, gPCWQLFilter, ACL changes
5137Directory object createdNew GPO object
5141Directory object deletedRemoved GPO object
5145Network share object checkedAccess to SYSVOL policy paths
4663File object accessModification inside policy folders when object auditing is enabled
4698Scheduled task createdImmediate task deployed to clients
4702Scheduled task updatedModified task on clients
7045Service installedService deployment through policy or follow-on execution

Domain controller review

Get-WinEvent -FilterHashtable @{LogName='Security'; Id=5136,5137,5141} |
  Where-Object { $_.Message -match 'Policies|gPLink|gPOptions|gPCWQLFilter|groupPolicyContainer' } |
  Select-Object TimeCreated,Id,ProviderName,Message

SYSVOL review

Get-ChildItem "\\ootw.local\SYSVOL\ootw.local\Policies" -Recurse |
  Sort-Object LastWriteTime -Descending |
  Select-Object -First 100 FullName,LastWriteTime,Length

Payload hunt

Get-ChildItem "\\ootw.local\SYSVOL\ootw.local\Policies" -Recurse -Include *.xml,*.ps1,*.bat,*.vbs,*.cmd,Registry.pol,GptTmpl.inf |
  Select-Object FullName,LastWriteTime

Scheduled task hunt on clients

Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4698,4702} |
  Select-Object TimeCreated,Id,Message

Group Policy client log

Get-WinEvent -LogName "Microsoft-Windows-GroupPolicy/Operational" |
  Select-Object -First 50 TimeCreated,Id,ProviderName,Message

Export current GPO state

New-Item -ItemType Directory -Force C:\GPO-Review | Out-Null
Get-GPOReport -All -ReportType XML -Path C:\GPO-Review\all-gpos.xml
Backup-GPO -All -Path C:\GPO-Review\backup

Check permissions

Get-GPO -All | ForEach-Object {
  $GpoName = $_.DisplayName
  Get-GPPermission -Name $GpoName -All |
    Select-Object @{Name='GPO';Expression={$GpoName}},Trustee,TrusteeType,Permission
}

Cleanup commands

Remove-GPLink -Name "Workstation Baseline" -Target "OU=Workstations,OU=OOTW Lab,DC=ootw,DC=local"
Remove-GPO -Name "Workstation Baseline"
Restore-GPO -Name "Misconfigured Policy" -Path C:\GPO-Review\backup

Hardening checklist

  • Restrict GPO creation and edit rights.
  • Review GenericAll, GenericWrite, WriteDACL, WriteOwner, and GPO edit delegation on all GPOs.
  • Alert on gPLink, gPOptions, gPCWQLFilter, and groupPolicyContainer changes.
  • Alert on new or modified scripts, scheduled task XML, service XML, registry preferences, and Registry.pol under SYSVOL.
  • Remove legacy GPP cpassword artifacts.
  • Require change tickets for GPO creation, linking, and Domain Controllers OU policy changes.
  • Keep tested backups of all GPOs.