What is LDAP Injection and How to Prevent It

LDAP injection

What is LDAP?

Lightweight Directory Access Protocol (LDAP) is a common software protocol designed to enable anyone on a network to find resources such as other individuals, files, and devices. Directory services such as LDAP are useful for intranets. It can also be used to store usernames and passwords as part of a single sign-on (SSO) system.

What is LDAP injection?

LDAP Injection is an attack used to exploit web based applications that construct LDAP statements based on user input. When an application fails to properly sanitize user input, it’s possible to modify LDAP statements through techniques similar to SQL Injection.

LDAP injection attacks could result in the granting of permissions to unauthorized queries, and content modification inside the LDAP tree.

How LDAP Injection Works?

As with SQL injection and related code injection attacks, LDAP injection vulnerabilities occur when an application inserts unsanitized user input directly into an LDAP statement. By crafting suitable string values using LDAP filter syntax, attackers can cause the LDAP server to execute a variety of queries and other LDAP statements. If combined with misconfigured or compromised permissions, LDAP injections may allow attackers to modify the LDAP tree and tamper with business-critical information.

While LDAP injections come in many shapes and sizes, here are two typical approaches:

  • Authentication bypass: Directory services are commonly used for user authentication and authorization, so the most basic LDAP injection attacks attempt to bypass password checking. Take the following vulnerable JavaScript code that directly assembles a simple LDAP filter from user inputs stored in the variables enteredUser and enteredPwd:
filterContent = "(&(userID=" + enteredUser + ")(password=" + 
  enteredPwd + "))"

For non-malicious users, the resulting filter should be something like:

(&(userID=johndoe)(password=johnspwd))

If this query is true, the user and password combination exists in the directory, so the user is logged in. However, an attacker can enter LDAP filter code as the user ID (shown in red) to create a filter that is always true, for example:

(&(userID=*)(userID=*))(|(userID=*)(password=anything))

This can allow the attacker to gain access without a valid user name or password.

  • Information disclosure: If a vulnerable application uses LDAP filters to provision shared resources, for example printers, an attacker performing recon might inject LDAP filter code to list all resources in the organization’s directory. Let’s say the following filter intended to list printers and scanners is assembled in an unsafe way:
(|(resType=printer)(resType=scanner))

If the attacker can enter another value instead of printer and knows that userID is used for user names in the directory, they might inject the following code:

(|(resType=printer)(userID=*))(resType=scanner))

This will list all printer and user objects, and the scanner part will be ignored by the server (only the first complete filter is processed).

Blind LDAP Injection

To directly query an LDAP server, the attacker needs to know (or guess) the attribute names so they can be specified in a filter. Blind LDAP injection is a more advanced exploitation technique for extracting unknown information by sending multiple requests and checking server responses to determine if the query is valid. Combined with additional optimizations and automation, this allows attackers to obtain information using a series of yes/no questions: a valid server response means “yes”, and a server error means “no”. Effective blind injection attacks typically involve several steps:

  • Attribute discovery: Attackers can query a variety of likely attributes and monitor server responses. If an attribute exists, the server will return a valid response. Otherwise, an error or empty response is returned. Let’s say an application unsafely constructs an AND filter to retrieve users, such as:
(&(userID=John Doe)(objectClass=user))

If the attacker can manipulate the user ID value, they can inject code like the following to check if user objects in this directory have a department attribute:

(&(userID=John Doe)(department=*))(objectClass=user))

If the department attribute exists (and John Doe is a valid user ID), the server will return a valid response. Otherwise, the attacker can try other attribute names.

  • Booleanization: Once an attribute name is known, the attacker can send a series of requests containing wildcards and/or comparison operators to determine specific attribute values. Again, only two server responses are considered, so booleanization is the process of transforming the search process into a series of true/false tests.

Let’s say the department attribute from the previous example exists. To discover the department name, the attacker can start by injecting the following code to check the first letter:

(&(userID=John Doe)(department=a*))(objectClass=user))

A valid server response means that a department starting with the letter “a” exists. The attacker can continue the process for ab*, ac*, and so forth, to discover subsequent characters. For numeric values, the operators <= (less than or equal to) and >= (greater than or equal to) can be used to go through the likely value space.

  • Character set reduction: To minimize the number of requests, attackers can use multiple wildcards to find out which characters are present anywhere in the target value. For example, a valid server response for the following injection:
(&(userID=John Doe)(department=*x*))(objectClass=user))

means that a department name containing the letter “x” exists. If an error or empty response is returned, the attacker can eliminate this character from the scan. This can greatly reduce the number of requests needed to find the target value.

LDAP Injection Example

  • The web application has to take the input from the user in order to process it further. The attacker can take leverage of this if the value entered by the users is not sanitized properly and directly goes to the database for execution. Here we will see how the LDAP injection could be launched on any of the web application that is prone to this attack.
<input type="text" size=15 name="uName">IEnter your name</input>
  • The query mentioned above will be transformed into LDAP friendly command so that the application makes it easy for the query to be executed well.
String ldapQueryToSearch= "(sq=" + $userName + ")";
System.out.println(ldapQueryToSearch);
  • In the above case, if the value submitted by the user is not sanitized, it can lead to getting the name of all the existing users by putting “*” in the input box. An asterisk denotes all the available options so when the database will process the asterisk rather any particular username, it will be given all the objects stored in the LDAP database. The actual query that will be executing in the database will be
findingLogin="(&(usrid="+username+")(userPwd={MD5}"+base64(pack("H*",md5(pass)))+"))";
  • When the data is not sanitized and the database accepts the asterisk value to the process, the code will be like below.
findingLogin="(&(usrid=*)(usrid=*))(|(usrid=*)(userPwd={MD5}Xkjr1Hj5LydgyfeuILpxM==))";

As soon as the above vulnerable code will run into the LDAP database, it will through all the objects stored in the LDAP database and will lead to cause harm to the web application. The outcome of LDAP injection will be then used by the hacker to abuse the system and cause the security breach.

How you can Protect form LDAP Injection attacks?

  • Enforce input validation:- Prior to including untrusted input in LDAP queries, the input should be validated against a whitelist of allowed strings or characters. This validation should always be conducted server-side even if the input is previously validated client-side.Structured inputs like social security numbers, phone numbers, and email addresses can be validated using a strong regular expression pattern. Inputs like usernames should be validated against an approved set of characters that exclude LDAP filter control characters.
  • Escape input with encoding:- Escape user-controlled input strings in such a way that any control characters in the input don’t change the intended meaning of the LDAP search filter. For example, in a Java application, metacharacters in an LDAP query can be prepared with backslashes as escape characters. With this method, untrusted inputs are appended to a search filter are as literal string values, not as LDAP predicates.
  • Harden directory authorization:- This defense technique is meant to minimize the impact of any injection attempt by employing the principle of least privilege. The LDAP account used for binding the directory in an application must have restricted access. With this approach, only authorized LDAP queries can be executed against the LDAP server.

Related Post

Leave a Reply

Your email address will not be published. Required fields are marked *