Mimikatz深度解析:WDigest凭据提取技术详解
1. WDigest概述
WDigest是Windows系统中用于缓存用户凭据的组件,在Windows Server 2008 R2及更早版本中默认启用明文凭据缓存。Mimikatz通过sekurlsa::wdigest命令可以提取这些缓存的凭据。
关键特性:
- 默认在Windows Server 2008 R2及更早版本中启用
- 缓存凭据使用对称加密算法保护
- 可通过注册表项
UseLogonCredential控制是否缓存凭据
2. WDigest工作原理
2.1 凭据缓存流程
- 用户登录时,凭据通过
wdigest!SpAcceptCredentials函数传递 - 凭据被
LsaProtectMemory函数加密 - 加密后的凭据存储在内存中的链表中
2.2 加密机制
WDigest使用两种加密算法保护凭据:
- AES:当数据块长度能被8整除时使用
- 3DES:其他情况下使用
加密密钥存储在:
lsasrv!hAesKey- AES加密密钥lsasrv!h3DesKey- 3DES加密密钥
这些密钥在lsass启动时通过BCryptGenRandom随机生成。
3. 凭据提取技术
3.1 关键数据结构
3.1.1 加密密钥结构
typedef struct _KIWI_BCRYPT_HANDLE_KEY {
ULONG size;
ULONG tag; // 'UUUR'
PVOID hAlgorithm;
PKIWI_BCRYPT_KEY key;
PVOID unk0;
} KIWI_BCRYPT_HANDLE_KEY, *PKIWI_BCRYPT_HANDLE_KEY;
typedef struct _KIWI_BCRYPT_KEY81 {
ULONG size;
ULONG tag; // 'MSSK'
ULONG type;
ULONG unk0;
ULONG unk1;
ULONG unk2;
ULONG unk3;
ULONG unk4;
PVOID unk5; // before, align in x64
ULONG unk6;
ULONG unk7;
ULONG unk8;
ULONG unk9;
KIWI_HARD_KEY hardkey;
} KIWI_BCRYPT_KEY81, *PKIWI_BCRYPT_KEY81;
typedef struct _KIWI_HARD_KEY {
ULONG cbSecret;
BYTE data[ANYSIZE_ARRAY]; // 实际密钥数据
} KIWI_HARD_KEY, *PKIWI_HARD_KEY;
3.1.2 WDigest凭据链表结构
typedef struct _KIWI_WDIGEST_LIST_ENTRY {
struct _KIWI_WDIGEST_LIST_ENTRY *Flink;
struct _KIWI_WDIGEST_LIST_ENTRY *Blink;
ULONG UsageCount;
struct _KIWI_WDIGEST_LIST_ENTRY *This;
LUID LocallyUniqueIdentifier;
} KIWI_WDIGEST_LIST_ENTRY, *PKIWI_WDIGEST_LIST_ENTRY;
链表节点后跟三个LSA_UNICODE_STRING字段:
- 偏移0x30:用户名
- 偏移0x40:主机名
- 偏移0x50:加密密码
3.2 提取步骤
-
定位密钥:
- 在lsass进程内存中搜索
hAesKey和h3DesKey - 解析密钥结构获取实际加密密钥
- 在lsass进程内存中搜索
-
遍历凭据链表:
- 从
wdigest!l_LogSessList开始遍历链表 - 提取每个节点的用户名、主机名和加密密码
- 从
-
解密凭据:
- 根据密码长度选择AES或3DES解密算法
- 使用提取的密钥解密密码
4. UseLogonCredential绕过技术
Windows默认禁用WDigest明文凭据缓存,通过修改注册表项HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest\UseLogonCredential可以重新启用,但通常需要重启。
4.1 内存修改技术
可以直接修改lsass进程内存中的g_fParameter_UseLogonCredential变量来启用WDigest缓存,无需修改注册表或重启系统:
- 定位
wdigest.dll中的g_fParameter_UseLogonCredential变量 - 将其值从0改为1
- 新登录的凭据将被缓存
4.2 实现原理
wdigest!SpAcceptCredentials函数检查两个条件:
g_IsCredGuardEnabled是否为1g_fParameter_UseLogonCredential是否为0
如果任一条件为真,则调用LogSessHandlerNoPasswordInsert不缓存密码;否则调用LogSessHandlerPasswdSet缓存密码。
5. 高级技术:DLL注入LSASS
5.1 通过注册表加载DLL
发现lsasrv.dll中的LsapLoadLsaDbExtensionDll函数会加载用户指定的DLL:
-
创建注册表项:
HKLM\SYSTEM\CurrentControlSet\Services\NTDS\LsaDbExtPt值为DLL路径
-
系统重启时,DLL将被加载到lsass进程
重要:DLL的DllMain函数必须返回FALSE,避免后续GetProcAddress调用导致系统蓝屏。
5.2 通过SAMR RPC远程加载DLL
samsrv.dll中存在类似功能:
-
创建注册表项:
HKLM\SYSTEM\CurrentControlSet\Services\NTDS\DirectoryServiceExtPt值为DLL路径
-
触发SAMR RPC调用(如
hSamConnect)加载DLL
这种方法无需重启系统,可以通过网络触发。
6. 防御与检测
6.1 防御措施
- 启用Credential Guard
- 确保
UseLogonCredential注册表值为0 - 监控lsass进程的异常内存访问
- 限制对关键注册表项的修改
- 启用PPL(Protected Process Light)保护lsass
6.2 检测方法
- 监控对lsass进程的
WriteProcessMemory调用 - 检测异常DLL加载行为
- 监控可疑注册表修改
- 检测WDigest相关API的异常调用模式
7. 总结
Mimikatz的WDigest凭据提取功能依赖于对lsass进程内存的深入分析和Windows认证组件的逆向工程。理解这些技术原理不仅有助于渗透测试,也能帮助蓝队开发更有效的防御措施。通过内存操作绕过安全控制的技术展示了攻击者如何在不触发传统检测机制的情况下达成目标,强调了深度防御的重要性。