July 4, 2026
LDAP in Active Directory: The Query Language Every Security Pro Must Know
Blog 10 of “Mastering Active Directory — Simplified.” Blog 9 covered DNS and how clients find Domain Controllers. This blog covers LDAP…

By Atharva Deshmukh
9 min read
Blog 10 of "Mastering Active Directory — Simplified." Blog 9 covered DNS and how clients find Domain Controllers. This blog covers LDAP, the protocol that clients use to actually talk to Active Directory once they have found it. Read in order for the best experience.
If DNS is how you find Active Directory, LDAP is how you talk to it. Every enumeration tool used in AD security, PowerView, BloodHound, ldapsearch, ADExplorer, and every custom script that pulls user or computer data from the domain, works by sending LDAP queries to a Domain Controller. Understanding LDAP means understanding exactly what these tools are doing under the hood, which makes you far more effective at both using them and detecting their use.
LDAP in Active Directory is also where a significant portion of the attack surface lives. The search filter syntax that attackers use to find Kerberoastable accounts, locate accounts with pre-authentication disabled, or identify computers configured for unconstrained delegation is all LDAP. The anonymous bind vulnerability that exposes directory data to unauthenticated users is an LDAP configuration issue. The NTLM relay attack path that targets LDAP on Domain Controllers is one of the most commonly used privilege escalation chains in modern red team engagements.
This blog covers what LDAP is, how the directory tree maps onto Active Directory structure, how search filters work, which queries attackers run and why, and the defensive controls that protect the LDAP interface from abuse.
What LDAP Is and Why Active Directory Uses It
LDAP stands for Lightweight Directory Access Protocol. It is an open, vendor-neutral protocol designed for accessing and maintaining distributed directory services over a network. Microsoft built Active Directory on top of LDAP, meaning AD is essentially an LDAP-compliant directory service with a large number of Microsoft-specific extensions and integrations layered on top.
When any application, tool, or user wants to read or write data in Active Directory, it does so through LDAP. Creating a new user account, changing a group membership, searching for all computers with a specific attribute set, reading the permissions on an AD object — all of it goes through LDAP queries sent to a Domain Controller.
LDAP runs on port 389 over TCP and UDP. LDAPS, the encrypted version of LDAP running over TLS, uses port 636. The difference between the two matters from a security perspective. LDAP on port 389 sends queries and responses in cleartext. An attacker with network access between a client and a DC can capture LDAP traffic and read directory data directly. LDAPS encrypts that traffic, protecting it from interception. In modern environments LDAPS should be required, but a significant number of enterprise environments still accept plaintext LDAP connections for compatibility with legacy applications.
The port distinction also matters for NTLM relay attacks. Relaying NTLM authentication to LDAP on port 389 allows certain AD modifications, such as creating computer accounts or reading data. Relaying to LDAPS on port 636 allows a broader set of operations including more sensitive modifications. Attackers specifically target both depending on what the environment allows and what their goal is.
The LDAP Directory Tree and Distinguished Names
Active Directory exposes its data through an LDAP directory tree. Every object in the directory, every user, every computer, every group, every OU, has a unique address in that tree called a Distinguished Name, or DN.
Understanding Distinguished Names is important because every LDAP query references objects by their DN, and enumeration output from tools like PowerView and ldapsearch is full of them.
A Distinguished Name is a comma-separated sequence of attribute-value pairs read from the most specific component on the left to the most general on the right. Each component is called a Relative Distinguished Name, or RDN. The components used in AD Distinguished Names are:
CN stands for Common Name. Used for most leaf objects like users, computers, and groups.
OU stands for Organizational Unit. Used for OU containers in the directory hierarchy.
DC stands for Domain Component. Used to represent each part of the domain's DNS name.
A user called John Smith in the Finance OU of corp.local would have a Distinguished Name of:
CN=John Smith,OU=Finance,DC=corp,DC=localCN=John Smith,OU=Finance,DC=corp,DC=localA group called Domain Admins in the default Users container would look like:
CN=Domain Admins,CN=Users,DC=corp,DC=localCN=Domain Admins,CN=Users,DC=corp,DC=localThe Domain Controller itself in a child domain would look like:
CN=DC01,OU=Domain Controllers,DC=dev,DC=corp,DC=localCN=DC01,OU=Domain Controllers,DC=dev,DC=corp,DC=localThe Base DN is the starting point for an LDAP search. When you tell an LDAP query to start at DC=corp,DC=local, you are telling it to search the entire domain. When you specify OU=Finance,DC=corp,DC=local as the base, you are restricting the search to objects within the Finance OU. Attackers typically use the domain root as the base DN during enumeration to ensure they catch every object in the directory regardless of which OU it lives in.
LDAP Operations: What You Can Do to the Directory
LDAP defines a set of operations for interacting with the directory. Not all of them are equally relevant from a security perspective, but knowing which ones exist and what each does helps when reading tool output or audit logs.
Bind is the authentication operation. Before a client can do anything else with LDAP, it binds to the server by providing credentials. A simple bind sends a username and password. A SASL bind uses a mechanism like Kerberos or NTLM. An anonymous bind sends no credentials at all. Whether anonymous binds are permitted depends on the server configuration, and in environments where they are allowed, unauthenticated users can query directory data without providing any identity.
Search is the operation attackers and administrators use most. A search query specifies a base DN to start from, a scope defining how deep to search, a filter defining which objects to return, and a list of attributes to include in the results. This is the operation behind every enumeration query in tools like PowerView and ldapsearch.
Add creates a new object in the directory. Attackers with sufficient permissions use LDAP Add operations to create new computer accounts during RBCD attacks, which requires only the default MachineAccountQuota permission granted to every domain user.
Modify changes attributes on existing objects. This is the operation behind ACL abuse techniques like setting an SPN on a user object, modifying group membership, or changing the msDS-AllowedToActOnBehalfOfOtherIdentity attribute for RBCD setup.
Delete removes objects from the directory. Less commonly used in attacks but relevant in some persistence cleanup scenarios where attackers remove evidence of created accounts or modified objects.
LDAP Search Filters: The Syntax Behind Every Enumeration Query
LDAP search filters are the query language of Active Directory enumeration. Every time PowerView runs Get-DomainUser or BloodHound's SharpHound collects user data, it is sending LDAP queries with specific filters to a Domain Controller. Understanding the filter syntax means you can read exactly what a tool is asking for, write your own targeted queries, and spot suspicious LDAP queries in network traffic or logs.
LDAP filters use a prefix notation wrapped in parentheses. The basic format for a single condition is:
(attribute=value)(attribute=value)Multiple conditions are combined using logical operators also wrapped in parentheses:
(&(condition1)(condition2)) — AND: both must be true
(|(condition1)(condition2)) — OR: either can be true
(!(condition)) — NOT: condition must be false(&(condition1)(condition2)) — AND: both must be true
(|(condition1)(condition2)) — OR: either can be true
(!(condition)) — NOT: condition must be falseWildcards use the asterisk character. (cn=*) matches any object that has a Common Name attribute set, which is effectively all objects.
Here are the LDAP filters that come up most often during Active Directory security assessments:
All users with SPNs set (Kerberoasting candidates):
(&(objectClass=user)(servicePrincipalName=*))(&(objectClass=user)(servicePrincipalName=*))All users with Kerberos pre-authentication disabled (AS-REP Roasting candidates):
(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=4194304))(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=4194304))All computers with Unconstrained Delegation enabled:
(&(objectClass=computer)(userAccountControl:1.2.840.113556.1.4.803:=524288))(&(objectClass=computer)(userAccountControl:1.2.840.113556.1.4.803:=524288))All members of Domain Admins:
(&(objectClass=user)(memberOf=CN=Domain Admins,CN=Users,DC=corp,DC=local))(&(objectClass=user)(memberOf=CN=Domain Admins,CN=Users,DC=corp,DC=local))All accounts with AdminCount set to 1 (protected objects):
(&(objectClass=user)(adminCount=1))(&(objectClass=user)(adminCount=1))All enabled user accounts:
(&(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))(&(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))The userAccountControl filters use a bitwise matching rule, which is why they look more complex than simple attribute comparisons. The OID 1.2.840.113556.1.4.803 means "bitwise AND" and is used to check whether a specific bit in the UserAccountControl integer is set. Bit 4194304 corresponds to DONT_REQUIRE_PREAUTH. Bit 524288 corresponds to TRUSTED_FOR_DELEGATION. These bitwise filters are the reason UserAccountControl is so useful during enumeration despite being a single numeric attribute — it encodes dozens of account properties as individual bits.
Anonymous LDAP Bind: When the Directory Talks Without Asking Who You Are
By default in modern Active Directory configurations, anonymous LDAP binds are partially restricted. A client that sends an LDAP bind with no credentials will receive a successful bind response but with limited access to the directory. In this default state, anonymous users can typically read a small subset of attributes on the root DSE object, which is a special entry that describes the capabilities of the LDAP server.
However, in older environments or in environments where administrators have explicitly relaxed the restriction to support legacy applications, anonymous LDAP binds can return much more. In these cases, an unauthenticated user on the network can send LDAP search queries to a Domain Controller on port 389 and receive user objects, group objects, computer objects, and attribute data in return.
The implication is significant. An attacker who does not yet have any domain credentials can enumerate usernames, group memberships, and account properties from Active Directory without authenticating at all. This turns the directory into a pre-authentication intelligence source, providing everything needed to plan a password spraying attack, an AS-REP Roasting attempt against no-preauth accounts, or a targeted phishing campaign based on real usernames.
Checking for anonymous LDAP bind is one of the first things done during an external penetration test against an organization with internet-exposed LDAP. Finding it open is considered a significant finding because it exposes internal directory data before any authentication barrier has been cleared.
LDAP Signing and Channel Binding
These two controls are the most important LDAP-specific defenses in any Active Directory environment and they are frequently misconfigured or simply never enabled.
LDAP Signing requires that all LDAP traffic be cryptographically signed to prove it has not been tampered with in transit. When LDAP signing is enforced on a Domain Controller, any client that connects without signing enabled will have its connection rejected. This breaks NTLM relay attacks that target LDAP on port 389, because the relay involves forwarding authentication from a third party and the relayed session cannot sign traffic it did not originate.
LDAP Channel Binding ties the LDAP authentication to the specific TLS channel it is being performed over. It prevents an attacker from taking an authenticated LDAP session established over one TLS connection and using it over a different connection. This breaks NTLM relay attacks that target LDAPS on port 636 by ensuring the authentication is bound to a specific encrypted channel that the attacker cannot replicate.
Both controls need to be enabled together to be fully effective. Enforcing signing without channel binding still leaves LDAPS-based relay attacks possible. Enforcing channel binding without signing still leaves unsigned LDAP relay attacks viable.
Microsoft has recommended enabling both since 2020 and released advisories flagging environments where neither is enforced. Despite this, a large number of enterprise environments still operate with both controls disabled or in advisory-only mode, which generates log events but does not block the connections.
A Real-World Scenario: LDAP Enumeration to Attack Planning
A red team has gained domain user credentials through a phishing email. Before running SharpHound or any tool that generates large volumes of authentication traffic, they want to understand the environment quietly using targeted LDAP queries.
They connect to the Domain Controller on port 389 using their compromised credentials and start with basic domain information. The root DSE query tells them the domain's base DN, the forest functional level, and which DC they are connected to.
They query for all users with SPNs set using the Kerberoastable filter. Eleven accounts come back. They note the SPN types: six are MSSQLSvc SPNs for SQL Server instances, three are HTTP SPNs for web applications, two are for custom services. They check the password last set attribute on each account. Four of the eleven have passwords older than three years.
They query for users with pre-authentication disabled. Two accounts come back. Both are service accounts for a legacy application. No special privileges showing in their memberOf attributes, but the accounts are worth an AS-REP Roast attempt anyway since they might have local admin rights set directly on machines rather than through groups.
They query for computers with Unconstrained Delegation enabled using the delegation filter. Nine computers come back. Three are Domain Controllers, which is expected. Six are not. Two of the non-DC machines are identified by their hostnames as web servers.
They query for AdminCount=1 accounts. Forty-three accounts come back, far more than the number of active administrators they would expect. This suggests old admin accounts were never cleaned up after employees left or roles changed.
In under fifteen minutes, using only LDAP queries that any authenticated domain user can run, they have a complete picture of Kerberoasting targets, AS-REP Roasting candidates, misconfigured delegation, and over-privileged accounts. That picture drives every subsequent decision in the engagement.
Cheat Sheet: LDAP Quick Reference for AD Security
Up Next
Blog 11 covers Active Directory replication and DCSync: how Domain Controllers replicate data between each other, what the DRS protocol is, and how attackers abuse the replication interface to pull every password hash in the domain silently over the network without ever logging into a Domain Controller.
Follow the series on Medium to stay in order.
This blog is part of "Mastering Active Directory — Simplified" by w0lfstrong. Aligned with CRT-P, CRTP, red team engagements, and internal penetration testing. Read more at medium.com/@w0lfstrong