1. Introduction
Group Policy is how Active Directory enforces configuration and security at scale — password policy, service settings, firewall rules, scripts and thousands of other options pushed to users and computers. That reach is exactly why Group Policy is a double-edged sword: whoever can edit a widely-linked GPO can run code or change security settings on every machine in scope. Group Policy is both a powerful hardening tool and, when its permissions are loose, a domain-wide code-execution primitive. Historically it also leaked credentials directly.
2. How It Works
A Group Policy Object has two parts: a Group Policy Container (the AD object under CN=Policies,CN=System) and a Group Policy Template (files in the SYSVOL share, replicated to every DC). GPOs are linked to sites, domains or OUs; computers and users apply the policies that target them at boot/logon and on refresh.
GPO = [ GPC in AD (metadata, links, ACL) ] + [ GPT in \\domain\SYSVOL\...\{GUID} ]
Domain / OU --link--> GPO --applies to--> Users & Computers in scope
SYSVOL (readable by all authenticated users) holds scripts, registry.pol, GptTmpl.inf
Because SYSVOL is readable by all authenticated users and clients trust and execute what a linked GPO tells them (startup/logon scripts, scheduled tasks, Restricted Groups membership, etc.), the write permission on a GPO is security-critical.
3. The Security Problem
The core risks: (1) Over-permissive GPO ACLs — a non-admin with edit rights on a GPO linked to many machines can add a startup script or scheduled task that runs as SYSTEM everywhere in scope. (2) Restricted Groups / Group Policy Preferences can add attacker-controlled accounts to local Administrators fleet-wide. (3) Group Policy Preferences (GPP) passwords: older GPP features stored credentials in SYSVOL encrypted with a publicly known AES key (the “cpassword” issue) — any authenticated user could decrypt them. Although patched to prevent new ones, legacy cpassword values still linger in SYSVOL in many domains. (4) Writable SYSVOL scripts referenced by GPOs.
4. How Attackers Abuse It
Concept: An attacker enumerates GPO permissions to find one they can edit that is linked broadly, then (in a lab) adds an immediate scheduled task or startup script to gain SYSTEM on target machines — or uses Restricted Groups to place a controlled account into local Administrators. Separately, they search SYSVOL for legacy cpassword values and decrypt them to recover service/local passwords. GPO abuse is attractive because it is “living off the land” — the delivery mechanism is a trusted, native feature.
In an authorized test, this is shown against a lab GPO to prove the permission gap; the report lists each GPO, who can edit it, and what it is linked to, plus any residual cpassword findings.
5. How to Detect It
Command
Get-GPO -All | ForEach-Object { $g = $_; Get-GPPermission -Guid $g.Id -All | Where-Object { $_.Permission -match 'Edit|GpoEditDeleteModifySecurity' -and $_.Trustee.Name -notmatch 'Domain Admins|Enterprise Admins|SYSTEM|Administrators' } | Select-Object @{n='GPO';e={$g.DisplayName}}, @{n='Trustee';e={$_.Trustee.Name}}, Permission }
What it does: Iterates every GPO and reports edit-level permissions granted to trustees outside the expected admin groups.
What to look for: Any ordinary user or broad group (e.g. Authenticated Users, a helpdesk group) with edit rights on a GPO — especially one linked domain-wide.
Defensive use: Directly surfaces the GPO-edit privilege-escalation paths for remediation.
Command
Get-ChildItem "\\corp.local\SYSVOL\corp.local\Policies" -Recurse -Include *.xml,*.inf,*.ini -ErrorAction SilentlyContinue | Select-String -Pattern "cpassword" | Select-Object Path, LineNumber
What it does: Searches SYSVOL for the legacy cpassword attribute left behind by Group Policy Preferences.
What to look for: Any match — a cpassword value is decryptable by anyone and must be removed, and the exposed credential rotated.
Defensive use: Finds one of the most common, high-severity legacy exposures in a single pass.
Command
gpresult /r /scope:computer
What it does: Shows which GPOs are applied to the current computer and their link order/precedence.
What to look for: Unexpected GPOs applying to a host, or GPOs from unexpected OUs — potential unauthorized linkage.
Defensive use: Validates the effective policy set on a specific machine during an audit or incident.
Command
Get-GPO -All | Select-Object DisplayName, GpoStatus, CreationTime, ModificationTime | Sort-Object ModificationTime -Descending
What it does: Lists all GPOs with status and last-modified time.
What to look for: Recently modified GPOs that do not correspond to a change ticket, or enabled GPOs that should be retired.
Defensive use: Provides a change-tracking baseline to spot unauthorized edits.
6. How to Audit the Environment
- Review edit permissions on every GPO; only tier-0 admins should edit domain/OU-wide GPOs.
- Scan SYSVOL for cpassword and any embedded secrets in scripts.
- Check NTFS permissions on SYSVOL scripts — no non-admin should be able to write them.
- Review Restricted Groups and GPP local-user/local-group settings for unexpected accounts being added to Administrators.
- Confirm startup/logon scripts and scheduled tasks in GPOs point only to trusted, non-writable locations.
- Enumerate GPO links per OU to understand blast radius.
7. How to Fix / Harden It
- Remove non-tier-0 edit rights on GPOs; delegate narrowly and prefer separate GPOs for delegated scopes.
- Remove all cpassword occurrences and rotate any exposed credentials immediately.
- Lock down SYSVOL script permissions to admins-write, authenticated-read.
- Use LAPS instead of GPP/Restricted Groups tricks for local admin management.
- Enable “Configuration change” auditing on the Policies container and SYSVOL.
- Consider enforcing UNC hardening and SYSVOL/NETLOGON signing (already default via MS15-011/MS15-014).
8. Detection & Monitoring
- Event ID 5136 / 5137 / 5141 (directory object modified/created/deleted) on GPO objects — watch for GPO creation, link changes and ACL edits.
- Event ID 4663 / 4670 (object access / permissions changed) on SYSVOL policy files.
- Event ID 4698 (scheduled task created) appearing on many endpoints simultaneously can indicate GPO-delivered task abuse.
- File-integrity monitoring on SYSVOL scripts and registry.pol.
9. MITRE ATT&CK Mapping
| Technique | ID |
|---|---|
| Domain Policy Modification: Group Policy Modification | T1484.001 |
| Unsecured Credentials: Group Policy Preferences | T1552.006 |
| Scheduled Task/Job: Scheduled Task | T1053.005 |
| Account Manipulation | T1098 |
10. Practical Lab
In an isolated lab:
- Grant a non-admin edit rights on a test GPO and confirm your GPO-permission audit script flags the trustee.
- Create a legacy GPP drive-map/local-user with a password, then run the cpassword scan and confirm it is found; remediate and re-scan.
- Use
gpresult /rto confirm which GPOs apply to a test machine before and after linking changes. - Enable 5136/5141 auditing on the Policies container and observe events when you edit or link a GPO.
- Replace a Restricted-Groups local-admin approach with LAPS and verify unique local passwords.
11. Key Takeaways
- GPO edit rights equal code execution in scope — restrict them to tier-0 and audit continuously.
- Legacy GPP cpassword values are decryptable by anyone; scan SYSVOL and eliminate them.
- Prefer LAPS over Restricted Groups/GPP for local admin management.
- Alert on GPO creation, linking and ACL changes (Events 5136/5137/5141) and on mass scheduled-task creation (4698).
Continue learning: Active Directory security
This guide is part of our Active Directory Security series. Related guides: