SharpDPAPI: C# port of some Mimikatz DPAPI functionality
SharpDPAPI
SharpDPAPI is a C# port of some DPAPI functionality from @gentilkiwi‘s Mimikatz project.
The SharpChrome subproject is an adaptation of work from @gentilkiwi and @djhohnstein, specifically his SharpChrome project. However, this version of SharpChrome uses a different version of the C# SQL library that supports the lockless opening. SharpChrome is built as a separate project in SharpDPAPI because of the size of the SQLite library utilized.
SharpChrome also uses a minimized version of @AArnott’s BCrypt P/Invoke code released under the MIT License.
If you’re unfamiliar with DPAPI, check out this post for more background information. For more information on Credentials and Vaults in regards to DPAPI, check out Benjamin’s wiki entry on the subject.
SharpDPAPI
One of the goals with SharpDPAPI is to operationalize Benjamin’s DPAPI work in a way that fits with our workflow.
How exactly you use the toolset will depend on what phase of an engagement you’re in. In general, this breaks into “have I compromised the domain or not”.
If domain admin (or equivalent) privileges have been obtained, the domain DPAPI backup key can be retrieved with the backupkey command (or with Mimikatz). This domain private key never changes and can decrypt any DPAPI masterkeys for domain users. This means, given a domain DPAPI backup key, an attacker can decrypt masterkeys for any domain user that can then be used to decrypt any Vault/Credentials/Chrome Logins/other DPAPI blobs/etc. The key retrieved from the backupkey command can be used with the masterkeys, credentials, vaults, rdg, or triage commands.
If DA privileges have not been achieved, using Mimikatz’ sekurlsa::dpapi
command will retrieve DPAPI masterkey {GUID}:SHA1 mappings of any loaded master keys (user and SYSTEM) on a given system (tip: running dpapi::cache
after key extraction will give you a nice table). If you change these keys to a {GUID1}:SHA1 {GUID2}:SHA1...
type format, they can be supplied to the credentials, vaults, rdg, or triage commands. This lets you triage all Credential files/Vaults on a system for any user who’s currently logged in, without having to do file-by-file decrypts.
For decrypting RDG/RDCMan.settings files with the rdg command, the /unprotect
flag will use CryptUnprotectData() to decrypt any saved RDP passwords, if the command is run from the user context who saved the passwords. This can be done from an unprivileged context, without the need to touch LSASS. For why this approach isn’t used for credentials/vaults, see Benjamin’s documentation here.
For machine-specific DPAPI triage, the machinemasterkeys|machinecredentials|machinevaults|machinetriage
commands will do the machine equivalent of user DPAPI triage. If in an elevated context (that is, you need local administrative rights), SharpDPAPI will elevate to SYSTEM privileges to retrieve the “DPAPI_SYSTEM” LSA secret, which is then used to decrypt any discovered machine DPAPI masterkeys. These keys are then used as lookup tables for machine credentials/vaults/etc.
For more offensive DPAPI information, check here.
SharpChrome
SharpChrome is a Chrome-specific implementation of SharpDPAPI capable of cookies and logins decryption/triage. It is built as a separate project in SharpDPAPI because of the size of the SQLite library utilized.
Since Chrome Cookies/Login Data are saved without CRYPTPROTECT_SYSTEM, CryptUnprotectData() is back on the table. If SharpChrome is run from an unelevated content, it will attempt to decrypt any logins/cookies for the current user using CryptUnprotectData(). A /pvk:[BASE64|file.pvk]
, {GUID}:SHA1 lookup table, or /mkfile:FILE
of {GUID}:SHA1 values can also be used to decrypt values. Also, the C# SQL library used (with a few modifications) supports lockless opening, meaning that Chrome does not have to be closed/target files do not have to be copied to another location.
If Chrome is version 80+, an AES state key is stored in AppData\Local\Google\Chrome\User Data\Local State – this key is protected with DPAPI, so we can use CryptUnprotectData()/pvk/masterkey lookup tables to decrypt it. This AES key is then used to protect new cookie and login data entries.
By default, cookies and logins are displayed as a csv – this can be changed with /format:table
for table output, and /format:json
for cookies specifically. The json option outputs cookies in a json format that can be imported into the EditThisCookie Chrome extension for easy reuse.
The cookies command also has /cookie:REGEX
and /url:REGEX
arguments to only return cookie names or urls matching the supplied regex. This is useful with /format:json
to easily clone access to specific sites.
Download & Use
Copyright (c) 2018, Will Schroeder
All rights reserved.