Can Doom Connect Using Both LDAP and LDAPS? A Complete Guide to Dual-Protocol Authentication
Yes, Doom automatically supports both LDAP and LDAPS connections through a single helper function that attempts unsecured LDAP first and transparently falls back to LDAPS when stronger authentication is required.
The 000pp/doom repository provides a robust LDAP authentication module that eliminates manual protocol selection. Whether your Active Directory environment requires standard LDAP on port 389 or encrypted LDAPS on port 636, Doom handles the negotiation automatically without requiring separate configuration flags.
How Doom Implements Dual-Protocol LDAP Support
The core logic resides in src/doom/protocols/ldap.py, specifically within the get_ldap_connection function. This implementation uses the ldap3 library to create a seamless authentication experience that adapts to server requirements in real-time.
The Connection Logic: LDAP First, LDAPS Fallback
When initiating a connection, Doom follows a specific priority sequence:
- Initial LDAP attempt: The function first creates a server object targeting
ldap://{host}on port 389 withuse_ssl=False. - NTLM authentication: It attempts to bind using NTLM authentication with
session_security="ENCRYPT"requested. - Fallback trigger: If the server responds with a
strongerAuthRequirederror, the code catches this specific exception and proceeds to LDAPS.
This approach ensures compatibility with environments that support both protocols while prioritizing the less restrictive connection when possible.
TLS Configuration and Certificate Handling
For the LDAPS fallback, Doom configures a TLS context that disables certificate validation—a common requirement for internal Active Directory environments using self-signed certificates:
tls = ldap3.Tls(
validate=ssl.CERT_NONE,
version=ssl.PROTOCOL_TLSv1_2,
ciphers='ALL:@SECLEVEL=0'
)
The LDAPS server object targets ldaps://{host} on port 636 with use_ssl=True and the custom TLS context applied.
Authenticating with NTLM and Pre-Hashed Credentials
The get_ldap_connection function handles credential formatting automatically:
- Domain user construction: It builds the NTLM user string as
f"{domain}\\{username}"(line 10 insrc/doom/protocols/ldap.py). - Pre-hashed password detection: If the provided password is exactly 32 characters, the function assumes an NTLM hash and prepends the
aad3b435b51404eeaad3b435b51404eeprefix (lines 12-14).
This allows penetration testers to pass either cleartext passwords or pre-computed NTLM hashes without modifying the connection logic.
Practical Implementation: Using get_ldap_connection
Here is a complete example demonstrating how to use Doom's LDAP functionality in your own scripts:
from doom.protocols.ldap import get_ldap_connection
# Define connection parameters
host = "ad.example.com"
username = "jdoe"
password = "Password123!" # Or 32-char NTLM hash
domain = "EXAMPLE"
try:
# Attempt connection (LDAP first, LDAPS fallback)
conn, base_dn = get_ldap_connection(host, username, password, domain)
# Determine which protocol succeeded
protocol = "LDAPS" if conn.server.use_ssl else "LDAP"
print(f"Successfully connected via {protocol}")
print(f"Base DN: {base_dn}")
# Perform LDAP queries
conn.search(
search_base=base_dn,
search_filter="(objectClass=user)",
attributes=["sAMAccountName", "mail"]
)
for entry in conn.entries:
print(f"User: {entry.sAMAccountName}, Email: {entry.mail}")
except Exception as e:
print(f"Connection failed: {e}")
finally:
if 'conn' in locals():
conn.unbind()
This implementation automatically handles the protocol negotiation, allowing you to focus on querying Active Directory rather than managing connection parameters.
Summary
- Doom's
get_ldap_connectionfunction insrc/doom/protocols/ldap.pyprovides automatic dual-protocol support. - The implementation attempts LDAP on port 389 first, then falls back to LDAPS on port 636 if the server requires stronger authentication.
- NTLM authentication is used for both protocols, with support for both cleartext passwords and pre-hashed NTLM tokens.
- The TLS context disables certificate validation by default, accommodating internal AD environments with self-signed certificates.
- No manual protocol selection is required; the function handles negotiation transparently.
Frequently Asked Questions
Does Doom require separate configuration for LDAP and LDAPS?
No. The get_ldap_connection function handles both protocols automatically. You only need to provide the hostname, username, password, and domain. The code first attempts a standard LDAP connection on port 389, and only if the server responds with a strongerAuthRequired error does it switch to LDAPS on port 636.
What authentication method does Doom use for LDAP connections?
Doom uses NTLM authentication for both LDAP and LDAPS connections. The implementation constructs the user string in the format domain\username and supports both cleartext passwords and pre-computed NTLM hashes. When using hashes, the code automatically prepends the required aad3b435b51404eeaad3b435b51404ee prefix to the 32-character hash.
Is certificate validation enabled for LDAPS connections?
No, certificate validation is disabled by default. The TLS context in src/doom/protocols/ldap.py explicitly sets validate=ssl.CERT_NONE and uses ciphers='ALL:@SECLEVEL=0'. This configuration is designed to work with internal Active Directory environments that commonly use self-signed or enterprise certificates that might not validate against standard trust stores.
Which port numbers does Doom use for LDAP and LDAPS?
Doom uses the standard port numbers: port 389 for unsecured LDAP and port 636 for LDAPS. These are hardcoded in the server object definitions within the get_ldap_connection function. The LDAP server object targets ldap://{host} with use_ssl=False, while the LDAPS server object targets ldaps://{host} with use_ssl=True.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →