LDAP protocol basics and the LDAP Injection attack
Tags: cybersecurity, security, hacktoberfest, hacking
Published: 2023-12-03 14:16:58


It is very likely that when you go to your first job interview for a security position, you will encounter a question about the LDAP protocol. It is one of the basic concepts and is one of the most frequently discussed topics with people taking their first steps in the industry. In this article we will look at LDAP, learn about the LDAP Injection vulnerability and how to defend against it.

## Lightweight Directory Access Protocol

Registered users on Linux systems are kept in the `/etc/passwd` file.

```
file: /etc/passwd
root:x:0:0:root:/root:/bin/zsh
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
```

When there are few supported machines and their users, managing them should not be much of a problem. On the other hand, when there is a high number of users, changing their passwords, deleting accounts, etc. can become problematic. Then centralized systems for managing user accounts come to the rescue. To implement them, LDAP protocol is most often used.

Lightweight Directory Access Protocol uses the TCP/IP protocol for information exchange. LDAP ultimately allows access to address directories, which can be compared to a standard relational database. OpenLDAP describes communication with the protocol as follows:

> The LDAP directory service is based on a client-server model. One or more LDAP servers contain the data that makes up the directory information tree (DIT). A client connects to the servers and asks them a question. The server responds with an answer and/or an indication of where the client can obtain additional information (usually another LDAP server). Regardless of which LDAP server the client connects to, it sees the same view of the directory; the name presented to one LDAP server refers to the same entry that would be found on another LDAP server. This is an important feature of a global directory service such as LDAP.
>
> <https://www.openldap.org/doc/admin21/intro.html>

LDAP is used in software such as Active Directory from Microsoft and SSSD on Linux systems, among others.

## LDAP Injection

As with the SQL Injection attack, LDAP Injection involves the misuse of user input. Based on them, the application constructing LDAP statements, which are not filtered in any way, can lead to the execution of arbitrary commands on the server such as granting permissions to unauthorized queries and modifying the contents of the LDAP tree.

## Examples

### Access Controll Bypass

The first example we will discuss is used to bypass access control (Access Controll Bypass). Let's imagine a situation where there is a standard login page, where you have to enter a login and password to log in. To confirm the existence of a user in the application database, LDAP constructs search filters and sends them to the LDAP server, which processes only the first filter (`USER`). The sent construction looks as follows:

```
(&(USER=ENTERED_USERNAME_FROM_FORM)(PASSWORD=ENTERED_PASSWORD_FROM_FORM))
```

Assuming that the user sends a valid username as the `USER` value with an additional string appended, our construction will look like this:

```
(&(USER=John)(&))(PASSWORD=ENTERED_PASSWORD_FROM_FORM))
```

As you can see, the additional string that is included is `)(&))`. Thanks to it, it is possible to enclose the transmitted structure in a place we control. In addition, the LDAP server reads as a password the value `&`, which itself means absolute truth. This results in the server reading the request as correct, and we will be logged in. The rest of the construction, i.e. (`(PASSWORD=ENTERED_PASSWORD_FROM_FORM)`) is irrelevant.

### Information Disclosure

Some LDAP systems use `OR` queries. Its form may look as follows:

```
(|(type=MY_TYPE_01)(type=MY_TYPE_02))
```

The above constructs are used when we want to filter the database for several types of a given source. As an example, we could search for all blog posts whose category is `programming` or `linux`. Assuming that the server supports such filtering capability, we can set the value of `category` to `linux)(uid=*))`. Thus constructed, the structure looks as follows:

```
(|(category=linux)(uid=*))(category=programming))
```

The asterisk sign on LDAP servers is interpreted as "all." This means that in the response we could (if the server was vulnerable) get all blog posts with the `linux` category and all users. This is because `uid` refers to the `id` of said users.

### Blind LDAP Injection

The last of the ways to exploit vulnerable LDAP servers is blind LDAP Injection. It involves the user entering unfiltered values by the server into an LDAP query. Based on the response (true of false), we are able to determine whether the query given was valid. If it was, it means that the value we entered is also correct.

As an example, suppose we have a database of users. One of the application's functionalities is to display the user's non-sensitive data after accessing his account. Let's assume that their phone numbers are also stored in the database. The query directed to the LDAP server after accessing the user's profile looks like this:

```
(&(uid=12))
```

As in the previous examples, let's append an additional string `12)(phonenumber=*` to the id value. Thus, our created query is:

```
(&(uid=12)(phonenumber=*))
```

Since the `phonenumber` field can take any value, the server will return true. Suppose the phone number of a user with `id` equal to `12` is `000-000-000`.

```
(&(uid=12)(phonenumber=0*))
```

By trial and error, we are able to guess (based on the server's response) the user's phone number. A similar attack was described in one of our previous posts.

## How to defend yourself?

There are several ways to protect yourself. These include:

- Filtering the data received and returned to the user (creating a whitelist and filtering the data based on regular expressions seems to be the easiest),
- Using frameworks proven to automatically defend against LDAP Injection attacks,
- Limiting the application's privilege to the necessary (principle of least privilege).

## Sources

<https://en.wikipedia.org/wiki/List_of_LDAP_software>
<https://www.openldap.org/doc/admin21/intro.html>
<https://bugspace.pl/phonebook-hack-the-box/>
<https://cheatsheetseries.owasp.org/cheatsheets/LDAP_Injection_Prevention_Cheat_Sheet.html>