LocalAccountTokenFilterPolicy is the registry value behind the CIS check “Apply UAC restrictions to local accounts on network logons”. When it is 1, local administrator accounts get a full admin token over the network, which makes pass-the-hash lateral movement easy. Fix it by setting the value to 0 (or deleting it) and running credentialed scans with a domain account.
What the scanner is actually detecting
This is a configuration audit, not a missing patch. The scanner reads one DWORD under HKLMSOFTWAREMicrosoftWindowsCurrentVersionPoliciesSystem and compares it with the benchmark.
| Scanner | Finding title | What it checks |
|---|---|---|
| Tenable (CIS Windows audits) | Ensure ‘Apply UAC restrictions to local accounts on network logons’ is set to ‘Enabled’ (server benchmarks add “(MS only)”). The item number changes between benchmark versions, for example 18.3.1, 18.4.1 or 18.6.1. | LocalAccountTokenFilterPolicy should be 0 |
| Tenable (Microsoft security baseline audits) | Apply UAC restrictions to local accounts on network logons | Same value, same expected state |
| Wazuh SCA (cis_win2022.yml, check 27150, CIS 18.4.1) | Ensure ‘Apply UAC restrictions to local accounts on network logons’ is set to ‘Enabled’ (MS only). | Passes if the key is missing, the value is missing, or the value is 0 |
The value has two meanings. Microsoft’s KB 951016 describes 0 as building a filtered token with the administrator credentials removed, and says this is the default. 1 builds an elevated token. A missing value behaves like 0. The Group Policy setting maps directly: Enabled writes 0, Disabled writes 1.
“(MS only)” means the CIS server benchmarks apply this item to member servers, not domain controllers, which keep their accounts in Active Directory rather than a local SAM. Workstation benchmarks include it as well.
If the value is 1, someone probably set it on purpose. Tenable’s documentation for credentialed Windows checks offers LocalAccountTokenFilterPolicy = 1 as the alternative to turning UAC off when you scan with a local account. Management tools that log in with a local administrator are the other usual reason.
Real-world risk
With the value at 1, anyone holding the password or NTLM hash of a local administrator account gets full admin rights on that host over SMB, WinRM and other remote interfaces. If the same local admin password was baked into an image, one compromised machine hands the attacker every machine built from that image.
With the value at 0, a local account logging on over the network gets a standard user token with no way to elevate. Per Microsoft, such a session cannot reach C$ or ADMIN$ or perform remote administration. The limits:
- It is not a remote exploit. The attacker already needs a local account’s credentials.
- Domain accounts are not affected. A domain user in the local Administrators group still gets a full token remotely.
- The built-in Administrator account (RID 500) is not filtered by default, because Admin Approval Mode for that account is off unless you enable it.
- Remote Desktop is an interactive logon and is not affected.
- If UAC is disabled entirely (EnableLUA = 0), Microsoft notes that the restriction is removed too, whatever this value says.
Treat it as a lateral movement control. It matters most where local admin passwords are shared, and it pairs with protecting credentials on the host in the first place (see LSA protection and Credential Guard).
How to confirm it on the host
reg query "HKLMSOFTWAREMicrosoftWindowsCurrentVersionPoliciesSystem" /v LocalAccountTokenFilterPolicy
0x1 is the finding. 0x0 is compliant. “ERROR: The system was unable to find the specified registry key or value.” means the value is absent, which is the Windows default. To see the related UAC values at the same time:
Get-ItemProperty -Path 'HKLM:SOFTWAREMicrosoftWindowsCurrentVersionPoliciesSystem' |
Select-Object LocalAccountTokenFilterPolicy, EnableLUA, FilterAdministratorToken
EnableLUA should be 1. A blank FilterAdministratorToken means Admin Approval Mode for the built-in Administrator is not configured. List the local administrators so you know which accounts the setting affects, and generate a Group Policy report to find out whether a GPO is writing the 1:
Get-LocalGroupMember -Group Administrators
gpresult /h C:Tempgp.html
How to fix it
First: stop scanning with a local account
If your scanner logs in with a local administrator, setting the value to 0 will cut its admin access and your credentialed results will degrade. Create a dedicated domain account for scanning and add it to the local Administrators group on the targets through Group Policy. Domain accounts are not subject to this filtering, so the restriction can stay on. For the rest of the credentialed scan checklist (firewall, services, admin shares), see why Windows credentialed scans fail.
Domain-joined hosts: Group Policy with the SecGuide template
- Download the Microsoft Security Compliance Toolkit and take SecGuide.admx and SecGuide.adml from the Templates folder of a Windows security baseline package.
- Copy SecGuide.admx to the central store at \<domain>SYSVOL<domain>PoliciesPolicyDefinitions and SecGuide.adml to its en-US subfolder.
- Edit a GPO linked to the member servers and workstations and open Computer Configuration > Policies > Administrative Templates > MS Security Guide > Apply UAC restrictions to local accounts on network logons.
- Set it to Enabled.
Enforcing the default explicitly is the point: if an installer or script sets the value to 1 later, the next Group Policy refresh puts it back.
Domain-joined hosts without the ADMX
Microsoft documents a Group Policy Preferences alternative. Go to Computer Configuration > Preferences > Windows Settings > Registry, choose New > Registry Item, and set Action Replace, Hive HKEY_LOCAL_MACHINE, Key Path SOFTWAREMicrosoftWindowsCurrentVersionPoliciesSystem, Value name LocalAccountTokenFilterPolicy, type REG_DWORD, data 0.
Standalone or workgroup hosts: registry
reg add "HKLMSOFTWAREMicrosoftWindowsCurrentVersionPoliciesSystem" /v LocalAccountTokenFilterPolicy /t REG_DWORD /d 0 /f
Deleting the value also restores the default:
reg delete "HKLMSOFTWAREMicrosoftWindowsCurrentVersionPoliciesSystem" /v LocalAccountTokenFilterPolicy /f
Prefer the explicit 0. It reads unambiguously in every audit tool.
Intune-managed devices
The setting is in the MSSecurityGuide area of the Policy CSP (Windows 10 version 1803 and later, device scope): ./Device/Vendor/MSFT/Policy/Config/MSSecurityGuide/ApplyUACRestrictionsToLocalAccountsOnNetworkLogon. It is ADMX-backed (SecGuide.admx), so configure it from the settings catalog, or use a custom OMA-URI with the SyncML format Microsoft describes for ADMX-backed policies.
Close the built-in Administrator gap
Microsoft’s guidance for enforcing local account restrictions pairs the registry value with two Security Options under Computer Configuration > Policies > Windows Settings > Security Settings > Local Policies > Security Options: User Account Control: Run all administrators in Admin Approval Mode and User Account Control: Admin Approval Mode for the Built-in Administrator account, both Enabled. For a hard block on domain-joined machines, Microsoft also recommends adding Local account and member of Administrators group to Deny access to this computer from the network and Deny log on through Remote Desktop Services under User Rights Assignment. Windows LAPS removes shared local admin passwords altogether.
How to verify the fix and rescan
gpupdate /force /target:computer
reg query "HKLMSOFTWAREMicrosoftWindowsCurrentVersionPoliciesSystem" /v LocalAccountTokenFilterPolicy
Expected output:
HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionPoliciesSystem
LocalAccountTokenFilterPolicy REG_DWORD 0x0
To test the behavior, connect from another machine with a fresh session using a local admin account that is not the built-in Administrator. It should fail with access denied:
net use \HOST01ADMIN$ * /user:HOST01localadmin
net use \HOST01ADMIN$ /delete
The built-in Administrator still connects if Admin Approval Mode for it is off; that is expected. To check many hosts from a domain admin session:
Invoke-Command -ComputerName (Get-Content .hosts.txt) -ScriptBlock {
Get-ItemProperty -Path 'HKLM:SOFTWAREMicrosoftWindowsCurrentVersionPoliciesSystem' |
Select-Object LocalAccountTokenFilterPolicy, EnableLUA, FilterAdministratorToken
} | Select-Object PSComputerName, LocalAccountTokenFilterPolicy, EnableLUA, FilterAdministratorToken
Then rerun the Tenable compliance scan or wait for the next Wazuh SCA pass. The item should show PASSED. The audit only reads the registry, so no reboot is needed for the rescan.
What can break and how to roll back
- Credentialed scans that use a local account lose administrative access. Move them to a domain account before you roll out.
- Remote administration with local admin accounts stops working: mapping C$ or ADMIN$, WinRM sessions, and tools that push software or run commands through admin shares.
- Workgroup machines have no domain account to switch to. Use Remote Desktop, which is not affected, or a management agent.
Back up the key first:
reg export "HKLMSOFTWAREMicrosoftWindowsCurrentVersionPoliciesSystem" C:Temppolicies-system.reg /y
If a critical tool breaks, roll back narrowly: set the value to 1 only on the affected hosts, or set the policy to Disabled in a GPO scoped to just those hosts. Record a documented exception while you move the tool to a domain account. Do not disable UAC as a shortcut.
Common false positive reasons
- Domain controllers checked against a member server item. The CIS server item is marked MS only, so a DC result should be scoped out, not remediated.
- Value missing. Absence is the secure default, and Wazuh passes it. If another audit engine fails a host with no value, set 0 explicitly; the host was not exposed.
- Stale results. The scan ran before the host picked up the GPO, or the host was offline during the refresh.
- Wrong value type. A script that wrote REG_SZ instead of REG_DWORD may not match what the check expects.
- The finding keeps coming back. This is not a false positive. Something rewrites the 1, often a scanner onboarding script, a management tool installer or a conflicting GPO. The gpresult report shows which GPO wins.
The opposite case also exists: a host with EnableLUA = 0 passes this check while the restriction is not in force. Check EnableLUA alongside it.
FAQ
Does LocalAccountTokenFilterPolicy = 0 break Nessus credentialed scans?
Only when the scan uses a local account other than the built-in Administrator. Scans with a domain account in the local Administrators group are not affected.
Is deleting the value the same as setting it to 0?
Functionally, yes: 0 is the default. Enforcing 0 through Group Policy is better, because a refresh restores it if something changes it later.
Does this stop pass-the-hash completely?
No. It does not cover domain accounts, and it does not cover the built-in Administrator unless Admin Approval Mode is enabled for that account. Combine it with Windows LAPS, the deny-network-logon rights for local administrators, and reduced NTLM use (see disabling NTLM safely).
Should I disable UAC instead of setting the value to 1?
No. Microsoft notes that disabling UAC removes this restriction along with every other UAC protection. If a tool needs remote admin rights, give it a domain account.
Tracking this finding across many hosts
This item tends to appear on every member server and workstation that shares an image, sometimes from both Tenable and Wazuh. SITEY, a self-hosted vulnerability management platform, imports findings from 16 scanners and merges duplicates within each scanner (not across scanners). Its AI can write host-specific remediation scripts that run only after human approval, deployed by SITEY agents on Windows endpoints, and it re-tests to verify closure. Per-finding retest covers Nessus, Acunetix and Burp results; for Wazuh, confirm with the next SCA scan.