Post by SimoThis is in 4178 5.b, this is not the case you are looking for, as in
the NTLM case you exchange an odd number of tokens (Negotiate,
Challenge, Auth), while in the kerberos case you exchange an even
number of tokens (initiate token and accept token)
So you need to look at 4178 5.c
if the
negState was request-mic in the first reply from the target, a
mechlistMIC token MUST be included; otherwise, the mechlistMIC
token is OPTIONAL.
(in this pcacp the state was accept-incomplete)
In the case that the optimistic mechanism token is the only
mechanism token for the initiator's preferred mechanism, the
mechlistMIC token is OPTIONAL.
(in this pcap NTLM was attempted optimistically and the initiator did
not provide any other mechanism.
All this would still require the mechlistMIC to be produced from the
server because the client did in fact send a mechlistMIC token except
SPNEGO implementations in Microsoft Windows 2000/Windows XP/Windows
Server 2003 have the following behavior: no mechlistMIC is produced
and mechlistMIC is not processed if one is provided; if the initiator
sends the last mechanism token, the acceptor will send back a
negotiation token with an accept_complete state and no mechlistMIC
token.
I think this is the behavior we are seeing.
Ah, this is staring to make sense. In MS-NLMP we have:
If the CHALLENGE_MESSAGE TargetInfo field (section 2.2.1.2) has an MsvAvTimestamp present,
the client SHOULD provide a MIC<51>:
So I'm guessing that in the latest version of the Apple
server they added support for the MsvAvTimestamp in their
NTLM implementation, but didn't add support for MIC processing
in SPNEGO.
So they act like a modern post-Windows 2003 server in terms
of the MsvAvTimestamp, which causes us to turn on our
MIC code, but then don't reply containing a mechlistMIC,
like a a pre-Windows 2008 server.
We work against a Windows 2003 server as it never sends
the MsvAvTimestamp I'd guess, so in that case we don't
send or expect any mechlistMIC.
In fact commit 0d641ee36ae2c shows exactly how this
happened:
+ if (timestamp != NULL) {
+ uint32_t sign_features =
+ GENSEC_FEATURE_SESSION_KEY |
+ GENSEC_FEATURE_SIGN |
+ GENSEC_FEATURE_SEAL;
+
+ server_timestamp = ×tamp->Value.AvTimestamp;
+
+ if (ntlmssp_state->force_old_spnego) {
+ sign_features = 0;
+ }
+
+ if (gensec_security->want_features & sign_features) {
+ struct AV_PAIR *av_flags = NULL;
+
+ av_flags = ndr_ntlmssp_find_av(&ntlmssp_state->client.av_pair_list,
+ MsvAvFlags);
+ if (av_flags == NULL) {
+ av_flags = eol;
+ eol++;
+ count++;
+ *eol = *av_flags;
+ av_flags->AvId = MsvAvFlags;
+ av_flags->Value.AvFlags = 0;
+ }
+
+ av_flags->Value.AvFlags |= NTLMSSP_AVFLAG_MIC_IN_AUTHENTICATE_MESSAGE;
+ ntlmssp_state->new_spnego = true;
+ }
+ }
note the 'ntlmssp_state->new_spnego = true' when timestamp != NULL.
And it looks like the Windows client doesn't check the
mechlistMIC in this case, so we might need to losen our
check also.
This would also fix the smbclient connecting to the Microsoft
Azure server problem - that server also only does NTLM and
doesn't send the mechlistMIC in the ACCEPT_COMPLETED reply.
Attached is a possible patch, but I'm *really* unsure
if this is safe w.r.t. downgrade attacks.
Metze, can you take a look at this and let me know what you
think ?
Jeremy.