What it is#
Domain controllers answer SMB, RPC and LDAP requests from every machine in the domain. Normally each request carries an identity. A null session is a connection made with an empty username and password, which Windows treats as the built-in ANONYMOUS LOGON identity.
Older Windows versions relied on anonymous access for trusts and legacy clients, so it was allowed by default. Modern Windows restricts it, but the permissive settings often survive in domains that were upgraded over many years, that were created with "permissions compatible with pre-Windows 2000", or where a policy was loosened once for a legacy application and never tightened again.
- Anonymous SMB sessions: the domain controller accepts an unauthenticated connection to the
IPC$share. - Anonymous SAM and LSA queries: over that session, RPC interfaces return users, groups, group members, shares, the domain SID and the password policy.
- Anonymous SID and name translation: account names can be resolved from SIDs, which reveals built-in and renamed administrator accounts.
- Anonymous LDAP: the directory allows unauthenticated reads beyond the basic server information every client needs.
Why it matters#
- A complete list of domain user accounts, including service accounts and disabled or stale accounts, with no credentials required.
- Group membership such as Domain Admins and Enterprise Admins, which tells an attacker exactly which accounts to target.
- The password and lockout policy, which lets an attacker tune password guessing to stay just under the lockout threshold.
- Account descriptions and other attributes, which sometimes contain passwords or other sensitive notes.
- Anyone on the network gets this head start: a guest Wi-Fi user, a contractor laptop, or a compromised printer or IoT device that can reach a domain controller.
- The queries look like ordinary directory traffic, so they are rarely noticed without specific monitoring.
Medium when anonymous access exposes limited information such as the domain name or SID. High when it returns full user and group lists, privileged group membership or the password policy, especially when domain controllers are reachable from guest, partner or other untrusted networks. Actual severity depends on context: who is affected, what data or actions are reachable, and existing controls.
Examples#
; Vulnerable: anonymous sessions can enumerate SAM accounts and shares,
; and permissions granted to Everyone also apply to anonymous users.
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa]
"RestrictAnonymous"=dword:00000000
"RestrictAnonymousSAM"=dword:00000000
"EveryoneIncludesAnonymous"=dword:00000001
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters]
"RestrictNullSessAccess"=dword:00000000
; Fixed: the values a domain controller hardening GPO writes.
; Set them through Group Policy, not by editing each server by hand.
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa]
"RestrictAnonymous"=dword:00000001
"RestrictAnonymousSAM"=dword:00000001
"EveryoneIncludesAnonymous"=dword:00000000
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanManServer\Parameters]
"RestrictNullSessAccess"=dword:00000001
The registry values are only half of the picture. If ANONYMOUS LOGON or Everyone is a member of the Pre-Windows 2000 Compatible Access group, anonymous callers can still read user and group objects from the directory.
How to fix it#
1. Restrict anonymous access with Group Policy. In a GPO linked to the Domain Controllers OU, under Computer Configuration › Policies › Windows Settings › Security Settings › Local Policies › Security Options, set:
- Network access: Allow anonymous SID/Name translation: Disabled
- Network access: Do not allow anonymous enumeration of SAM accounts: Enabled
- Network access: Do not allow anonymous enumeration of SAM accounts and shares: Enabled
- Network access: Let Everyone permissions apply to anonymous users: Disabled
- Network access: Restrict anonymous access to Named Pipes and Shares: Enabled
2. Remove anonymous principals from Pre-Windows 2000 Compatible Access. If something still needs the group, Authenticated Users is the usual replacement. Group names are localized on non-English systems.
:: Fixed: run once on a domain controller after checking for legacy dependencies
net localgroup "Pre-Windows 2000 Compatible Access" "ANONYMOUS LOGON" /delete
net localgroup "Pre-Windows 2000 Compatible Access" Everyone /delete
3. Keep anonymous LDAP disabled. Anonymous LDAP operations beyond the root DSE are allowed only if the seventh character of the forest's dsHeuristics value is 2. Leave it unset or set to anything else, and remove read permissions granted to ANONYMOUS LOGON on directory objects.
# Audit: an empty result means the default, which blocks anonymous LDAP operations
$cfg = (Get-ADRootDSE).configurationNamingContext
(Get-ADObject "CN=Directory Service,CN=Windows NT,CN=Services,$cfg" -Properties dsHeuristics).dsHeuristics
4. Keep anonymous pipes and shares to the minimum. Leave Shares that can be accessed anonymously empty, and keep Named Pipes that can be accessed anonymously to what your hardening baseline specifies for domain controllers.
5. Start from a recognized baseline. Apply the Microsoft Security Baseline or the CIS Benchmark for domain controllers, and check for drift on every domain controller, including read-only domain controllers and those in remote sites.
6. Limit who can reach domain controllers. Guest, IoT and partner networks should not be able to reach domain controller SMB, RPC or LDAP ports at all. Firewall rules reduce exposure when a setting drifts.
7. Find legacy dependencies before you enforce. Old appliances, scanners, NAS devices and very old trusts sometimes rely on anonymous lookups. Review anonymous logons for a period first, then give those systems a dedicated low-privilege service account.
8. Monitor anonymous logons. Collect Security event 4624 from domain controllers and alert on network logons (logon type 3) by ANONYMOUS LOGON from unexpected sources.
How to test for it#
- Agree scope and authorization first. Test every domain controller, not just the one DNS returns first.
- From a host that is not joined to the domain, on the same network segments as user devices and VPN clients, try to open an SMB session to each domain controller with an empty username and password. A hardened controller either refuses it or returns access denied for user, group, share and password policy queries.
- Try an anonymous LDAP bind and confirm only the root DSE (basic server information) is readable.
- Check the effective policy on each domain controller (
gpresultor Resultant Set of Policy), not only the GPO itself, since a higher-precedence GPO can override it. - Review membership of Pre-Windows 2000 Compatible Access and the
dsHeuristicsvalue. - Repeat the unauthenticated tests from guest, IoT and partner networks to confirm domain controllers are unreachable there.
- Retest after every change, and confirm normal sign-in, Group Policy processing and trust authentication still work.
References#
- CWE-287: Improper Authentication ↗ (opens in a new tab)cwe.mitre.org
- CWE-200: Exposure of Sensitive Information to an Unauthorized Actor ↗ (opens in a new tab)cwe.mitre.org
- OWASP Top 10 A05:2021 Security Misconfiguration ↗ (opens in a new tab)owasp.org
- Microsoft: Network access: Do not allow anonymous enumeration of SAM accounts and shares ↗ (opens in a new tab)learn.microsoft.com
- Microsoft: Network access: Restrict anonymous access to Named Pipes and Shares ↗ (opens in a new tab)learn.microsoft.com
- MITRE ATT&CK T1087.002 Account Discovery: Domain Account ↗ (opens in a new tab)attack.mitre.org
- CIS Benchmarks: Microsoft Windows Server ↗ (opens in a new tab)cisecurity.org