SubAuthentication package gets Zero LogonId

Hi all,

The other day I worked on an issue related to a SubAuthentication package that one of my customers had developed. One of the things that package was doing was getting the LogonId field of the LogonInformation struct being passed to Msv1_0SubAuthenticationFilter method by the Authentication package.

This SubAuth package had been working fine on i.e. Windows XP, but when doing interactive logon on a Windows Server 2003 Domain Controller, LogonId field was always set to Zero. But doing i.e. Network logon on the same DC returned a valid LogonId value. Why?

I debugged the issue and I found out what was going on.

SubAuth packages can only get called by the following Authentication packages: Kerberos or MSV1_0/NTLM.

MSV1_0 (MICROSOFT_AUTHENTICATION_PACKAGE_V1_0) package will provide our SubAuth dll with LogonId info, while Kerberos package won’t. Kerberos ignores LogonId on purpose. This is by design and happens in all versions of Windows.

So every time we get a valid LogonId, it is because logon is taking place through MSV1_0 Auth package. Note that LogonId is just a local ID on the machine and it's not of actual use for SubAuth packages. The purpose of SubAuth packages is not for capturing or tracking logon activities.

SubAuth package supplements part of the authentication and validation criteria used by the main Auth package. It can enforce additional restrictions to the authentication sequence when the DLL is registered under Auth0 registry value for MSV1_0 or Kerberos.

SubAuth package (Msv1_0SubAuthenticationFilter) will get called only after the corresponding Windows logon authentication is successful. The built-in Auth packages get first chance at logon authentication, before SubAuth DLL code gets invoked.

For domain user logon authentication, SubAuth DLLs installed on the DCs of that domain will be called. For local user logon authentication, SubAuth DLLs installed on that member machine will be called.

If you are simply tracking logon events, you would need to enable Auditing Account Logon and look for events logged in the Security Event Log. Audit logon events and Audit account logon events provide tracking of logons at workstations, servers, and DCs (see Audit Account Logon Events for details).

Then an application may get those events programmatically with i.e. WMI and its Win32_NTLogEvent class. I’ve seen people using this idea, for instance here.

There is one thing left to explain. Why is Kerberos always getting used on the DC when doing Interactive logon? We've already seen the Auth packages that can get used, and according to MSDN:

Kerberos
"
The Kerberos authentication package is used when logging on to a network; local logons are handled by MSV1_0.
"

MSV1_0
"
MSV1_0 also supports domain logons. MSV1_0 processes domain logons using pass-through authentication
"

Summing up, MSV1_0 deals with local logons and both MSV1_0 and Kerberos with network logons.

Now, whether Negotiate/Kerberos or NTLM/MSV1_0 is used for network logon depends on the client machine and the component that is doing the authentication. Windows logon components will always attempt to use Kerberos if they can, if there is an SPN (Service Principal Name) for the target name specified. For example, if you are accessing a server say MYSERVER that requires windows authentication and you want to use Kerberos, you have to supply a name that matches an SPN defined on the server account such as MYSERVER.MYDOMAIN.COM. Just specifying MYSERVER may use NTLM if there is no matching SPN. If there is no matching SPN, Kerberos will fall-back to NTLM.

So in my customer's environment we ended up using NTLM/MSV1_0 with network logons and most of local logons, thus getting a valid LogonId thanks to MSV1_0 Auth package.

Now, the exception for local logons are the DCs. Local logon is for local accounts only and not for AD (Active Directory) accounts. Doing an Interactive logon on a DC is not considered a local logon. Because of that we try to use Negotiate/Kerberos first as expected, and we just succeed. And we don't get LogonId because Kerberos Auth package won't provide us with it.

 

I hope this helps.
Regards,

 

Alex (Alejandro Campos Magencio)