AD-INF-005: LDAP signing not required¶
medium Infrastructure MITRE ATT&CK T1557 Reads: LDAP probe
A domain controller accepts an unsigned NTLM bind on plain LDAP, so authentication relayed from a coerced host can be used to modify the directory.
Also known as: ldap-signing
Why it matters¶
When a DC does not require LDAP signing, an NTLM authentication captured anywhere can be relayed to its plain LDAP port and used as the victim. Attackers get that authentication for free: PetitPotam, PrinterBug and similar coercion bugs make a server authenticate to a host of the attacker's choice, and WebDAV or name-resolution poisoning collects it from workstations.
Relayed to LDAP, a computer account's authentication can write
msDS-AllowedToActOnBehalfOfOtherIdentity on itself (resource-based delegation, then
local admin on that server) or msDS-KeyCredentialLink (shadow credentials); a relayed
administrator can add accounts to privileged groups. One DC that does not require
signing is enough, because the attacker chooses which DC to relay to.
How ad-doctor detects it¶
ad-doctor performs an NTLM bind without signing on the plain LDAP port of each DC
(--signing-probe-port, 389 by default). A DC that requires signing rejects it with
strongerAuthRequired (result 8); a successful bind means it does not. Any other answer
is inconclusive and is written to the scan notes, not reported.
The probe needs a DOMAIN\user account with a password (NTLM); it is skipped with a
note when scanning with Kerberos. By default every enabled DC in the domain is probed by
its dNSHostName; --single-dc limits it to the DC being scanned. Each object is a DC
host name, for example DC01.adlab.test, and the detail says how many of the probed DCs
failed.
Attributes and probes read
LDAP bind result (strongerAuthRequired)
Severity¶
Always medium on its own. Combined with a machine account quota above 0 it is part of the relay-to-RBCD chain reported as high by AD-CHAIN-001.
False positives and limits¶
None expected: the probe observes the DC's actual behaviour. A DC that could not be reached is not reported here; see AD-INF-013.
Fix¶
- Find clients that still bind without signing before enforcing: on each DC, raise
the LDAP interface event logging (
16 LDAP Interface Events= 2) and collect event 2889 for a few days. -
Require signing on every DC through the Default Domain Controllers Policy: Computer Configuration > Policies > Windows Settings > Security Settings > Local Policies > Security Options > Domain controller: LDAP server signing requirements = Require signing. The setting lands in the registry; read it to confirm:
-
Enforce LDAPS channel binding as well (AD-INF-010): signing protects plain LDAP only.
- Set
ms-DS-MachineAccountQuotato 0 (AD-POL-002) to take away the easiest follow-up of a successful relay.
Verify¶
To accept the risk instead, add an entry to the file passed with --accept (see accepted risks):
[[accept]]
check = "AD-INF-005"
objects = ["..."] # optional; without it the whole check is accepted
reason = "..."
expires = 2027-03-31
Related checks¶
References¶
Microsoft and vendors
- How to enable LDAP signing in Windows Server
- 2020, 2023, and 2024 LDAP channel binding and LDAP signing requirements for Windows (KB4520412)
- Domain controller: LDAP server signing requirements
Research
MITRE ATT&CK
Available since 0.1.0.