Using the NTLM Application Verifier Plug-in
Updated: November 21, 2012
Applies To: Windows 7, Windows 8, Windows Server 2008 R2, Windows Server 2012
This topic describes the NTLM Application Verifier plug-in and how to use it to identify NTLM traffic throughout your Windows environment.
In this topic
What is the NTLM Application Verifier plug-in?
How the NTLM Application Verifier plug-in works
Additional resources
What is the NTLM Application Verifier plug-in?
The NTLM Application Verifier plug-in monitors an application’s individual process calls to the authentication APIs AcquireCredentialsHandle and InitializeSecurityContext to detect uses of the NTLM protocol.
Why is the plug-in useful when analyzing NTLM usage?
NTLM v1 and v2 are based on the challenge/response authentication architecture that inherently lacks server authentication thereby exposing flaws that potentially compromise the security of applications and the operating system. Two types of attacks are possible on the challenge/response authentication architecture: reflection and relay. Both of these types have been mitigated through updates over the years to the operating system, whether through design changes to applications or actual updates to the operating system.
Important
Of the three protocols in the NTLM Security Support Provider, LanManager (LM) is the least secure and should not be used because its hashes have been compromised. For information how to disable LM on your computers, see article 299656 in the Microsoft Knowledge Base. Using simple passwords with NTLM v1 can also lead to compromised security. For information about how to enforce the use of NTLM v2, see LmCompatibilityLevel.
Although Kerberos has been available for a number of years many applications are still written to use NTLM only, which reduces the security level of those applications. Kerberos cannot replace NTLM in all scenarios—principally those where a client needs to authenticate to systems that are not joined to a domain (a home network perhaps being the most common of these).
The Negotiate security service provider (authentication package) allows a backwards-compatible compromise that uses Kerberos whenever possible and only reverts to NTLM when there is no other option. Switching an application’s authentication code to use Negotiate instead of NTLM will significantly increase the security effectiveness while introducing few or no application compatibilities.
What factors cause NTLM to be “hard-coded” in an application?
In many currently deployed applications, the following two factors may cause a dependency on NTLM:
The application explicitly selects NTLM as the authentication package
Sometimes the use of NTLM is obvious, such as in the call to the API AcquireCredentialsHandle by using the NTLM function. In other protocol usage, the usage of NTLM might not be so obvious. For example, the RPC default authentication package (RPC_C_AUTHN_DEFAULT) is actually an alias to NTLM when RPC is used over the network. In addition, the explicit flag to select NTLM doesn’t have the NTLM abbreviation anywhere in it (RPC_C_AUTH_WINNT). By using this construct, it is easier to select NTLM without necessarily knowing you have done so.
In place of NTLM, developers should use the Negotiate package (also known as the SPNEGO or SNEGO package). Package selection needs to match on both client and server components to allow Negotiate to attempt to use Kerberos. In other words, both client and server parts of the application need to use Negotiate. If either side uses NTLM (as might be the case with legacy versions), Negotiate will still work but will always revert to NTLM.
The client fails to supply a valid server target name to the authentication process
In protocols that support or require mutual authentication, such as Kerberos, the target name is used to achieve mutual authentication. Authentication APIs, such as InitializeSecurityContext, take an optional parameter, usually called something like “TargetName,” “PrincipalName,” or “ServerPrincipalName.”. This is the identifier used by domain controllers to select the correct domain account for obtaining credentials for the target service. Because NTLM architecture does not use server authentication, this parameter is not required for native NTLM to successfully authenticate. However, this requirement is enforced when Extended Protection for Authentication has been applied.
Failed Kerberos authentication attempts
Mutual authentication depends on a central authority attesting to the binding between the target name and the target itself. Kerberos, which uses this architecture, requires that a client computer obtains a service ticket that is valid for the service that the client computer is authenticating to. This is achieved by the domain controller issuing to the client computer a ticket corresponding to the target name. This ticket is encrypted with a key that only the target server can decrypt. When the client computer presents the ticket to the server the fact that the latter demonstrates to the client computer that it can decrypt the ticket proves to the client computer that the server is really the possessor of the target name.
Kerberos authentication will always fail if no target name or an invalid target name is specified. When Negotiate is selected as the authentication package, the absence of a target name or supplying an invalid target name will cause NTLM to be used. Most authentication APIs that have the target name as an optional parameter will accept NULL without error—unless the developer overrides this and provides an explicit target name NTLM.
How the NTLM Application Verifier plug-in works
The plug-in detects the following errors:
The NTLM package is directly specified in the call to AcquireCredentialsHandle (or a higher-level wrapper API).
The target name in the call to InitializeSecurityContext is NULL.
The target name in the call to InitializeSecurityContext is not a properly formed service principal name (SPN), user principal name (UPN), or NetBIOS-style domain name.
The following table describes several different events that the NTLM plug-in can detect.
Event name | Description | API |
---|---|---|
NTLMCaller - UNCLASSIFIED_ERROR |
An unclassified error is detected. |
AcquireCredentialsHandle |
NTLMCaller - INTERNAL_ERROR |
Internal error. Please report this to the provider owner. |
AcquireCredentialsHandle |
NTLMCaller - ACH_EXPLICIT_NTLM_PACKAGE |
Explicit usage of NTLM package is detected in AcquireCredentialsHandle. This manifests a straight NTLM call. Negotiate package should be used to remove this verifier stop. |
AcquireCredentialsHandle |
NTLMCaller - ACH_IMPLICITLY_USE_NTLM |
Only NTLM can be negotiated given the supplied package list. See Param1 for the package list. |
AcquireCredentialsHandle |
NTLMCaller - ACH_IMPLICITLY_USE_NTLM |
Only NTLM can be negotiated given the supplied package list. See Param1 for the package list. |
AcquireCredentialsHandle |
NTLMCaller - ACH_BAD_NTLM_EXCLUSION |
Wrong exclusion syntax -NTLM is detected. !NTLM should be used instead. See Param1 for the package list. |
AcquireCredentialsHandle |
NTLMCaller - ISC_NO_TARGET |
NTLM is to be used because no target is supplied into InitializeSecurityContext. |
InitializeSecurityContext |
NTLMCaller - ISC_WRONG_TARGET |
NTLM is to be used because a wrongly formatted target is supplied into InitializeSecurityContext—because of wrongly formatted pszTargetName. |
InitializeSecurityContext |
NTLMDowngrade - UNCLASSIFIED_ERROR |
An unclassified error is detected. |
InitializeSecurityContext |
NTLMDowngrade - INTERNAL_ERROR |
Internal error. Please report this to the provider owner. |
InitializeSecurityContext |
NTLMDowngrade - FALLBACK_TO_NTLM |
An authentication has been detected that is being downgraded to NTLM. This should be investigated if the downgrade is not expected. |
InitializeSecurityContext |
The plug-in also logs warnings when it detects downgrades to NTLM, for example, when an SPN is not found by the domain controller. These are only logged as warnings since they are often legitimate cases, such as authenticating to a system that is not joined to a domain.