Skip to main content
LDAP and LDAPS are the highest-value NTLM relay targets in most Active Directory environments. Relaying to LDAP/LDAPS allows an attacker to write arbitrary attributes to AD objects — including adding themselves to privileged groups, setting RBCD, or performing a shadow credential attack. RelayKing checks both the plaintext LDAP port (389) for signing enforcement and the TLS LDAP port (636) for channel binding enforcement.

What is checked

CheckPortAuth requiredNotes
LDAP signing requirement389NoProbed by attempting a bind without signing using impacket; strongerAuthRequired error = signing enforced
LDAPS channel binding636Yes (password)Probed with ldap3 NTLM bind without CBT; 80090346 error = CBT enforced
Anonymous bind389 / 636NoTested in --null-auth mode
DC identificationBothOptionalUsed for severity escalation in relay path analysis
LDAP signing is checked before authentication is attempted. The signing probe works regardless of whether credentials are valid — it uses the impacket LDAPConnection with signing=False and inspects whether the server returns a strongerAuthRequired error on an anonymous-domain bind.

Relay conditions

LDAP  + signing not required                    →  RELAYABLE  (CRITICAL)
LDAPS + channel binding not enforced            →  RELAYABLE  (CRITICAL)
LDAP  + signing not required + NTLMv1 enabled   →  RELAYABLE  (CRITICAL, cross-protocol)
LDAPS + channel binding enforced                →  NOT relayable
LDAP  + signing required                        →  NOT relayable
Domain controllers with LDAP signing disabled are the highest-value NTLM relay targets in an environment. A successful relay to LDAP on a DC allows attribute writes that can lead directly to domain compromise (shadow credentials, RBCD, DCSync-enabled group membership).

Signing check detail

The signing probe uses impacket’s LDAPConnection with signing=False and calls login(domain=...) with no password. The possible outcomes are:
Server responsesigning_required valueMeaning
Bind succeedsFalseSigning not required — relay-vulnerable
strongerAuthRequired errorTrueSigning enforced
NTLM disabled errorNoneCannot determine (NTLM auth unavailable on this server)
Any other errorNoneUnknown — treated conservatively as not relay-able

Channel binding check detail (LDAPS)

The LDAPS channel binding check uses ldap3 (not impacket) because ldap3 does not automatically calculate and attach channel binding tokens — which means a successful bind confirms the server does not enforce CBT.
Outcomechannel_binding valueMeaning
Bind succeedsFalseCBT not enforced — relay-vulnerable
Error 80090346 (SEC_E_BAD_BINDINGS)TrueCBT enforced
Error 52e (invalid credentials)FalseBad creds but CBT not the issue
Any other error / no passwordNoneUnknown — treated conservatively as not relay-able
The LDAPS channel binding check requires a password. It cannot be performed with --null-auth or pass-the-hash (NT hash only) credentials, because ldap3 does not natively support pass-the-hash for NTLM. In those cases channel_binding is set to None and a note is recorded in additional_info.

Flags and ports

ParameterValue
--protocols valueldap, ldaps
Default port (LDAP)389
Default port (LDAPS)636
Auth requiredNo for signing check; password required for LDAPS CBT check

Example commands

python3 relayking.py -u lowpriv -p 'P@ssw0rd' -d corp.local \
  --dc-ip 10.0.0.1 -vv --audit \
  --protocols smb,ldap,ldaps,mssql,http,https \
  --threads 10 -o plaintext,json \
  --output-file relayking-scan \
  --proto-portscan --gen-relay-list relaytargets.txt

Severity

Relay path analysis assigns the following severities to LDAP/LDAPS findings:
FindingSeverity
DC with LDAP signing not requiredCRITICAL
DC with LDAPS channel binding not enforcedCRITICAL
Non-DC with LDAP signing not requiredHIGH
Non-DC with LDAPS channel binding not enforcedHIGH
DC findings are escalated because relaying to LDAP on a DC gives write access to the most sensitive AD objects in the domain.

Build docs developers (and LLMs) love