/// <summary> /// Negotiate, SessionSetup, TreeConnect /// </summary> /// <returns>Return true for success, false for failure</returns> private void ConnectToShare( string sharename, DetectionInfo info, Smb2Client client, out ulong messageId, out ulong sessionId, out uint treeId) { Packet_Header header; Guid clientGuid; NEGOTIATE_Response negotiateResp; bool encryptionRequired = false; UserLogon(info, client, out messageId, out sessionId, out clientGuid, out negotiateResp, out encryptionRequired); #region TreeConnect TREE_CONNECT_Response treeConnectResp; string uncSharePath = Smb2Utility.GetUncPath(info.targetSUT, sharename); logWriter.AddLog(DetectLogLevel.Information, "Client sends TreeConnect to server"); if (info.smb2Info.MaxSupportedDialectRevision == DialectRevision.Smb311) // When dialect is 3.11, TreeConnect must be signed or encrypted. { client.EnableSessionSigningAndEncryption(sessionId, true, encryptionRequired); } client.TreeConnect( 1, 1, (info.smb2Info.IsRequireMessageSigning || info.smb2Info.MaxSupportedDialectRevision == DialectRevision.Smb311) ? Packet_Header_Flags_Values.FLAGS_SIGNED : Packet_Header_Flags_Values.NONE, messageId++, sessionId, uncSharePath, out treeId, out header, out treeConnectResp); // When dialect is 3.11, for the messages other than TreeConnect, signing is not required. // Set it back to the configuration of the SUT. if (info.smb2Info.MaxSupportedDialectRevision == DialectRevision.Smb311) { client.EnableSessionSigningAndEncryption(sessionId, info.smb2Info.IsRequireMessageSigning, encryptionRequired); } if (header.Status != Smb2Status.STATUS_SUCCESS) { LogFailedStatus("TREECONNECT", header.Status); throw new Exception("TREECONNECT failed with " + Smb2Status.GetStatusCode(header.Status)); } #endregion }
private ShareInfo[] RetrieveShareProperties(string[] shareList, DetectionInfo info) { List <ShareInfo> shareInfoList = new List <ShareInfo>(); string uncShare; foreach (var share in shareList) { using (Smb2Client smb2Client = new Smb2Client(new TimeSpan(0, 0, defaultTimeoutInSeconds))) { Packet_Header header; ulong messageId; ulong sessionId; Guid clientGuid; uncShare = string.Format(@"\\{0}\{1}", SUTName, share); try { NEGOTIATE_Response negotiateResp; bool encryptionRequired = false; UserLogon(info, smb2Client, out messageId, out sessionId, out clientGuid, out negotiateResp, out encryptionRequired); uint treeId; TREE_CONNECT_Response treeConnectResp; if (info.smb2Info.MaxSupportedDialectRevision == DialectRevision.Smb311) // When dialect is 3.11, TreeConnect must be signed or encrypted. { smb2Client.EnableSessionSigningAndEncryption(sessionId, true, encryptionRequired); } logWriter.AddLog(LogLevel.Information, string.Format("Client sends TreeConnect to {0} to retrieve the share properties.", uncShare)); smb2Client.TreeConnect( 1, 1, (info.smb2Info.IsRequireMessageSigning || info.smb2Info.MaxSupportedDialectRevision == DialectRevision.Smb311) ? Packet_Header_Flags_Values.FLAGS_SIGNED : Packet_Header_Flags_Values.NONE, messageId++, sessionId, uncShare, out treeId, out header, out treeConnectResp); if (header.Status != Smb2Status.STATUS_SUCCESS) { continue; } // When dialect is 3.11, for the messages other than TreeConnect, signing is not required. // Set it back to the configuration of the SUT. if (info.smb2Info.MaxSupportedDialectRevision == DialectRevision.Smb311) { smb2Client.EnableSessionSigningAndEncryption(sessionId, info.smb2Info.IsRequireMessageSigning, encryptionRequired); } ShareInfo shareInfo = new ShareInfo(); shareInfo.ShareName = share; shareInfo.ShareCapabilities = treeConnectResp.Capabilities; shareInfo.ShareFlags = treeConnectResp.ShareFlags; shareInfo.ShareType = treeConnectResp.ShareType; shareInfoList.Add(shareInfo); TREE_DISCONNECT_Response treeDisconnectResponse; smb2Client.TreeDisconnect( 1, 1, info.smb2Info.IsRequireMessageSigning ? Packet_Header_Flags_Values.FLAGS_SIGNED : Packet_Header_Flags_Values.NONE, messageId++, sessionId, treeId, out header, out treeDisconnectResponse); LOGOFF_Response logoffResponse; smb2Client.LogOff(1, 1, Packet_Header_Flags_Values.NONE, messageId++, sessionId, out header, out logoffResponse); } catch (Exception ex) { logWriter.AddLog(LogLevel.Information, string.Format("Exception when retrieving share properties: " + ex.Message)); // Swallow all exceptions when cleaning up. } } } return(shareInfoList.ToArray()); }
private ShareInfo[] RetrieveShareProperties(string[] shareList, DetectionInfo info) { List<ShareInfo> shareInfoList = new List<ShareInfo>(); string uncShare; foreach (var share in shareList) { using (Smb2Client smb2Client = new Smb2Client(new TimeSpan(0, 0, defaultTimeoutInSeconds))) { Packet_Header header; ulong messageId; ulong sessionId; Guid clientGuid; uncShare = string.Format(@"\\{0}\{1}", SUTName, share); try { NEGOTIATE_Response negotiateResp; bool encryptionRequired = false; UserLogon(info, smb2Client, out messageId, out sessionId, out clientGuid, out negotiateResp, out encryptionRequired); uint treeId; TREE_CONNECT_Response treeConnectResp; if (info.smb2Info.MaxSupportedDialectRevision == DialectRevision.Smb311) // When dialect is 3.11, TreeConnect must be signed or encrypted. { smb2Client.EnableSessionSigningAndEncryption(sessionId, true, encryptionRequired); } logWriter.AddLog(LogLevel.Information, string.Format("Client sends TreeConnect to {0} to retrieve the share properties.", uncShare)); smb2Client.TreeConnect( 1, 1, (info.smb2Info.IsRequireMessageSigning || info.smb2Info.MaxSupportedDialectRevision == DialectRevision.Smb311) ? Packet_Header_Flags_Values.FLAGS_SIGNED : Packet_Header_Flags_Values.NONE, messageId++, sessionId, uncShare, out treeId, out header, out treeConnectResp); if (header.Status != Smb2Status.STATUS_SUCCESS) continue; // When dialect is 3.11, for the messages other than TreeConnect, signing is not required. // Set it back to the configuration of the SUT. if (info.smb2Info.MaxSupportedDialectRevision == DialectRevision.Smb311) { smb2Client.EnableSessionSigningAndEncryption(sessionId, info.smb2Info.IsRequireMessageSigning, encryptionRequired); } ShareInfo shareInfo = new ShareInfo(); shareInfo.ShareName = share; shareInfo.ShareCapabilities = treeConnectResp.Capabilities; shareInfo.ShareFlags = treeConnectResp.ShareFlags; shareInfo.ShareType = treeConnectResp.ShareType; shareInfoList.Add(shareInfo); TREE_DISCONNECT_Response treeDisconnectResponse; smb2Client.TreeDisconnect( 1, 1, info.smb2Info.IsRequireMessageSigning ? Packet_Header_Flags_Values.FLAGS_SIGNED : Packet_Header_Flags_Values.NONE, messageId++, sessionId, treeId, out header, out treeDisconnectResponse); LOGOFF_Response logoffResponse; smb2Client.LogOff(1, 1, Packet_Header_Flags_Values.NONE, messageId++, sessionId, out header, out logoffResponse); } catch (Exception ex) { logWriter.AddLog(LogLevel.Information, string.Format("Exception when retrieving share properties: " + ex.Message)); // Swallow all exceptions when cleaning up. } } } return shareInfoList.ToArray(); }
/// <summary> /// Negotiate, SessionSetup, TreeConnect /// </summary> /// <returns>Return true for success, false for failure</returns> private void ConnectToShare( string sharename, DetectionInfo info, Smb2Client client, out ulong messageId, out ulong sessionId, out uint treeId) { Packet_Header header; Guid clientGuid; NEGOTIATE_Response negotiateResp; bool encryptionRequired = false; UserLogon(info, client, out messageId, out sessionId, out clientGuid, out negotiateResp, out encryptionRequired); #region TreeConnect TREE_CONNECT_Response treeConnectResp; string uncSharePath = Smb2Utility.GetUncPath(info.targetSUT, sharename); logWriter.AddLog(LogLevel.Information, "Client sends TreeConnect to server"); if (info.smb2Info.MaxSupportedDialectRevision == DialectRevision.Smb311) // When dialect is 3.11, TreeConnect must be signed or encrypted. { client.EnableSessionSigningAndEncryption(sessionId, true, encryptionRequired); } client.TreeConnect( 1, 1, (info.smb2Info.IsRequireMessageSigning || info.smb2Info.MaxSupportedDialectRevision == DialectRevision.Smb311) ? Packet_Header_Flags_Values.FLAGS_SIGNED : Packet_Header_Flags_Values.NONE, messageId++, sessionId, uncSharePath, out treeId, out header, out treeConnectResp); // When dialect is 3.11, for the messages other than TreeConnect, signing is not required. // Set it back to the configuration of the SUT. if (info.smb2Info.MaxSupportedDialectRevision == DialectRevision.Smb311) { client.EnableSessionSigningAndEncryption(sessionId, info.smb2Info.IsRequireMessageSigning, encryptionRequired); } if (header.Status != Smb2Status.STATUS_SUCCESS) { LogFailedStatus("TREECONNECT", header.Status); throw new Exception("TREECONNECT failed with " + Smb2Status.GetStatusCode(header.Status)); } #endregion }
public DetectResult CheckIOCTL_ValidateNegotiateInfo(string sharename, ref DetectionInfo info) { logWriter.AddLog(LogLevel.Information, "===== Detecting IOCTL ValidateNegotiateInfo ====="); using (Smb2Client client = new Smb2Client(new TimeSpan(0, 0, defaultTimeoutInSeconds))) { ulong messageId; ulong sessionId; uint treeId; NEGOTIATE_Response negotiateResponse; Guid clientGuid; bool encryptionRequired = false; UserLogon(info, client, out messageId, out sessionId, out clientGuid, out negotiateResponse, out encryptionRequired); #region TreeConnect TREE_CONNECT_Response treeConnectResp; string uncShare = string.Format(@"\\{0}\{1}", SUTName, sharename); Packet_Header header; logWriter.AddLog(LogLevel.Information, "Client sends TreeConnect to server"); if (info.smb2Info.MaxSupportedDialectRevision == DialectRevision.Smb311) // When dialect is 3.11, TreeConnect must be signed or encrypted. { client.EnableSessionSigningAndEncryption(sessionId, true, encryptionRequired); } client.TreeConnect( 1, 1, (info.smb2Info.IsRequireMessageSigning || info.smb2Info.MaxSupportedDialectRevision == DialectRevision.Smb311) ? Packet_Header_Flags_Values.FLAGS_SIGNED : Packet_Header_Flags_Values.NONE, messageId++, sessionId, uncShare, out treeId, out header, out treeConnectResp); if (header.Status != Smb2Status.STATUS_SUCCESS) { LogFailedStatus("TREECONNECT", header.Status); throw new Exception("TREECONNECT failed with " + Smb2Status.GetStatusCode(header.Status)); } // When dialect is 3.11, for the messages other than TreeConnect, signing is not required. // Set it back to the configuration of the SUT. if (info.smb2Info.MaxSupportedDialectRevision == DialectRevision.Smb311) { client.EnableSessionSigningAndEncryption(sessionId, info.smb2Info.IsRequireMessageSigning, encryptionRequired); } #endregion TREE_DISCONNECT_Response treeDisconnectResponse; #region IOCTL FSCTL_VALIDATE_NEGOTIATE_INFO VALIDATE_NEGOTIATE_INFO_Request validateNegotiateInfoReq; validateNegotiateInfoReq.Guid = clientGuid; validateNegotiateInfoReq.Capabilities = 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; validateNegotiateInfoReq.SecurityMode = SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED; validateNegotiateInfoReq.DialectCount = (ushort)(info.requestDialect.Length); validateNegotiateInfoReq.Dialects = info.requestDialect; byte[] inputBuffer = TypeMarshal.ToBytes <VALIDATE_NEGOTIATE_INFO_Request>(validateNegotiateInfoReq); byte[] outputBuffer; VALIDATE_NEGOTIATE_INFO_Response validateNegotiateInfoResp; IOCTL_Response ioCtlResponse; byte[] respInput = new byte[1024]; FILEID ioCtlFileId = new FILEID(); ioCtlFileId.Persistent = 0xFFFFFFFFFFFFFFFF; ioCtlFileId.Volatile = 0xFFFFFFFFFFFFFFFF; logWriter.AddLog(LogLevel.Information, "Client sends FSCTL_VALIDATE_NEGOTIATE_INFO to server"); client.IoCtl( 1, 1, info.smb2Info.IsRequireMessageSigning ? Packet_Header_Flags_Values.FLAGS_SIGNED : Packet_Header_Flags_Values.NONE, messageId++, sessionId, treeId, CtlCode_Values.FSCTL_VALIDATE_NEGOTIATE_INFO, ioCtlFileId, 0, inputBuffer, 64 * 1024, IOCTL_Request_Flags_Values.SMB2_0_IOCTL_IS_FSCTL, out respInput, out outputBuffer, out header, out ioCtlResponse, 0); DetectResult result = DetectResult.UnSupported; if (header.Status != Smb2Status.STATUS_SUCCESS) { LogFailedStatus("Validate Negotiate Information", header.Status); } else { validateNegotiateInfoResp = TypeMarshal.ToStruct <VALIDATE_NEGOTIATE_INFO_Response>(outputBuffer); if ((Capabilities_Values)negotiateResponse.Capabilities != validateNegotiateInfoResp.Capabilities) { logWriter.AddLog(LogLevel.Information, "Capabilities returned in ValidateNegotiateInfo response doesn't eaqual to server capabilities in original Negotiate response"); } if (negotiateResponse.ServerGuid != validateNegotiateInfoResp.Guid) { logWriter.AddLog(LogLevel.Information, "ServerGuid returned in ValidateNegotiateInfo response doesn't eaqual to server ServerGuid in original Negotiate response"); } if ((SecurityMode_Values)negotiateResponse.SecurityMode != validateNegotiateInfoResp.SecurityMode) { logWriter.AddLog(LogLevel.Information, "SecurityMode returned in ValidateNegotiateInfo response doesn't eaqual to server SecurityMode in original Negotiate response"); } if (negotiateResponse.DialectRevision != validateNegotiateInfoResp.Dialect) { logWriter.AddLog(LogLevel.Information, "Validation failed for dialect supported on server"); } result = DetectResult.Supported; logWriter.AddLog(LogLevel.Information, "FSCTL_VALIDATE_NEGOTIATE_INFO is supported"); } #endregion #region Tree Disconnect client.TreeDisconnect( 1, 1, info.smb2Info.IsRequireMessageSigning ? Packet_Header_Flags_Values.FLAGS_SIGNED : Packet_Header_Flags_Values.NONE, messageId++, sessionId, treeId, out header, out treeDisconnectResponse); if (header.Status != Smb2Status.STATUS_SUCCESS) { LogFailedStatus("TREEDISCONNECT", header.Status); } #endregion return(result); } }
/// <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)); }
public DetectResult CheckIOCTL_ValidateNegotiateInfo(string sharename, ref DetectionInfo info) { logWriter.AddLog(LogLevel.Information, "===== Detecting IOCTL ValidateNegotiateInfo ====="); using (Smb2Client client = new Smb2Client(new TimeSpan(0, 0, defaultTimeoutInSeconds))) { ulong messageId; ulong sessionId; uint treeId; NEGOTIATE_Response negotiateResponse; Guid clientGuid; bool encryptionRequired = false; UserLogon(info, client, out messageId, out sessionId, out clientGuid, out negotiateResponse, out encryptionRequired); #region TreeConnect TREE_CONNECT_Response treeConnectResp; string uncShare = string.Format(@"\\{0}\{1}", SUTName, sharename); Packet_Header header; logWriter.AddLog(LogLevel.Information, "Client sends TreeConnect to server"); if (info.smb2Info.MaxSupportedDialectRevision == DialectRevision.Smb311) // When dialect is 3.11, TreeConnect must be signed or encrypted. { client.EnableSessionSigningAndEncryption(sessionId, true, encryptionRequired); } client.TreeConnect( 1, 1, (info.smb2Info.IsRequireMessageSigning || info.smb2Info.MaxSupportedDialectRevision == DialectRevision.Smb311) ? Packet_Header_Flags_Values.FLAGS_SIGNED : Packet_Header_Flags_Values.NONE, messageId++, sessionId, uncShare, out treeId, out header, out treeConnectResp); if (header.Status != Smb2Status.STATUS_SUCCESS) { LogFailedStatus("TREECONNECT", header.Status); throw new Exception("TREECONNECT failed with " + Smb2Status.GetStatusCode(header.Status)); } // When dialect is 3.11, for the messages other than TreeConnect, signing is not required. // Set it back to the configuration of the SUT. if (info.smb2Info.MaxSupportedDialectRevision == DialectRevision.Smb311) { client.EnableSessionSigningAndEncryption(sessionId, info.smb2Info.IsRequireMessageSigning, encryptionRequired); } #endregion TREE_DISCONNECT_Response treeDisconnectResponse; #region IOCTL FSCTL_VALIDATE_NEGOTIATE_INFO VALIDATE_NEGOTIATE_INFO_Request validateNegotiateInfoReq; validateNegotiateInfoReq.Guid = clientGuid; validateNegotiateInfoReq.Capabilities = 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; validateNegotiateInfoReq.SecurityMode = SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED; validateNegotiateInfoReq.DialectCount = (ushort)(info.requestDialect.Length); validateNegotiateInfoReq.Dialects = info.requestDialect; byte[] inputBuffer = TypeMarshal.ToBytes<VALIDATE_NEGOTIATE_INFO_Request>(validateNegotiateInfoReq); byte[] outputBuffer; VALIDATE_NEGOTIATE_INFO_Response validateNegotiateInfoResp; IOCTL_Response ioCtlResponse; byte[] respInput = new byte[1024]; FILEID ioCtlFileId = new FILEID(); ioCtlFileId.Persistent = 0xFFFFFFFFFFFFFFFF; ioCtlFileId.Volatile = 0xFFFFFFFFFFFFFFFF; logWriter.AddLog(LogLevel.Information, "Client sends FSCTL_VALIDATE_NEGOTIATE_INFO to server"); client.IoCtl( 1, 1, info.smb2Info.IsRequireMessageSigning ? Packet_Header_Flags_Values.FLAGS_SIGNED : Packet_Header_Flags_Values.NONE, messageId++, sessionId, treeId, CtlCode_Values.FSCTL_VALIDATE_NEGOTIATE_INFO, ioCtlFileId, 0, inputBuffer, 64 * 1024, IOCTL_Request_Flags_Values.SMB2_0_IOCTL_IS_FSCTL, out respInput, out outputBuffer, out header, out ioCtlResponse, 0); DetectResult result = DetectResult.UnSupported; if (header.Status != Smb2Status.STATUS_SUCCESS) { LogFailedStatus("Validate Negotiate Information", header.Status); } else { validateNegotiateInfoResp = TypeMarshal.ToStruct<VALIDATE_NEGOTIATE_INFO_Response>(outputBuffer); if ((Capabilities_Values)negotiateResponse.Capabilities != validateNegotiateInfoResp.Capabilities) { logWriter.AddLog(LogLevel.Information, "Capabilities returned in ValidateNegotiateInfo response doesn't eaqual to server capabilities in original Negotiate response"); } if (negotiateResponse.ServerGuid != validateNegotiateInfoResp.Guid) { logWriter.AddLog(LogLevel.Information, "ServerGuid returned in ValidateNegotiateInfo response doesn't eaqual to server ServerGuid in original Negotiate response"); } if ((SecurityMode_Values)negotiateResponse.SecurityMode != validateNegotiateInfoResp.SecurityMode) { logWriter.AddLog(LogLevel.Information, "SecurityMode returned in ValidateNegotiateInfo response doesn't eaqual to server SecurityMode in original Negotiate response"); } if (negotiateResponse.DialectRevision != validateNegotiateInfoResp.Dialect) { logWriter.AddLog(LogLevel.Information, "Validation failed for dialect supported on server"); } result = DetectResult.Supported; logWriter.AddLog(LogLevel.Information, "FSCTL_VALIDATE_NEGOTIATE_INFO is supported"); } #endregion #region Tree Disconnect client.TreeDisconnect( 1, 1, info.smb2Info.IsRequireMessageSigning ? Packet_Header_Flags_Values.FLAGS_SIGNED : Packet_Header_Flags_Values.NONE, messageId++, sessionId, treeId, out header, out treeDisconnectResponse); if (header.Status != Smb2Status.STATUS_SUCCESS) { LogFailedStatus("TREEDISCONNECT", header.Status); } #endregion return result; } }