Introduction

Have you ever wondered how the Mimikatz pass-the-hash (PtH) command works internally? You are likely familiar with the concept of pass-the-hash at a high level; however, how does Mimikatz associate this hash with your process, and what are the operational security considerations when using this command during an engagement? In this two-part series, we delve into the inner workings of Windows (part one) and the Mimikatz source code (part two) to better understand how this functionality works.

As red team operators trying to avoid detection, it is often necessary to have a detailed understanding of the tools we use. Outside of understanding the usage of a particular tool, understanding how a tool works down to the Windows APIs used to implement it can be paramount in evading detection within a target environment.

In part one, we aim to provide a high-level overview of the Windows authentication model’s various components such as the LSA, SAM, various authentication providers, and access tokens. We provide further references for the interested reader. Readers with the requisite Windows internals knowledge may find less value in part 1and more value in part 2 where we dive deep into the Mimikatz source code itself.

Local Security Authority Subsystem Service (LSASS) Overview

The Local Security Authority Subsystem Service (LSASS) is the primary process used by Windows NT to implement authentication, audit policies, and other security-related tasks [4]. The two primary components loaded by the LSASS are the Local Security Authority (LSA) [5] and the Security Account Manager (SAM) components [7]. The Security Account Manager provides information about users and groups and stores NTLM password hashes for local accounts. The Local Security Authority (LSA) is responsible for handling user authentication and exposes an interface via Advanced Local Procedure Call (ALPC) that is invoked by Winlogon during user authentication [6].

In addition to the LSA and SAM services, LSASS also hosts several other system-critical services for the DPAPI, Encrypted File Service, Key Isolation Service, and Netlogon Service. The LSASS process also communicates with the SRM (Security Reference Monitor), a kernel-mode component implemented within the NT Executive [9] via ALPC to support logging object accesses to the event log [17].

Local Security Authority (LSA) Overview

The Local Security Authority (LSA) is the primary service responsible for handling authentication on Windows. The LSA supports plugin-driven authentication mechanisms through the loading of Security Support Providers (SSP) and Authentication Packages (AP).

An SSP implements the Security Support Provider Interface (SSPI) and is usually used to implement network authentication protocols such as the NT LAN Manager or Kerberos authentication protocols [2]. For instance, the WDigest SSP is used to implement seamless authentication over HTTP to IIS servers using the digest authentication protocol.

A central tenet of Windows authentication is that users should only ever have to input their credentials once during login. The credential is then automatically sent to authenticate to systems using any supported protocol (e.g., Kerberos) implemented by any loaded security support provider. The user won’t need to enter their credentials when attempting to mount a network share as the security support provider caches the credential within LSASS.

Authentication packages are responsible for authenticating the user using various authentication methods [23]. A single “plugin” can function as both a security support provider and an authentication package [24] as is the case for the two primary authentication providers in Windows: MSV1_0 and Kerberos. These are referred to by Microsoft as being a security support provider/authentication package (SSP/AP) [24].

To understand the mechanisms used by Mimikatz to implement pass-the-hash, we must first review both of these authentication providers.

Windows Interactive Logon Process Overview

During an interactive logon, multiple Windows components work together to facilitate a successful authentication. First, the Winlogon.exe process spawns an instance of LogonUI.exe, which is responsible for displaying the Windows logon interface [26]. The LogonUI.exe process is then responsible for loading a series of credential providers from the Windows registry responsible for collecting authentication material from the user, such as a username and password [26]. Winlogon.exe then retrieves the authentication material entered by the user from LogonUI.exe and passes it to the LSASS process by invoking the LsaLogonUser function [26]. The LsaLogonUser function communicates with the LSASS process via the LsaAuthenticationPort ALPC port to pass the authentication material to the appropriate authentication package [26].

Upon receiving the credential material, the Local Security Authority invokes the appropriate authentication provider to handle authentication using the provided credential material. The two primary authentication providers are the MSV1_0 and Kerberos providers, responsible for NTLM and Kerberos authentication, respectively [26]. The MSV1_0 and Kerberos authentication providers are explained in more depth in later sections.

For a local user authentication, the MSV1_0 authentication provider accesses the SAM database containing local account credentials. For domain user authentication, when a domain controller is not accessible, the MSV1_0 authentication provider will attempt to authenticate the user using cached domain user credentials by reading cached domain user credentials from the SECURITY registry hive [26].

For a domain authentication where the system is able to contact a domain controller, the Kerberos authentication provider is invoked by default [26]. This authentication provider is responsible for performing network authentication using the Kerberos protocol (88/TCP).

The diagram given below summarizes the authentication process for an interactive console logon where a user jsmith is authenticating to their corporate workstation (JSMITH-DESKTOP) within the corp.local domain environment. The user enters their credentials into the Windows logon screen, and their workstation subsequently performs Kerberos authentication against the ATX-DC-1 domain controller. The user is subsequently authenticated, and their system requests a TGS ticket to access the files.corp.local SMB file server.

MSV1_0 Authentication Provider

The MSV1_0 authentication provider is invoked in many scenarios. The first scenario is when a user wishes to authenticate using a local user account. In this scenario, the MSV1_0 authentication provider authenticates users using hashes stored in the SAM [3].

Another scenario where the MSV1_0 authentication is invoked is when the user wishes to log in to the computer using domain user credentials when a domain controller is not accessible. For example, this could occur when the user is off-site. If that particular domain user has previously authenticated to the computer, the MSV1_0 authentication provider caches a copy of the domain user’s credentials [1].

The mechanism used is quite fascinating. It does not merely store the user’s NTLM hash. Instead, the MSV1_0 authentication provider stores half of the hash in the registry. This cached “half-hash” is considered sufficient to verify the user’s identity while not exposing the user’s entire password hash [10, page 559].

The MSV1_0 security package implements the NT LAN Manager authentication protocols (NetNTLMv1 and NetNTLMv2). In domain-joined environments, Kerberos is usually the preferred method of authenticating to systems over the network. In scenarios where the specified hostname does not match a registered service principal name, or if an IP address is used, Windows falls back to legacy protocols such as NetNTLMv2 authentication.

Authentication packages also support sub-authentication packages that can extend an existing authentication package [16]. For red team operations, sub-authentication packages could be a stealthy alternative to registering a new authentication package or security support provider.

Kerberos Authentication Provider

The Kerberos authentication provider is the primary authentication mechanism in domain-joined environments [2]. When selecting an SSP to use for network-based authentication, Windows gives preference to the Kerberos authentication protocol as it is considered more secure than the NT LAN Manager (NetNTLMv1 and NetNTLMv2) authentication protocols.

Modern Microsoft Kerberos deployments typically support both the RC4 and AES algorithms. When authenticating to the Kerberos Key Distribution Center (KDC) hosted on a domain controller, the client encrypts a pre-authentication request using the user’s NTLM hash (when RC4 is used). The client first sends a pre-authentication message to the KDC. If the pre-authentication message is valid the KDC generates and signs a ticket granting ticket (TGT) for the corresponding user account [25]. The KDC subsequently encrypts this TGT with the user’s account password and returns it to the client [25]. The client can then decrypt this TGT and use it to request Ticket Granting Service (TGS) tickets associated with authenticating to a particular Service Principal Name (SPN) [18].

The idea behind pre-authentication is that the KDC should not return an encrypted TGT before verifying that the user possesses the NTLM hash associated with that account. The reason behind this is if the KDC did not enforce pre-authentication, then an attacker could request TGTs for every user account and perform an offline brute force attack to recover credentials [19]. Active Directory supports an attribute to disable pre-authentication for specific accounts to support legacy clients that do not support modern Kerberos features. This configuration option opens up an attack vector documented by Will Schroeder called “AS-REP Roasting”.

An Example of the Windows Authentication Process

This section aims to provide a rough outline of the authentication flow for an interactive logon to the local console. The Winlogon process is responsible for handling user logins through the local console as well as via RDP.

When a user initiates a new logon to the system, the Winlogon process spawns the LogonUI process responsible for presenting the user interface to authenticate the end-user. The LogonUI process loads a set of credential providers to create the authentication interface. These credential providers are loaded as in-process COM objects within the LogonUI process [10, page 491].

A rough outline of how Winlogon communicates with LSASS is given below. This outline leaves out many details for the sake of simplicity.

  1. When a username and password have been entered, the Winlogon process retrieves a handle to the authentication package. The LsaLogonUser [8] function is then invoked via ALPC to attempt to authenticate using this authentication package. This process is repeated for every installed authentication package on the system. If none of them succeeds, the logon attempt fails [10, page 558].
  2. If one of the authentication packages successfully authenticates the user, then after the user has been authenticated, the LSA performs checks to determine if the user can log in to the system using the requested logon type [10, page 559].
  3. LSASS creates a new access token associated with a logon session and duplicates the handle it retrieved to this token. The copied access token is then passed to the Winlogon process [10, page 559].
  4. The Winlogon process creates a new session and uses the access token to create a new process by reading the startup program’s path to be executed from the registry. By default, this is the userinit.exe process [10, page 562].

Access Tokens

Every process has an access token associated with it. This access token associates a process with a particular logon session. In addition to this, the access token includes an “AuthenticationID” locally unique identifier (LUID) value that is used to map network authentication credentials cached in LSASS to a particular logon session. The LUID is a 64-bit value meant to be unique on the system on which it was generated [15].

Internally, the NT Executive stores references to the access tokens associated with a process within the EPROCESS structure. The EPROCESS structure is used to store information on user-mode processes within the NT Executive subsystem. The first entry of the EPROCESS structure contains the KPROCESS structure used by the NT Kernel.

We can use the Windbg Kernel Debugger to locate the EPROCESS structure’s address and the address of the ETHREAD [12] structures associated with an instance of Explorer.exe running on a test system. Specifically, we use the “!process” command provided by Windbg:

We can look at this structure in more depth using the “dt” command. A truncated version of the EPROCESS structure is given below, with the “Token” field highlighted.

If you look closely, the Token attribute is listed as a type of “_EX_FAST_REF” ; this is simply a 64-bit “struct” where the four least significant (rightmost) bits are used as a reference counter. To get the actual address of the object, we must first zero these four bits. Furthermore, we can probably assume that all allocated structures used with _EX_FAST_REF are subject to 16-byte alignment. In the image given below, you can see the _EX_FAST_REF structure that contains an encoded pointer to the _TOKEN structure.

Decoding the pointer by clearing the rightmost four bits of 0xffffa20a5707a06d gives us0xffffa20a5707a060. We then use this address to view the contents of the“_TOKEN” structure used to represent an access token in kernel mode. The contents of the access token associated with our Explorer.exe process are given below. The access token contains the “AuthenticationId” LUID and information such as the LogonSession and groups associated with the access token [22].

If we now look at the AuthenticationId LUID, we can see that it has a value of 0x612f5.

We can use the logon sessions utility from SysInternals to print information on the current logon sessions for the host and the associated processes. We can see that the AuthenticationID LUID we just retrieved (0x612f5) matches the output:

If we run the Mimikatz “sekurlsa::msv” command, we can obtain the NTLM hash associated with this AuthenticationId within the LSASS process memory. This is shown in the image given below.

Access Tokens and Thread Impersonation

As mentioned previously, access tokens can be applied to both threads and processes. This section will examine the ETHREAD structure associated with one of the threads in the Explorer.exe process that we previously examined. The ETHREAD structure is used by the Windows Kernel Executive to represent a thread. The image given below shows one the ETHREAD structure for one of the instances of Explorer.exe that we are examining.

Each thread has its own ETHREAD structure. The ClientSecurity field of type _PS_CLIENT_SECURITY_CONTEXT [11] is used by a thread to perform impersonation. (Note: Prior to Windows Vista this was instead a structure of type PS_IMPERSATION_INFORMATION and was called ImpersonationInfo.) When a thread performs impersonation, it runs under a different access token than the process under which it is currently executing. Threads perform impersonation using APIs such as “SetThreadToken” [14] or “ImpersonateLoggedOnUser” [13].

Thread impersonation is another method by which an operator can leverage compromised Windows credentials. Impersonation is the method implemented by Cobalt Strike’s make_token command, which leverages the LogonUser and SetThreadToken functions. Unfortunately, this method does not work for conducting a pass-the-hash attack because the LogonUser function only accepts a password rather than an NTLM hash [20].

Conclusion

This article aimed to provide a quick overview of the authentication mechanisms used on Windows systems to implement authentication. In part two, we will examine the various mechanisms used by Mimikatz to implement the pass-the-hash technique.

References

[1] https://docs.microsoft.com/en-us/windows/win32/secauthn/msv1-0-authentication-package

[2] https://docs.microsoft.com/en-us/windows/win32/secauthn/kerberos-ssp-ap

[3] https://support.microsoft.com/en-us/help/102716/ntlm-user-authentication-in-windows

[4]https://docs.microsoft.com/en-us/windows-server/security/windows-authentication/credentials-processes-in-windows-authentication

[5] https://docs.microsoft.com/en-us/windows/win32/secauthn/lsa-authentication-model

[6] https://www.coresecurity.com/corelabs-research/publications/modifying-windows-nt-logon-credential

[7] https://www.itprotoday.com/security/where-nt-stores-passwords

[8]https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-logonusera?redirectedfrom=MSDN

[9] https://blogs.msdn.microsoft.com/hanybarakat/2007/02/25/deeper-into-windows-architecture/

[10]https://www.microsoftpressstore.com/store/windows-internals-part-1-9780735648739

[11] https://www.nirsoft.net/kernel_struct/vista/PS_CLIENT_SECURITY_CONTEXT.html

[12] https://www.geoffchappell.com/studies/windows/km/ntoskrnl/structs/ethread/index.htm

[13] https://docs.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-impersonateloggedonuser

[14] https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreadtoken

[15] https://msdn.microsoft.com/en-us/windows/desktop/ff557080

[16] https://docs.microsoft.com/en-us/windows/win32/secauthn/subauthentication-packages

[17] https://www.microsoftpressstore.com/articles/article.aspx?p=2228450&seqNum=2

[18] https://gerardnico.com/security/auth/kerberos/tgt

[19] https://www.harmj0y.net/blog/activedirectory/roasting-as-reps/

[20] https://blog.cobaltstrike.com/2015/12/16/windows-access-tokens-and-alternate-credentials/

[21] https://en.wikipedia.org/wiki/Graphical_identification_and_authentication

[22] https://docs.microsoft.com/en-us/windows/win32/secauthz/access-tokens

[23] https://docs.microsoft.com/en-us/windows/win32/secauthn/windows-authentication-packages

[24] https://docs.microsoft.com/en-us/windows/win32/secauthn/security-support-provider-authentication-packages

[25] http://web.mit.edu/kerberos/krb5-1.4/krb5-1.4.4/doc/krb5-user/Introduction.html

[26] https://www.microsoftpressstore.com/articles/article.aspx?p=2228450&seqNum=8