AD-INF-004: Unsafe dsHeuristics settings¶
low medium high Infrastructure MITRE ATT&CK T1087.002, T1098 Reads: LDAP
The forest-wide dSHeuristics value weakens the directory: anonymous LDAP or NSPI, operators outside AdminSDHolder, uniqueness or encryption checks off, or CVE-2021-42291 checks disabled.
Also known as: dsheuristics
Why it matters¶
dSHeuristics on CN=Directory Service,CN=Windows NT,CN=Services in the configuration
partition is a string of single-character switches that change directory behaviour for
the whole forest. Positions count from 1, as MS-ADTS numbers them. These weaken security:
-
3rd character
1(fDoListObject). Turns on List Object mode, soLIST_OBJECTrights are enforced. It is not a weakness by itself, and some forests use it to hide objects, but an account denied that right sees nothing of the object. The scan then can miss objects with no error, so its results may be incomplete. -
7th character
2(fLDAPBlockAnonOpsoff). Anonymous LDAP clients may run operations beyond the rootDSE, limited only by ACLs. Together with Anonymous Logon or Everyone in Pre-Windows 2000 Compatible Access (AD-PRIV-005), anyone on the network can enumerate users, groups and computers without an account, which feeds password spraying and target selection. - 8th character not
0(fAllowAnonNSPI). Anonymous clients may call the NSPI RPC bind method, the address book interface, instead of authenticated clients only. - 16th character (
dwAdminSDExMask) not0. The hex digit removes Account, Server, Print and/or Backup Operators from AdminSDHolder protection. Their members then keep whatever ACL their own objects carry, so a helpdesk ACE inherited from an OU can be used to reset the password of an operator and, through the operator group's rights on DCs, climb to domain admin (AD-PRIV-008). - 21st character (
DoNotVerifyUPNAndOrSPNUniqueness). A bitwise value: bit 0 stops the uniqueness check onuserPrincipalName, bit 1 onservicePrincipalName, bit 2 the SPN alias check. Duplicates are then possible, and Kerberos can resolve a name to the wrong account. - 28th character
2(AttributeAuthorizationOnLDAPAdd) and 29th character2(BlockOwnerImplicitRights). KB5008383 heads these Additional AuthZ verifications for LDAP Add operations and Temporary removal of Implicit Owner for LDAP Modify operations. They guard computer objects against CVE-2021-42291:0audits,1enforces,2turns both off. Microsoft marks2as not recommended. - 31st character (
DisableConfidentialAttributeEncryptionRequirements). A bitwise value: bit 0 allows reading confidential attributes over an unencrypted connection, bit 1 writing them on modify, bit 2 on add. They then cross the network in clear text.
How ad-doctor detects it¶
ad-doctor reads dSHeuristics from the configuration partition and checks characters 3, 7,
8, 16, 21, 28, 29 and 31. A character past the end of the string, or a value that is not set
(the default), takes its default and is not reported. That includes 28 and 29: unset means audit
mode, the state of most forests, and only an explicit 2 is reported, not a missing 1.
When the object cannot be read at all, the report has a note instead of a clean result.
The object is the dSHeuristics string itself, for example 0000002 (anonymous
operations allowed); the detail names each character found.
Attributes and probes read
dSHeuristics
Severity¶
The highest grade among the characters set:
- High: anonymous LDAP operations (7th character
2) or anonymous NSPI (8th not0). - Medium: AdminSDHolder exclusion (16th not
0), uniqueness checks off (21st), CVE-2021-42291 checks disabled (28th or 29th2), confidential attributes without encryption (31st). - Low: List Object mode (3rd
1), which is mostly about what this scan can see, and values that cannot be judged (28th or 29th3, or a 21st or 31st that is not a known bit).
False positives and limits¶
- Applications that need anonymous LDAP, such as some old printers or Unix clients. Give them a service account instead; if that is impossible, accept the finding with an owner and an expiry date (accepted risks).
- A deliberate AdminSDHolder exclusion for an operator group that is kept empty is low risk, but the clean fix is to reset the character and leave the group empty.
- List Object mode set on purpose, for example to hide tenants from each other. Accept it, and scan with an account that can list everything.
Fix¶
-
Read the current value.
-
Reset the affected characters to
0, except the 28th and 29th: set those to1to enforce KB5008383 once its audit events are clean. If no other character is set on purpose, clear the attribute; otherwise write the string back with only those positions changed (keep the 10th character1, the 20th2and the 30th3when the string is that long: they are check characters). Run as an Enterprise Admin: -
If the AdminSDHolder exclusion was removed, wait for SDProp to run (every 60 minutes) and check that the operator accounts got the protected ACL.
Verify¶
To accept the risk instead, add an entry to the file passed with --accept (see accepted risks):
[[accept]]
check = "AD-INF-004"
objects = ["..."] # optional; without it the whole check is accepted
reason = "..."
expires = 2027-03-31
Related checks¶
References¶
Microsoft and vendors
- KB5008383: Active Directory permissions updates (CVE-2021-42291)
- Appendix C: Protected Accounts and Groups in Active Directory
Specifications
MITRE ATT&CK
Available since 0.1.0.