SMB Null-Session Enumeration: The Anonymous Recon Foothold Hiding in RestrictNullSessAccess
How anonymous null-session access lets an unauthenticated attacker enumerate your shares, accounts, and host info over SMB, and how to shut it with one registry value.
Every credential-based attack needs a first step that requires no credentials. On a Windows network, one of the oldest and most reliable is the SMB null session: a connection to a machine's file-sharing stack made with an empty username and an empty password. When null sessions are allowed, an attacker who can merely reach TCP 445 can bind to the machine's named pipes and, depending on configuration, enumerate its shares, local accounts, groups, and password policy — all before authenticating to anything. It is reconnaissance for free, and it maps directly to MITRE ATT&CK T1135 (Network Share Discovery) and the account-discovery techniques that follow it.
The single registry value that governs this on a modern host is RestrictNullSessAccess. This post explains what a null session actually is, what an attacker gets when the value is off, why it is still off on more machines than you would expect, and how to verify and fix it.
What a null session actually is
SMB lets a client set up an anonymous session — RFC-speak for "log on with no user". Historically this existed so that inter-machine services (browser service, printer negotiation, trust enumeration) could ask a peer simple questions without a domain account. The problem is that the same anonymous channel exposes the IPC$ "inter-process communication" share and, through it, a set of named pipes (\PIPE\lsarpc, \PIPE\samr, \PIPE\srvsvc) that answer questions a stranger has no business asking.
Establishing one from another machine is trivial:
:: Classic null-session bind to the IPC$ share (empty user, empty password)
net use \\TARGET\IPC$ "" /user:""
Once that bind succeeds, the pipes behind it become queryable. Tooling that has done this for two decades — enum4linux, rpcclient, Nmap's smb-enum-* scripts — turns the raw RPC calls into a tidy report:
rpcclient -U "" -N TARGET
rpcclient $> srvinfo # OS version, server type
rpcclient $> netshareenumall # every share, including the non-obvious ones
rpcclient $> enumdomusers # local/domain user accounts
rpcclient $> querydominfo # password policy, lockout threshold
What the attacker gets when it is off
An open null session is not "just" a list of shares. In a single unauthenticated pass an attacker can typically collect:
- Every share and its path — including admin shares and the "we forgot that was shared" ones that hold backups, config, or credentials.
- Local and (on a domain member) domain user accounts — real usernames to spray or target, plus their RIDs.
- Group memberships — who is a local administrator, who is in privileged groups.
- The password and lockout policy — the exact minimum length, complexity, and lockout threshold, so a password-spraying campaign can be tuned to stay below the lockout limit.
- OS build and server role — to select the right exploit or lateral-movement path.
None of this trips an authentication log, because nobody authenticated. It is the quiet, patient first move that makes the loud later moves — password spraying, targeted phishing, share looting — far more effective.
A null session doesn't break in. It reads the floor plan, the guest list, and the alarm code off the wall, and walks away — so the actual break-in looks like it was done by someone who already worked there.
Why it is still open
Modern Windows sets RestrictNullSessAccess = 1 by default, so it is easy to assume the problem is dead. In practice it is still found off because:
- Legacy GPOs. An old baseline built for line-of-business apps that genuinely needed anonymous enumeration cleared the value — and the GPO outlived the app by a decade.
- In-place upgrades and imaging. A setting relaxed on a Windows 7-era gold image can ride an in-place upgrade all the way to Windows 11.
- "Make it work" fixes. A share or printer that failed to enumerate got "fixed" by turning null sessions back on instead of granting the right account.
- Explicit null-session pipes/shares. Even with the restriction on, entries under
NullSessionPipes/NullSessionSharescan carve exceptions that reopen the channel for specific names.
Verify it on a single machine
The governing value lives under the LanmanServer parameters. Read it directly:
Get-ItemProperty `
'HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters' `
-Name RestrictNullSessAccess -ErrorAction SilentlyContinue |
Select-Object RestrictNullSessAccess
1 means anonymous access to named pipes and shares is restricted (good). 0, or the value missing on an older host, means it is open. While you are there, check for explicit exceptions that undo the restriction:
Get-ItemProperty `
'HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters' |
Select-Object NullSessionPipes, NullSessionShares
Fix it
Set the value on, and prune any lingering exception lists that reopen the door:
Set-ItemProperty `
'HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters' `
-Name RestrictNullSessAccess -Value 1 -Type DWord
# Optional but recommended: clear explicit null-session carve-outs
Set-ItemProperty `
'HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters' `
-Name NullSessionPipes -Value @() -Type MultiString
Set-ItemProperty `
'HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters' `
-Name NullSessionShares -Value @() -Type MultiString
Under Group Policy this is Computer Configuration → Windows Settings → Security Settings → Local Policies → Security Options → "Network access: Restrict anonymous access to Named Pipes and Shares", backed by the CIS Windows L1 benchmark. Pair it with restricting anonymous SAM enumeration (RestrictAnonymous / RestrictAnonymousSAM) for defense in depth, and — because 445 should rarely be reachable from untrusted networks in the first place — make sure the host firewall isn't quietly exposing SMB on a public profile.
Where WinSentinel fits
Checking one machine by hand is easy; knowing that every machine is set correctly, and staying that way after the next re-image or GPO change, is the hard part. WinSentinel's SMB hardening module audits RestrictNullSessAccess alongside SMB signing (server and client), the legacy SMBv1 protocol, share encryption, and the insecure-guest-logon fallback — flagging an open null session as a warning with the exact one-line fix, and mapping it to CIS Windows L1. It reads local registry state only, so it runs entirely on the machine with no agent phoning home. Run it free from the CLI:
dotnet tool install --global WinSentinel.Cli
winsentinel --audit --category "SMB / File Sharing"
Every audit finding carries its severity, its rationale, and a copy-pasteable remediation — so "is anonymous SMB enumeration open here?" goes from a manual registry hunt to a single line in a report.