Skip to content

Group Policy and SYSVOL

Group Policy is how the domain pushes settings to every machine, which makes it the most valuable thing in the domain to tamper with. A user who can edit a GPO can run a script as SYSTEM on every computer it's linked to. Two jobs here: make sure policy actually gets applied, and make sure only administrators can change it.

Policy processing settings

These apply to DCs and members alike (both profiles). gpedit.msc or a domain GPO → Computer ConfigurationAdministrative TemplatesSystemGroup Policy.

CIS Setting Value Why
18.9.19.2 Configure security policy processing: Do not apply during periodic background processing Enabled, box unticked (FALSE) Security settings refresh in the background every 90 minutes, not only at boot
18.9.19.3 Configure security policy processing: Process even if the Group Policy objects have not changed Enabled, box ticked (TRUE) A setting someone changed locally gets put back at the next refresh even though the GPO itself didn't change
18.9.19.5 Turn off background refresh of Group Policy Disabled If background refresh is off, a policy change waits for the next reboot, and a local change survives until then

The Windows 11 STIG asks for the same on registry policy processing (WN11-CC-000090, on the Other Security Options page). Together they mean the domain re-asserts itself every refresh.

reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" /v NoBackgroundPolicy /t REG_DWORD /d 0 /f
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\Group Policy\{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" /v NoGPOListChanges /t REG_DWORD /d 0 /f
reg delete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v DisableBkGndGroupPolicy /f
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient" /v EnableNetbios /t REG_DWORD /d 2 /f
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\System" /v DontEnumerateConnectedUsers /t REG_DWORD /d 1 /f

The GUID is the security settings client-side extension; NoGPOListChanges = 0 is "process even if not changed". The last two lines are the NetBIOS and connected-users settings from the next table.

Other domain-wide settings

CIS Setting Path Value Why
18.6.4.2 Configure NetBIOS settings Network → DNS Client Enabled: Disable NetBIOS name resolution on public networks NetBIOS name queries are spoofable; on a domain, DNS answers everything
18.9.29.3 Do not enumerate connected users on domain-joined computers System → Logon Enabled The sign-in screen doesn't show who else has logged in
9.1.1 to 9.1.7 Windows Firewall: Domain profile wf.msc properties → Domain Profile tab Same values as the Private and Public profiles on the Firewall page A domain machine uses the Domain profile whenever it can see its DC, so this is the profile that's active
2.3.6.1 to 2.3.6.6 Domain member: secure channel settings Security Options Sign and encrypt always, machine password changes allowed, 30-day max age, strong session key The channel between a member and the DC; on the Authentication Protocols page

Who can edit a GPO

gpmc.msc → the GPO → Delegation tab. The default and correct list (STIG WN22-DC-000090): Authenticated Users with Read (and Apply), Domain Admins, Enterprise Admins, SYSTEM, and ENTERPRISE DOMAIN CONTROLLERS with Edit or Read. A user or a group like Domain Users with Edit settings or Edit settings, delete, modify security is a domain compromise waiting to happen.

Faster from PowerShell:

Get-GPO -All | ForEach-Object { $g=$_; Get-GPPermission -Guid $_.Id -All | Where { $_.Permission -like 'GpoEdit*' -or $_.Permission -eq 'GpoCustom' } | Select @{n='GPO';e={$g.DisplayName}}, Trustee, Permission }

Remove an entry: Set-GPPermission -Name "Default Domain Policy" -TargetName bob -TargetType User -PermissionLevel None.

Also check who can create GPOs: Get-ADGroupMember "Group Policy Creator Owners". Empty, or the README's administrators only.

Unknown GPOs

An image can carry a GPO the README never mentions, linked to the domain root, that adds an account to Administrators on every machine or runs a startup script.

Get-GPO -All | Select DisplayName, ModificationTime, GpoStatus
Get-GPOReport -All -ReportType Html -Path C:\gpos.html

Open the report and read each GPO's settings. A GPO with Computer Configuration → Policies → Windows Settings → Scripts (Startup), Preferences → Local Users and Groups, or Restricted Groups deserves a close look. Unlink (Remove-GPLink) rather than delete until you're sure, so the snapshot isn't your only undo.

SYSVOL permissions

SYSVOL (C:\Windows\SYSVOL\sysvol\<domain>) is the share on the DC where GPO files and logon scripts live, replicated to every DC and read by every machine. A user who can write to it can edit a logon script that runs on every computer at startup. Defaults (STIG WN22-DC-000080): Authenticated Users and Server Operators with Read & execute, Administrators and SYSTEM with Full control, CREATOR OWNER on subfolders.

icacls C:\Windows\SYSVOL
icacls C:\Windows\SYSVOL\sysvol\corp.local\scripts

Users, Everyone, Domain Users, or a named user with M or F is a finding. Remove the entry: icacls C:\Windows\SYSVOL /remove:g "Domain Users" /t.

While you're there, look for passwords in SYSVOL. Old Group Policy Preferences stored account passwords in Groups.xml and similar files with a key Microsoft published years ago:

Get-ChildItem C:\Windows\SYSVOL -Recurse -Include *.xml | Select-String -Pattern "cpassword" | Select Path

Any hit is a stored password; remove the preference item from the GPO and change that account's password.

Verify

gpresult /r
Get-GPO -All | Select DisplayName, GpoStatus
icacls C:\Windows\SYSVOL

Example

Get-GPOReport -All shows a GPO called "Workstation Maintenance" linked at the domain root. Its computer startup script is \\DC01\SYSVOL\corp.local\scripts\maint.bat, which adds svc_maint to the local Administrators group on every machine. The README doesn't describe any of this. Unlink the GPO, remove svc_maint from every machine's Administrators group, and check icacls on the scripts folder: Domain Users has Modify. Remove it.

Next

Domain Auditing