Impacket CheckLDAPStatus.py
Back to the Category Index / Back to the Command Index
Overview
Section titled “Overview”Checks whether a domain controller requires LDAP signing and LDAPS channel binding.
| Item | Details |
|---|---|
| Implementation | examples/CheckLDAPStatus.py |
| Category | Active Directory / LDAP / Account Management |
| Size | 128 lines |
| Distribution | Installed as a script through scripts=examples/*.py in setup.py |
CLI and Inputs
Section titled “CLI and Inputs”Check python examples/CheckLDAPStatus.py -h for the current option definitions.
| Argument | Description |
|---|---|
-dc-ip | IP address of a domain controller or DNS resolver for the domain. Required. |
-domain | Domain name. Required. |
-debug | Turn DEBUG output ON |
-timeout | DNS timeout. Default: 15. |
-ts | Adds timestamp to every logging output |
Detailed Processing Flow
Section titled “Detailed Processing Flow”CheckLDAP.list_dc() identifies the target DCs, then run() tests LDAP signing and LDAPS CBT on each DC in sequence. The former is determined from the LDAPConnection bind result; the latter from authentication results with changed TLS connections and channel binding. The timeout affects both DNS and the connection.
How It Works
Section titled “How It Works”The command does not merely check whether the LDAP port is open. It determines how a domain controller requires signing and TLS channel binding during authentication. For LDAP signing, it observes the response to a SASL/NTLM bind without signing on a plain LDAP session to determine whether the server rejects unsigned binds. For LDAPS CBT, it compares a normal authentication attempt using channel binding data from the TLS server certificate with attempts where CBT is missing or mismatched, and examines the LDAP status difference.
With only -domain, list_dc() discovers candidate DCs from DNS SRV records.
-dc-ip skips discovery and fixes the test to one DC.
Policies may differ among DCs in a domain, so treat each result as
the current response of the tested DC, not as a domain-wide property.
TLS handshake failures, rejected credentials, and CBT policy rejections are
different failures. When changing check_ldaps_cbt(), separate OpenSSL transport
exceptions from LDAP result codes, and do not mistake a failure to authenticate
for CBT enforcement.
Key Implementation Elements
Section titled “Key Implementation Elements”| Symbol | Location | Entry Point for Tracing Behavior |
|---|---|---|
CheckLDAP | 30 | __init__(), list_dc(), run(), check_ldaps_cbt(), check_ldap_signing() |
Dependencies
Section titled “Dependencies”Internal Impacket Modules
Section titled “Internal Impacket Modules”| Module | Main Names Used |
|---|---|
impacket | version |
impacket.examples | logger |
impacket.ldap.ldap | LDAPConnection, LDAPSessionError |
External Packages (Direct Use)
Section titled “External Packages (Direct Use)”| Import Name | Distribution Package | Usage / Declaration Status |
|---|---|---|
OpenSSL | pyOpenSSL | Imported directly; declared dependency |
dns | dnspython | Imported directly; not declared as a direct dependency |
Output, Side Effects, and Required Privileges
Section titled “Output, Side Effects, and Required Privileges”- Primarily queries and authentication attempts. Repeated runs can affect audit logs, account lockouts, and target load.
Failure Paths and Cleanup
Section titled “Failure Paths and Cleanup”- On failure, use protocol status to determine whether name resolution, connection, authentication, service state, or permissions stopped the operation.
When Changing the Implementation
Section titled “When Changing the Implementation”This command uses impacket.ldap.ldap, OpenSSL, and dns.resolver. CheckLDAP owns the main behavior. Since dnspython is not declared as a direct dependency, take care when changing distribution.
Verification
Section titled “Verification”- Syntax:
python -m py_compile examples/CheckLDAPStatus.py - CLI:
python examples/CheckLDAPStatus.py -h - Related test:
tests/SMB_RPC/test_ldap.py

