ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Windows密码存储机制解析:从NTLM哈希到LSASS进程安全

Windows密码存储机制解析:从NTLM哈希到LSASS进程安全 1. 从一次“忘记密码”的应急处理说起那天下午同事小李的电脑屏幕锁定了。他尝试了几次常用的密码组合无一例外地弹出了那个令人沮丧的红色提示框。重启、再试依然无效。眼看一个重要的线上会议即将开始他急得团团转。作为团队里对系统底层稍有了解的人我被拉去“救火”。我的第一反应不是去猜密码而是思考Windows的登录密码到底以何种形式存在我们有没有可能在不破坏数据的前提下绕过或重置这个密码这个看似简单的日常问题背后牵扯出的是一整套Windows身份验证与安全存储的复杂机制。很多人可能认为密码就是被“记住”在某个文件里就像记事本记录一串字符。但事实远非如此。Windows尤其是从NT时代延续至今的现代版本出于安全考虑绝不会以明文形式存储你的密码。它存储的是一种被称为“哈希值”的密码“指纹”。理解这个过程不仅是系统管理员、安全工程师的必修课对于每一位需要管理自己电脑、处理突发状况的普通用户而言也能让你在遇到类似小李的情况时不至于手足无措至少能明白哪些方法是可行的哪些是徒劳甚至危险的。本文将深入Windows系统的腹地拆解从你按下回车键到登录成功的短短瞬间系统背后完成的密码验证与存储之旅。我们会聚焦于几个核心组件负责交互的Winlogon、掌管安全的LSASS进程、以及最终的密码仓库——SAM文件。同时我们会剖析关键的NTLM哈希算法并探讨围绕这套机制衍生的实用技术与安全考量。2. 登录链条的核心参与者Winlogon、LSASS与SAM当你坐在电脑前输入密码并点击“登录”时一个精密的链条便开始运转。这个链条主要由三个核心角色构成理解它们各自的分工是理解整个存储过程的基础。2.1 Winlogon登录界面的“前台经理”WinlogonWindows Logon Application是用户直接打交道的部分。它负责显示那个熟悉的登录界面例如锁屏界面捕获你输入的用户名和密码。你可以把它想象成银行大堂的接待经理。他的工作不是处理核心业务验证你的账户里有没有钱而是收集你的业务请求存/取款单和身份凭证银行卡和密码然后将其转交给后台的“风控与业务处理中心”。在技术实现上Winlogon进程winlogon.exe在系统启动早期就由SMSS会话管理器创建。它加载关键的图形界面DLL如msgina.dll或现代系统上的LogonUI呈现登录UI。当你提交凭证后Winlogon会将这些信息打包通过一个安全的本地过程调用LPC/RPC通道发送给系统中真正的安全权威——LSASS。注意在旧版Windows如XP中我们常听说用osk.exe屏幕键盘替换utilman.exe轻松使用来绕过登录界面。其本质就是利用了Winlogon在特定时机如按WinU会调用utilman.exe的特性。替换后触发的是cmd.exe并且这个cmd.exe继承了Winlogon的高权限SYSTEM从而可以修改密码或创建新用户。但这并非破解了密码存储机制而是利用了登录界面辅助功能的管理漏洞。2.2 LSASS系统的“安全守门人”LSASSLocal Security Authority Subsystem Service本地安全机构子系统服务是整个Windows安全体系的心脏。它作为一个服务运行lsass.exe接收来自Winlogon的凭证并负责执行实际的验证工作。LSASS的工作流程可以细分为以下几步接收凭证从Winlogon处获取用户名和密码此时密码仍是用户输入的原始文本。计算哈希LSASS使用指定的哈希算法对于本地账户主要是NTLM对用户输入的密码进行计算生成一个固定长度的哈希值。这个计算过程是单向的理论上无法从哈希值反推出原始密码。获取存储的哈希LSASS会访问系统的安全账户数据库即SAM文件读取对应用户名存储的密码哈希值。这个哈希值是在用户创建或更改密码时计算并存储下来的。比对验证LSASS将刚刚计算出的哈希值来自用户输入与从SAM中读取的存储哈希值进行比对。如果两者完全一致则判定密码正确否则登录失败。生成访问令牌验证成功后LSASS会为该用户会话创建一个唯一的访问令牌Access Token。这个令牌包含了用户的身份标识SID和所属的权限组如Administrators、Users等。之后用户启动的任何进程都将附带这个令牌系统资源管理器如文件系统、注册表通过检查令牌来决定是否允许访问。LSASS进程的内存中因此包含了大量敏感信息包括当前登录用户的密码哈希、甚至可能是明文密码取决于认证方式。这使得它成为攻击者垂涎的首要目标。著名的Mimikatz工具就是通过注入代码到LSASS进程或读取其转储文件lsass.dmp来提取这些凭证的。2.3 SAM文件密码哈希的“保险库”如果LSASS是验证官那么SAMSecurity Accounts Manager安全账户管理器文件就是存放所有本地用户和组账户信息的核心数据库特别是密码哈希的最终存储地。SAM文件位于%SystemRoot%\system32\config\SAM例如C:\Windows\System32\config\SAM。在系统运行时该文件被系统内核以独占方式锁定任何用户态的程序都无法直接读取或修改这是操作系统对其施加的核心保护。SAM文件的结构类似于一个微型注册表数据库它本身也是Windows注册表HKEY_LOCAL_MACHINE\SAM子键的对应文件。它内部以二进制格式存储了以下关键信息用户账户的RID相对标识符是用户SID的最后一部分。例如管理员账户的RID通常是500第一个新建用户的RID从1001开始。用户的NTLM哈希值这是密码经过NTLM哈希算法计算后的结果是验证密码的关键。用户的LM哈希值一种更古老、更脆弱的哈希用于向后兼容非常古老的系统如Windows 95/98和网络环境。在现代Windows如Vista之后中默认情况下LM哈希是禁用的存储为空值或一个固定的禁用标记这极大地提升了安全性。账户的其他属性如账户是否禁用、密码是否永不过期、上次密码修改时间等。由于SAM文件在运行时被锁定传统的攻击手法是在离线环境下进行操作。例如使用另一个系统启动盘如WinPE、Linux Live CD挂载原系统的硬盘然后直接读取%SystemRoot%\system32\config\SAM和同目录下的SYSTEM文件。SYSTEM文件中包含了一个名为Syskey的密钥用于加密SAM数据库中的部分数据主要是哈希值。只有同时拥有SAM和SYSTEM文件才能解密出可用的NTLM哈希。3. NTLM哈希密码的“不可逆指纹”我们反复提到了“NTLM哈希”它是整个本地密码存储和验证的密码学基石。理解它就理解了Windows密码安全的核心。3.1 什么是哈希哈希函数是一种单向加密算法。它接收任意长度的输入比如你的密码“Pssw0rd!”通过一系列复杂的数学运算输出一个固定长度的字符串比如NTLM哈希是32个十六进制字符。这个输出被称为哈希值或消息摘要。 哈希函数有几个关键特性确定性相同的输入永远产生相同的哈希值。快速计算给定输入能快速计算出哈希值。抗碰撞性极难找到两个不同的输入产生相同的哈希值。单向性原像攻击困难给定一个哈希值极难在计算上不可行反推出原始的输入是什么。正是“单向性”使得存储哈希值比存储明文密码安全。即使攻击者窃取了数据库SAM文件他得到的也只是哈希值而非你的真实密码。3.2 NTLM哈希的计算过程NTLM哈希的计算相对直接将用户密码的Unicode编码每个字符用两个字节表示作为输入。对这个Unicode字节序列应用MD4哈希算法。输出一个128位16字节的哈希值通常表示为32个十六进制字符。例如密码“123456”的NTLM哈希是32ED87BDB5FDC5E9CBA88547376818D4。你可以用简单的PowerShell命令验证这个过程注意这会在内存中生成密码的哈希仅用于学习# 方法一使用 .NET 方法 $text [System.Text.Encoding]::Unicode.GetBytes(123456) $md4 New-Object System.Security.Cryptography.MD4CryptoServiceProvider $hash $md4.ComputeHash($text) [System.BitConverter]::ToString($hash).Replace(-, ).ToLower() # 输出应为32ed87bdb5fdc5e9cba88547376818d4 # 方法二借助第三方模块或在线工具理解概念实操心得在真实渗透测试或安全审计中我们绝不会在目标机器上直接计算密码哈希因为这可能触发安全警报或留下痕迹。所有哈希计算和破解操作都应在受控的、隔离的分析环境中进行。3.3 NTLM哈希的局限性与其引发的攻击尽管哈希提供了基础安全但NTLM机制本身存在一些弱点使得它并非固若金汤无盐Salt哈希现代密码存储最佳实践要求在计算哈希前为每个密码拼接一个随机字符串称为“盐”再将结果哈希。盐会和哈希值一起存储。这样即使两个用户密码相同他们的哈希值也不同并且可以极大增加预计算攻击如彩虹表的成本。然而传统的NTLM哈希在计算时不使用盐。这意味着密码“123456”在任何Windows系统上其NTLM哈希都是相同的32ED87BDB5FDC5E9CBA88547376818D4。攻击者可以预先计算海量常用密码的NTLM哈希形成“彩虹表”然后直接与窃取的哈希比对瞬间破解弱密码。传递哈希攻击这是针对NTLM认证的一个经典攻击。由于系统验证密码的方式是比对哈希值而非原始密码那么如果一个攻击者已经获取了某个用户的NTLM哈希例如从内存中dump出来他就可以直接使用这个哈希值去尝试访问其他使用NTLM认证的服务如文件共享SMB、远程桌面等而无需知道原始密码。系统会接受这个正确的哈希作为凭证。防御此类攻击需要启用NTLMv2它引入了挑战-响应机制使得直接传递哈希无效或更安全的Kerberos认证并实施强密码策略。离线破解一旦攻击者获取了SAM和SYSTEM文件他就可以在自己强大的计算机上例如使用多张GPU显卡进行离线暴力破解或字典攻击。由于NTLM哈希计算速度快MD4本身很快这使得尝试数十亿甚至数万亿个密码组合成为可能。一个强度不足的密码可能在几分钟甚至几秒内被破解。4. 密码存储的实战探查与验证理论需要结合实际。我们可以通过一些安全工具在授权和合法的环境下直观地查看系统是如何处理密码哈希的。4.1 使用Mimikatz查看内存中的凭证Mimikatz是一款著名的Windows安全工具它能够从LSASS进程内存中提取各种凭证。请注意仅在自己的测试环境或拥有明确授权的环境中使用。以管理员权限运行Mimikatz因为需要调试LSASS进程所以需要高权限。执行命令privilege::debug sekurlsa::logonpasswordsprivilege::debug命令尝试启用SeDebugPrivilege权限这是访问其他进程内存所必需的。sekurlsa::logonpasswords命令则会列出当前系统中所有可提取的登录会话信息。分析输出在输出中你会看到类似下面的内容Authentication Id : 0 ; 123456 (00000000:0001e240) Session : Interactive from 1 User Name : Alice Domain : DESKTOP-ABC123 Logon Server : DESKTOP-ABC123 Logon Time : 2023/10/27 10:00:00 SID : S-1-5-21-1234567890-123456789-123456789-1001 msv : [00000003] Primary * Username : Alice * Domain : DESKTOP-ABC123 * NTLM : 32ed87bdb5fdc5e9cba88547376818d4 * SHA1 : ... tspkg : wdigest : * Username : Alice * Domain : DESKTOP-ABC123 * Password : (null) kerberos : * Username : Alice * Domain : DESKTOP-ABC123 * Password : (null) ssp : credman :这里清晰地显示了用户Alice的NTLM哈希值。在某些配置下如系统启用WDigest或进行特定类型的认证时甚至可能直接看到Password字段为明文密码这正是为什么微软一直在推动禁用不安全的认证协议并引入Credential Guard等特性来隔离LSASS中凭证的原因。4.2 离线提取SAM哈希如果系统无法启动或者需要在外部进行分析离线提取是另一种方法。这需要物理接触或通过启动盘访问硬盘。获取SAM和SYSTEM文件从目标系统的%SystemRoot%\system32\config\目录下复制SAM和SYSTEM文件。由于它们运行时被锁定你需要从另一个系统启动如WinPE或对硬盘进行卷影复制。使用工具解析将这两个文件导入专门的工具。一个经典的选择是samdump2Linux环境下或creddump7框架中的工具。在Kali Linux中可以使用samdump2samdump2 SYSTEM SAM -o hashes.txt这条命令会使用SYSTEM文件中的密钥解密SAM文件并输出所有用户的用户名、RID和NTLM/LM哈希到hashes.txt。结果格式输出文件内容通常如下Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: Alice:1001:aad3b435b51404eeaad3b435b51404ee:32ed87bdb5fdc5e9cba88547376818d4:::这是LM:NTLM格式。aad3b435b51404eeaad3b435b51404ee是LM哈希的空白或禁用占位符。31d6cfe0d16ae931b73c59d7e0c089c0是空密码的NTLM哈希。最后一行是用户Alice的NTLM哈希。重要警告这些操作仅用于安全研究、取证或在自己完全拥有所有权的系统上进行故障排除。未经授权获取他人系统的密码哈希是非法行为。5. 针对密码存储机制的防御与加固实践了解了攻击面我们就可以有针对性地进行防御。以下是一些提升本地密码存储安全性的实操建议。5.1 启用强密码策略与禁用LM哈希这是最基本也是最有效的一步。通过组策略gpedit.msc或安全策略secpol.msc可以强制实施密码必须符合复杂性要求启用。要求密码包含大小写字母、数字和符号。密码长度最小值设置为至少12位或更长。密码最短使用期限根据需要设置防止频繁更改。密码最长使用期限设置一个合理的期限如90天强制定期更换。强制密码历史记住最近5-10个密码防止重复使用。禁用LM哈希在组策略中路径为计算机配置 - Windows 设置 - 安全设置 - 本地策略 - 安全选项找到“网络安全: 不要在下次更改密码时存储 LAN Manager 哈希值”将其设置为“已启用”。对于已存在的账户在更改密码后旧的LM哈希才会被清除。你也可以通过修改注册表HKLM\SYSTEM\CurrentControlSet\Control\Lsa下的NoLMHash值为1来全局禁用。5.2 实施Credential Guard与LSA保护对于Windows 10/11 Enterprise或Windows Server 2016及以上版本可以利用硬件安全特性如VT-d/AMD-Vi和TPM来提供更深层次的保护。Credential Guard它利用基于虚拟化的安全VBS将LSASS进程隔离在一个安全的、受Hypervisor保护的环境中运行。传统的进程内存读取工具如Mimikatz无法访问这个隔离环境中的LSASS从而有效防止凭证从内存中被窃取。启用Credential Guard通常需要通过组策略或使用DG_Readiness_Tool工具。LSA保护这是一个稍弱的保护措施它要求任何尝试调试或读取LSASS进程的代码必须具有“受信任的调用方”权限。这可以阻止一些非特权攻击但无法抵御具有内核权限的攻击者。可以通过组策略计算机配置 - 管理模板 - 系统 - 本地安全机构 - 配置 LSASS 以作为受保护进程运行来启用。5.3 监控与审计LSASS访问即使无法立即启用高级功能加强监控也能及时发现异常。启用审计进程创建在“高级审核策略配置”中启用审核详细跟踪 - 审核进程创建。成功启用后事件查看器中会记录事件ID 4688包含新进程的详细信息。你可以监控是否有异常进程如procdump.exe,mimikatz.exe或其变种被创建。监控LSASS进程的句柄打开请求通过Sysinternals Suite中的Sysmon工具并配置精细的规则可以监控对LSASS进程的访问尝试。例如可以配置规则在进程lsass.exe被以PROCESS_VM_READ权限打开时生成警报。使用Windows Defender ATP或类似EDR解决方案这些高级端点检测与响应平台内置了检测凭证盗窃攻击如Mimikatz活动的行为模型能够提供更自动化的防护和响应。5.4 应对密码遗忘安全的重置方法回到文章开头小李的问题。在了解了密码存储机制后我们就知道直接“破解”存储在SAM中的NTLM哈希在紧急情况下是不现实的耗时。更实际的方法是“重置”或“绕过”。使用密码重置盘这是最官方、最安全的方法。前提是你在忘记密码之前已经创建了它在控制面板的用户账户中设置。插入U盘重置密码不会导致数据加密密钥丢失对于使用了EFS加密的文件至关重要。使用其他管理员账户如果系统中有另一个具有管理员权限的账户可以直接登录然后在“计算机管理 - 本地用户和组”中重置小李的密码。使用Windows安装介质这是一个常见的离线方法。从Windows安装U盘或光盘启动在安装界面按ShiftF10打开命令提示符。然后使用命令行工具move或copy来替换utilman.exe或sethc.exe粘滞键方法如前文所述从而在登录界面获得一个高权限的cmd来创建新用户或重置密码。使用第三方启动盘工具如Hiren‘s BootCD PE、Offline NT Password Registry Editor等。这些工具可以直接加载系统的SAM数据库并允许你将某个用户的密码哈希清空或设置为已知值。务必注意对于使用了BitLocker全盘加密的系统此方法无效你需要BitLocker恢复密钥。同时清空密码哈希会导致该用户所有基于EFS加密的文件无法访问除非有备份的密钥。踩坑实录我曾经帮助一位同事用第三方工具重置了密码他成功登录了。但一周后他哭诉所有工作文档都打不开了提示“拒绝访问”。原来他的重要文件都使用了EFS加密而Windows的EFS加密密钥与用户密码是关联的。重置密码导致旧的加密密钥丢失新生成的密钥无法解密旧文件。最终通过找到并导入他之前无意中备份的EFS证书和密钥才解决。教训重置本地账户密码前务必确认该用户是否使用了EFS加密文件。如果可能优先使用“密码重置盘”或“其他管理员账户修改密码”的方式这两种方式通常不会破坏EFS密钥链。6. 从本地到网络NTLM认证的延伸NTLM哈希不仅用于本地登录它更是Windows网络认证特别是早期版本的基石。当一台Windows计算机尝试访问另一台计算机上的共享资源如\\server\share时如果没有建立Kerberos信任如在工作组环境中就会使用NTLM挑战/响应协议。客户端发起请求客户端向服务器发送访问请求。服务器发送挑战服务器生成一个16字节的随机数称为“挑战”Challenge发送给客户端。客户端计算响应客户端使用自己的NTLM哈希作为密钥对这个挑战进行加密计算生成一个24字节的“响应”Response发送回服务器。关键点这里客户端发送的不是哈希本身而是用哈希加密挑战后的结果。服务器验证服务器拥有该用户存储的NTLM哈希可能来自本地SAM或域控制器。它用这个哈希同样对之前发出的挑战进行加密计算得到一个值。将此值与客户端发来的响应进行比对。一致则认证通过。这个过程比直接传递哈希Pass-the-Hash安全因为每次认证的挑战都不同响应也随之变化避免了重放攻击。但NTLMv1仍然存在弱点如挑战可能被预测因此应优先使用NTLMv2或Kerberos。在企业域环境中密码哈希存储在域控制器DC的NTDS.dit数据库中其验证原理类似但规模更大、引入了Kerberos票据等更复杂的机制。本地SAM可以看作是一个微型的、单机的账户数据库。理解Windows登录的密码存储过程就像拿到了一张系统的安全蓝图。它解释了为什么密码不能简单找回为什么某些攻击手段会生效以及我们应该从哪些层面去加固自己的系统。从Winlogon到LSASS再到SAM文件中的NTLM哈希每一个环节都体现了安全与便利之间的权衡。作为用户或管理员强密码是防御的第一道也是最重要的一道防线。在此基础上结合系统提供的高级安全功能如Credential Guard和良好的监控实践才能构建起更稳固的本地安全防线。下次再遇到登录问题时希望你能更清晰地知道问题可能出在链条的哪个环节又该如何科学、安全地应对。
返回列表