Menu

This Application Verifier plug-in monitors an individual process� calls to the authentication APIs AcquireCredentialsHandle and InitializeSecurityContext in order to detect uses of the NTLM protocol.

Why the NTLM Plug-in is Needed

NTLM is an outdated authentication protocol with flaws that potentially compromise the security of applications and the operating system. The most important shortcoming is the lack of server authentication, which could allow an attacker to trick users into connecting to a spoofed server. As a corollary of missing server authentication, applications using NTLM can also be vulnerable to a type of attack known as a �reflection� attack. This latter allows an attacker to hijack a user�s authentication conversation to a legitimate server and use it to authenticate the attacker to the user�s computer. NTLM�s vulnerabilities and ways of exploiting them are the target of increasing research activity in the security community.

Although Kerberos has been available for many years, many applications are still written to use NTLM only. This needlessly reduces the security of applications. Kerberos cannot however 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 package allows a backwards-compatible compromise that uses Kerberos whenever possible and only reverts to NTLM when there is no other option. Switching code to use Negotiate instead of NTLM will significantly increase the security for our customers while introducing few or no application compatibilities. Negotiate by itself is not a silver bullet � there are cases where an attacker can force downgrade to NTLM but these are significantly more difficult to exploit. However, one immediate improvement is that applications written to use Negotiate correctly are automatically immune to NTLM reflection attacks.

By way of a final word of caution against use of NTLM: In Windows 7 and Windows Server 2008 R2 and later versions of Windows it is possible to disable the use of NTLM at the operating system level. If applications have a hard dependency on NTLM they will simply fail to authenticate when NTLM is disabled.

What factors cause NTLM to be �hard-coded� in an application?

There are two factors that will cause a hard dependency on NTLM. The first is explicitly selecting NTLM as the authentication package to be used by the application. For some protocols and APIs the choice of NTLM is obvious, such as in the call to the API AcquireCredentialsHandle (). For other protocols, it may not be so obvious. For example, RPC�s default authentication package (RPC_C_AUTHN_DEFAULT) is actually an alias to NTLM when RPC is used over the network and even the explicit flag to select NTLM doesn�t have the NTLM abbreviation anywhere in it (RPC_C_AUTH_WINNT). This kind of construct makes it easier to select NTLM without necessarily knowing you have done so.

In place of NTLM, developers should use the Negotiate package (this is also sometimes referred to as the SPNEGO or SNEGO package). Package selection needs to match on both client and server components in order for Negotiate to be able to attempt to use Kerberos - so 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. How to tell your application to use Negotiate varies by protocol. Some of the most common protocols (RPC, LDAP, DCOM, HTTP) are covered in detail later in topic 5000 � Application Has Explicitly Selected NTLM Package.

The second factor that results in NTLM being used is when the client does not 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 what 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. Since NTLM has no concept of server authentication this parameter is not required for NTLM to successfully authenticate. Kerberos, on the other hand, requires that a client obtains a service ticket that is valid for the service that the client is authenticating to. Kerberos authentication will always fail if no target name or an invalid target name is specified. When Negotiate is selected as the package, supplying no target name (or an invalid target name) will cause Kerberos to be skipped altogether and NTLM to be used. Most authentication APIs have the target name as an optional parameter will accept if NULL without error. Unless the developer overrides this and provides an explicit target name, NTLM, (and moreover, reflectable NTLM) is the result.

How the Plug-in Works

The Verifier plug detects the following errors:

�The NTLM package is directly specified in the call to AcquireCredentialsHandle (or higher level wrapper API).

�The target name in the call to InitializeSecurityContext is NULL. In this case, Negotiate falls back to NTLM directly.

�The target name in the call to InitializeSecurityContext is not a properly-formed SPN, UPN or NetBIOS-style domain name. In this case, the domain controller returns a �principal not found� error, which causes Negotiate to fall back to NTLM.

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 � for example, when authenticating to a system that is not domain-joined.

Configuring Plug-in Stop Options

By default all events categorized as Error are set to cause a debug break. All warning events are set to log the event details only.

Error Events cause a Stop/Break:

�5000 � Application Has Explicitly Selected NTLM Package

�5001 � Negotiate Package List Includes only NTLM

�5002 � Negotiate Package List Wrong NTLM Exclusion

�5003 � No target name or malformed target name for Server

Warning Events logged:

5010 � Downgrade to NTLM Detected

NTLM Stops

5000 � Application Has Explicitly Selected NTLM Package

Severity � Error

The application or subsystem explicitly selects NTLM instead of Negotiate in the call to AcquireCredentialsHandle. Even though it may be possible for the client and server to authenticate using Kerberos this is prevented by the explicit selection of NTLM.

How to Fix this Error

The fix for this error is to select the Negotiate package in place of NTLM. How this is done will depend on the particular Network subsystem being used by the client or server. Some examples are given below. You should consult the documentation on the particular library or API set that you are using.

APIs(parameter) Used by Application

Incorrect Value

Correct Value

Notes

AcquireCredentialsHandle (pszPackage)

�NTLM�

NEGOSSP_NAME or �Negotiate�

RPC Client: RPCBindingSetAuthInfoEx RPCBindingSetAuthInfoEx (AuthnSv) RPC Server: RPCServerRegisterAuthInfo(AuthnSvc)

RPC_C_AUTHN_WINNT or RPC_C_AUTH_DEFAULT

RPC_C_AUTH_GSS_NEGOTIATE

It is not an error for an RPC server to register the NTLM/WINNT package. This is often required to support older clients that only support NTLM. It is an error if only the NTLM package is registered since this forces all clients to use NTLM even if they are capable of using Kerberos.

DCOM: SetBlanket CoSetProxyBlanket (dwAuthnSvc) CoCreateInstanceEx (passed as dwAuthnSvc member of COAUTHINFO structure, which itself is a member of the COSERVERINFO struct passed to the API)

RPC_C_AUTHN_WINNT

RPC_C_AUTHN_DEFAULT or RPC_C_AUTHN_GSS_NEGOTIATE

Negotiate should only be used if the communication always occurs across a network. If the DCOM call ever occurs between client and server on the same machine you must use DEFAULT and allow DCOM to choose the correct package to use.

LDAP: ldap_bind_s (method)

LDAP_AUTH_NTLM

LDAP_AUTH_NEGOTIATE

HTTP WinHTTPSetCredentials (AuthScheme)

WINHTTP_AUTH_SCHEME_NTLM

WINHTTP_AUTH_SCHEME_NEGOTIATE

5001 � Negotiate Package List Includes only NTLM

Severity � Error

When using AcquireCredentialsHandle it is possible to supply a list of packages to be used or ignored by Negotiate. Depending on the list specified, this may override the logic built into Negotiate for choosing the most appropriate and secure authentication package. If the package list includes only NTLM or excludes Kerberos the result is identical to bypassing Negotiate altogether and explicitly selecting the NTLM SSP package directly.

Specifying a sub-package list is only possible when calling AcquireCredentialsHandle directly since most higher-layer APIs (such as RPC) do not allow the caller to control the Negotiate package list.

Microsoft does not recommend that applications try to manipulate the Negotiate package list in this way.

How to Fix this Error

Use the Negotiate package without specifying a list of subpackages or ensure that Kerberos is included.

APIs(parameter) Used by Application

Incorrect Value

Correct Value

AcquireCredentialsHandle (PackageList member of SEC_WINNT_AUTH_IDENTITY_EX struct passed as pAuthData parameter)

�!Kerberos� or �NTLM�

NULL or �Kerberos, NTLM� or �Kerberos, !NTLM� or �!NTLM�

5002 � Negotiate Package List Wrong NTLM Exclusion

Severity - Warning

When calling AcquireCredentialsHandle the application has attempted to exclude NTLM from the list of packages supported by Negotiate. However, the wrong syntax has been used to exclude NTLM, so it remains in the list.

How to Fix this Error

Use the following syntax to exclude the NTLM package from Negotiate:

APIs(parameter) Used by Application

Incorrect Value

Correct Value

AcquireCredentialsHandle (PackageList member of SEC_WINNT_AUTH_IDENTITY_EX struct passed as pAuthData parameter)

�-NTLM�

�!NTLM�

5003 � No target name or malformed target name for Server

Severity � Error

When using the Negotiate package, supplying a null or invalid target name (sometimes referred to as principal name) will cause Kerberos to fail and NTLM to be used in its place. You should always specify a valid target name when making an authentication call. The target name is a unique identifier that allows a domain controller to obtain the account details of the server that your application is trying to authenticate to. Once the domain controller has this information it can build appropriate Kerberos tickets that will be understood (decryptable) by both the client and the server.

How to Fix this Error

Target names can be specified in three different formats, each of which is can be used by domain controllers to locate the correct server account object. These formats are Service Principal Name (SPN), User Principal Name (UPN) and NetBIOS two-part domain\account name. The SPN is the most common form and the most interoperable with other Kerberos implementations. A full discussion of SPNs is beyond the scope of this document but the simplest and most common SPN form has two parts � a service class and a host name. The service class identifies the type of server application (e.g. specific application type like http or ldap or as generic as host).The second part is either the fully qualified domain name or flat (NetBIOS) name of the server. Windows clients and servers automatically register SPNs for �host� for the FQDN and flat names. Domain controllers will also map around 40 application-specific service classes on to the �host� SPN for things like �http�, �ldap�, �rpc�, �tapi�, etc. <<Technet Ref>>. o specify a target name for an application running in the context of the server operating system (e.g. localsystem, network service or localservice) client applications can use the automatically-registered �host� SPN or one of its aliases. To authenticate to an application running in the context of a domain user account you must register an SPN for that account.

For user accounts you can also use the implicit UPN form that built from the user account name tha and the domain that the account resides in: useraccountname@domain.dom. Although you can create additional UPNs for user account (using the UPN suffixes that can be created for each domain) these will not work as Kerberos targetnames � only the UPN corresponding to the actual logon account name and actual domain where the account lives can be used.

Finally you can still use the NT4-style domain\username (or domain\computername in the case of services running as localsystem, networkservice or localservice). This works for targets that are running in the context of domain user account or computer accounts.

APIs(parameter) Used by Application

Parameter to set target name

Notes

InitializeSecurityContext

pszTargetName

RPC Client: RPCBindingSetAuthInfoEx RPCBindingSetAuthInfoEx (AuthnSv)

ServerPrincipalName

This should be the target name for the account under which the server/service is running. It does not have to be the same as the value set in RPCServerRegisterAuthInfo

DCOM: SetBlanket CoSetProxyBlanket (dwAuthnSvc) CoCreateInstanceEx (passed as dwAuthnSvc member of COAUTHINFO structure, which itself is a member of the COSERVERINFO struct passed to the API)

pServerPrincName

Can use COLE_DEFAULT_PRINCIPAL to let COM automatically select name from binding information

LDAP: none

Automatically generated by LDAP client.

HTTP none

WinHTTP and WinInet supply the targetname from the URL server name

5010 � Downgrade to NTLM Detected

Severity - Warning

Even though the application specific Negotiate and used a correctly-formatted target name something occurred to cause Negotiate to downgrade to NTLM. Depending on what the circumstances were this may indicate an error or expected behavior. For example, when a computer is not part of a domain or is being used in a location where a domain controller is not accessible it is expected that Negotiate will silently downgrade to allow the application to authenticate using NTLM. However, if this stop occurs when a domain controller is available and you would normally expect Kerberos to be used it almost certainly indicates that something is wrong.

How to Fix This Error

Assuming that you have determined that Kerberos should have been used and not NTLM in this circumstance, there are a number of possibilities why the downgrade took place:

�The target name, even though it may have been in the correct format, did not exist in the domain (or forest).

oYou should check that you are building the correct target name in the client application. Is the service class correct? Is the host name correct?

oIs the server process running in the context of the computer or another domain account. In the former case SPNs are automatically registered, in the latter case you may have to register the SPN or use an alternative form such as an implicit UPN or a flat name.

oMight there be network connectivity problems preventing communication with a domain controller or DNS server?

oIs the target SPN registered on more than one account? This will cause the domain controller to reject authentication attempts to it.