Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Send MIC by Default #69

Open
jborean93 opened this issue Mar 15, 2022 · 10 comments
Open

Send MIC by Default #69

jborean93 opened this issue Mar 15, 2022 · 10 comments

Comments

@jborean93
Copy link

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.

@simo5
Copy link
Collaborator

simo5 commented Apr 1, 2022

Now that I released 1.1 we can take a look at this.

@amandeepgautam
Copy link

@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.

@amandeepgautam
Copy link

This issue is related to something I raised long back: #6 . Is the fix going to be something along those lines or something else?

@simo5
Copy link
Collaborator

simo5 commented Jul 8, 2022

@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.

@amandeepgautam
Copy link

@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.

pcap.zip

@jborean93
Copy link
Author

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.

/* SPNEGO Require MIC OID
* When the NTLMSSP mechanism produces a MIC in the authenticate message,
* the SPNEGO mechanism also must produce a mechlistMIC token otherwise
* Windows servers get confused and fail the authentication.
* This OID is queried by the SPNEGO mechanism after each token is generated.
* After the Negotiate token is produced, a query for this context property
* signals us that the SPNEGO implementation knows how to deal with the MIC,
* After the Authenticate token is produced we return whether a MIC was
* produced or not */
#define GSS_SPNEGO_REQUIRE_MIC_OID_STRING GSS_NTLMSSP_BASE_OID_STRING "\x02"
#define GSS_SPNEGO_REQUIRE_MIC_OID_LENGTH GSS_NTLMSSP_BASE_OID_LENGTH + 1

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.

@filipnavara
Copy link

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.

@simo5
Copy link
Collaborator

simo5 commented Jul 10, 2022

@filipnavara we fixed that in #64 right ?

@filipnavara
Copy link

Correct, it is fixed. Most distros still distribute version 0.7 though.

@amandeepgautam
Copy link

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants