我们知道在 win10/server2012 及以上版本开启 Wdigest 的情况下通过 mimikatz 是拿不到明文密码的,需要通过注册表开启 wdigest 才能抓到明文密码,本文通过 windbg 调试来看内存中发生了怎样的变化
在调试之前先来看一下 Windows 凭证机制的基础知识
Windows凭证机制
关键基础设施
SAM文件
SAM (安全账户管理器),SAM 用来存储 Windows 操作系统密码的数据库文件,为了避免明文密码泄露,SAM 文件中保存的是明文密码经过一系列算法处理过的 Hash 值,被保存的 Hash 分为 LM Hash(现已废弃)、NTLMHash(长度32bit由字母数字组成)。在用户在本地或者远程登陆系统时,会将 Hash 值与 SAM 文件中保存的 Hash 值进行对比。在后期的 Windows 系统中,SAM 文件中被保存的密码 Hash 都被密钥 SYSKEY 加密
- SAM 文件在磁盘中的位置在:C:\windows\system32\config\sam
- SAM 文件在 Windows 系统启动后被系统锁定,无法进行移动和复制
- SAM 就是用来存放用户密码、Internet Explorer 密码,服务账号密码、SQL 密码、系统账户密码、配置的计划任务账户密码
Lsass进程
本地安全管理局子系统服务 (LSASS) 是 Microsoft Windows 操作系统中的一个进程,负责在系统上强制执行安全策略。它验证用户登录到 Windows 计算机或服务器、处理密码更改、创建访问令牌等。我们常说的 dump lsass 就是对转存 Lsass 进程中的明文登陆密码
Windows认证流程
Windows本地认证
Window 本地登录过程如上图所示:注销或开机后:弹出登录界面,用于接受用户输入,winlogon.exe 进程用于管理用户的登录和退出,用户输入密码进行登录时发生如下操作:
- winlogon.exe 进程将账号密码给 lsass.exe 进程进行处理,并将明文密码缓存在进程中
- lsass.exe 进程,将明文密码加密成 NTLM Hash,对 SAM 数据库比较认证
如果比较结果相同则登录成功,不相同登录失败,分析整个过程会存在两个问题:
- lsass.exe 进程会将明文密码换存在进程中,这也是为什么低版本系统可以直接抓到明文密码的原因
- 使用 NTLM hash 进行比较,由于 NTLM 协议没有对认证发起人进行校验,如果攻击者通过某些手段可以拿到 hash,攻击者可以通过捕获密码的 hash 值(对应着密码的值),以此来横向访问其他网络系统,即 PTH 哈希传递攻击
补充:除了本地认证还有基于 NTLM 协议实现的网络认证和基于 Kerberos 协议实现的域认证
什么是Wdigest?
WDigest 即摘要身份验证,摘要身份验证是一种质询/响应协议,主要在 Windows Server 2003 中用于 LDAP 和基于 Web 的身份验证。它利用超文本传输协议 (HTTP) 和简单身份验证安全层 (SASL) 交换进行身份验证。WDigest 的问题是它将密码存储在内存中,并且无论是否使用它,都会将其存储在内存中
在 win 7 和 2008 r2 及之前都是默认开启 Wdigest 且无法禁用,需要额外安装 KB2871997 补丁禁用 wdigest(但是 WIN7 以及 08 以后的系统中微软都默认禁止了 Wdigest 协议)
所以在 win10/server2012 及以上版本关闭 Wdigest 的情况下,抓密码需要手工修改注册表 + 强制锁屏 + 等待目标系统管理员重新登录 = 截取明文密码
修改注册表的命令:
1 | reg add HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest /v UseLogonCredential /t REG_DWORD /d 1 /f |
也可以通过 powershell、msf 等修改注册表
关于 mimikatz 是如何实现 sekurlsa::wdigest 的代码分析可以看这篇文章:调试mimikatz源码:wdigest功能源码调试详细过程及分析
windbg调试
Windbg 是微软开发的免费源码级调试工具。Windbg 可以用于 Kernel 模式调试和用户模式调试,还可以调试 Dump 文件
官方文档及下载地址:https://docs.microsoft.com/zh-cn/windows-hardware/drivers/debugger/debugger-download-tools
在调试 windows 时,无法简单地将 WinDBG 附加到 lsass
上,如果这么操作,Windows 会停止运行,警告用户系统即将重启。因此,我们需要 attach 内核,然后从 Ring-0 切换到 lsass
进程
双机远程调试环境搭建
实验环境
- Windows 11 物理机 + windbg
- Windows 10 虚拟机(桥接模式)
微软
旧版使用com接口:
新版使用网络连接:
-
注意:运行调试器的计算机称为主计算机,正在调试的计算机称为目标计算机。 使用自动设置主计算机必须运行 Windows 7 或更高版本,并且目标计算机必须 Windows 8 或更高版本运行
接下来我们进行配置,我是用的是最基础的 com 串口方式连接
目标虚拟机设置串口,使用命名的管道要
\\.\pipe\
前缀,后面的名字可以自己写一个短的好记的目标机器内配置调试参数
bcdedit 根据 default 生成一个新的启动项,用来调试,其实通过 bcdedit /enum 并没有看到 default 这个名字
1
bcdedit /copy {default} /d "vmdebug"
已将该项成功复制到 {7985b4ec-581d-11ec-bee9-8214e8b021aa}
复制一下这个 id,粘贴到真实机的文档里面
此时重启的话会有多一个启动项选择,但是看不到,需要设置 timeout,让系统停留在启动项的选择界面
1
bcdedit /timeout 10
设置 timeout 会在启动项选择界面停留 10 秒钟,超过 10 秒钟则进入默认启动项
重启后从 vmdebug 选项进入,设置 vmdebug 为调试模式,以免影响默认启动方式的系统环境
1
bcdedit /dbgsettings serial baudrate:115200 debugport:2
注意这个 debugport,就是创建虚拟机串口的端口号,从创建时的截图看,串行端口 2,debugport 应该就是 2,如果不知道。那只能先设置一个,然后连不上的时候再重新输入命令修改串口
1
bcdedit /debug {ID} ON
ID是从 bcdedit /copy 创建出 vmdebug 后生成的 id,也可以通过 bcdedit /enum 查询
重启,停在开机启动项
使用 windbg 链接
如果一直提示 busy,使用 ctrl+break 键中断,87 键键盘需要(FN+Pause),进入调试器
TIP:
- 内核调试必须使用双机调试
- windbg preview 比旧版好用
- 等系统进入输入密码界面,再 break,之后就会有 lsass 进程
调试分析
命令行参数
attach内核调试器后,我们需要抓取
lsass
进程的EPROCESS
地址,可以使用如下命令!process 0 0 lsass.exe
确定
EPROCESS
地址后(ffff9d01325a7080
),我们可以请求将调试会话切换到lsass
进程的上下文1
.process /i /p /r ffff9d01325a7080
使用
lm
命令来确定空间的访问权限
在开启 wdigest 前通过 mimikatz 导出密码
通过修改注册表开启 UseLogonCredential ,查看内存中的变化
(图片引用自安全客)
锁屏后等待用户重新登录,然后再导密码就是保存的明文密码了
关于 mimikatz wdigest 模块是如何实现可以看以下两篇分析文章:
参考链接