[cifs-protocol] RE: Status: raw NTLMSSP tokens in GSS-API/SPNEGO?
SRX080803600053
Bill Wesse
billwe at microsoft.com
Fri Aug 8 16:27:54 GMT 2008
Good afternoon Mr. Simpkins. I have provided summaries concerning your follow up questions on the original questions 1, 2 & 4. In addition, I have attached the full text and responses (with the material below interpolated) for the sake of completeness.
To summarize, you raised several issues (I have provided indented response summaries; there are more complete responses in the follow up section for each question, and an attachment with both original and follow up text).
Please let me know if there is anything that I have not answered fully (or misconstrued); I want to make sure we pare this down to specific document changes or product bugs that may apply.
Summary:
========
Question 1.
Windows does not generate well-formed NTLMv2 GSS InitialContextTokens as
specified in RFC 4178 section 3.2 (re: spnego_ntlmssp.cap frame 6), as is
done with Kerberos (re: spnego_krb.cap frame 7).
Your comments appear correct. The current Windows implementations are
subject to backward compatibility constraints.
Question 2.
Windows does not accept well-formed NTLMv2 GSS InitialContextTokens as
specified in RFC 4178 section 3.2 (re: gss_ntlmssp.cap frame 7), as is done
with Kerberos (re: spnego_krb.cap frame 7).
As noted, this appears to be an interoperability deficiency. Action on our
part may well require bug filings against newer versions of Windows.
Could you advise me of any known implementations that do this? That would
be necessary for evidence to justify any Windows updates.
Question 4.
Windows generates and accepts raw NTLM tokens (re: raw_ntlmssp.cap frame 7),
and denotes Kerberos behavior as Windows Behavior.
The Windows Behavior noted applies to Kerberos OID encoding - Windows 2000
encoded this incorrectly; subsequent Windows versions encode this
correctly. Reference: [MS-SPNG] Appendix A notes <5> and <8>
Full Responses:
===============
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Question 1 Follow-up:
---------------------
Just to clarify terminology, the mechToken (inside the SPNEGO NegTokenInit)
is what's at 0x97-0xBE.
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 InitialContextToken.
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:
http://anonsvn.mit.edu/cgi-bin/viewcvs.cgi/trunk/src/lib/gssapi/spnego/spnego_mech.c?rev=19831&view=markup
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.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Response:
Thanks for correcting my terminology on the text 'negotiate message is
encapsulated', which should have been 'the mechToken (inside the SPNEGO
NegTokenInit) is what's at 0x97-0xBE'.
I agree - the below extract from 'RFC 4178 section 3.2 (c)' implies that a
new inner context should be established (as is done with Kerberos, as shown
in spnego_krb.cap frame 7).
The possibility of guaranteeing an update to a majority of deployed Windows
clients and servers approaches the impossible. This constrains Windows
versions to preserve backward compatibility for some time to come. Any updates
would need to be accomodated per the follow up on Question 2, below.
RFC 4178 section 3.2 (c)
...
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(). If a response mechanism token is
returned, it MUST be included in the response negotiation token.
Otherwise, the target will not generate a response mechanism token
in the first reply.
spnego_krb.cap frame 7:
- GssApi:
+ ApplicationHeader:
+ ThisMech: SpnegoToken (1.3.6.1.5.5.2)
- InnerContextToken: 0x1
- SpnegoToken: 0x1
+ Tag0:
- NegTokenInit: ([RFC2478] NegotiationToken, negTokenInit [0] NegTokenInit)
+ SequenceHeader:
+ Tag0:
+ MechTypes: ([RFC2478] mechTypes [0] MechTypeList OPTIONAL)
+ Tag2: ([RFC2478] mechToken [2] OCTET STRING OPTIONAL)
+ OctetStringHeader:
- MechToken: 0x1
+ MsKerberosToken: 0x1
- GssApi: ([RFC4178] section 3.2 (c))
+ ApplicationHeader:
+ ThisMech: KerberosToken (1.2.840.113554.1.2.2)
+ InnerContextToken: 0x1
spnego_ntlmssp.cap frame 6:
- GssApi:
+ ApplicationHeader:
+ ThisMech: SpnegoToken (1.3.6.1.5.5.2) ([RFC2078])
- InnerContextToken: 0x1
- SpnegoToken: 0x1
+ Tag0:
- NegTokenInit: ([RFC2478] NegotiationToken, negTokenInit [0] NegTokenInit)
+ SequenceHeader:
+ Tag0:
- MechTypes: ([RFC2478] mechTypes [0] MechTypeList OPTIONAL)
+ SequenceHeader:
+ MechType: NtlmSsp (1.3.6.1.4.1.311.2.2.10)
+ Tag2: ([RFC2478] mechToken [2] OCTET STRING OPTIONAL)
+ OctetStringHeader:
MechToken: 0x1 (NtlmSsp: NTLM NEGOTIATE MESSAGE)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Question 2 Follow-up:
---------------------
Windows servers do not seem to accept well-formed GSS InitialContextTokens
containing NTLMSSP (re: gss_ntlmssp.cap frame 7), as is done with Kerberos
(re: spnego_krb.cap frame 7).
Response:
This refers to the same GSS-API construction information referenced in
Question 1. above.
As noted, this appears to be an interoperability deficiency. Action on our
part may well require bug filings against newer versions of Windows.
Could you advise me of any known implementations that do this? That would
be necessary for evidence to justify any Windows updates.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Question 4 Follow-up:
---------------------
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 to SPNEGO.
According to MS-SMB section 2.2.4 and MS-SMB 3.2.4.2.3, 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 (1.3.6.1.5.5.2), 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 general.
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.
Response:
raw_ntlmssp.cap frame 7:
Microsoft's implementation does indeed accept raw NTLMSSP data (per Reference
A below) in the SecurityBlob in an SMB_COM_SESSION_SETUP_ANDX request packet.
This does not relate to SPNEGO negotiation, and was introduced in the NTLMv2
implementation on Windows NT 4 Service Pack 4.
Kerberos support (under GSSAPI/SPNEGO) was, of course, introduced in
Windows 2000 (along with NTLMSSP; Reference A does not apply here).
spnego_krb.cap frame 7:
Kerberos behavior (per Reference B below), is indeed Windows Behavior. I
assume that you are referring to the follow up to Question 1 (RFC 4178
section 3.2 (c)). In this case, the Windows Behavior that applies also
refers to Reference C below, which is specific to the Kerberos OID
encoding (erroneous: 1.2.840.48018.1.2.2, correct: 1.2.840.113554.1.2.2).
Reference A:
[MS-SMB] 3.2.4.2.3
User Authentication / 'Implicit NTLM
Reference B:
[MS-SPNG]
3.2.5.2 Universal Receiver
<8>
...
6 Appendix A: Windows Behavior
<8> Section 3.2.5.2: 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.
Reference C:
[MS-SPNG]
6 Appendix A: Windows Behavior
<5> Section 3.1.5.2: Windows versions offer and accept two distinct OIDs
as identifiers for the Kerberos authentication mechanism. The SPNEGO
extensions consider both OIDs as equivalent and make no distinction
between them.
Windows 2000 incorrectly encoded the OID for the Kerberos protocol.
Rather than the OID { iso(1) member-body(2) United States(840)
mit(113554) infosys(1) gssapi(2) krb5(2) }, an implementation error
truncated the values at 16 bits. Therefore, the OID became { iso(1)
member-body(2) United States(840) ???(48018) infosys(1) gssapi(2) krb5
(2) }. 48018 is not a known member under that OID branch; this is an
error.
Windows XP, Windows Server 2003, Windows Vista, and Windows Server
2008 do not truncate the value, and they correctly offer and receive
1.2.840.113554.1.2.2. For compatibility reasons, the erroneous value
(1.2.840.48018.1.2.2) is still offered and accepted by systems that
run Windows 2000. The presence of this value can be used to determine
that the peer is a Windows 2000 implementation.
Regards,
Bill Wesse
MCSE / Escalation Engineer, US-CSS DSC PROTOCOL TEAM
8055 Microsoft Way
Charlotte, NC 28273
TEL: 980-776-8200
CELL: 704-661-5438
FAX: 704-665-9606
-------------- next part --------------
==============================================================================
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 (1.3.6.1.5.5.2) ([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 3.2.4.2.3:
SecurityBlob (variable): This field MUST be the authentication token
sent to the server, as specified in section 3.2.4.2.3 and [RFC4178].
[RFC4178] specifies the 'InitialContextToken' to be in the format
defined in [RFC2078]:
[APPLICATION 0] IMPLICIT SEQUENCE {
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.
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.
See 'Reference 1 / Extended Security' [MS-SMB] below.
ThisMech: SpnegoToken (1.3.6.1.5.5.2) See 'Reference 3' below.
OID Repository - Home
http://www.oid-info.com/
iso(1) identified-organization(3) dod(6) internet(1) security(5)
mechanisms(5) snego(2)
Child OID: modules(4)
Ref: http://www.ietf.org/rfc/rfc2743.txt
------------------------------------------------------------------------------
Capture Details (Network Monitor 3.2)
- CSessionSetupAndXNTLMESS:
WordCount: 12 (0xC)
ANDXCommand: No Secondary Command 255(0xFF)
AndXReserved: 0 (0x0)
ANDXOffset: 236 (0xEC)
MaxBufferSize: 16644 (0x4104)
MaxMpxCount: 50 (0x32)
VcNumber: 0 (0x0)
SessionKey: 0 (0x0)
SecurityBlobLength: 74 (0x4A)
Reserved: 0 (0x0)
+ Capabilities: 0xA00000D4
ByteCount: 177 (0xB1)
- SecurityBlob:
- GssApi:
+ ApplicationHeader:
+ ThisMech: SpnegoToken (1.3.6.1.5.5.2) ([RFC2078])
- InnerContextToken: 0x1
- SpnegoToken: 0x1
+ Tag0:
- NegTokenInit: ([RFC2478] NegotiationToken, negTokenInit [0] NegTokenInit)
+ SequenceHeader:
+ Tag0:
- MechTypes: ([RFC2478] mechTypes [0] MechTypeList OPTIONAL)
+ SequenceHeader:
+ MechType: NtlmSsp (1.3.6.1.4.1.311.2.2.10)
+ Tag2: ([RFC2478] mechToken [2] OCTET STRING OPTIONAL)
+ OctetStringHeader:
MechToken: 0x1 (NtlmSsp: NTLM NEGOTIATE MESSAGE)
+ UnicodeParameters:
ANDXPadding: Binary Large Object (2 Bytes)
- NtlmSsp: NTLM NEGOTIATE MESSAGE
Signature: NTLMSSP
MessageType: Negotiate Message (0x00000001)
- NtlmsspNegotiateMessage:
+ NegotiateFlags: 0xE2088297 (NTLM v2128-bit encryption, Always Sign)
+ WorkstationDomainHeader: Length: 0, Offset: 0
+ WorkstationNameHeader: Length: 0, Offset: 0
+ Version: Windows 5.1 Build 10250 NTLMSSPv15
0075 60 48 06 06 2B 06 01 05 05 02 GssApi:
007E A0 InnerContextToken: (SpnegoToken:)
0080 3E 30 3C A0 0E 30 0C 06 0A 2B 06 01 04 01 82 37
0090 02 02 0A A2 2A 04 28
0096 4E 54 4C 4D 53 53 50 00 01 MechToken: (NtlmSsp: NTLM NEGOTIATE MESSAGE)
00A0 00 00 00 97 82 08 E2 00 00 00 00 00 00 00 00 00
00B0 00 00 00 00 00 00 00 05 01 28 0A 00 00 00 0F
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Question 1 Follow-up:
---------------------
Just to clarify terminology, the mechToken (inside the SPNEGO NegTokenInit)
is what's at 0x97-0xBE.
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 InitialContextToken.
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:
http://anonsvn.mit.edu/cgi-bin/viewcvs.cgi/trunk/src/lib/gssapi/spnego/spnego_mech.c?rev=19831&view=markup
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.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Response:
Thanks for correcting my terminology on the text 'negotiate message is
encapsulated', which should have been 'the mechToken (inside the SPNEGO
NegTokenInit) is what's at 0x97-0xBE'.
I agree - the below extract from 'RFC 4178 section 3.2 (c)' implies that a
new inner context should be established (as is done with Kerberos, as shown
in spnego_krb.cap frame 7).
The possibility of guaranteeing an update to a majority of deployed Windows
clients and servers approaches the impossible. This constrains Windows
versions to preserve backward compatibility for some time to come. Any updates
would need to be accomodated per the follow up on Question 2, below.
RFC 4178 section 3.2 (c)
...
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(). If a response mechanism token is
returned, it MUST be included in the response negotiation token.
Otherwise, the target will not generate a response mechanism token
in the first reply.
spnego_krb.cap frame 7:
- GssApi:
+ ApplicationHeader:
+ ThisMech: SpnegoToken (1.3.6.1.5.5.2)
- InnerContextToken: 0x1
- SpnegoToken: 0x1
+ Tag0:
- NegTokenInit: ([RFC2478] NegotiationToken, negTokenInit [0] NegTokenInit)
+ SequenceHeader:
+ Tag0:
+ MechTypes: ([RFC2478] mechTypes [0] MechTypeList OPTIONAL)
+ Tag2: ([RFC2478] mechToken [2] OCTET STRING OPTIONAL)
+ OctetStringHeader:
- MechToken: 0x1
+ MsKerberosToken: 0x1
- GssApi: ([RFC4178] section 3.2 (c))
+ ApplicationHeader:
+ ThisMech: KerberosToken (1.2.840.113554.1.2.2)
+ InnerContextToken: 0x1
spnego_ntlmssp.cap frame 6:
- GssApi:
+ ApplicationHeader:
+ ThisMech: SpnegoToken (1.3.6.1.5.5.2) ([RFC2078])
- InnerContextToken: 0x1
- SpnegoToken: 0x1
+ Tag0:
- NegTokenInit: ([RFC2478] NegotiationToken, negTokenInit [0] NegTokenInit)
+ SequenceHeader:
+ Tag0:
- MechTypes: ([RFC2478] mechTypes [0] MechTypeList OPTIONAL)
+ SequenceHeader:
+ MechType: NtlmSsp (1.3.6.1.4.1.311.2.2.10)
+ Tag2: ([RFC2478] mechToken [2] OCTET STRING OPTIONAL)
+ OctetStringHeader:
MechToken: 0x1 (NtlmSsp: NTLM NEGOTIATE MESSAGE)
==============================================================================
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.)
Response:
---------
I believe this refers to the same GSS-API construction information I
referenced in Question 1. above.
ThisMech: NtlmSsp (1.3.6.1.4.1.311.2.2.10)
OID Repository - Home
http://www.oid-info.com/
iso(1) identified-organization(3) dod(6) internet(1) private(4)
enterprise(1) microsoft(311) 2
Child OID: modules(4)
Ref: http://www.ietf.org/rfc/rfc2743.txt
------------------------------------------------------------------------------
Capture Details (Network Monitor 3.2)
- CSessionSetupAndXNTLMESS:
WordCount: 12 (0xC)
ANDXCommand: No Secondary Command 255(0xFF)
AndXReserved: 0 (0x0)
ANDXOffset: 146 (0x92)
MaxBufferSize: 16384 (0x4000)
MaxMpxCount: 50 (0x32)
VcNumber: 1 (0x1)
SessionKey: 0 (0x0)
SecurityBlobLength: 46 (0x2E)
Reserved: 0 (0x0)
+ Capabilities: 0x8000C25C
ByteCount: 87 (0x57)
- SecurityBlob:
- GssApi:
+ ApplicationHeader:
+ ThisMech: NtlmSsp (1.3.6.1.4.1.311.2.2.10)
InnerContextToken: 0x1
+ UnicodeParameters:
ANDXPadding: Binary Large Object (2 Bytes)
- NtlmSsp: NTLM NEGOTIATE MESSAGE
Signature: NTLMSSP
MessageType: Negotiate Message (0x00000001)
- NtlmsspNegotiateMessage:
+ NegotiateFlags: 0xA0000217 (NTLM v1128-bit encryption, , Sign)
+ WorkstationDomainHeader: Length: 0, Offset: 0
+ WorkstationNameHeader: Length: 0, Offset: 0
0081 60 2C GssApi:
0083 06 0A 2B 06 01 04 01 82 37 02 02 0A ThisMech: NtlmSsp (1.3.6.1.4.1.311.2.2.10)
008F 4E InnerContextToken: 0x1 (NtlmSsp: NTLM NEGOTIATE MESSAGE)
0090 54 4C 4D 53 53 50 00 01 00 00 00 17 02 00 A0 00
00A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Question 2 Follow-up:
---------------------
Windows servers do not seem to accept well-formed GSS InitialContextTokens
containing NTLMSSP (re: gss_ntlmssp.cap frame 7), as is done with Kerberos
(re: spnego_krb.cap frame 7).
Response:
This refers to the same GSS-API construction information referenced in
Question 1. above.
As noted, this appears to be an interoperability deficiency. Action on our
part may well require bug filings against newer versions of Windows.
Could you advise me of any known implementations that do this? That would
be necessary for evidence to justify any Windows updates.
==============================================================================
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.
Response:
---------
I agree totally; thank you for the detail.
ThisMech: SpnegoToken (1.3.6.1.5.5.2) See 'Reference 3' ([RFC2743]) below.
OID Repository - Home
http://www.oid-info.com/
iso(1) identified-organization(3) dod(6) internet(1) security(5)
mechanisms(5) snego(2)
Child OID: modules(4)
Ref: http://www.ietf.org/rfc/rfc2743.txt
NtlmSsp: NTLM NEGOTIATE MESSAGE
- this is indented, since NTLM is considered a separate protocol by Network
Monitor 3.2. The InnerContextToken is from offset 0x7F - 0xBE. The
negotiate message is encapsulated (offset 0x97 - 0xBE).
------------------------------------------------------------------------------
Capture Details (Network Monitor 3.2)
- CSessionSetupAndXNTLMESS:
WordCount: 12 (0xC)
ANDXCommand: No Secondary Command 255(0xFF)
AndXReserved: 0 (0x0)
ANDXOffset: 2772 (0xAD4)
MaxBufferSize: 16644 (0x4104)
MaxMpxCount: 50 (0x32)
VcNumber: 0 (0x0)
SessionKey: 0 (0x0)
SecurityBlobLength: 2610 (0xA32)
Reserved: 0 (0x0)
+ Capabilities: 0xA00000D4
ByteCount: 2713 (0xA99)
- SecurityBlob:
- GssApi:
+ ApplicationHeader:
+ ThisMech: SpnegoToken (1.3.6.1.5.5.2)
- InnerContextToken: 0x1
- SpnegoToken: 0x1
+ Tag0:
- NegTokenInit:
+ SequenceHeader:
+ Tag0:
+ MechTypes:
+ Tag2:
+ OctetStringHeader:
- MechToken: 0x1
+ MsKerberosToken: 0x1
- GssApi:
+ ApplicationHeader:
+ ThisMech: KerberosToken (1.2.840.113554.1.2.2)
+ InnerContextToken: 0x1
0070 60 82 0A 2E 06 06 2B 06 01 05 05 GssApi:
0080 02
....
0081 A0 82 0A 22 30 82 0A 1E A0 24 30 22 06 09 2A InnerContextToken:
0090 86 48 82 F7 12 01 02 02 06 09 2A 86 48 86 F7 12
00A0 01 02 02 06 0A 2B 06 01 04 01 82 37 02 02 0A A2
00B0 82 09 F4 04 82 09 F0
....
00B7 60 82 09 EC 06 09 2A 86 48 MechToken: (MsKerberosToken:)
00C0 86 F7 12 01 02 02
00C6 01 00 6E 82 09 DB 30 82 09 D7 InnerContextToken:
00D0 A0 03 02 01 05 A1 03 02 01 0E A2 07 03 05 00 20
....
Follow-up Question / Comment:
-----------------------------
Yes, there isn't really a question here. I'm just demonstrating that when
Kerberos is negotiated, the SPNEGO mechToken is a GSS InitialContextToken.
==============================================================================
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 3.2.4.2.3, 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 3.2.5.2: 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.
------------------------------------------------------------------------------
Capture Details (Network Monitor 3.2)
- CSessionSetupAndXNTLMESS:
WordCount: 12 (0xC)
ANDXCommand: No Secondary Command 255(0xFF)
AndXReserved: 0 (0x0)
ANDXOffset: 202 (0xCA)
MaxBufferSize: 4356 (0x1104)
MaxMpxCount: 50 (0x32)
VcNumber: 0 (0x0)
SessionKey: 0 (0x0)
SecurityBlobLength: 40 (0x28)
Reserved: 0 (0x0)
+ Capabilities: 0xA00000D4
ExtenedSecurity: (1... ...) Supports extended security exchange (CAP_EXTENDED_SECURITY)
ByteCount: 143 (0x8F)
SecurityBlob:
+ UnicodeParameters:
ANDXPadding: Binary Large Object (2 Bytes)
- NtlmSSP: NTLM NEGOTIATE MESSAGE
Signature: NTLMSSP
MessageType: Negotiate Message (0x00000001)
- NtlmsspNegotiateMessage:
+ NegotiateFlags: 0xA2088207 (NTLM v2128-bit encryption, Always Sign)
+ WorkstationDomainHeader: Length: 0, Offset: 0
+ WorkstationNameHeader: Length: 0, Offset: 0
+ Version: Windows 5.1 Build 10250 NTLMSSPv15
0075 4E 54 4C 4D 53 53 50 00 01 00 00 SecurityBlob: (NtlmSSP: NTLM NEGOTIATE MESSAGE)
0080 00 07 82 08 A2 00 00 00 00 00 00 00 00 00 00
0090 00 00 00 00 00 00 05 01 28 0A 00 00 00 0F
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Question 4 Follow-up:
---------------------
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 to SPNEGO.
According to MS-SMB section 2.2.4 and MS-SMB 3.2.4.2.3, 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 (1.3.6.1.5.5.2), 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 general.
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.
Response:
raw_ntlmssp.cap frame 7:
Microsoft's implementation does indeed accept raw NTLMSSP data (per Reference
A below) in the SecurityBlob in an SMB_COM_SESSION_SETUP_ANDX request packet.
This does not relate to SPNEGO negotiation, and was introduced in the NTLMv2
implementation on Windows NT 4 Service Pack 4.
Kerberos support (under GSSAPI/SPNEGO) was, of course, introduced in
Windows 2000 (along with NTLMSSP; Reference A does not apply here).
Kerberos behavior (per Reference B below), is indeed Windows Behavior. Am I
correct that you are referring to the follow up to Question 1 (RFC 4178
section 3.2 (c))? If so, the Windows Behavior noted applies to
Reference A:
[MS-SMB] 3.2.4.2.3
User Authentication / 'Implicit NTLM
Reference B:
[MS-SPNG]
3.2.5.2 Universal Receiver
<8>
...
6 Appendix A: Windows Behavior
<8> Section 3.2.5.2: 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.
Reference C:
[MS-SPNG]
6 Appendix A: Windows Behavior
<5> Section 3.1.5.2: Windows versions offer and accept two distinct OIDs
as identifiers for the Kerberos authentication mechanism. The SPNEGO
extensions consider both OIDs as equivalent and make no distinction
between them.
Windows 2000 incorrectly encoded the OID for the Kerberos protocol.
Rather than the OID { iso(1) member-body(2) United States(840)
mit(113554) infosys(1) gssapi(2) krb5(2) }, an implementation error
truncated the values at 16 bits. Therefore, the OID became { iso(1)
member-body(2) United States(840) ???(48018) infosys(1) gssapi(2) krb5
(2) }. 48018 is not a known member under that OID branch; this is an
error.
Windows XP, Windows Server 2003, Windows Vista, and Windows Server
2008 do not truncate the value, and they correctly offer and receive
1.2.840.113554.1.2.2. For compatibility reasons, the erroneous value
(1.2.840.48018.1.2.2) is still offered and accepted by systems that
run Windows 2000. The presence of this value can be used to determine
that the peer is a Windows 2000 implementation.
==============================================================================
Reference 1:
============
[MS-SMB] Server Message Block (SMB) Protocol Specification
2.2.4 SMB_COM_SESSION_SETUP_ANDX Client Request Extension
...
SecurityBlob (variable): This field MUST be the authentication token sent
to the server, as specified in section 3.2.4.2.3 and [RFC4178].
3.2.4.2.3 User Authentication
-----------------------------
...
Extended Security
-----------------
If the CAP_EXTENDED_SECURITY bit in ServerCapabilities is set, the
SMB_COM_SESSION_SETUP_ANDX command MUST be generated, as defined here.
Otherwise, the client MUST generate the authentication portion, as
described in section Implicit NTLM.
The client MUST do one of the following:
o Pass the GSSNegotiateToken (if valid) to the configured GSS
authentication mechanism to obtain a GSS output token for the
authentication protocol exchange.
-OR-
o Choose to ignore the GSSNegotiateToken received from the server, and give
an empty input token to the configured GSS authentication protocol to
obtain a GSS output token for the authentication protocol exchange.
In either case, it initializes the GSS authentication protocol with the
MutualAuth and Delegate options, which are specified in [MS-KILE] section
3.2.1.1.<152>
The client creates an SMB_COM_SESSION_SETUP_ANDX request (section 2.2.4)
message. The client MUST set CAP_EXTENDED_SECURITY in the Capabilities
field, SMB_FLAGS2_EXTENDED_SECURITY in the SMB header Flags2 field, the
SecurityBlob field to the output token generated above, and the
SecurityBlobLength to the token length. The Uid field in the SMB header
MUST be set to 0.
Implicit NTLM
-------------
If the CAP_EXTENDED_SECURITY bit in ServerCapabilities is not set, the
SMB_COM_SESSION_SETUP_ANDX request MUST be generated, as defined here.
This is not new to the extension, but is included for completeness.
The server MUST construct an NTLM CHALLENGE_MESSAGE, as specified in
[MS-NLMP]. The CHALLENGE_MESSAGE is used by the server to challenge the
client to prove its identity. The following parameters MUST be set to the
following values.
o The Signature field is set to an 8-byte character array that MUST contain
the ASCII string ('N', 'T', 'L', 'M', 'S', 'S', 'P', '\0').
...
The client creates the appropriate AUTHENTICATE_MESSAGE to respond to the
CHALLENGE_MESSAGE, as specified in [MS-NLMP].
The client MUST build an SMB_COM_SESSION_SETUP_ANDX , as specified in
[CIFS] section 4.1.2. The following fields MUST be set to these values:
o The CaseSensitivePasswordLength field is set to the Length of the
NtChallengeResponse from the AUTHENTICATE_MESSAGE.
o The CaseSensitivePassword field is set to the value of the
NtChallengeResponse field from the AUTHENTICATE_MESSAGE.
o The CaseInsensitivePasswordLength field is set to the Length of the
LmChallengeResponse from the AUTHENTICATE_MESSAGE.
o The CaseInsensitivePassword field is set to the value of the
LmChallengeResponse field from the AUTHENTICATE_MESSAGE.
o The AccountName field is set to the value of the UserName field
from the AUTHENTICATE_MESSAGE.
o The PrimaryDomain field is set to the value of the DomainName field
from the AUTHENTICATE_MESSAGE.
==============================================================================
Reference 2:
============
Generic Security Service Application Program Interface, Version 2
http://www.ietf.org/rfc/rfc2078.txt
1.1.4: Mechanism Types
...
... The OID
representing the DASS MechType, for example, is 1.3.12.2.1011.7.5,
and that of the Kerberos V5 mechanism, once advanced to the level of
Proposed Standard, will be 1.2.840.113554.1.2.2.
3.1: Mechanism-Independent Token Format
... InitialContextToken ::=
-- option indication (delegation, etc.) indicated within
-- mechanism-specific token
[APPLICATION 0] IMPLICIT SEQUENCE {
thisMech MechType,
innerContextToken ANY DEFINED BY thisMech
-- contents mechanism-specific
-- ASN.1 structure not required
}
==============================================================================
Reference 3:
============
Generic Security Service Application Program Interface Version 2, Update 1
http://www.ietf.org/rfc/rfc2743.txt
1.1.4: Mechanism Types
...
The OID representing the DASS ([RFC-1507]) MechType, for example, is
1.3.12.2.1011.7.5, and that of the Kerberos V5 mechanism ([RFC-
1964]), having been advanced to the level of Proposed Standard, is
1.2.840.113554.1.2.2.
3.1: Mechanism-Independent Token Format
InitialContextToken ::=
-- option indication (delegation, etc.) indicated within
-- mechanism-specific token
[APPLICATION 0] IMPLICIT SEQUENCE {
thisMech MechType,
innerContextToken ANY DEFINED BY thisMech
-- contents mechanism-specific
-- ASN.1 structure not required
}
MechType ::= OBJECT IDENTIFIER
3.2. Negotiation Tokens
The syntax of the negotiation tokens follows the InitialContextToken
syntax defined in [1]. The security mechanism of the initial
negotiation token is identified by the Object Identifier
iso.org.dod.internet.security.mechanism.snego (1.3.6.1.5.5.2).
3.2.1. Syntax
This section specifies the syntax of the corresponding
"innerContextToken" field for the first token and subsequent
negotiation tokens. During the mechanism negociation, the
"innerContextToken" field contains the ASN.1 structure
"NegociationToken" given below, encoded using the DER encoding
conventions.
NegotiationToken ::= CHOICE {
negTokenInit [0] NegTokenInit,
negTokenTarg [1] NegTokenTarg }
MechTypeList ::= SEQUENCE OF MechType
NegTokenInit ::= SEQUENCE {
mechTypes [0] MechTypeList OPTIONAL,
reqFlags [1] ContextFlags OPTIONAL,
mechToken [2] OCTET STRING OPTIONAL,
mechListMIC [3] OCTET STRING OPTIONAL
}
==============================================================================
Reference 4:
============
The Simple and Protected GSS-API Negotiation Mechanism
http://www.ietf.org/rfc/rfc2478.txt
3.2.1. Syntax
1. ABSTRACT
The Simple and Protected GSS-API Negotiation Mechanism defined here
is a pseudo-security mechanism, represented by the object identifier
iso.org.dod.internet.security.mechanism.snego (1.3.6.1.5.5.2) which
3.1. Mechanism Type
MechType::= OBJECT IDENTIFIER
mechType
Each security mechanism is as defined in [1].
3.2.1. Syntax
NegotiationToken ::= CHOICE {
negTokenInit [0] NegTokenInit,
negTokenTarg [1] NegTokenTarg }
MechTypeList ::= SEQUENCE OF MechType
NegTokenInit ::= SEQUENCE {
mechTypes [0] MechTypeList OPTIONAL,
reqFlags [1] ContextFlags OPTIONAL,
mechToken [2] OCTET STRING OPTIONAL,
mechListMIC [3] OCTET STRING OPTIONAL
}
[1] Linn, J., "Generic Security Service Application Program
Interface", RFC 2078, January 1997.
==============================================================================
Reference 5:
============
The Simple and Protected Generic Security Service Application Program
Interface (GSS-API) Negotiation Mechanism
http://www.ietf.org/rfc/rfc4178.txt
3.2. Negotiation Procedure
...
c) The GSS-API initiator application sends the token to the target
application. The GSS-API target application passes the token by
invoking GSS_Accept_sec_context(). The acceptor will do one of
the following:
I) If none of the proposed mechanisms are acceptable, the
negotiation SHALL be terminated. GSS_Accept_sec_context
indicates GSS_S_BAD_MECH. The acceptor MAY output a
negotiation token containing a reject state.
II) If either the initiator's preferred mechanism is not accepted
by the target or this mechanism is accepted but is not the
acceptor's most preferred mechanism (i.e., the MIC token
exchange as described in Section 5 is required),
GSS_Accept_sec_context() indicates GSS_S_CONTINUE_NEEDED.
The acceptor MUST output a negotiation token containing a
request-mic state.
==============================================================================
Reference 6:
============
Re: ThisMech: NtlmSsp (1.3.6.1.4.1.311.2.2.10)
Object IDs associated with Microsoft cryptography
http://support.microsoft.com/kb/287547
CTL for Software Publishers Trusted CAs 1.3.6.1.4.1.311.2.2
(sub-subtree is defined for Software Publishing trusted CAs)
...
szOID_TRUSTED_CLIENT_AUTH_CA_LIST 1.3.6.1.4.1.311.2.2.2
[MS-SPNG]: Simple and Protected Generic Security Service Application Program
Interface Negotiation Mechanism (SPNEGO) Protocol Extensions
...
Protocol Examples
http://msdn.microsoft.com/en-us/library/cc247074.aspx
...
The protocol variation is a single message addition, as specified in [RFC4178], so only a sample message can be shown.
NegTokenInit message, a constructed sequence, at byte offsets 0x10 through 0x3f
inclusive, is the following.
[a0] [Context Specific 0]
[30] Sequence
[6] Object ID 1.2.840.48018.1.2.2
[6] Object ID 1.2.840.113554.1.2.2
[6] Object ID 1.2.840.113554.1.2.2.3
[6] Object ID 1.3.6.1.4.1.311.2.2.10
More information about the cifs-protocol
mailing list