Windows服务器默认会以LM哈希(LAN Manager Hash)的形式存储用户密码,这是一种极其脆弱的加密方式,攻击者几分钟内就能暴力破解。要彻底解决这个问题,你需要通过修改注册表禁用LM哈希的存储,同时启用NTLMv2认证协议,从根本上提升服务器密码安全等级。具体操作路径是:打开注册表编辑器,定位到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa,将"LMCompatibilityLevel"的值设置为5,同时确保"NoLMHash"键值设为1。这两步做完,服务器就不会再以LM哈希形式存储密码了。
很多运维人员知道要改密码策略,但忽略了LM哈希这个底层隐患。LM哈希诞生于上世纪80年代,它把密码强制转成大写、截断成7个字符、再分成两段分别加密,安全性几乎等于明文。在现代网络环境下,任何一台Windows服务器如果还在存LM哈希,就相当于把大门钥匙插在锁孔里。今天这篇文章,我会把从原理到实操、从单机到域环境、从注册表到组策略的所有方法一次性讲透。
什么是LM哈希以及为什么必须禁用LM哈希全称LAN Manager Hash,是微软早期Windows系统(如Windows 95、Windows NT 3.x/4.0)使用的密码存储格式。它的加密算法存在三个致命缺陷:第一,不区分大小写,所有字符统一转大写;第二,密码超过14个字符会被分成两个7字符段分别加密;第三,使用DES算法,密钥空间极小。用现代GPU集群,每秒可以尝试数十亿次组合,一个8位以内的纯大写密码几秒钟就能被跑出来。
虽然从Windows Vista和Server 2008开始,微软默认已经不再生成LM哈希,但在很多老旧系统、域控制器迁移场景、或者某些特定配置下,LM哈希依然会被存储。更危险的是,如果你的域控制器还在用NTLMv1认证,客户端在登录时会主动发送LM哈希响应,这就是所谓的"NTLM中继攻击"的入口。所以禁用LM哈希不是可选项,是必选项。
方法一:通过注册表直接禁用LM哈希存储这是最直接、最有效的方法,适用于所有Windows Server版本(2008/2012/2016/2019/2022)。操作步骤如下:按Win+R输入regedit打开注册表编辑器,导航到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa,找到或新建以下两个DWORD值:
"LMCompatibilityLevel" = dword:00000005 "NoLMHash" = dword:00000001
这里解释一下这两个键值的含义。"LMCompatibilityLevel"设为5表示:只使用NTLMv2认证,拒绝LM和NTLMv1。"NoLMHash"设为1表示:密码更改时不再生成LM哈希。两个配合使用,既不存储也不使用。修改完成后必须重启服务器才能生效。注意,修改注册表前一定要先导出备份,万一出问题可以快速恢复。
如果你管理的是域环境,这两个键值需要在域控制器上统一设置,并且通过组策略下发到所有成员服务器。域控制器上的设置会覆盖本地设置,所以优先级要搞清楚。另外,如果你的环境还有Windows XP或更老的客户端需要访问,LMCompatibilityLevel设为5可能导致这些老客户端无法认证,这时候需要评估是否要降级到3(允许NTLMv2但拒绝LM和NTLMv1),但从安全角度,我强烈建议直接设为5并淘汰老旧客户端。
方法二:通过本地安全策略或组策略配置对于不想直接动注册表的运维人员,可以通过图形界面的安全策略来完成同样的配置。打开"本地安全策略"(secpol.msc)或者"组策略管理编辑器"(gpmc.msc),依次进入:计算机配置 → Windows设置 → 安全设置 → 本地策略 → 安全选项。
在这里你会找到两个关键策略:第一是"网络安全:不要存储LAN Manager哈希值的下一次密码更改",设置为"已启用";第二是"网络安全:LAN Manager身份验证级别",设置为"仅发送NTLMv2响应。拒绝LM和NTLM"。这两个策略的效果和注册表修改完全一致,只是通过策略引擎下发,更适合批量管理。
如果是域环境,建议在域级别的组策略对象(GPO)中配置,路径是:计算机配置 → 策略 → Windows设置 → 安全设置 → 本地策略 → 安全选项。这样所有加入域的机器都会自动继承这个配置,不需要逐台操作。配置完成后,在客户端执行gpupdate /force强制刷新策略即可。
方法三:使用PowerShell脚本批量禁用如果你管理几十台甚至上百台服务器,手动改注册表或者点策略太慢了。这时候PowerShell就是最佳工具。下面这段脚本可以批量检查并设置LM哈希禁用状态:
$servers = Get-Content "C:\servers.txt"
foreach ($server in $servers) {
Invoke-Command -ComputerName $server -ScriptBlock {
$regPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"
Set-ItemProperty -Path $regPath -Name "NoLMHash" -Value 1 -Type DWord
Set-ItemProperty -Path $regPath -Name "LMCompatibilityLevel" -Value 5 -Type DWord
Write-Host "LM Hash disabled on $env:COMPUTERNAME"
}
}
这个脚本会读取一个服务器列表文件,逐台远程执行注册表修改。执行前确保WinRM服务已开启,并且你有足够的权限。脚本执行完后,建议再用另一段脚本验证设置是否生效:
Invoke-Command -ComputerName $server -ScriptBlock {
$lm = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name "NoLMHash"
$compat = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name "LMCompatibilityLevel"
Write-Host "NoLMHash: $($lm.NoLMHash), LMCompatibilityLevel: $($compat.LMCompatibilityLevel)"
}
批量操作完成后,记得统一安排重启窗口,因为注册表修改需要重启才能完全生效。如果业务不能停机,可以设置计划重启,比如凌晨3点自动重启。
禁用LM哈希后还需要做什么配套安全措施光禁用LM哈希还不够,这只是密码安全的一个环节。你还需要同步做以下几件事:第一,强制启用NTLMv2并禁用NTLMv1,在同一个注册表路径下确认LMCompatibilityLevel确实是5而不是3或4;第二,设置强密码策略,最小长度12位以上,包含大小写、数字和特殊字符;第三,启用账户锁定策略,比如5次失败锁定30分钟,防止暴力破解;第四,定期审计密码哈希存储状态,可以用工具如Mimikatz的检测模块或者微软的Security Compliance Toolkit来扫描。
另外特别提醒,如果你的服务器上跑着IIS、SQL Server或者其他需要Windows身份验证的服务,禁用LM哈希后要测试这些服务是否正常。大部分现代服务都支持NTLMv2,但某些老旧应用可能还依赖NTLMv1,这时候需要升级应用或者做兼容性评估。我见过不少案例,改完LM哈希后某个内部系统突然登不上了,就是因为那个系统还在用NTLMv1。
域环境下的特殊注意事项在Active Directory域环境中,LM哈希的禁用需要从域控制器层面统一管控。域控制器上的密码策略会强制下发到所有域成员。你需要在"默认域策略"或者新建的GPO中配置前面提到的安全选项。同时,域控制器本身的SAM数据库里如果还存着旧账户的LM哈希,需要用工具清理掉。
还有一个容易被忽略的点:如果域中存在只读域控制器(RODC),RODC默认不缓存密码哈希,但如果你手动配置了密码复制策略,它可能会缓存LM哈希。所以RODC的密码复制策略也要检查,确保只复制NTLMv2哈希。此外,Azure AD Connect同步的混合环境中,本地AD的LM哈希策略同样需要配置,否则同步过来的账户可能在本地保留旧的哈希格式。
如何验证LM哈希是否已经被成功禁用修改完成并重启后,你需要验证效果。最简单的方法是用命令行工具检查注册表值是否正确:
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v NoLMHash reg query "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v LMCompatibilityLevel
输出结果应该是NoLMHash为0x1,LMCompatibilityLevel为0x5。更深入的验证可以用审计工具扫描服务器的SAM数据库,看是否还存在LM哈希条目。微软提供的Security Compliance Toolkit里有专门的基线扫描功能,可以一键检测包括LM哈希在内的数十项安全配置是否合规。
另外,你还可以从网络层面验证:用抓包工具(如Wireshark)监控客户端登录时的认证过程,如果看到的是NTLMv2响应(以0x02开头),说明LM哈希已经不再参与认证流程。如果还能抓到NTLMv1或LM响应,说明配置没有完全生效,需要排查是哪台机器或者哪个策略还在拖后腿。
常见问题和踩坑经验实际操作中,我总结了几个最常见的坑:第一,改了注册表但没重启,以为生效了其实没有,重启是必须的;第二,域环境中本地策略被域策略覆盖,你在本地改了但域策略又改回来了,所以一定要在域级别统一配置;第三,某些第三方安全软件或者备份软件会修改Lsa注册表项,导致你的设置被覆盖,需要定期巡检;第四,Windows Server 2003和更老的系统可能不支持LMCompatibilityLevel设为5,需要先升级系统或者接受较低的安全级别。
还有一个实战经验:如果你的服务器之前被入侵过,攻击者可能已经提取了LM哈希并离线破解了。所以禁用LM哈希只是防止未来的风险,已经泄露的密码必须强制全部重置。建议在禁用LM哈希的同时,触发一次全域密码重置策略,确保所有账户使用新的强密码。
总结禁用Windows服务器的LM哈希存储是一项基础但极其重要的安全加固操作。核心就是两步:注册表中NoLMHash设为1、LMCompatibilityLevel设为5。域环境通过组策略统一下发,单机环境直接改注册表重启。配套措施包括强制NTLMv2、强密码策略、账户锁定和定期审计。这件事不复杂,但很多企业就是没做,结果被攻击者利用LM哈希轻松拿下管理员权限。安全无小事,今天就把这个隐患彻底堵上。
