LDAP Injection
LDAP Injection is an attack used to exploit web based applications that construct LDAP statements based on user input.
Detecting LDAP Injection
From the below image, we have been given a valid credential username: hacker, password: hacker
which allowed us to login as user hacker
. Well but our aim here is to find a way to login to any account without a valid credential.
To do that, let’s replace our credential with username: any, password: any
. By Attempting to login with this invalid credential, we get unauthenticated
text telling us that our supplied credential is invalid. see the below image.
Let’s attempt to predict the ldap query. Since the interface is using username and password to authenticate users, the query may be something like this (&(name=user)(password=pass))
, by supplying name=any&password=any
, it will be something like (&(name=any)(password=any))
.
with )
By using )
, we can determine whether or not the backend is using ldap query. If we supply the following parameters name=)&password=any
, the query will be something like (&(name=))(password=any))
. If the backend is using ldap query, it will throw an error as )
will break the ldap query.
The above image shows an ldap error, this means our backend is using ldap query and our supplied input )
broke the command as we predicted.
with %00
Given that )
breaks the ldap query, let’s attempt to fix the query using %00
, ldap query ignores anything that comes after %00
, by supplying the following parameters name=))%00&password=any
, the query will be something like (&(name=))%00)(password=any))
, ldap will ignore anything that comes after %00
, and the final query will be something like (&(name=))
, since this is a valid query, it will be executed without throwing any error.
The above image didn’t show the ldap error, this means our supplied input didn’t break the ldap query as we predicted.
Exploitation
User Login
By using *
in conjunction with %00
, we can login to a user account without valid credential. *
is a regex that tells the ldap to match anything, by supplying the following payload name=*))%00&password=any
, the ldap will interpret it as something like (&(name=*))
which means to match any name, this will allow us to login to a user account that first matches the query.
From the above image, we were able to login as user hacker
.
Admin Login
We can also login to other user’s account by changing our previous payload to something like name=a*))%00&password=any
, the ldap will interpret it as something like (&(name=a*))
which means to match any name that starts with alphaber a
, this will allow us to login to a user account that starts with alphaber a
From the above image, we were able to login as user admin
.
Mitigations
- Escape all variables using the right LDAP encoding function
- Use a framework (like LINQtoLDAP that escapes automatically.