コード例 #1
0
 /// <summary>
 /// Check whether actual dialect is bigger than expected dialect or not.
 /// </summary>
 /// <param name="expectedMinimalDialect">Expected minimal dialect.</param>
 /// <param name="response">Negotiate response header.</param>
 public void CheckNegotiateDialect(DialectRevision expectedMinimalDialect, NEGOTIATE_Response response)
 {
     if (response.DialectRevision < expectedMinimalDialect)
     {
         Site.Assert.Inconclusive(
             "This test case is not applicable due to that actual dialect {0} is less than expected minimal dialect {1}",
             (DialectRevision)response.DialectRevision,
             (DialectRevision)expectedMinimalDialect);
     }
 }
コード例 #2
0
        private void CheckNegotiateResponse(
            Packet_Header header,
            NEGOTIATE_Response response,
            DialectRevision clientMaxDialectSupported,
            EncryptionAlgorithm[] encryptionAlgs)
        {
            DialectRevision expectedDialect = clientMaxDialectSupported < TestConfig.MaxSmbVersionSupported
                        ? clientMaxDialectSupported : TestConfig.MaxSmbVersionSupported;

            BaseTestSite.Assert.AreEqual(
                Smb2Status.STATUS_SUCCESS,
                header.Status,
                "{0} should succeed, actually server returns {1}.", header.Command, Smb2Status.GetStatusCode(header.Status));
            BaseTestSite.Assert.AreEqual(expectedDialect, response.DialectRevision, "Selected dialect should be {0}", expectedDialect);

            if (expectedDialect >= DialectRevision.Smb311)
            {
                BaseTestSite.Assert.AreEqual(
                    PreauthIntegrityHashID.SHA_512,
                    client.SelectedPreauthIntegrityHashID,
                    "[MS-SMB2] 3.3.5.4 The server MUST set Connection.PreauthIntegrityHashId to one of the hash algorithms " +
                    "in the client's SMB2_PREAUTH_INTEGRITY_CAPABILITIES HashAlgorithms array.");

                if (encryptionAlgs != null)
                {
                    BaseTestSite.Assert.IsTrue(
                        TestConfig.SupportedEncryptionAlgorithmList.Contains(client.SelectedCipherID),
                        "[MS-SMB2] 3.3.5.4 The server MUST set Connection.CipherId to one of the ciphers in the client's " +
                        "SMB2_ENCRYPTION_CAPABILITIES Ciphers array in an implementation-specific manner.");
                }
                else
                {
                    BaseTestSite.Assert.AreEqual(
                        EncryptionAlgorithm.ENCRYPTION_NONE,
                        client.SelectedCipherID,
                        "[MS-SMB2] if client doesn't present SMB2_ENCRYPTION_CAPABILITIES context in negotiate request, " +
                        "server should not present this context in negotiate response.");
                }
            }
            else
            {
                // If server supported dialect version is lower than 3.11, server should ignore the negotiate contexts.
                BaseTestSite.Assert.AreEqual(
                    PreauthIntegrityHashID.HashAlgorithm_NONE,
                    client.SelectedPreauthIntegrityHashID,
                    "[MS-SMB2] The server must ignore the SMB2_PREAUTH_INTEGRITY_CAPABILITIES context if Connection.Dialect is less than 3.11. ");
                BaseTestSite.Assert.AreEqual(
                    EncryptionAlgorithm.ENCRYPTION_NONE,
                    client.SelectedCipherID,
                    "[MS-SMB2] The server must ignore the SMB2_ENCRYPTION_CAPABILITIES context if Connection.Dialect is less than 3.11. ");
            }

            CheckServerCapabilities(response);
        }
コード例 #3
0
        /// <summary>
        /// Negotiate, SessionSetup and TreeConnect
        /// </summary>
        public void SetupConnection(ModelDialectRevision dialect, ModelCapabilities capabilities, SecurityMode_Values securityMode)
        {
            #region Connect to server
            testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress);
            #endregion

            // It MUST be a GUID generated by the client, if the Dialects field contains a value other than 0x0202. Otherwise, the client MUST set this to 0.
            Guid clientGuid = (dialect == ModelDialectRevision.Smb2002) ? Guid.Empty : Guid.NewGuid();

            #region negotiate
            testClient.Negotiate(
                Packet_Header_Flags_Values.NONE,
                Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(dialect)),
                securityMode,
                (Capabilities_Values)capabilities,
                clientGuid,
                (header, response) =>
            {
                Site.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, header.Status, "{0} should succeed", header.Command);
                negotiateResponse = response;
            });
            #endregion

            #region session setup
            testClient.SessionSetup(
                testConfig.DefaultSecurityPackage,
                testConfig.SutComputerName,
                testConfig.AccountCredential,
                testConfig.UseServerGssToken,
                (SESSION_SETUP_Request_SecurityMode_Values)securityMode);
            #endregion

            #region treeconnect
            testClient.TreeConnect(
                Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare),
                out treeId);
            #endregion

            Connection_Dialect            = ModelUtility.GetModelDialectRevision(negotiateResponse.DialectRevision);
            Connection_ClientCapabilities = (Capabilities_Values)capabilities;
            if (dialect >= ModelDialectRevision.Smb30) // GLOBAL_CAP_ENCRYPTION will be added in Functional client when dialect >= SMB30
            {
                Connection_ClientCapabilities |= Capabilities_Values.GLOBAL_CAP_ENCRYPTION;
            }
            Connection_ClientSecurityMode = securityMode;
            Connection_ClientGuid         = clientGuid;
        }
コード例 #4
0
        public void NegotiateRequest(Sequence <DialectRevision> dialects)
        {
            Packet_Header      responseHeader  = new Packet_Header();
            DialectRevision    selectedDialect = DialectRevision.Smb2Unknown;
            NEGOTIATE_Response responsePayload = new NEGOTIATE_Response();

            byte[]          smb2ClientGssToken;
            ModelSmb2Status status = ModelSmb2Status.STATUS_SUCCESS;

            try
            {
                status = (ModelSmb2Status)smb2Client.Negotiate(0, 1, Packet_Header_Flags_Values.NONE, messageId++, dialects.ToArray(), SecurityMode_Values.NONE, Capabilities_Values.NONE, Guid.NewGuid(),
                                                               out selectedDialect, out smb2ClientGssToken, out responseHeader, out responsePayload);
                if (status != ModelSmb2Status.STATUS_SUCCESS)
                {
                    selectedDialect = DialectRevision.Smb2Unknown;
                }
                this.NegotiateResponse(status, selectedDialect);
            }
            catch
            {
            }
        }
コード例 #5
0
 public void CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values capValue, NEGOTIATE_Response response)
 {
     if (!response.Capabilities.HasFlag(capValue))
     {
         Site.Assert.Inconclusive("This test case is not applicable due to following capability is not supported: {0}", (Capabilities_Values)capValue);
     }
 }
コード例 #6
0
        public void UserLogon(
            DetectionInfo info,
            Smb2Client client,
            out ulong messageId,
            out ulong sessionId,
            out Guid clientGuid,
            out NEGOTIATE_Response negotiateResp,
            out bool encryptionRequired)
        {
            messageId = 1;
            sessionId = 0;
            logWriter.AddLog(LogLevel.Information, "Client connects to server");
            client.ConnectOverTCP(SUTIpAddress);

            #region Negotiate

            DialectRevision selectedDialect;
            byte[]          gssToken;
            Packet_Header   header;
            clientGuid = Guid.NewGuid();
            logWriter.AddLog(LogLevel.Information, "Client sends multi-protocol Negotiate to server");
            MultiProtocolNegotiate(
                client,
                1,
                1,
                Packet_Header_Flags_Values.NONE,
                messageId++,
                info.requestDialect,
                SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED,
                Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU
                | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES | Capabilities_Values.GLOBAL_CAP_ENCRYPTION,
                clientGuid,
                out selectedDialect,
                out gssToken,
                out header,
                out negotiateResp);

            if (header.Status != Smb2Status.STATUS_SUCCESS)
            {
                LogFailedStatus("NEGOTIATE", header.Status);
                throw new Exception(string.Format("NEGOTIATE failed with {0}", Smb2Status.GetStatusCode(header.Status)));
            }

            #endregion

            #region Session Setup

            SESSION_SETUP_Response sessionSetupResp;

            SspiClientSecurityContext sspiClientGss =
                new SspiClientSecurityContext(
                    SecurityPackageType,
                    Credential,
                    Smb2Utility.GetCifsServicePrincipalName(SUTName),
                    ClientSecurityContextAttribute.None,
                    SecurityTargetDataRepresentation.SecurityNativeDrep);

            // Server GSS token is used only for Negotiate authentication when enabled
            if (SecurityPackageType == SecurityPackageType.Negotiate)
            {
                sspiClientGss.Initialize(gssToken);
            }
            else
            {
                sspiClientGss.Initialize(null);
            }

            do
            {
                logWriter.AddLog(LogLevel.Information, "Client sends SessionSetup to server");
                client.SessionSetup(
                    1,
                    64,
                    Packet_Header_Flags_Values.NONE,
                    messageId++,
                    sessionId,
                    SESSION_SETUP_Request_Flags.NONE,
                    SESSION_SETUP_Request_SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED,
                    SESSION_SETUP_Request_Capabilities_Values.GLOBAL_CAP_DFS,
                    0,
                    sspiClientGss.Token,
                    out sessionId,
                    out gssToken,
                    out header,
                    out sessionSetupResp);

                if ((header.Status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED || header.Status == Smb2Status.STATUS_SUCCESS) && gssToken != null && gssToken.Length > 0)
                {
                    sspiClientGss.Initialize(gssToken);
                }
            } while (header.Status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED);

            if (header.Status != Smb2Status.STATUS_SUCCESS)
            {
                LogFailedStatus("SESSIONSETUP", header.Status);
                throw new Exception(string.Format("SESSIONSETUP failed with {0}", Smb2Status.GetStatusCode(header.Status)));
            }

            byte[] sessionKey;
            sessionKey         = sspiClientGss.SessionKey;
            encryptionRequired = sessionSetupResp.SessionFlags == SessionFlags_Values.SESSION_FLAG_ENCRYPT_DATA;
            client.GenerateCryptoKeys(
                sessionId,
                sessionKey,
                info.smb2Info.IsRequireMessageSigning, // Enable signing according to the configuration of SUT
                encryptionRequired,
                null,
                false);

            #endregion
        }
コード例 #7
0
        /// <summary>
        /// This method will send ComNegotiate request before sending a Negotiate request to simulate windows client behaviour.
        /// If ComNegotiate failed, the Negotiate request will still be sent.
        /// </summary>
        public uint MultiProtocolNegotiate(
            Smb2Client client,
            ushort creditCharge,
            ushort creditRequest,
            Packet_Header_Flags_Values flags,
            ulong messageId,
            DialectRevision[] dialects,
            SecurityMode_Values securityMode,
            Capabilities_Values capabilities,
            Guid clientGuid,
            out DialectRevision selectedDialect,
            out byte[] gssToken,
            out Packet_Header responseHeader,
            out NEGOTIATE_Response responsePayload)
        {
            uint status = client.MultiProtocolNegotiate(
                new string[] { "SMB 2.002", "SMB 2.???" },
                out selectedDialect,
                out gssToken,
                out responseHeader,
                out responsePayload);

            if (responseHeader.Status != Smb2Status.STATUS_SUCCESS)
            {
                LogFailedStatus("ComNegotiate", responseHeader.Status);
            }

            // If server only supports Smb2002, no further SMB2 negotiate needed
            if (selectedDialect == DialectRevision.Smb2002)
            {
                return(status);
            }

            PreauthIntegrityHashID[] preauthHashAlgs = null;
            EncryptionAlgorithm[]    encryptionAlgs  = null;

            // For back compatibility, if dialects contains SMB 3.11, preauthentication integrity context should be present.
            if (Array.IndexOf(dialects, DialectRevision.Smb311) >= 0)
            {
                preauthHashAlgs = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 };
                encryptionAlgs  = new EncryptionAlgorithm[] {
                    EncryptionAlgorithm.ENCRYPTION_AES128_GCM,
                    EncryptionAlgorithm.ENCRYPTION_AES128_CCM
                };
            }

            status = client.Negotiate(
                creditCharge,
                creditRequest,
                flags,
                messageId,
                dialects,
                securityMode,
                capabilities,
                clientGuid,
                out selectedDialect,
                out gssToken,
                out responseHeader,
                out responsePayload,
                0,
                preauthHashAlgs,
                encryptionAlgs);

            return(status);
        }
コード例 #8
0
 protected override uint Negotiate(ushort creditCharge, ushort creditRequest, ulong messageId, Guid clientGuid,
                                   out DialectRevision selectedDialect, out byte[] gssToken, out Packet_Header responseHeader, out NEGOTIATE_Response responsePayload)
 {
     return(client.Negotiate(
                creditCharge,
                creditRequest,
                Packet_Header_Flags_Values.NONE,
                messageId,
                new DialectRevision[] { this.dialect },
                SecurityMode_Values.NONE,
                Capabilities_Values.NONE,
                clientGuid,
                out selectedDialect,
                out gssToken,
                out responseHeader,
                out responsePayload));
 }
コード例 #9
0
        private void CheckServerCapabilities(NEGOTIATE_Response response)
        {
            // Check capability: Leasing
            if (TestConfig.IsLeasingSupported &&
                response.DialectRevision != DialectRevision.Smb2002)
            {
                BaseTestSite.Assert.AreEqual <NEGOTIATE_Response_Capabilities_Values>(
                    NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_LEASING,
                    response.Capabilities & NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_LEASING,
                    "The \"Capabilities\" of Negotiate Response should has flag GLOBAL_CAP_LEASING set.");
            }

            // Check capability: Large MTU
            if (TestConfig.IsMultiCreditSupported &&
                response.DialectRevision != DialectRevision.Smb2002)
            {
                BaseTestSite.Assert.AreEqual <NEGOTIATE_Response_Capabilities_Values>(
                    NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_LARGE_MTU,
                    response.Capabilities & NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_LARGE_MTU,
                    "The \"Capabilities\" of Negotiate Response should has flag GLOBAL_CAP_LARGE_MTU set.");
            }

            // Check capability: MultiChannel
            if (TestConfig.IsMultiChannelCapable &&
                response.DialectRevision != DialectRevision.Smb2002 &&
                response.DialectRevision != DialectRevision.Smb21)
            {
                BaseTestSite.Assert.AreEqual <NEGOTIATE_Response_Capabilities_Values>(
                    NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL,
                    response.Capabilities & NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL,
                    "The \"Capabilities\" of Negotiate Response should has flag GLOBAL_CAP_MULTI_CHANNEL set.");
            }

            // Check capability: Persistent Handle
            if (TestConfig.IsPersistentHandlesSupported &&
                response.DialectRevision != DialectRevision.Smb2002 &&
                response.DialectRevision != DialectRevision.Smb21)
            {
                BaseTestSite.Assert.AreEqual <NEGOTIATE_Response_Capabilities_Values>(
                    NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES,
                    response.Capabilities & NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES,
                    "The \"Capabilities\" of Negotiate Response should has flag GLOBAL_CAP_PERSISTENT_HANDLES set.");
            }

            // Check capability: Directory Leasing
            if (TestConfig.IsDirectoryLeasingSupported &&
                response.DialectRevision != DialectRevision.Smb2002 &&
                response.DialectRevision != DialectRevision.Smb21)
            {
                BaseTestSite.Assert.AreEqual <NEGOTIATE_Response_Capabilities_Values>(
                    NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING,
                    response.Capabilities & NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING,
                    "The \"Capabilities\" of Negotiate Response should has flag GLOBAL_CAP_DIRECTORY_LEASING set.");
            }

            // Check capability: Encryption
            if (TestConfig.IsEncryptionSupported &&
                response.DialectRevision == DialectRevision.Smb30 &&
                response.DialectRevision == DialectRevision.Smb302)
            {
                BaseTestSite.Assert.AreEqual <NEGOTIATE_Response_Capabilities_Values>(
                    NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_ENCRYPTION,
                    response.Capabilities & NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_ENCRYPTION,
                    "The \"Capabilities\" of Negotiate Response should has flag GLOBAL_CAP_ENCRYPTION set.");
            }
        }
コード例 #10
0
        private bool UserLogon(DetectionInfo info, Smb2Client client, out ulong messageId, out ulong sessionId, out Guid clientGuid, out NEGOTIATE_Response negotiateResp)
        {
            messageId = 0;
            sessionId = 0;
            client.ConnectOverTCP(Dns.GetHostAddresses(info.ContentServerName)[0]);

            #region Negotiate

            DialectRevision selectedDialect;
            byte[]          gssToken;
            Packet_Header   header;
            clientGuid = Guid.NewGuid();

            client.Negotiate(
                1,
                1,
                Packet_Header_Flags_Values.NONE,
                messageId++,
                new DialectRevision[] { DialectRevision.Smb30 },
                SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED,
                Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES,
                clientGuid,
                out selectedDialect,
                out gssToken,
                out header,
                out negotiateResp);

            if (header.Status != Smb2Status.STATUS_SUCCESS)
            {
                LogFailedStatus("NEGOTIATE", header.Status);
                throw new Exception(string.Format("NEGOTIATE failed with {0}", Smb2Status.GetStatusCode(header.Status)));
            }

            #endregion

            #region Session Setup

            SESSION_SETUP_Response    sessionSetupResp;
            SspiClientSecurityContext sspiClientGss =
                new SspiClientSecurityContext(
                    SecurityPackageType,
                    Credential,
                    Smb2Utility.GetCifsServicePrincipalName(ContentServerName),
                    ClientSecurityContextAttribute.None,
                    SecurityTargetDataRepresentation.SecurityNativeDrep);

            // Server GSS token is used only for Negotiate authentication when enabled
            if (SecurityPackageType == SecurityPackageType.Negotiate)
            {
                sspiClientGss.Initialize(gssToken);
            }
            else
            {
                sspiClientGss.Initialize(null);
            }

            do
            {
                client.SessionSetup(
                    1,
                    64,
                    Packet_Header_Flags_Values.NONE,
                    messageId++,
                    sessionId,
                    SESSION_SETUP_Request_Flags.NONE,
                    SESSION_SETUP_Request_SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED,
                    SESSION_SETUP_Request_Capabilities_Values.GLOBAL_CAP_DFS,
                    0,
                    sspiClientGss.Token,
                    out sessionId,
                    out gssToken,
                    out header,
                    out sessionSetupResp);

                if ((header.Status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED || header.Status == Smb2Status.STATUS_SUCCESS) && gssToken != null && gssToken.Length > 0)
                {
                    sspiClientGss.Initialize(gssToken);
                }
            } while (header.Status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED);

            if (header.Status != Smb2Status.STATUS_SUCCESS)
            {
                LogFailedStatus("SESSIONSETUP", header.Status);
                throw new Exception(string.Format("SESSIONSETUP failed with {0}", Smb2Status.GetStatusCode(header.Status)));
            }

            byte[] sessionKey;
            sessionKey = sspiClientGss.SessionKey;
            client.GenerateCryptoKeys(sessionId, sessionKey, true, false, null, false);

            #endregion

            return(true);
        }