gss-ntlmssp
gss-ntlmssp copied to clipboard
Send MIC by Default
Currently gss-ntlmssp only adds the MIC to the authentication message if the caller has also called gss_inquire_sec_context_by_oid(ctx, spnego_req_mechlistMIC_oid)
. This sets an internal flag that tells gss-ntlmssp
that the caller knows enough about the library and SPNEGO to include the mechListMIC
in the wrapper token. I believe that the default should have gss-ntlmssp always add the MIC regardless of this being called first. At this point in time I feel like any users of gss-ntlmssp
will know how to reset the crypto state for the mechListMIC
or even use the inquiry to determine if the MIC was set (server is new enough) rather than having to call it twice to enable the MIC as well.
I know this is a complex setup so happy to look into it further if needed.
Now that I released 1.1 we can take a look at this.
@simo5 Any idea how this can be fixed? I am suspecting that this is causing an issue with one of the servers we are trying to authenticate with. I would be happy to send a patch if you can help me.
This issue is related to something I raised long back: https://github.com/gssapi/gss-ntlmssp/issues/6 . Is the fix going to be something along those lines or something else?
@amandeepgautam it should be easy enough, it is just a change of defaults. You can easily test if #6 is connected to this my unconditionally calling gss_inquire_sec_context_by_oid(ctx, spnego_req_mechlistMIC_oid) in your server.
@simo5 Please pardon my ignorance, but I am not sure which defaults you refer to. Also, the client which we use (libsmb2) calls gss_inquire_sec_context_by_oid unconditionally. See: https://github.com/sahlberg/libsmb2/blob/1c3819e22e446f896141fb4ea9dd3fc8472421d8/lib/krb5-wrapper.c#L300
In this case, as well, MIC is not always added. While the windows client seems to be adding MIC almost always. Please see the attached packet traces.
attempt1_success.pcap is the attempt from the windows client.
The code is calling gss_inquire_sec_context_by_oid
but with the OID GSS_C_INQ_SSPI_SESSION_KEY
to retrieve the NTLM session key in the authentication. What simo is referring to is using the spnego_req_mechlistMIC_oid
instead.
https://github.com/gssapi/gss-ntlmssp/blob/8149435632628a2c4d814624954f48564a3a5d9e/src/gssapi_ntlmssp.h#L35-L45
When you all gss_inquire_sec_context_by_oid(ctx, spnego_req_mechlistMIC_oid)
after creating the Negotiate
token it sets an internal flag that gss-ntlmssp uses to determine if it should populate the MIC field in the Authenticate
token that is generated later. So the general workflow would look like
// Generate Negotiate token
gss_init_sec_context(...);
// Notify gss-ntlmssp that it should add the MIC to the Authenticate token
gss_inquire_sec_context_by_oid(ctx, spnego_req_mechlistMIC_oid);
// Exchange Negotiate and get the Challenge token
// Then generate the Authenticate token
gss_init_sec_context(...);
The code in libsmb2 would have to be updated to call gss_inquire_sec_context_by_oid
with the spnego_req_mechlistMIC_oid
OID in order for gss-ntlmssp to add the MIC. What I am hoping to get out of this issue is have gss-ntlmssp just do it by default like Windows does.
Just a warning that if you use spnego_req_mechlistMIC_oid
with older versions of gssntlm-ssp (like the ones distributed in all major Linux distros up to and including Ubuntu 22.04) you are very likely to get the MIC generated at wrong offset. The authentication will fail. Newer Windows Server NTLM implementations unilaterally send the NegotiateVersion flag that counters this bug but most other NTLM implementations do not.
That's one of the reasons why I scrapped my experiment with using this context option in production. It is fine for testing though.
@filipnavara we fixed that in #64 right ?
Correct, it is fixed. Most distros still distribute version 0.7 though.
@jborean93 thanks for explaining.
@filipnavara Thanks for the heads up. We have the flexibility to update gssapi/gss-ntlmssp so we should be fine.
@simo5 I did add the unconditional call to gss_inquire_sec_context_by_oid(ctx, spnego_req_mechlistMIC_oid); and it resolved the logon issue. So, having this by default is definitely useful and expected by some servers. I am not sure if this is protocol compliant or not.