Skip to content
HackIndex logo

HackIndex

LDAP Authenticated Deep Dive

4 min read May 15, 2026

Beyond user and group enumeration, authenticated LDAP access exposes domain trusts, Group Policy objects, organizational unit structure, computer accounts, and ACL configurations that reveal attack paths not visible in basic queries. Run this when you have credentials and need a complete picture of the domain before planning your next move.

Domain and forest structure

┌──(kali㉿kali)-[~]
└─$ # Domain controllers
┌──(kali㉿kali)-[~]
└─$ ldapsearch -x -H ldap://$TARGET_IP -D "$USER@$DOMAIN" -w "$PASSWORD" -b "$BASE_DN" "(&(objectClass=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))" dNSHostName operatingSystem
 
┌──(kali㉿kali)-[~]
└─$ # Domain trusts
┌──(kali㉿kali)-[~]
└─$ ldapsearch -x -H ldap://$TARGET_IP -D "$USER@$DOMAIN" -w "$PASSWORD" -b "CN=System,$BASE_DN" "(objectClass=trustedDomain)" name trustDirection trustType trustAttributes flatName
 
┌──(kali㉿kali)-[~]
└─$ # Sites and subnets (reveals internal network layout)
┌──(kali㉿kali)-[~]
└─$ ldapsearch -x -H ldap://$TARGET_IP -D "$USER@$DOMAIN" -w "$PASSWORD" -b "CN=Sites,CN=Configuration,$BASE_DN" "(objectClass=site)" cn
┌──(kali㉿kali)-[~]
└─$ ldapsearch -x -H ldap://$TARGET_IP -D "$USER@$DOMAIN" -w "$PASSWORD" -b "CN=Subnets,CN=Sites,CN=Configuration,$BASE_DN" "(objectClass=subnet)" cn siteObject

trustDirection values: 1 = inbound (they trust us), 2 = outbound (we trust them), 3 = bidirectional. An outbound trust means accounts from the trusted domain can authenticate in this domain. trustAttributes value 8 means the trust is transitive — it extends to all domains trusted by the trusted domain. For exploitation paths, see AD Domain Trust Abuse.

Organizational units

OU structure tells you how the environment is organised and where specific computer types and users live. High-value OUs to note: servers, domain controllers, service accounts, and any OU that appears locked down differently from the rest.

┌──(kali㉿kali)-[~]
└─$ # All OUs with description
┌──(kali㉿kali)-[~]
└─$ ldapsearch -x -H ldap://$TARGET_IP -D "$USER@$DOMAIN" -w "$PASSWORD" -b "$BASE_DN" "(objectClass=organizationalUnit)" ou description
 
┌──(kali㉿kali)-[~]
└─$ # Objects in a specific OU
┌──(kali㉿kali)-[~]
└─$ ldapsearch -x -H ldap://$TARGET_IP -D "$USER@$DOMAIN" -w "$PASSWORD" -b "OU=Servers,$BASE_DN" "(objectClass=computer)" dNSHostName operatingSystem
 
┌──(kali㉿kali)-[~]
└─$ # Count objects per OU
┌──(kali㉿kali)-[~]
└─$ ldapsearch -x -H ldap://$TARGET_IP -D "$USER@$DOMAIN" -w "$PASSWORD" -b "$BASE_DN" "(objectClass=organizationalUnit)" ou | grep "^ou:"
Explain command
-x Use simple authentication instead of SASL.
-H ldap://$TARGET_IP Specify the LDAP server URI to connect to.
-D "$USER@$DOMAIN" Bind DN (distinguished name) used for authentication.
-w "$PASSWORD" Password for the bind DN authentication.
-b "$BASE_DN" Search base DN to start the LDAP query from.
(objectClass=organizationalUnit) LDAP filter to match only organizational unit objects.
ou description Attributes to retrieve: OU name and description.
-b "OU=Servers,$BASE_DN" Restricts search base to the Servers OU subtree.
(objectClass=computer) LDAP filter to match only computer objects.
dNSHostName operatingSystem Attributes to retrieve: DNS hostname and OS of computers.
ou Attribute to retrieve: organizational unit name only.
grep "^ou:" Filters output to lines starting with the ou attribute.

Computer accounts

Computer accounts are often overlooked as attack targets. They have passwords, can have SPNs, and can have delegation configured. A machine account compromise can be leveraged the same way a user account can.

┌──(kali㉿kali)-[~]
└─$ # All computers with OS and last logon
┌──(kali㉿kali)-[~]
└─$ ldapsearch -x -H ldap://$TARGET_IP -D "$USER@$DOMAIN" -w "$PASSWORD" -b "$BASE_DN" "(objectClass=computer)" dNSHostName operatingSystem operatingSystemVersion lastLogon sAMAccountName
 
┌──(kali㉿kali)-[~]
└─$ # Computers with SPNs set
┌──(kali㉿kali)-[~]
└─$ ldapsearch -x -H ldap://$TARGET_IP -D "$USER@$DOMAIN" -w "$PASSWORD" -b "$BASE_DN" "(&(objectClass=computer)(servicePrincipalName=*))" dNSHostName servicePrincipalName
 
┌──(kali㉿kali)-[~]
└─$ # Computers not logged in for 90+ days (stale — often unpatched)
┌──(kali㉿kali)-[~]
└─$ ldapsearch -x -H ldap://$TARGET_IP -D "$USER@$DOMAIN" -w "$PASSWORD" -b "$BASE_DN" "(&(objectClass=computer)(lastLogon<=133000000000000000))" dNSHostName operatingSystem
Explain command
-x Use simple authentication instead of SASL.
-H ldap://$TARGET_IP Specify the LDAP server URI to connect to.
-D "$USER@$DOMAIN" Bind DN (credentials) used to authenticate to LDAP.
-w "$PASSWORD" Password for the bind DN provided via -D.
-b "$BASE_DN" Base DN defining the search starting point in the directory.
(objectClass=computer) LDAP filter matching all computer objects in the directory.
dNSHostName operatingSystem operatingSystemVersion lastLogon sAMAccountName Requested attributes: DNS name, OS info, last logon time, and account name.
(&(objectClass=computer)(servicePrincipalName=*)) LDAP filter matching computers with at least one SPN set.
dNSHostName servicePrincipalName Requested attributes: DNS hostname and associated SPNs.
(&(objectClass=computer)(lastLogon<=133000000000000000)) LDAP filter matching computers with lastLogon at or before the given timestamp.
dNSHostName operatingSystem Requested attributes: DNS hostname and operating system name.

Group Policy Objects

GPOs frequently contain useful information — local admin configurations, software deployments, logon scripts, and occasionally hardcoded credentials in script paths. The GPO name alone tells you a lot about what is being configured.

┌──(kali㉿kali)-[~]
└─$ # All GPOs
┌──(kali㉿kali)-[~]
└─$ ldapsearch -x -H ldap://$TARGET_IP -D "$USER@$DOMAIN" -w "$PASSWORD" -b "CN=Policies,CN=System,$BASE_DN" "(objectClass=groupPolicyContainer)" displayName gPCFileSysPath
 
┌──(kali㉿kali)-[~]
└─$ # GPO links on OUs
┌──(kali㉿kali)-[~]
└─$ ldapsearch -x -H ldap://$TARGET_IP -D "$USER@$DOMAIN" -w "$PASSWORD" -b "$BASE_DN" "(gPLink=*)" distinguishedName gPLink
 
┌──(kali㉿kali)-[~]
└─$ # Read GPO files from SYSVOL (credentials often in scripts)
┌──(kali㉿kali)-[~]
└─$ ldapsearch -x -H ldap://$TARGET_IP -D "$USER@$DOMAIN" -w "$PASSWORD" -b "CN=Policies,CN=System,$BASE_DN" "(objectClass=groupPolicyContainer)" gPCFileSysPath | grep gPCFileSysPath
gPCFileSysPath: \\corp.local\SysVol\corp.local\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}
Explain command
-x Use simple authentication instead of SASL.
-H ldap://$TARGET_IP Specify the LDAP server URI to connect to.
-D "$USER@$DOMAIN" Bind DN (distinguished name) used for authentication.
-w "$PASSWORD" Password for the bind DN provided via -D.
-b "CN=Policies,CN=System,$BASE_DN" Search base DN scoped to the Group Policy Policies container.
(objectClass=groupPolicyContainer) LDAP filter matching Group Policy Container objects.
displayName Requested attribute returning the human-readable GPO name.
gPCFileSysPath Requested attribute returning the SYSVOL UNC path of the GPO.
-b "$BASE_DN" Search base DN set to the root of the domain.
(gPLink=*) LDAP filter matching objects that have any GPO link applied.
distinguishedName Requested attribute returning the full DN of matched objects.
gPLink Requested attribute listing GPOs linked to each OU.
| grep gPCFileSysPath Pipes output and filters lines containing the SYSVOL path attribute.

The gPCFileSysPath value is the UNC path to the GPO's files on SYSVOL. Mount that path via SMB and inspect the scripts and XML files — Group Policy Preferences XML files historically contained encrypted passwords (cpassword) that are trivially decrypted with a published AES key.

ACL-based attack paths

Object ACLs in AD control who can modify objects. Misconfigurations like WriteDACL, GenericWrite, or ForceChangePassword rights on high-value objects allow privilege escalation without exploiting any software vulnerability.

┌──(kali㉿kali)-[~]
└─$ # Read ACL of a specific object
┌──(kali㉿kali)-[~]
└─$ ldapsearch -x -H ldap://$TARGET_IP -D "$USER@$DOMAIN" -w "$PASSWORD" -b "$BASE_DN" "(sAMAccountName=targetuser)" nTSecurityDescriptor
 
┌──(kali㉿kali)-[~]
└─$ # windapsearch — formatted ACL output
┌──(kali㉿kali)-[~]
└─$ windapsearch -d $DOMAIN --dc $TARGET_IP -u $USER -p $PASSWORD -m custom --filter "(sAMAccountName=Domain Admins)" --attrs nTSecurityDescriptor
 
┌──(kali㉿kali)-[~]
└─$ # BloodHound is the most effective tool for ACL path analysis
┌──(kali㉿kali)-[~]
└─$ # Run SharpHound on a domain-joined host:
┌──(kali㉿kali)-[~]
└─$ SharpHound.exe -c All --outputdirectory C:\Windows\Temp\bh
 
┌──(kali㉿kali)-[~]
└─$ # Or from Linux with BloodHound.py
┌──(kali㉿kali)-[~]
└─$ pip3 install bloodhound --break-system-packages
┌──(kali㉿kali)-[~]
└─$ bloodhound-python -d $DOMAIN -u $USER -p $PASSWORD -dc $TARGET_IP -c All

BloodHound is the most practical tool for ACL-based attack path analysis. After collection, the pre-built queries Shortest Paths to Domain Admins and Find Principals with DCSync Rights immediately surface the most direct escalation paths in the environment. For structured ACL enumeration see Active Directory ACL Enumeration; for exploitation see ACL Abuse Privilege Escalation.

Using windapsearch for structured output

windapsearch wraps common AD LDAP queries and formats output cleanly. Faster than raw ldapsearch for most tasks.

┌──(kali㉿kali)-[~]
└─$ # All users
┌──(kali㉿kali)-[~]
└─$ windapsearch -d $DOMAIN --dc $TARGET_IP -u $USER -p $PASSWORD -m users
 
┌──(kali㉿kali)-[~]
└─$ # All computers
┌──(kali㉿kali)-[~]
└─$ windapsearch -d $DOMAIN --dc $TARGET_IP -u $USER -p $PASSWORD -m computers
 
┌──(kali㉿kali)-[~]
└─$ # All groups
┌──(kali㉿kali)-[~]
└─$ windapsearch -d $DOMAIN --dc $TARGET_IP -u $USER -p $PASSWORD -m groups
 
┌──(kali㉿kali)-[~]
└─$ # Privileged users
┌──(kali㉿kali)-[~]
└─$ windapsearch -d $DOMAIN --dc $TARGET_IP -u $USER -p $PASSWORD -m privileged-users
 
┌──(kali㉿kali)-[~]
└─$ # GPOs
┌──(kali㉿kali)-[~]
└─$ windapsearch -d $DOMAIN --dc $TARGET_IP -u $USER -p $PASSWORD -m gpos
 
┌──(kali㉿kali)-[~]
└─$ # Unconstrained delegation
┌──(kali㉿kali)-[~]
└─$ windapsearch -d $DOMAIN --dc $TARGET_IP -u $USER -p $PASSWORD -m unconstrained-users
┌──(kali㉿kali)-[~]
└─$ windapsearch -d $DOMAIN --dc $TARGET_IP -u $USER -p $PASSWORD -m unconstrained-computers
Explain command
-d $DOMAIN Specifies the target Active Directory domain name.
--dc $TARGET_IP Specifies the IP address of the domain controller to query.
-u $USER Username for LDAP bind authentication.
-p $PASSWORD Password for LDAP bind authentication.
-m users Enumerates all user objects in the domain via LDAP.
-m computers Enumerates all computer objects in the domain via LDAP.
-m groups Enumerates all group objects in the domain via LDAP.
-m privileged-users Enumerates users in high-privilege groups (e.g. Domain Admins).
-m gpos Enumerates all Group Policy Objects in the domain.
-m unconstrained-users Enumerates user accounts with unconstrained Kerberos delegation set.
-m unconstrained-computers Enumerates computer accounts with unconstrained Kerberos delegation set.

Unconstrained delegation results feed directly into Unconstrained Delegation Abuse. For ADCS template misconfigurations discovered via LDAP, see ADCS Misconfiguration Discovery.

References