[cifs-protocol] Re: Status: raw NTLMSSP tokens in GSS-API/SPNEGO? SRX080803600053

Adam Simpkins simpkins at cisco.com
Tue Aug 5 20:21:53 GMT 2008

On Tue, Aug 05, 2008 at 09:00:26AM -0700, Bill Wesse wrote:
> Good morning Mr. Simpkins. I have conducted an initial investigation
> of the questions you raised concerning NTLMSSP tokens carried in
> GSS-API/SPNEGO. The below splits your comments and questions into 4
> parts. I have also provided extracts from various references in the
> responses.
> Please let me know if I have sufficiently addressed your concerns;
> please do not hesitate to comment on my answers and pose any
> additional questions.

Thanks for your reply.  I have responded to your statements below:

> ==============================================================================
> Question 1
> ==========
> spnego_ntlmssp.cap
> frame 6
> Question / Comment:
> -------------------
> This was taken between a client running Windows XP SP3 and a server running
> Windows Server 2003 SP2 (Enterprise Edition).
> Frame 6 contains the initial SESSION_SETUP_ANDX request.  This contains a
> GSS-API InitialContextToken that uses SPNEGO.  The mechToken inside the
> SPNEGO NegTokenInit contains just raw NTLMSSP data.  According to RFC 4178
> section 3.2 item (c), this should be a GSS InitialContextToken.
> Response:
> ---------
>    Please correct me if I missed anything.
>    I have annotated spnego_ntlmssp.cap frame 6 below, and it seems to me
>    that we meet the specification, given that [RFC2078] defines the
>    InnerContextToken (+ ThisMech: SpnegoToken ( ([RFC2078]))
>    to be defined as mechanism-specific, not requiring ASN.1 encoding.
>    Please see 'Reference 1' below; [MS-SMB] specifies additional information
>    in sections 2.2.4 and
>       SecurityBlob (variable): This field MUST be the authentication token
>       sent to the server, as specified in section and [RFC4178].
>    [RFC4178] specifies the 'InitialContextToken' to be in the format
>    defined in [RFC2078]:
>                thisMech MechType,
>                innerContextToken ANY DEFINED BY thisMech
>                   -- contents mechanism-specific
>                   -- ASN.1 structure not required
>                }
>    o See 'Reference 2' [RFC2078] below Section 3.1 for the description
>      of the InitialContextToken. Definition:
>         innerContextToken ANY DEFINED BY thisMech
>    o  [RFC4178] : See 'Reference 5' below for the BNF.
>       3.2. Negotiation Tokens
>       The syntax of the negotiation tokens follows the InitialContextToken
>       syntax defined in [1] ([RFC2078])
>       See 'Reference 5' [RFC4178] below for the negotiation token BNF.

Yes, I agree with everything up to this point.  (Although note that
RFC 2078 is obsolete, and has been replaced by RFC 2743.)

>    o In the capture details below, 'NtlmSsp: NTLM NEGOTIATE MESSAGE' is
>      indented, since NTLM is considered a separate protocol by Network
>      Monitor 3.2. As you know, the InnerContextToken is from offset
>      0x7F - 0xBE, and the negotiate message is encapsulated at offset
>      0x97 - 0xBE.

Just to clarify terminology, the mechToken (inside the SPNEGO
NegTokenInit) is what's at 0x97-0xBE.

As mentioned in my earlier email, RFC 4178 section 3.2 item (c) states:

      If the initiator's preferred mechanism is accepted, and an
      optimistic mechanism token was included, this mechanism token MUST
      be passed to the selected mechanism by invoking

GSS_Accept_sec_context() is defined in RFC 2743, and the first token
passed to it must use the format specified in section 3.1 (i.e., it must
be an InitialContextToken).

In this trace, the mechToken contains raw NTLMSSP data, not an
InitialContextToken containing NTLMSSP data.  Based on the references I
listed above, this behavior appears to be different than what is
required by RFC 4178 and RFC 2743.

Perhaps there is some confusion here because RFC 4178 section 3.2
mentions two separate calls to GSS_Accept_sec_context().  Initially, the
entire GSS token (bytes 0x75-0xBE in this trace) is passed to
GSS_Accept_sec_context(), as mentioned at the beginning of item (c), so
it can be processed by the SPNEGO mechanism.  Then, if the SPNEGO
mechanism accepts the initiator's preferred mechanism, and the initiator
included an optimistic mechToken (bytes 0x97-0xBE in this trace), the
optimistic mechToken must be passed to GSS_Accept_sec_context() so it
can be processed by the negotiated mechanism.  This behavior is from the
end of item (c), which I quote above.

Based on my understanding, this second call to GSS_Accept_sec_context()
is establishing a new "inner" context that uses the negotiated
mechanism.  Therefore this call to GSS_Accept_sec_context() is the also
first call for this context, so it should receive an

Admittedly, RFC 4178 could be a bit clearer in this regard.  However,
other available SPNEGO implementations appear to agree with my
interpretation.  For example, this appears to be how the MIT Kerberos
implementation behaves:


They pass the received tokens to gss_init_sec_context()/
gss_accept_sec_context() with a separate inner context.  As a result,
the initial mechToken is always a GSS InitialContextToken.

> ==============================================================================
> Question 2
> ==========
> gss_ntlmssp.cap
> frame 7
> Question / Comment:
> -------------------
> Another related point that should probably be documented is that Windows
> servers do not seem to accept well-formed GSS InitialContextTokens containing
> NTLMSSP.  I have attached a trace of that, too.  (The server is the same
> Windows Server 2003 system as in the other traces.)

Yes, you have my question/request for clarification correct.

> ==============================================================================
> Question 3
> ==========
> spnego_krb.cap
> frame 7
> Question / Comment:
> -------------------
> This was taken between a client running Windows XP SP3 and a server running
> Windows Server 2003 SP2 (Enterprise Edition), using Kerberos over SPNEGO.
> In this trace, the mechToken is a GSS InitialContextToken.

Yes, there isn't really a question here.  I'm just demonstrating that
when Kerberos is negotiated, the SPNEGO mechToken is a GSS

> ==============================================================================
> Question 4
> ==========
> raw_ntlmssp.cap
> frame 7
> Question / Comment:
> -------------------
> Here's another trace of a Windows XP SP3 client sending raw NTLMSSP
> (no SPNEGO) to a server.  This server is just a proxy in front of a Windows
> Server 2003 machine, but I configured it to strip off the securit blob from
> the server's NEGOTIATE response before sending it to the client.
> This causes the client to send raw NTLMSSP instead of SPNEGO.
> Based on the documentation in MS-SMB 2.2.4 and MS-SMB, I would
> expect the client to send a GSS authentication token here (i.e., an
> InitialContextToken).  However, in this case the client sends raw NTLMSSP
> data.
> A reasonable explanation for this would be that Microsoft's GSS-API
> implementation accepts raw NTLMSSP data for the first token, in addition to
> normal GSS InitialContextTokens.  I think this is what item <8> of MS-SPNG
> Appendix A is trying to explain, but it mentions this as an extension of
> SPNEGO, not GSS-API.  Assuming that this is a general extension that Microsoft
> has made to their GSS-API implementation, this would also explain the lack of
> the InitialContextToken for NTLMSSP when SPNEGO is used.
> Response:
> ---------
>    You are indeed correct - this, of course, per [MS-SPNG] <8>, is not
>    GSS-API. Please see 'Reference 1 / Implicit NTLM' ([MS-SMB]) below
>    for additional information.
>    Reference:
>    [MS-SPNG]: Simple and Protected Generic Security Service Application
>    Program Interface Negotiation Mechanism (SPNEGO) Protocol Extensions
>    <8> Section This behavior is present on Windows 2000, Windows XP,
>        Windows Server 2003, and Windows Vista. For backward compatibility and
>        historical reasons, a Windows implementation of SPNEGO has the
>        following behavior: it accepts raw Kerberos messages that are based on
>        [RFC4121] and [RFC4120], and it accepts raw NTLM messages that are not
>        embedded in [RFC4178] SPNEGO messages. This behavior is known as the
>        universal receiver behavior.

Yes, I assumed this is the behavior that this section of the text was
trying to describe.  However, it's not clear to me how this is related

According to MS-SMB section 2.2.4 and MS-SMB, the security
blob in the SESSION_SETUP_ANDX request should be a GSS authentication
token.  According to RFC 2743, the thisMech field of the GSS
InitialContextToken indicates which security mechanism has been selected
by the client.  If the thisMech field is the SPNEGO OID (,
one would expect SPNEGO to be in use.

However, in this case the security blob isn't a GSS InitialContextToken,
and doesn't include the SPNEGO OID.  It's therefore unclear to me why
one would assume that this is related to SPNEGO, and not just GSS-API in

Also, note that the Kerberos behavior described by this passage does not
seem like a Windows extension.  This seems to be normal behavior for a
GSS-API acceptor when the thisMech field is the Kerberos OID.

Adam Simpkins
simpkins at cisco.com

More information about the cifs-protocol mailing list