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 Configuration → Administrative Templates → System → Group 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.