Tag Archives: LDAP

LDAP Injection

What is LDAP

LDAP (Lightweight Directory Access
Protocol) is a standard protocol for managing directories, that is to say,
access to databases of information. This information is generally related to
users, but they are sometimes used for other purposes such as to manage the
equipment in a company.

What is the best way to protect
yourself from SQLi? Don’t use it, period. This simple idea made eventually its
way to some organization (like banks!) and introduced a new question, how to
replace SQL. Hey LDAP should be right! And boom, LDAP auth from a website is
born. And bang, LDAP injection also! The same advanced exploitation techniques
available in SQL Injection can also be similarly applied in LDAP Injection.

Initially based on X.500 protocol
(and named X500-DAP) in lately 1980’s, LDAP is based on TCP/IP stack since 1993
(by default on TCP port 389) and has earned the Lightweight in the same time.
As it’s only a protocol, LDAP defines how the data is accessed from the client
to the server, and not the way in which information is stored. LDAP provides
the information as a hierarchical tree called DIT (Directory Information Tree).
An attribute has a name (an attribute type or attribute description) and one or
more values.

The common methods are:

  • Bind – authenticate and specify LDAP protocol version
  • Search – search for and/or retrieve directory entries
  • Compare – test if a named entry contains a given attribute value
  • Add a new entry
  • Delete an entry
  • Modify an entry
  • Unbind – close the connection (not the inverse of Bind)

Common LDAP servers are:

  • Apache Directory Server
  • Open Directory d’Apple
  • Red Hat Directory Server
  • OpenLDAP
  • Novell eDirectory
  • Active Directory de Microsoft

Save me from SQL
injection!

What is the best way to protect
yourself from SQLi? Don’t use it, period. This simple idea made eventually its
way to some organization (like banks!) and introduced a new question, how to
replace SQL. Hey LDAP should be right! And boom, LDAP auth from a website is
born. And bang, LDAP injection also! The same advanced exploitation techniques
available in SQL Injection can also be similarly applied in LDAP Injection.

LDAP Query

LDAP Query use simple
attribute-value match. For example, if you want to find all objects that have
the first name of Alice, you would use:

(givenName=Alice)

Parentheses are included to
emphasize the beginning and end of the LDAP statement.

Multiple conditions

If you want to find all objects that
have the first name of Alice AND is in Toronto, you would use:

(&(givenName=Alice)(l=Toronto))

  You can also use the OR token:

(|(givenName=Alice) (givenName=Bob))

First and last parentheses are
included to emphasize the beginning and end of the LDAP statement. You can even
make a search with more condition:

(&(givenName=Alice)(|(l=Montreal)(l=Toronto)))  

Wildcard

Here is the best; LDAP loves
wildcard. You can find all objects that have a title attribute:

(title=*)

Or all objects that have the first
name starting with A:

(givenName=A*)

Parentheses are included to
emphasize the beginning and end of the LDAP statement.

Selection of
attributes

In SQL, we can select attributes
with SELECT:

SELECT name, job, phone FROM list WHERE name=$name

In LDAP, we can do the same with ;
at the end of the statement:

(givenName=$name);givenName,phone,job

If an attribute doesn’t exist, there
is an error

(givenName=$name) ;givenName,phone,job,color

Weird returns

On some LDAP server, like OpenLdap,
only the first group of parantheses is evaluated:

(givenName=Alice) (givenName=Bob)

This returns only objects that have
the first name of Alice, without any error.

Another interesting thing is that
there is no error if an attribute that doesn’t exist BUT starts with a valid
name, is simply ignored.

(givenName=$name) ;givenName,phone,jobYGCIUDHOISUHD,job

LDAP Injection

A login page has two text box fields
for entering user name and password. Uname and Pwd are the user inputs for USER
and PASWORD. To verify the existence of the user/password pair supplied by a
client, an LDAP search filter is constructed and sent to the LDAP server:

(&(USER=$Uname)(PASSWORD=$Pwd))

WildCard Injection

If wildcard are available, a simple * in password
should do the trick:

User Injection

We can also use the fact that only
the first group is evaluated:

Password Injection

In LDAP, password is rarely
injectable because it is often hashed before to be sent to the LDAP server.

(&(USER=$Uname)(PASSWORD={MD5}fd9ee57179a15116ed6a560a15d30afd))

Attribute Injection

Example of a phone directory:

(& (ou=$Ugroup)(cn=$Uname));cn,telephone

We can use here the starting
attribute trick and request all passwords:

Blind Injection

If we can’t use Attribute Injection,
we can use, just like Blind SQLi, Blind LDAP Injection, by recursively trying
every first chars of a value of a specific attribute.

If we want to get the street address of Alice from the Phone book:

(& (ou=$Ugroup)(cn=$Uname));cn,telephone

Mitigation

Just like SQLi, the mitigation is
quiet simple: User Input Validation!

The escape sequence for properly
using user supplied input into LDAP differs depending on if the user input is
used to create the DN (Distinguished Name) or used as part of the search
filter. The listings below shows the character that needs to be escape and the
appropriate escape method for each case.

Finally, ignore the request if there
are more than 2 externals parentheses.

Rémi Menegon, M.Sc.A., BEng, CISSP