windows凭证机制浅析

我们知道在 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本地认证

截屏2022-09-07 16.17.06

Window 本地登录过程如上图所示:注销或开机后:弹出登录界面,用于接受用户输入,winlogon.exe 进程用于管理用户的登录和退出,用户输入密码进行登录时发生如下操作:

  1. winlogon.exe 进程将账号密码给 lsass.exe 进程进行处理,并将明文密码缓存在进程中
  2. lsass.exe 进程,将明文密码加密成 NTLM Hash,对 SAM 数据库比较认证

如果比较结果相同则登录成功,不相同登录失败,分析整个过程会存在两个问题:

  1. lsass.exe 进程会将明文密码换存在进程中,这也是为什么低版本系统可以直接抓到明文密码的原因
  2. 使用 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接口:

新版使用网络连接:

接下来我们进行配置,我是用的是最基础的 com 串口方式连接

  1. 目标虚拟机设置串口,使用命名的管道要\\.\pipe\前缀,后面的名字可以自己写一个短的好记的

    QQ截图20220907182836

  2. 目标机器内配置调试参数

    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 秒钟则进入默认启动项

    QQ截图20220907195034

    重启后从 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 查询

    重启,停在开机启动项

  3. 使用 windbg 链接

    QQ截图20220907184645

    如果一直提示 busy,使用 ctrl+break 键中断,87 键键盘需要(FN+Pause),进入调试器

    QQ截图20220907195034

TIP:

  1. 内核调试必须使用双机调试
  2. windbg preview 比旧版好用
  3. 等系统进入输入密码界面,再 break,之后就会有 lsass 进程

调试分析

命令行参数

WinDbg 命令手册

windbg使用详解

  1. attach内核调试器后,我们需要抓取lsass进程的EPROCESS地址,可以使用如下命令!process 0 0 lsass.exe

    截屏2022-09-07 19.55.18

  2. 确定EPROCESS地址后(ffff9d01325a7080),我们可以请求将调试会话切换到lsass进程的上下文

    1
    .process /i /p /r ffff9d01325a7080

    截屏2022-09-07 19.58.19

  3. 使用lm命令来确定空间的访问权限

    截屏2022-09-07 19.58.56

在开启 wdigest 前通过 mimikatz 导出密码

QQ截图20220909135851

通过修改注册表开启 UseLogonCredential ,查看内存中的变化

(图片引用自安全客)

锁屏后等待用户重新登录,然后再导密码就是保存的明文密码了

ssss

关于 mimikatz wdigest 模块是如何实现可以看以下两篇分析文章:

探索Mimikatz-第1部分-WDigest

深入分析Mimikatz:WDigest

参考链接

Windows凭证机制

利用WinDbg本地内核调试器攻陷 Windows 内核