public void Negotiate_SMB311_ContextID_NetName() { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Send NEGOTIATE request with SMB2_NETNAME_NEGOTIATE_CONTEXT_ID context."); DialectRevision clientMaxDialectSupported = DialectRevision.Smb311; PreauthIntegrityHashID[] preauthHashAlgs = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }; EncryptionAlgorithm[] encryptionAlgs = new EncryptionAlgorithm[] { EncryptionAlgorithm.ENCRYPTION_AES128_GCM, EncryptionAlgorithm.ENCRYPTION_AES128_CCM }; BaseTestSite.Log.Add( LogEntryKind.TestStep, "Send Negotiate request with dialect SMB 3.11, SMB2_PREAUTH_INTEGRITY_CAPABILITIES context and " + "SMB2_ENCRYPTION_CAPABILITIES context and SMB2_NETNAME_NEGOTIATE_CONTEXT_ID context."); NegotiateWithNegotiateContexts( clientMaxDialectSupported, preauthHashAlgs, encryptionAlgs, addNetNameContextId: true, checker: (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "[MS-SMB2] section 2.2.3.1.3: The SMB2_NETNAME_NEGOTIATE_CONTEXT_ID context is specified in an SMB2 NEGOTIATE request to indicate the server name the client connects to. The server MUST ignore this context. " ); } ); }
/// <summary> /// Constructor /// </summary> /// <param name="piHashId">The context hash ID.</param> public PreauthIntegrityContext(PreauthIntegrityHashID piHashId) { preauthIntegrityHashID = piHashId; connectionPreauthIntegrityHashValue = null; sessionPreauthIntegrityHashValueTable = new Dictionary<ulong, byte[]>(); completedSessionSet = new HashSet<ulong>(); }
/// <summary> /// Constructor /// </summary> /// <param name="piHashId">The context hash ID.</param> public PreauthIntegrityContext(PreauthIntegrityHashID piHashId) { preauthIntegrityHashID = piHashId; connectionPreauthIntegrityHashValue = null; sessionPreauthIntegrityHashValueTable = new Dictionary <ulong, byte[]>(); completedSessionSet = new HashSet <ulong>(); }
public void Negotiate_SMB311_InvalidHashAlgorithm() { PreauthIntegrityHashID[] preauthHashAlgs = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.HashAlgorithm_Invalid }; if (TestConfig.MaxSmbVersionSupported < DialectRevision.Smb311) { BaseTestSite.Assert.Inconclusive("Stop to run this test case because the configured server max dialect is lower than 3.11."); } BaseTestSite.Log.Add( LogEntryKind.TestStep, "Send Negotiate request with dialect SMB 3.11, SMB2_PREAUTH_INTEGRITY_CAPABILITIES context and " + "set HashAlgorithm to an invalid value: 0xFFFF."); NegotiateWithNegotiateContexts( DialectRevision.Smb311, preauthHashAlgs, encryptionAlgs: null, checker: (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Verify server fails the negotiate request with STATUS_SMB_NO_PREAUTH_INTEGRITY_HASH_OVERLAP."); BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_SMB_NO_PREAUTH_INTEGRITY_HASH_OVERLAP, header.Status, "[MS-SMB2] 3.3.5.4 If the SMB2_PREAUTH_INTEGRITY_CAPABILITIES HashAlgorithms array does not contain any hash algorithms " + "that the server supports, then the server MUST fail the negotiate request with STATUS_SMB_NO_PREAUTH_INTEGRITY_HASH_OVERLAP (0xC05D0000)."); }); }
private void NegotiateWithEncryptionCapabilitiesContext(EncryptionAlgorithm cipherId) { if (cipherId == EncryptionAlgorithm.ENCRYPTION_NONE) { throw new ArgumentException("CipherId should be either AES-128-CCM or AES-128-GCM."); } #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb311); TestConfig.CheckCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_ENCRYPTION); TestConfig.CheckEncryptionAlgorithm(cipherId); #endregion BaseTestSite.Log.Add( LogEntryKind.TestStep, "Client sends NEGOTIATE request with dialect 3.11, SMB2_ENCRYPTION_CAPABILITIES context. {0} is as the preferred cipher algorithm. ", cipherId); BaseTestSite.Log.Add( LogEntryKind.TestStep, "Server should reply NEGOTIATE response with dialect 3.11, SMB2_ENCRYPTION_CAPABILITIES context and {0} as cipher algorithm. ", cipherId); PreauthIntegrityHashID[] preauthHashAlgs = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }; EncryptionAlgorithm[] encryptionAlgs = new EncryptionAlgorithm[] { cipherId, cipherId == EncryptionAlgorithm.ENCRYPTION_AES128_CCM? EncryptionAlgorithm.ENCRYPTION_AES128_GCM : EncryptionAlgorithm.ENCRYPTION_AES128_CCM }; client.NegotiateWithContexts( Packet_Header_Flags_Values.NONE, TestConfig.RequestDialects, capabilityValue: Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_ENCRYPTION, preauthHashAlgs: preauthHashAlgs, encryptionAlgs: encryptionAlgs); BaseTestSite.Assert.AreEqual(cipherId, client.SelectedCipherID, "The selected Cipher Id should be {0}", cipherId); }
public void BVT_Negotiate_SMB311_Preauthentication_Encryption_GCM() { DialectRevision clientMaxDialectSupported = DialectRevision.Smb311; PreauthIntegrityHashID[] preauthHashAlgs = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }; EncryptionAlgorithm[] encryptionAlgs = new EncryptionAlgorithm[] { EncryptionAlgorithm.ENCRYPTION_AES128_GCM, EncryptionAlgorithm.ENCRYPTION_AES128_CCM }; if (TestConfig.MaxSmbVersionSupported < DialectRevision.Smb311) { BaseTestSite.Assert.Inconclusive("Stop to run this test case because the configured server max dialect is lower than 3.11."); } BaseTestSite.Log.Add( LogEntryKind.TestStep, "Send Negotiate request with dialect SMB 3.11, SMB2_PREAUTH_INTEGRITY_CAPABILITIES context and " + "SMB2_ENCRYPTION_CAPABILITIES context with AES-128-GCM preferred."); NegotiateWithNegotiateContexts( clientMaxDialectSupported, preauthHashAlgs, encryptionAlgs, checker: (Packet_Header header, NEGOTIATE_Response response) => { CheckNegotiateResponse(header, response, clientMaxDialectSupported, encryptionAlgs); } ); }
/// <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); } 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); }
private void NegotiateWithEncryptionCapabilitiesContext(EncryptionAlgorithm cipherId, bool sendCipherArray = false) { if (cipherId == EncryptionAlgorithm.ENCRYPTION_NONE) { throw new ArgumentException("CipherId should be either AES-128-CCM or AES-128-GCM."); } #region Check Applicability TestConfig.CheckDialect(DialectRevision.Smb311); TestConfig.CheckCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_ENCRYPTION); TestConfig.CheckEncryptionAlgorithm(cipherId); #endregion BaseTestSite.Log.Add( LogEntryKind.TestStep, "Client sends NEGOTIATE request with dialect 3.11, SMB2_ENCRYPTION_CAPABILITIES context. {0} is as the preferred cipher algorithm. ", cipherId); BaseTestSite.Log.Add( LogEntryKind.TestStep, "Server should reply NEGOTIATE response with dialect 3.11, SMB2_ENCRYPTION_CAPABILITIES context and {0} as cipher algorithm. ", cipherId); PreauthIntegrityHashID[] preauthHashAlgs = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }; EncryptionAlgorithm[] encryptionAlgs = null; if (sendCipherArray) { encryptionAlgs = new EncryptionAlgorithm[] { cipherId, cipherId == EncryptionAlgorithm.ENCRYPTION_AES128_CCM? EncryptionAlgorithm.ENCRYPTION_AES128_GCM : EncryptionAlgorithm.ENCRYPTION_AES128_CCM }; } else { encryptionAlgs = new EncryptionAlgorithm[] { cipherId }; } client.NegotiateWithContexts( Packet_Header_Flags_Values.NONE, TestConfig.RequestDialects, capabilityValue: Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_ENCRYPTION, preauthHashAlgs: preauthHashAlgs, encryptionAlgs: encryptionAlgs); if (sendCipherArray) { 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(cipherId, client.SelectedCipherID, "The selected Cipher Id should be {0}", cipherId); } }
public void Smb2Negotiate(DialectRevision[] requestDialects) { Packet_Header packetHeader; NEGOTIATE_Response response; PreauthIntegrityHashID[] preauthHashAlgs = null; EncryptionAlgorithm[] encryptionAlgs = null; if (requestDialects.Contains(DialectRevision.Smb311)) { // initial negotiation context for SMB 3.1.1 dialect preauthHashAlgs = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }; encryptionAlgs = new EncryptionAlgorithm[] { EncryptionAlgorithm.ENCRYPTION_AES128_CCM, EncryptionAlgorithm.ENCRYPTION_AES128_GCM }; } uint status = Negotiate( 0, RequestAndConsumeCredit(), Packet_Header_Flags_Values.NONE, GetMessageId(), requestDialects, SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, Capabilities_Values.GLOBAL_CAP_ENCRYPTION, clientGuid, out selectedDialect, out serverGssToken, out packetHeader, out response, 0, preauthHashAlgs, encryptionAlgs ); UpdateCredit(packetHeader); if (status != Smb2Status.STATUS_SUCCESS) { throw new InvalidOperationException(String.Format("Negotiate failed with {0:X08}.", status)); } signingRequired = response.SecurityMode.HasFlag(NEGOTIATE_Response_SecurityMode_Values.NEGOTIATE_SIGNING_REQUIRED); negotiated = true; maxReadSize = response.MaxReadSize; maxWriteSize = response.MaxWriteSize; }
public uint Smb2Negotiate(DialectRevision[] requestDialects, out DialectRevision selectedDialect) { uint status; NEGOTIATE_Response negotiateResponse; clientGuid = Guid.NewGuid(); PreauthIntegrityHashID[] preauthHashAlgs = null; EncryptionAlgorithm[] encryptionAlgs = null; if (requestDialects.Contains(DialectRevision.Smb311)) { // initial negotiation context for SMB 3.1.1 dialect preauthHashAlgs = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }; encryptionAlgs = new EncryptionAlgorithm[] { EncryptionAlgorithm.ENCRYPTION_AES128_CCM, EncryptionAlgorithm.ENCRYPTION_AES128_GCM }; } status = this.Negotiate( 1, 1, Packet_Header_Flags_Values.NONE, this.messageId, requestDialects, SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, CAPABILITIES, clientGuid, out selectedDialect, out this.gssToken, out packetHeader, out negotiateResponse, 0, preauthHashAlgs, encryptionAlgs ); this.Smb2MaxReadSize = negotiateResponse.MaxReadSize; this.Smb2MaxWriteSize = negotiateResponse.MaxWriteSize; CalculateSmb2AvailableCredits(1, packetHeader.CreditRequestResponse); return(status); }
public void BVT_Negotiate_SMB311_Preauthentication() { DialectRevision clientMaxDialectSupported = DialectRevision.Smb311; PreauthIntegrityHashID[] preauthHashAlgs = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }; if (TestConfig.MaxSmbVersionSupported < DialectRevision.Smb311) { BaseTestSite.Assert.Inconclusive("Stop to run this test case because the configured server max dialect is lower than 3.11."); } BaseTestSite.Log.Add( LogEntryKind.TestStep, "Send Negotiate request with dialect SMB 3.11 and SMB2_PREAUTH_INTEGRITY_CAPABILITIES context."); NegotiateWithNegotiateContexts( clientMaxDialectSupported, preauthHashAlgs, null, checker: (Packet_Header header, NEGOTIATE_Response response) => { CheckNegotiateResponse(header, response, clientMaxDialectSupported, null); }); }
public void BVT_Negotiate_SMB311() { DialectRevision clientMaxDialectSupported = DialectRevision.Smb311; PreauthIntegrityHashID[] preauthHashAlgs = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }; EncryptionAlgorithm[] encryptionAlgs = new EncryptionAlgorithm[] { EncryptionAlgorithm.ENCRYPTION_AES128_GCM, EncryptionAlgorithm.ENCRYPTION_AES128_CCM }; BaseTestSite.Log.Add( LogEntryKind.TestStep, "Send Negotiate request with dialect SMB 3.11, SMB2_PREAUTH_INTEGRITY_CAPABILITIES context and " + "SMB2_ENCRYPTION_CAPABILITIES context."); NegotiateWithNegotiateContexts( clientMaxDialectSupported, preauthHashAlgs, encryptionAlgs, checker: (Packet_Header header, NEGOTIATE_Response response) => { CheckNegotiateResponse(header, response, clientMaxDialectSupported, encryptionAlgs); }); }
public void BVT_Negotiate_SMB311_Preauthentication() { DialectRevision clientMaxDialectSupported = DialectRevision.Smb311; PreauthIntegrityHashID[] preauthHashAlgs = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }; if (TestConfig.MaxSmbVersionSupported < DialectRevision.Smb311) BaseTestSite.Assert.Inconclusive("Stop to run this test case because the configured server max dialect is lower than 3.11."); BaseTestSite.Log.Add( LogEntryKind.TestStep, "Send Negotiate request with dialect SMB 3.11 and SMB2_PREAUTH_INTEGRITY_CAPABILITIES context."); NegotiateWithNegotiateContexts( clientMaxDialectSupported, preauthHashAlgs, null, checker: (Packet_Header header, NEGOTIATE_Response response) => { CheckNegotiateResponse(header, response, clientMaxDialectSupported, null); } ); }
private void InternalConnectShare(string domain, string userName, string password, string shareName, TimeSpan timeout, SecurityPackageType securityPackage, bool useServerToken) { uint status; DialectRevision selectedDialect; Packet_Header header; byte[] serverGssToken; Array allDialects = Enum.GetValues(typeof(DialectRevision)); DialectRevision[] validDialects = new DialectRevision[allDialects.Length - 2]; int index = 0; foreach (var dialect in allDialects) { if ((DialectRevision)dialect != DialectRevision.Smb2Unknown && (DialectRevision)dialect != DialectRevision.Smb2Wildcard) { validDialects[index++] = (DialectRevision)dialect; } } PreauthIntegrityHashID[] preauthIntegrityHashIDArray = null; EncryptionAlgorithm[] encryptionAlgorithmArray = null; if (validDialects.Contains(DialectRevision.Smb311)) { preauthIntegrityHashIDArray = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }; encryptionAlgorithmArray = new EncryptionAlgorithm[] { EncryptionAlgorithm.ENCRYPTION_AES128_GCM, EncryptionAlgorithm.ENCRYPTION_AES128_CCM }; } // Negotiate: NEGOTIATE_Response negotiateResponse; CheckStatusCode( client.Negotiate( 1, 1, Packet_Header_Flags_Values.NONE, messageId++, // Will negotiate highest dialect server supports validDialects, SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_ENCRYPTION | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_LARGE_MTU, clientGuid, out selectedDialect, out serverGssToken, out header, out negotiateResponse, preauthHashAlgs: preauthIntegrityHashIDArray, encryptionAlgs: encryptionAlgorithmArray)); negotiatedDialect = selectedDialect; serverCapabilities = (Capabilities_Values)negotiateResponse.Capabilities; // 3.2.5.2: If the SecurityMode field in the SMB2 header of the response has the SMB2_NEGOTIATE_SIGNING_REQUIRED bit set, // the client MUST set Connection.RequireSigning to TRUE. // 3.2.5.3.1: If the global setting RequireMessageSigning is set to TRUE or // Connection.RequireSigning is set to TRUE then Session.SigningRequired MUST be set to TRUE bool session_SigningRequired = negotiateResponse.SecurityMode.HasFlag(NEGOTIATE_Response_SecurityMode_Values.NEGOTIATE_SIGNING_REQUIRED); if (session_SigningRequired) { // 3.2.4.1.1: If the client signs the request, it MUST set the SMB2_FLAGS_SIGNED bit in the Flags field of the SMB2 header. headerFlags |= Packet_Header_Flags_Values.FLAGS_SIGNED; } // Session setup: SESSION_SETUP_Response sessionSetupResponse; SspiClientSecurityContext sspiClientGss = new SspiClientSecurityContext( securityPackage, new AccountCredential(domain, userName, password), Smb2Utility.GetCifsServicePrincipalName(serverPrincipleName), ClientSecurityContextAttribute.None, SecurityTargetDataRepresentation.SecurityNativeDrep); if (securityPackage == SecurityPackageType.Negotiate) sspiClientGss.Initialize(serverGssToken); else sspiClientGss.Initialize(null); do { status = client.SessionSetup( 1, 1, 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 serverGssToken, out header, out sessionSetupResponse); CheckStatusCode(status); if ((status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED || status == Smb2Status.STATUS_SUCCESS) && serverGssToken != null && serverGssToken.Length > 0) { sspiClientGss.Initialize(serverGssToken); } } while (status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED); // 3.2.4.1.1 If Connection.Dialect is "3.1.1" and the message being sent is a TREE_CONNECT Request and the session identified by SessionId has Session.EncryptData equal to FALSE bool treeconnect_SigningRequired = session_SigningRequired || (selectedDialect >= DialectRevision.Smb311); client.GenerateCryptoKeys(sessionId, sspiClientGss.SessionKey, treeconnect_SigningRequired, false); this.sessionId = header.SessionId; // Session Key will be used in the MS-LSA SDK, see LsaClient.cs Line 179 SessionKey // Insert the session key to the global context Smb2ClientSession smb2CliSession = new Smb2ClientSession(); smb2CliSession.SessionKey = client.GetSessionKeyForAuthenticatedContext(sessionId); Smb2ClientConnection smb2CliConn = new Smb2ClientConnection(); smb2CliConn.SessionTable = new Dictionary<ulong, Smb2ClientSession>(); smb2CliConn.SessionTable.Add(sessionId, smb2CliSession); context.ConnectionTable = new Dictionary<string, Smb2ClientConnection>(); context.ConnectionTable.Add("Smb2ClientConnection", smb2CliConn); // Tree connect: TREE_CONNECT_Response treeConnectResponse; status = client.TreeConnect( 1, 1, treeconnect_SigningRequired? headerFlags| Packet_Header_Flags_Values.FLAGS_SIGNED:headerFlags, messageId++, sessionId, "\\\\" + serverPrincipleName + "\\" + shareName, out treeId, out header, out treeConnectResponse); this.treeId = header.TreeId; // For the messages followed by TREE_CONNECT, set them as signed/not signed following the normal proces client.EnableSessionSigningAndEncryption(sessionId, session_SigningRequired, false); }
private void NegotiateWithNegotiateContexts( DialectRevision clientMaxDialectSupported, PreauthIntegrityHashID[] preauthHashAlgs, EncryptionAlgorithm[] encryptionAlgs = null, ResponseChecker<NEGOTIATE_Response> checker = null) { // ensure clientMaxDialectSupported higher than 3.11 if (clientMaxDialectSupported < DialectRevision.Smb311) clientMaxDialectSupported = DialectRevision.Smb311; DialectRevision[] negotiateDialects = Smb2Utility.GetDialects(clientMaxDialectSupported); if (clientMaxDialectSupported > TestConfig.MaxSmbVersionClientSupported) { BaseTestSite.Assert.Inconclusive("Stop to run this test case because the configured MaxSmbVersionClientSupported {0} is lower than {1}.", TestConfig.MaxSmbVersionClientSupported, clientMaxDialectSupported); } status = client.NegotiateWithContexts( Packet_Header_Flags_Values.NONE, negotiateDialects, preauthHashAlgs: preauthHashAlgs, encryptionAlgs: encryptionAlgs, checker: checker); }
public void BVT_Negotiate_SMB311() { DialectRevision clientMaxDialectSupported = DialectRevision.Smb311; PreauthIntegrityHashID[] preauthHashAlgs = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }; EncryptionAlgorithm[] encryptionAlgs = new EncryptionAlgorithm[] { EncryptionAlgorithm.ENCRYPTION_AES128_GCM, EncryptionAlgorithm.ENCRYPTION_AES128_CCM }; BaseTestSite.Log.Add( LogEntryKind.TestStep, "Send Negotiate request with dialect SMB 3.11, SMB2_PREAUTH_INTEGRITY_CAPABILITIES context and " + "SMB2_ENCRYPTION_CAPABILITIES context."); NegotiateWithNegotiateContexts( clientMaxDialectSupported, preauthHashAlgs, encryptionAlgs, checker: (Packet_Header header, NEGOTIATE_Response response) => { CheckNegotiateResponse(header, response, clientMaxDialectSupported, encryptionAlgs); } ); }
/// <summary> /// Connect to the Server and establish the named pipe transport. /// </summary> private void ConnectToServer() { smb2Client = new Smb2Client(smb2ClientTimeout); if (IPAddress.TryParse(serverName, out var serverIp)) { smb2Client.ConnectOverTCP(serverIp); } else { var serverHostEntry = Dns.GetHostEntry(serverName); smb2Client.ConnectOverTCP(serverHostEntry.AddressList[0]); } var validDialects = new DialectRevision[] { DialectRevision.Smb2002, DialectRevision.Smb21, DialectRevision.Smb30, DialectRevision.Smb302, DialectRevision.Smb311 }; var preauthIntegrityHashIDs = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }; var encryptionAlgorithms = new EncryptionAlgorithm[] { EncryptionAlgorithm.ENCRYPTION_AES128_GCM, EncryptionAlgorithm.ENCRYPTION_AES128_CCM }; var status = smb2Client.Negotiate( creditCharge: 1, creditRequest: 1, flags: defaultFlags, messageId: messageId++, // Will negotiate highest dialect server supports dialects: validDialects, securityMode: SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, capabilities: Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_ENCRYPTION | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_LARGE_MTU, clientGuid: Guid.NewGuid(), out var selectedDialect, out var serverGssToken, out Packet_Header _, out var negotiateResponse, preauthHashAlgs: preauthIntegrityHashIDs, encryptionAlgs: encryptionAlgorithms); CheckStatusCode(status, nameof(Smb2Client.Negotiate)); var sessionSiginingRequired = negotiateResponse.SecurityMode.HasFlag(NEGOTIATE_Response_SecurityMode_Values.NEGOTIATE_SIGNING_REQUIRED); if (sessionSiginingRequired) { defaultFlags |= Packet_Header_Flags_Values.FLAGS_SIGNED; } var usedSecurityPackageType = (SecurityPackageType)Enum.Parse(typeof(SecurityPackageType), securityPackage); var sspiClientGss = new SspiClientSecurityContext( usedSecurityPackageType, new AccountCredential(domainName, userName, password), Smb2Utility.GetCifsServicePrincipalName(serverName), ClientSecurityContextAttribute.None, SecurityTargetDataRepresentation.SecurityNativeDrep); if (usedSecurityPackageType == SecurityPackageType.Negotiate && useServerGssToken) { sspiClientGss.Initialize(serverGssToken); } else { sspiClientGss.Initialize(null); } do { status = smb2Client.SessionSetup( creditCharge: 1, creditRequest: 1, flags: Packet_Header_Flags_Values.NONE, messageId: messageId++, sessionId: sessionId, sessionSetupFlags: SESSION_SETUP_Request_Flags.NONE, securityMode: SESSION_SETUP_Request_SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, capabilities: SESSION_SETUP_Request_Capabilities_Values.GLOBAL_CAP_DFS, previousSessionId: 0, clientGssToken: sspiClientGss.Token, out sessionId, out serverGssToken, out _, out _); CheckStatusCode(status, nameof(Smb2Client.SessionSetup)); if ((status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED || status == Smb2Status.STATUS_SUCCESS) && serverGssToken != null && serverGssToken.Length > 0) { sspiClientGss.Initialize(serverGssToken); } } while (status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED); var treeConnectSigningRequired = sessionSiginingRequired || (selectedDialect >= DialectRevision.Smb311); smb2Client.GenerateCryptoKeys( sessionId, sspiClientGss.SessionKey, treeConnectSigningRequired, false); status = smb2Client.TreeConnect( creditCharge: 1, creditRequest: 1, flags: treeConnectSigningRequired ? defaultFlags | Packet_Header_Flags_Values.FLAGS_SIGNED : defaultFlags, messageId: messageId++, sessionId: sessionId, $"\\\\{serverName}\\IPC$", out treeId, out _, out _); CheckStatusCode(status, nameof(Smb2Client.TreeConnect)); smb2Client.EnableSessionSigningAndEncryption(sessionId, sessionSiginingRequired, false); status = smb2Client.Create( creditCharge: 1, creditRequest: 1, flags: defaultFlags, messageId: messageId++, sessionId: sessionId, treeId: treeId, path: pipeName, desiredAccess: AccessMask.GENERIC_READ | AccessMask.GENERIC_WRITE, shareAccess: ShareAccess_Values.FILE_SHARE_READ, createOptions: CreateOptions_Values.NONE, createDispositions: CreateDisposition_Values.FILE_OPEN_IF, fileAttributes: File_Attributes.NONE, impersonationLevel: ImpersonationLevel_Values.Impersonation, securityFlag: SecurityFlags_Values.NONE, requestedOplockLevel: RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE, createContexts: null, out fileId, out _, out _, out _); CheckStatusCode(status, nameof(Smb2Client.Create)); }
/// <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; }
public void BVT_Negotiate_SMB311_Preauthentication_Encryption_GCM() { DialectRevision clientMaxDialectSupported = DialectRevision.Smb311; PreauthIntegrityHashID[] preauthHashAlgs = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }; EncryptionAlgorithm[] encryptionAlgs = new EncryptionAlgorithm[] { EncryptionAlgorithm.ENCRYPTION_AES128_GCM, EncryptionAlgorithm.ENCRYPTION_AES128_CCM }; if (TestConfig.MaxSmbVersionSupported < DialectRevision.Smb311) BaseTestSite.Assert.Inconclusive("Stop to run this test case because the configured server max dialect is lower than 3.11."); BaseTestSite.Log.Add( LogEntryKind.TestStep, "Send Negotiate request with dialect SMB 3.11, SMB2_PREAUTH_INTEGRITY_CAPABILITIES context and " + "SMB2_ENCRYPTION_CAPABILITIES context with AES-128-GCM preferred."); NegotiateWithNegotiateContexts( clientMaxDialectSupported, preauthHashAlgs, encryptionAlgs, checker: (Packet_Header header, NEGOTIATE_Response response) => { CheckNegotiateResponse(header, response, clientMaxDialectSupported, encryptionAlgs); } ); }
public void Negotiate_SMB311_InvalidHashAlgorithm() { PreauthIntegrityHashID[] preauthHashAlgs = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.HashAlgorithm_Invalid }; if (TestConfig.MaxSmbVersionSupported < DialectRevision.Smb311) BaseTestSite.Assert.Inconclusive("Stop to run this test case because the configured server max dialect is lower than 3.11."); BaseTestSite.Log.Add( LogEntryKind.TestStep, "Send Negotiate request with dialect SMB 3.11, SMB2_PREAUTH_INTEGRITY_CAPABILITIES context and " + "set HashAlgorithm to an invalid value: 0xFFFF."); NegotiateWithNegotiateContexts( DialectRevision.Smb311, preauthHashAlgs, encryptionAlgs: null, checker: (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Verify server fails the negotiate request with STATUS_SMB_NO_PREAUTH_INTEGRITY_HASH_OVERLAP."); BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_SMB_NO_PREAUTH_INTEGRITY_HASH_OVERLAP, header.Status, "[MS-SMB2] 3.3.5.4 If the SMB2_PREAUTH_INTEGRITY_CAPABILITIES HashAlgorithms array does not contain any hash algorithms " + "that the server supports, then the server MUST fail the negotiate request with STATUS_SMB_NO_PREAUTH_INTEGRITY_HASH_OVERLAP (0xC05D0000)."); }); }