LDAP Injection
Lightweight Directory Access Protocol (LDAP) is a protocol used to access directory servers such as Active Directory (AD) via queries to retrieve information. Web applications may use LDAP for integration with AD or other directory services for authentication or data retrieval purposes.
LDAP Fundamentals
Basic Terminology
Directory Server (DS)
The system that stores and manages directory data just like a database.
LDAP Entry
Represents a single entity (e.g., a user, group, or device) in the directory.
Distinguished Name (DN)
The unique identifier of an entry, made of one or more RDNs (e.g.uid=sfoffo,dc=example,dc=it).
Relative Distinguished Name (RDN)
A keyโvalue pair that forms part of a DN (uid=sfoffo).
Attributes
Hold the data for an entry (e.g., name, department).
Object Classes
Defines sets of related attributes for a specific type of object.
LDAP Operations
LDAP defines operations, which are actions that the client can initiate:
Bind
Client authentication with the server
Unbind
Close the client connection to the server
Add
Create a new entry
Delete
Delete an entry
Modify
Modify an entry
Search
Search for entries matching a search query
LDAP Search Filters (search queries)
LDAP search queries are called search filters.
A search filter may consist of multiple components enclosed in parentheses ().
Each base component consists of an attribute, an operand, and a value to search for.
Equality
=
(name=Kaylie)
Matches all entries that contain a name attribute with the value Kaylie
Greater-Or-Equal
>=
(uid>=10)
Matches all entries that contain a uid attribute with a value greater-or-equal to 10
Less-Or-Equal
<=
(uid<=10)
Matches all entries that contain a uid attribute with a value less-or-equal to 10
Approximate Match
~=
(name~=Kaylie)
Matches all entries that contain a name attribute with approximately the value Kaylie
Note: different LDAP implementations may have different result for approximate matches.
LDAP Search Operands and Values
And
(&()())
(&(name=Kaylie)(title=Manager))
Or
(|()())
(|(name=Kaylie)(title=Manager))
Not
(!())
(!(name=Kaylie))
True
(&)
False
(|)
LDAP supports wildcards such as:
(name=*)
Matches all entries that contain a name attribute
(name=S*)
Matches all entries that contain a name attribute that begins with S
(name=*s*)
Matches all entries that contain a name attribute that contains an s
Authentication Bypass
LDAP is commonly used to enable Active Directory users to access web applications. Considering an example of a web application that allows users to login using their username and password, we may suppose the underlying search query is:
This authentication mechanism can be bypassed in several ways:
Using Wildcards
If you know any valid username (such as admin), you might input:
to gain the following query, allowing you to login as admin without their password:
If you don't know any valid user, you can try using a wildcard for both parameters to make the search query return all users. This will most probably make you login as the first user returned by the query.
Without Wildcards
Wildcard operators might be blacklisted by the web application. In those cases, it is useful to leverage arithmetic logic units to create conditions that will always be true.
If you know a valid username (such as admin), you might input:
You may also try guessing usernames, such as by looking for usernames containing the word "admin" in them leveraging a username payload such as username=*admin*)(|(&
Of course, this requires you to be able to inject wildcards.
To gain the following query:
Step by step, this query is resolved to: -> (username=admin) AND (true OR password=wrong) --> (username=admin) AND (true OR false) ---> (username=admin) AND true
allowing you to bypass the password check and login as the admin user
Data Exfiltration
The easiest case of data exfiltration is when a search query displays the names of the entries displayed.
For example, consider you can input the uid parameter and the underlying query is the following
You can easily retrieve all user's informations using a wildcard:
Blind Exfiltration
Since LDAP does not provide a function similar to SQL's sleep, we need an indicator by the web application that informs us whether the query returns any results or not.
Consider a web application that allows sending emails to users.
If the provided username is valid, the web application responds with "Mail sent", otherwise it responds with a generic error, without providing any additional info. In that case, you can confirm whether an LDAP injection is in place by simply injecting a LDAP payload such as a wildcard:
If the LDAP injection exists, the web application will respond with "Mail sent", sending the email to the first username it found from the matching query.
In this example, we can bruteforce valid usernames by using queries containing substrings, one character at a time, for example:
Since the web application's response allows understanding whether the mail was sent, we can understand if a new character is valid.
After identifying a valid username, we may also try exfiltrating the user's password by injecting an AND clause that iterates again on the password attribute, for example:
If the email is successfully sent, the password attribute exists and can be injected, meaning you can proceed with the same iteration until you fully match the user's password.