🏢Active DirectoryNetworkAdvancedMonitoringAttack Paths

LDAP Channel Binding, Domain Controller, NTLM Relay, LDAPS: The Half of the 2020 Advisory Nobody Finished

LDAP signing and LDAP channel binding are two controls, not one. Signing leaves port 636 open to relay, and the channel binding value does not exist until you create it.

Younes AZABARBy Younes AZABAR16 min read
LDAP Channel Binding, Domain Controller, NTLM Relay, LDAPS: The Half of the 2020 Advisory Nobody Finished

LDAP channel binding, domain controller, NTLM relay, LDAPS — the four terms belong in the same sentence, because channel binding is the only domain controller setting that stops an NTLM relay landing inside an LDAPS session on port 636. Most Active Directory teams read Microsoft's 2020 hardening guidance as one item, closed the LDAP signing half, and moved on. The channel binding half is a separate registry value that, on Windows Server 2022 and earlier, does not exist until an administrator creates it — and Windows Server 2025 only changed that for brand-new deployments.

LDAP Channel Binding, Domain Controller, NTLM Relay, LDAPS: How the Pieces Fit

LDAP channel binding uses a Channel Binding Token (CBT) to tie the authentication that happens inside a TLS session to the TLS channel that carries it. Microsoft describes it as using CBTs "to cryptographically bind application-layer security (such as an SSL/TLS session) with the underlying network connection", so that an attacker who intercepts the encrypted session cannot hijack or downgrade it.

The token only exists in one place. The Windows policy reference for Domain controller: LDAP server channel binding token requirements is explicit: "CBT or EPA is used with TLS sessions when a SASL authentication method is used to authenticate the user. SASL means you use NTLM or Kerberos for user authentication. LDAP Simple Bind over TLS doesn't offer channel binding token protection and is therefore not recommended."

Two ports matter here. Plain LDAP listens on 389 — the port where unauthenticated enumeration problems such as anonymous LDAP access via dsHeuristics live. LDAPS uses port 636 and establishes SSL/TLS as soon as a client connects. Channel binding is a control for the second one.

The capability itself is not new. Per KB4520412, "LDAP channel binding support was added by CVE-2017-8563 on Windows Server 2008 and later versions", and channel binding tokens are supported on Windows 10 version 1709 and later. What CVE-2017-8563 shipped was Extended Protection for Authentication (EPA) support plus a registry entry an administrator has to create — not a changed default.

ℹ️

ℹ️ Note: EPA and channel binding are the same idea under two names. Microsoft's documentation uses both, sometimes in the same paragraph.

Why LDAP Signing Does Not Cover Your LDAPS Traffic

This is the part that gets skipped, and Microsoft's own vulnerability text says it plainly. The MSRC description of CVE-2017-8563 reads:

An elevation of privilege vulnerability exists in Microsoft Windows when a man-in-the-middle attacker is able to successfully forward an authentication request to a Windows LDAP server, such as a system running Active Directory Domain Services (AD DS) or Active Directory Lightweight Directory Services (AD LDS), which has been configured to require signing or sealing on incoming connections.

Read that last clause twice. The domain controller in that sentence already requires signing. It is still relayable. The fix Microsoft shipped was EPA, and the FAQ on the same advisory tells administrators that installing the update is not enough — they must additionally create the LdapEnforceChannelBinding registry setting.

The scoping of the signing control explains why. When LDAP signing is enforced, a domain controller "rejects LDAP simple binds over non-SSL/TLS connections and SASL binds that don't request signing". Both halves of that rule are about traffic that is not already inside TLS. A simple bind carried over LDAPS is not what the signing control rejects, and per the policy reference above it gets no channel binding token protection either: CBT applies when a SASL method — NTLM or Kerberos — does the authenticating, which is why Microsoft flags LDAP Simple Bind over TLS as "not recommended" rather than as something channel binding fixes.

If you are still working through the signing side, that control is covered separately in LDAP Signing Disabled: How Unsigned Binds Expose Active Directory. This article is the other value, on the other port.

The Default That Never Moved

Microsoft's advisory ADV190023, Microsoft Guidance for Enabling LDAP Channel Binding and LDAP Signing, is unusually blunt about the starting position: "A set of unsafe default configurations for LDAP channel binding and LDAP signing exist on Active Directory domain controllers that let LDAP clients communicate with them without enforcing LDAP channel binding and LDAP signing."

The March 10, 2020 updates that everyone remembers added the Group Policy setting and the event IDs. They did not flip anything. KB4520412 repeats the warning four times — in its introduction and once in each update section: "The March 10, 2020 updates, and updates in the foreseeable future, will not change LDAP signing or LDAP channel binding default policies or their registry equivalent on new or existing Active Directory domain controllers." The August 8, 2023 and October 10, 2023 auditing updates each restate it for their own release.

On the registry side, KB4034879 is equally direct: "By default, this setting is disabled" and "The LdapEnforceChannelBindings registry entry must be explicitly created."

Windows Server 2025 is where the story finally changes — partially.

Domain controllerEffective channel binding default
Windows Server 2019 and earlierNever
Windows Server 2022Never
Windows Server 2025, new AD deploymentWhen supported
Windows Server 2025, upgraded from an earlier versionExisting policy preserved

Microsoft's documentation states that Windows Server 2025 and later set channel binding to "When supported" by default with channel binding auditing enabled by default, and that these stronger defaults apply to new Active Directory deployments — while "upgrade installations maintain their current LDAP security settings to prevent disruption". So a Server 2025 domain controller joining a domain you built in 2016 is not automatically the hardened one from the marketing bullet. If a domain controller refresh is already on your plate, that distinction matters: see Windows Server 2016 End of Support: Active Directory Domain Controller Upgrade.

⚠️

⚠️ Warning: The Group Policy editor is actively misleading here. Microsoft's policy reference notes that "in newer versions of Windows, the policy's property page lists 'When supported'" while the table of actual effective defaults says Never for Windows Server 2022 and earlier. An administrator who opens the policy, reads "When supported" on the property page and closes it has verified nothing.

And "When supported" is not the finish line either. By Microsoft's own definition, at that level "only incorrect channel bindings will be blocked, and clients who don't support channel binding can continue to connect via LDAP over TLS". The documented best practice is Always.

The Attack Chain

Step 1 - Obtain an authentication to forward

The attacker needs a Windows machine or user account to authenticate toward a host under their control. The mechanics of that step — coercion, name resolution poisoning, a malicious share path — are the same ones covered in NTLM Relay Attacks: Hijacking Authentication in AD, and are unchanged by anything on the domain controller.

Step 2 - Relay it into LDAPS on port 636

Instead of terminating the authentication, the attacker opens their own TLS session to a domain controller on 636 and forwards the victim's authentication messages into it. This is exactly the scenario ADV190023 describes: "a man-in-the-middle attacker to successfully forward an authentication request to a Windows LDAP server ... which has not configured to require channel binding, and signing or sealing on incoming connections."

Step 3 - Bind and act as the relayed principal

With LdapEnforceChannelBinding absent or set to 0, the domain controller has no way to notice that the authentication was minted for a different TLS channel than the one it arrived on, and the bind succeeds. The attacker now holds an authenticated LDAP session carrying the relayed account's directory rights — which, if the relayed principal is a domain controller computer account or a privileged user, is a very short path to the rest of the domain. An authenticated LDAP session is also where directory objects get written, and defaults such as the machine account quota decide how much a low-privileged one can still do.

With CBT enforcement set to Always, the same relayed authentication carries no valid binding for the attacker's channel and the domain controller rejects it.

Detection

Start with what each domain controller currently does, not with what the GPO editor claims.

$dcs = (Get-ADDomainController -Filter *).HostName

Invoke-Command -ComputerName $dcs -ScriptBlock {
    $params = 'HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters'
    $diag   = 'HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics'
    [pscustomobject]@{
        DC          = $env:COMPUTERNAME
        OS          = (Get-CimInstance Win32_OperatingSystem).Caption
        CBT         = (Get-ItemProperty $params -Name LdapEnforceChannelBinding -ErrorAction SilentlyContinue).LdapEnforceChannelBinding
        Signing     = (Get-ItemProperty $params -Name LDAPServerIntegrity -ErrorAction SilentlyContinue).LDAPServerIntegrity
        LdapLogging = (Get-ItemProperty $diag -Name '16 LDAP Interface Events' -ErrorAction SilentlyContinue).'16 LDAP Interface Events'
    }
} | Format-Table -AutoSize

An empty CBT column means the value was never created. On Windows Server 2022 and earlier that is the same as 0 — Never.

Both settings live under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters, and KB4520412 maps them to the policy names as follows.

PolicyRegistry valueValues
Domain controller: LDAP server signing requirementsLDAPServerIntegrity1 = None, 2 = Require Signing
Domain controller: LDAP server channel binding token requirementsLdapEnforceChannelBinding0 = Never, 1 = When Supported, 2 = Always

Next, the events. All of them land in the Directory Service log with source Microsoft-Windows-ActiveDirectory_DomainService.

EventMeaningFires whenMinimum logging level
3041The server should be configured to enforce validation of channel binding tokensEvery 24h, on startup or service start, when the CBT policy is Never0
3040Count of unprotected LDAPS binds in the previous 24 hoursEvery 24h when the CBT policy is Never and at least one unprotected bind completed0
3074A client bound over SSL/TLS and would have failed CBT validationA client presents an improperly formatted CBT2
3075A client bound over SSL/TLS and provided no channel binding informationA CBT-capable client sends no token2
3039A client bound over SSL/TLS and failed CBT validationEnforcement is active and the token is missing or wrong2

🚨 Danger: There is a trap in that table. KB4520412 states that "Events 3039, 3074, and 3075 can only be generated when Channel Binding is set to When Supported or Always." A domain controller sitting at the default therefore produces zero client inventory — the audit events that tell you which clients would break do not exist until you have already moved off Never. The usual "audit first, then enable" instinct is backwards here: moving to 1 is the audit step.

Events 3040 and 3041 are the exception, and they are your baseline oracle. They fire at logging level 0 with no configuration at all, and only when the policy is Never. If a domain controller is logging 3041, channel binding is off on that domain controller — whatever the property page said.

Get-WinEvent -FilterHashtable @{
    LogName   = 'Directory Service'
    Id        = 3039, 3040, 3041, 3074, 3075
    StartTime = (Get-Date).AddDays(-7)
} -ErrorAction SilentlyContinue |
    Group-Object Id |
    Select-Object Name, Count |
    Sort-Object Name

To collect the client detail, raise the LDAP diagnostic level. KB4520412 gives the command verbatim:

Reg Add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics /v "16 LDAP Interface Events" /t REG_DWORD /d 2

At level 2, events 3074 and 3075 carry the fields you need to chase a client down: the client IP address and port, the identity the client attempted to authenticate as, whether the client supports channel binding, whether it was permitted in when-supported mode, and an audit result flag value.

Get-WinEvent -FilterHashtable @{ LogName = 'Directory Service'; Id = 3074, 3075 } -ErrorAction SilentlyContinue |
    ForEach-Object {
        if ($_.Message -match 'Client IP address:\s*(\d{1,3}(?:\.\d{1,3}){3}):\d+') { $Matches[1] }
    } |
    Group-Object |
    Sort-Object Count -Descending |
    Select-Object Count, Name

Adjust the pattern if any of your clients reach the domain controller over IPv6.

The audit result flags decode as follows, per KB4520412.

FlagValueMeaning
SEC_CHANNEL_BINDINGS_RESULT_CLIENT_SUPPORT0x01Auth package indicates client versions should support bindings
SEC_CHANNEL_BINDINGS_RESULT_ABSENT0x02The bindings are omitted or all zeroes
SEC_CHANNEL_BINDINGS_RESULT_NOTVALID_MISMATCH0x04The channel binding hash was incorrect
SEC_CHANNEL_BINDINGS_RESULT_NOTVALID_MISSING0x08Missing channel bindings are not allowed for this client
SEC_CHANNEL_BINDINGS_RESULT_VALID_MATCHED0x10The client and server bindings match
SEC_CHANNEL_BINDINGS_RESULT_VALID_PROXY0x20ASC_REQ_PROXY_BINDINGS required the client to provide a binding
SEC_CHANNEL_BINDINGS_RESULT_VALID_MISSING0x40Client permitted by ASC_REQ_ALLOW_MISSING_BINDINGS

Bits within 0x30 indicate a valid CBT; bits within 0x0C indicate a failed one.

ℹ️

ℹ️ Note: Microsoft's summary page on LDAP signing carries a condensed event table that labels 3039 as "channel binding not supported" and 3041 as "channel binding successful". That contradicts the detailed tables in KB4520412 quoted above, and the event text on your own domain controllers. Trust KB4520412 and the message body of the event.

The audit events also need the servicing floor: per ADV190023, channel binding audit events 3074 and 3075 became available without a manual enablement step with the November 14, 2023 updates on Windows Server 2022 and the January 9, 2024 updates on Windows Server 2019.

Remediation

💡

💡 Quick Win: Set LdapEnforceChannelBinding to 1 on one domain controller today. No restart is required, "When supported" blocks only incorrect bindings, and it is the only way to make the 3074/3075 client inventory appear.

1. Fix the plumbing first. Channel binding is a control on LDAPS, so LDAPS has to be healthy before you enforce anything: a valid certificate on every domain controller and a modern TLS configuration. If that ground is unverified, start with Domain Controller LDAPS Weak TLS, Print Spooler, Time Sync Audit.

2. Move to When Supported (value 1).

$params = 'HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters'
New-ItemProperty -Path $params -Name 'LdapEnforceChannelBinding' -PropertyType DWord -Value 1 -Force

KB4034879 confirms the operational cost is close to zero: "LDAP server responds dynamically to changes to this registry entry. Therefore, you do not have to restart the computer after you apply the registry change." Microsoft also recommends value 1 specifically to maximise compatibility with older operating systems.

3. Read the inventory for a full business cycle. With diagnostic logging at 2, collect 3074 and 3075 across every domain controller for long enough to catch monthly and quarterly jobs. KB4520412's guidance is to sort each source IP into three buckets: appliance or router (contact the vendor), non-Windows device (confirm with the OS and application vendor that both signing and channel binding are supported), and Windows device (verify the application is actually using channel binding).

4. Expect specific classes of breakage. Microsoft's LDAP FAQ calls out that clients connecting over SSL/TLS without a CBT will fail once the server requires it, and that "SSL/TLS connections that are terminated by an intermediate server that in turn issues a new connection to an Active Directory Domain Controller, will fail" — a load balancer doing TLS termination in front of your domain controllers is a guaranteed casualty. The same FAQ notes that "support for channel binding maybe less common on third-party operating systems and applications than it is for LDAP signing", which is precisely why so many environments finished signing and stalled here. KB4520412 adds two more failure modes. Windows XP "does not support LDAP channel binding and would fail when LDAP channel binding is configured by using a value of Always but would interoperate with DCs configured to use more relaxed LDAP channel binding setting of When supported" — it survives step 2 and breaks at step 5. And a client can have EPA switched off locally through the SuppressExtendedProtection registry setting; since KB4520412 defines a channel-binding-capable client as one where EPA is "installed or available in the OS and not disabled through the registry setting SuppressExtendedProtection", such a client never appears in your 3075 inventory either.

5. Enforce with Always (value 2), by policy. Once the inventory is clean, set the Group Policy Domain controller: LDAP server channel binding token requirements to Always under Computer Configuration > Policies > Windows Settings > Security Settings > Local Policies > Security Options in the Default Domain Controllers Policy, so new domain controllers inherit it instead of depending on someone remembering the registry value. Microsoft's stated best practice for this setting is Always; the documented side effect is that clients which do not support channel binding can no longer run LDAP queries against the domain controllers.

6. Verify by absence. Event 3041 fires only while the policy is Never. When a domain controller stops logging 3040 and 3041, and starts logging 3039 for genuine failures, enforcement is live on that host. Re-run the registry inventory from the Detection section across every domain controller — including any promoted after the change.

7. Close the neighbouring relay paths. Channel binding shuts one relay destination. The credentials being relayed usually originate somewhere with unsigned SMB, so pair this work with SMB Signing Disabled: Why It Still Enables NTLM Relay — and certificate enrollment endpoints are a separate destination worth auditing in the same campaign, covered in ADCS Attack Paths Explained.

How EtcSec Detects This

EtcSec reads the effective LDAP configuration of every domain controller during an Active Directory audit. LDAP_CHANNEL_BINDING_DISABLED flags domain controllers that do not require channel binding tokens, and LDAP_SIGNING_DISABLED flags the signing half of the same advisory — deliberately as two findings, because closing one does not close the other. NTLM_RELAY_OPPORTUNITY reports the relay exposure those defaults create, and DC_LDAPS_WEAK_TLS checks that the TLS layer channel binding depends on is itself sound.

ℹ️

ℹ️ Note: EtcSec automatically checks for this vulnerability during every AD/Azure audit. Run a free audit to verify your environment.

Official References

Explore the identity security pages that support this topic