private void DetermineSUTIPAddress(IPAddress[] ips) { using (Smb2Client client = new Smb2Client(new TimeSpan(0, 0, defaultTimeoutInSeconds))) { bool canConnect = false; foreach (var ip in ips) { canConnect = true; try { client.ConnectOverTCP(ip); } catch (Exception ex) { canConnect = false; logWriter.AddLog(LogLevel.Information, string.Format("Connect to IP {0} failed, reason: {1}", ip, ex.Message)); } if (canConnect) { this.SUTIpAddress = ip; break; } } if (!canConnect) { logWriter.AddLog(LogLevel.Error, string.Format("Can not connect to {0}.\r\nPlease check Target SUT.", SUTName)); } } }
public void SetupConnection() { smb2Client = new Smb2Client(testConfig.Timeout); smb2Client.DisableVerifySignature = this.testConfig.DisableVerifySignature; switch (testConfig.UnderlyingTransport) { case Smb2TransportType.Tcp: Site.Assert.IsTrue( testConfig.SutIPAddress != null && testConfig.SutIPAddress != System.Net.IPAddress.None, "Server IP should not be empty when transport type is TCP."); Site.Log.Add(LogEntryKind.Debug, "Connect to server {0} over TCP", testConfig.SutIPAddress.ToString()); smb2Client.ConnectOverTCP(testConfig.SutIPAddress); break; case Smb2TransportType.NetBios: Site.Assert.IsFalse(string.IsNullOrEmpty(testConfig.SutComputerName), "Server name should not be null when transport type is NetBIOS."); Site.Log.Add(LogEntryKind.Debug, "Connect to server {0} over NetBios", testConfig.SutComputerName); smb2Client.ConnectOverNetbios(testConfig.SutComputerName); break; default: Site.Assert.Fail("The transport type is {0}, but currently only Tcp and NetBIOS are supported.", testConfig.UnderlyingTransport); break; } smb2Client.Disconnected += new Action(OnServerDisconnected); messageId = 0; }
public NetworkInfo FetchLocalNetworkInfo(DetectionInfo info) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { LogIPConfig(); } //Get the network information with SUTIpList NetworkInfo networkInfo = info.networkInfo; #region Get Local IP List networkInfo.LocalIpList = new List <IPAddress>(); foreach (NetworkInterface adapter in NetworkInterface.GetAllNetworkInterfaces()) { if (adapter.OperationalStatus != OperationalStatus.Up) { continue; } if (adapter.NetworkInterfaceType == NetworkInterfaceType.Ethernet || adapter.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 || adapter.NetworkInterfaceType == NetworkInterfaceType.GigabitEthernet) { foreach (var ip in adapter.GetIPProperties().UnicastAddresses) { if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) { using (Smb2Client smb2Client = new Smb2Client(new TimeSpan(0, 0, defaultTimeoutInSeconds))) { try { smb2Client.ConnectOverTCP(SUTIpAddress, ip.Address); networkInfo.LocalIpList.Add(ip.Address); } catch (Exception ex) { logWriter.AddLog( DetectLogLevel.Information, string.Format("Connect from client IP {0} to SUT IP {1} failed, reason: {2}", ip.Address, SUTIpAddress, ex.Message)); } } } } } } if (networkInfo.LocalIpList.Count == 0) { logWriter.AddLog(DetectLogLevel.Error, "No available local IP address"); } #endregion return(networkInfo); }
private void FetchSmb2CompressionInfo(Smb2Info smb2Info) { if (smb2Info.MaxSupportedDialectRevision < DialectRevision.Smb311) { logWriter.AddLog(LogLevel.Information, "SMB dialect less than 3.1.1 does not support compression."); smb2Info.SupportedCompressionAlgorithms = new CompressionAlgorithm[0]; return; } var possibleCompressionAlogrithms = new CompressionAlgorithm[] { CompressionAlgorithm.LZ77, CompressionAlgorithm.LZ77Huffman, CompressionAlgorithm.LZNT1 }; // Iterate all possible compression algorithm for Windows will only return only one supported compression algorithm in response. var result = possibleCompressionAlogrithms.Where(compressionAlgorithm => { using (var client = new Smb2Client(new TimeSpan(0, 0, defaultTimeoutInSeconds))) { client.ConnectOverTCP(SUTIpAddress); DialectRevision selectedDialect; byte[] gssToken; Packet_Header responseHeader; NEGOTIATE_Response responsePayload; uint status = client.Negotiate( 0, 1, Packet_Header_Flags_Values.NONE, 0, new DialectRevision[] { DialectRevision.Smb311 }, SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, Capabilities_Values.NONE, Guid.NewGuid(), out selectedDialect, out gssToken, out responseHeader, out responsePayload, preauthHashAlgs: new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }, compressionAlgorithms: new CompressionAlgorithm[] { compressionAlgorithm } ); if (status == Smb2Status.STATUS_SUCCESS && client.CompressionInfo.CompressionIds.Length == 1 && client.CompressionInfo.CompressionIds[0] == compressionAlgorithm) { logWriter.AddLog(LogLevel.Information, $"Compression algorithm: {compressionAlgorithm} is supported by SUT."); return(true); } else { logWriter.AddLog(LogLevel.Information, $"Compression algorithm: {compressionAlgorithm} is not supported by SUT."); return(false); } } }); smb2Info.SupportedCompressionAlgorithms = result.ToArray(); }
public Smb2Info FetchSmb2Info(DetectionInfo info) { Smb2Info smb2Info = new Smb2Info(); using (Smb2Client smb2Client = new Smb2Client(new TimeSpan(0, 0, defaultTimeoutInSeconds))) { logWriter.AddLog(DetectLogLevel.Information, "Client connects to server"); smb2Client.ConnectOverTCP(SUTIpAddress); DialectRevision selectedDialect; byte[] gssToken; Packet_Header responseHeader; NEGOTIATE_Response responsePayload; ulong messageId = 1; logWriter.AddLog(DetectLogLevel.Information, "Client sends multi-protocol Negotiate to server"); MultiProtocolNegotiate( smb2Client, 0, 1, Packet_Header_Flags_Values.NONE, ref messageId, info.requestDialect, SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_ENCRYPTION | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES, Guid.NewGuid(), out selectedDialect, out gssToken, out responseHeader, out responsePayload); if (responseHeader.Status != Smb2Status.STATUS_SUCCESS) { LogFailedStatus("NEGOTIATE", responseHeader.Status); throw new Exception(string.Format("NEGOTIATE failed with {0}", Smb2Status.GetStatusCode(responseHeader.Status))); } smb2Info.MaxSupportedDialectRevision = responsePayload.DialectRevision; smb2Info.SupportedCapabilities = (Capabilities_Values)responsePayload.Capabilities; smb2Info.SelectedCipherID = smb2Client.SelectedCipherID; smb2Info.IsRequireMessageSigning = responsePayload.SecurityMode.HasFlag(NEGOTIATE_Response_SecurityMode_Values.NEGOTIATE_SIGNING_REQUIRED); } FetchSmb2CompressionInfo(smb2Info); FetchSmb2EncryptionInfo(smb2Info); return(smb2Info); }
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); }
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 }
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 }
public NetworkInfo FetchLocalNetworkInfo(DetectionInfo info) { LogIPConfig(); //Get the network information with SUTIpList NetworkInfo networkInfo = info.networkInfo; #region Get Local IP List networkInfo.LocalIpList = new List<IPAddress>(); foreach (NetworkInterface adapter in NetworkInterface.GetAllNetworkInterfaces()) { if (adapter.NetworkInterfaceType == NetworkInterfaceType.Ethernet || adapter.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 || adapter.NetworkInterfaceType == NetworkInterfaceType.GigabitEthernet) { foreach (var ip in adapter.GetIPProperties().UnicastAddresses) { if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) { using (Smb2Client smb2Client = new Smb2Client(new TimeSpan(0, 0, defaultTimeoutInSeconds))) { try { smb2Client.ConnectOverTCP(SUTIpAddress, ip.Address); networkInfo.LocalIpList.Add(ip.Address); } catch (Exception ex) { logWriter.AddLog( LogLevel.Information, string.Format("Connect from client IP {0} to SUT IP {1} failed, reason: {2}", ip.Address, SUTIpAddress, ex.Message)); } } } } } } if (networkInfo.LocalIpList.Count == 0) { logWriter.AddLog(LogLevel.Error, "No available local IP address"); } #endregion return networkInfo; }
public Smb2Info FetchSmb2Info(DetectionInfo info) { Smb2Info smb2Info = new Smb2Info(); using (Smb2Client smb2Client = new Smb2Client(new TimeSpan(0, 0, defaultTimeoutInSeconds))) { logWriter.AddLog(LogLevel.Information, "Client connects to server"); smb2Client.ConnectOverTCP(SUTIpAddress); DialectRevision selectedDialect; byte[] gssToken; Packet_Header responseHeader; NEGOTIATE_Response responsePayload; logWriter.AddLog(LogLevel.Information, "Client sends multi-protocol Negotiate to server"); MultiProtocolNegotiate( smb2Client, 0, 1, Packet_Header_Flags_Values.NONE, 1, info.requestDialect, SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_ENCRYPTION | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES, Guid.NewGuid(), out selectedDialect, out gssToken, out responseHeader, out responsePayload); if (responseHeader.Status != Smb2Status.STATUS_SUCCESS) { LogFailedStatus("NEGOTIATE", responseHeader.Status); throw new Exception(string.Format("NEGOTIATE failed with {0}", Smb2Status.GetStatusCode(responseHeader.Status))); } smb2Info.MaxSupportedDialectRevision = responsePayload.DialectRevision; smb2Info.SupportedCapabilities = (Capabilities_Values)responsePayload.Capabilities; smb2Info.SelectedCipherID = smb2Client.SelectedCipherID; smb2Info.IsRequireMessageSigning = responsePayload.SecurityMode.HasFlag(NEGOTIATE_Response_SecurityMode_Values.NEGOTIATE_SIGNING_REQUIRED); return smb2Info; } }
/// <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 = 1; ulong sessionId = 0; uint treeId; NEGOTIATE_Response negotiateResponse; Guid clientGuid; bool encryptionRequired = false; DialectRevision[] preferredDialects; logWriter.AddLog(LogLevel.Information, "Client connects to server"); client.ConnectOverTCP(SUTIpAddress); if (info.CheckHigherDialect(info.smb2Info.MaxSupportedDialectRevision, DialectRevision.Smb311)) { // VALIDATE_NEGOTIATE_INFO request is only used in 3.0 and 3.0.2 preferredDialects = Smb2Utility.GetDialects(DialectRevision.Smb302); } else { preferredDialects = info.requestDialect; } #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++, preferredDialects, 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 negotiateResponse); 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 #region TreeConnect TREE_CONNECT_Response treeConnectResp; string uncShare = string.Format(@"\\{0}\{1}", SUTName, sharename); logWriter.AddLog(LogLevel.Information, "Client sends TreeConnect to server"); client.TreeConnect( 1, 1, info.smb2Info.IsRequireMessageSigning ? 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)); } #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)(preferredDialects.Length); validateNegotiateInfoReq.Dialects = preferredDialects; 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; } }
private void FetchSmb2CompressionInfo(Smb2Info smb2Info) { if (smb2Info.MaxSupportedDialectRevision < DialectRevision.Smb311) { logWriter.AddLog(LogLevel.Information, "SMB dialect less than 3.1.1 does not support compression."); smb2Info.SupportedCompressionAlgorithms = new CompressionAlgorithm[0]; smb2Info.IsChainedCompressionSupported = false; return; } var allCompressionAlogrithms = Enum.GetValues(typeof(CompressionAlgorithm)).Cast <CompressionAlgorithm>().ToArray(); var possibleCompressionAlogrithms = Smb2Utility.GetSupportedPatternScanningAlgorithms(allCompressionAlogrithms).Concat(Smb2Utility.GetSupportedCompressionAlgorithms(allCompressionAlogrithms)); // Iterate all possible compression algorithm for Windows will only return only one supported compression algorithm in response. var result = possibleCompressionAlogrithms.Where(compressionAlgorithm => { using (var client = new Smb2Client(new TimeSpan(0, 0, defaultTimeoutInSeconds))) { client.ConnectOverTCP(SUTIpAddress); DialectRevision selectedDialect; byte[] gssToken; Packet_Header responseHeader; NEGOTIATE_Response responsePayload; uint status = client.Negotiate( 0, 1, Packet_Header_Flags_Values.NONE, 0, new DialectRevision[] { DialectRevision.Smb311 }, SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, Capabilities_Values.NONE, Guid.NewGuid(), out selectedDialect, out gssToken, out responseHeader, out responsePayload, preauthHashAlgs: new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }, compressionAlgorithms: new CompressionAlgorithm[] { compressionAlgorithm } ); if (status == Smb2Status.STATUS_SUCCESS && client.CompressionInfo.CompressionIds.Length == 1 && client.CompressionInfo.CompressionIds[0] == compressionAlgorithm) { logWriter.AddLog(LogLevel.Information, $"Compression algorithm: {compressionAlgorithm} is supported by SUT."); return(true); } else { logWriter.AddLog(LogLevel.Information, $"Compression algorithm: {compressionAlgorithm} is not supported by SUT."); return(false); } } }); smb2Info.SupportedCompressionAlgorithms = result.ToArray(); // Check for chained compression support using (var client = new Smb2Client(new TimeSpan(0, 0, defaultTimeoutInSeconds))) { client.ConnectOverTCP(SUTIpAddress); DialectRevision selectedDialect; byte[] gssToken; Packet_Header responseHeader; NEGOTIATE_Response responsePayload; uint status = client.Negotiate( 0, 1, Packet_Header_Flags_Values.NONE, 0, new DialectRevision[] { DialectRevision.Smb311 }, SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, Capabilities_Values.NONE, Guid.NewGuid(), out selectedDialect, out gssToken, out responseHeader, out responsePayload, preauthHashAlgs: new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }, compressionAlgorithms: possibleCompressionAlogrithms.ToArray(), compressionFlags: SMB2_COMPRESSION_CAPABILITIES_Flags.SMB2_COMPRESSION_CAPABILITIES_FLAG_CHAINED ); if (status == Smb2Status.STATUS_SUCCESS && client.CompressionInfo.SupportChainedCompression) { logWriter.AddLog(LogLevel.Information, "Chained compression is supported by SUT."); smb2Info.IsChainedCompressionSupported = true; } else { logWriter.AddLog(LogLevel.Information, "Chained compression is not supported by SUT."); smb2Info.IsChainedCompressionSupported = false; } } }
private bool DetectAP(DomainInfo domain, Server ap, KerberosDetector detector) { logWriter.AddLog(string.Format("===== Detect Application Server in Domain {0} =====", domain.Name), LogLevel.Normal); string hostname = ap.FQDN; IPAddress ip = IPAddress.Loopback; try { var hostentry = Dns.GetHostEntry(hostname); ip = hostentry.AddressList[0]; ap.IPv4 = ip.ToString(); string computerName = hostentry.HostName; string machineName = computerName.Split('.')[0]; ap.FQDN = ServerHelper.GetAccountAttribute(machineName, "Computers", "dNSHostName", domain.Name, domain.Admin, domain.AdminPassword); ap.IsWindows = detector.FetchPlatformInfo(computerName); } catch { logWriter.AddLog("Failed", LogLevel.Normal, false, LogStyle.StepFailed); logWriter.AddLineToLog(LogLevel.Advanced); return false; } if (ap.FQDN == null) { logWriter.AddLog("Failed", LogLevel.Normal, false, LogStyle.StepFailed); logWriter.AddLineToLog(LogLevel.Advanced); return false; } string[] tempArray = ap.FQDN.Split('.'); ap.ComputerName = tempArray[0]; try { ap.NetBIOS = ServerHelper.GetAccountAttribute(ap.ComputerName, "Computers", "sAMAccountName", domain.Name, domain.Admin, domain.AdminPassword);//DC01$: NetBIOS name ap.DefaultServiceName = "host/" + ap.FQDN.ToLower(); ap.ServiceSalt = domain.Name.ToUpper() + "host" + ap.FQDN.ToLower(); ap.smb2Service.SMB2ServiceName = "cifs/" + ap.FQDN.ToLower(); } catch { logWriter.AddLog("Failed", LogLevel.Normal, false, LogStyle.StepFailed); logWriter.AddLineToLog(LogLevel.Advanced); return false; } try { if (detectionInfo.HasSmbServer) { //get smb dialect Smb2Client clientForInitialOpen = new Smb2Client(new TimeSpan(0, 0, 15)); byte[] gssToken; Packet_Header header; try { clientForInitialOpen.ConnectOverTCP(ip); NEGOTIATE_Response negotiateResp; DialectRevision connection_Dialect = DialectRevision.Smb2Unknown; DialectRevision[] requestDialect = new DialectRevision[] { DialectRevision.Smb2002, DialectRevision.Smb21, DialectRevision.Smb30, DialectRevision.Smb302 }; ulong messageId = 0; uint status = clientForInitialOpen.Negotiate( 1, 1, Packet_Header_Flags_Values.NONE, messageId++, requestDialect, SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU, Guid.NewGuid(), out connection_Dialect, out gssToken, out header, out negotiateResp); if (header.Status != Smb2Status.STATUS_SUCCESS) { logWriter.AddLog("Failed", LogLevel.Normal, false, LogStyle.StepFailed); logWriter.AddLineToLog(LogLevel.Advanced); return false; } else { ap.smb2Service.SMB2Dialect = connection_Dialect.ToString(); } } catch { logWriter.AddLog("Failed", LogLevel.Normal, false, LogStyle.StepFailed); logWriter.AddLineToLog(LogLevel.Advanced); return false; } //detect smb share string[] shareList = ServerHelper.EnumShares(ap.IPv4, domain.Admin, domain.Name, domain.AdminPassword); if (shareList.Length > 0) { //only get the first one as default value //can ptftool support add more choices? for (int i = 0; i < shareList.Length; i++) { if (shareList[i].Substring(shareList[i].Length - 1, 1) != "$") { ap.smb2Service.DACShare = shareList[i]; ap.smb2Service.CBACShare = shareList[i]; break; } } } else { ap.smb2Service.DACShare = string.Empty; ap.smb2Service.CBACShare = string.Empty; } } if (detectionInfo.HasHttpServer) { //detect http server ap.httpService.HttpServiceName = "http/" + ap.FQDN.ToLower(); try { HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://" + ap.FQDN); request.Credentials = new NetworkCredential(domain.Admin + "@" + domain.Name, domain.AdminPassword); WebResponse response = request.GetResponse(); ap.httpService.Uri = response.ResponseUri.OriginalString; } catch { ap.httpService.Uri = string.Empty; } } } catch { logWriter.AddLog("Failed", LogLevel.Normal, false, LogStyle.StepFailed); logWriter.AddLineToLog(LogLevel.Advanced); return false; } logWriter.AddLog("Success", LogLevel.Normal, false, LogStyle.StepPassed); logWriter.AddLineToLog(LogLevel.Advanced); return true; }
public void ConnectToServerOverTCP(IPAddress serverIp) { client.ConnectOverTCP(serverIp); }
private void FetchSmb2EncryptionInfo(Smb2Info smb2Info) { EncryptionAlgorithm[] excludedEncryptionAlogrithms; if (smb2Info.MaxSupportedDialectRevision < DialectRevision.Smb311) { excludedEncryptionAlogrithms = new EncryptionAlgorithm[] { EncryptionAlgorithm.ENCRYPTION_NONE, EncryptionAlgorithm.ENCRYPTION_INVALID, EncryptionAlgorithm.ENCRYPTION_AES256_CCM, EncryptionAlgorithm.ENCRYPTION_AES256_GCM }; } else { excludedEncryptionAlogrithms = new EncryptionAlgorithm[] { EncryptionAlgorithm.ENCRYPTION_NONE, EncryptionAlgorithm.ENCRYPTION_INVALID }; } var possibleEncryptionAlogrithms = Enum.GetValues(typeof(EncryptionAlgorithm)).Cast <EncryptionAlgorithm>().Except(excludedEncryptionAlogrithms); logWriter.AddLog(DetectLogLevel.Information, $"Available EncryptionAlgorithms ==> {String.Join(";", possibleEncryptionAlogrithms.Select(encryptionAlgorithm => encryptionAlgorithm.ToString()))}"); // Iterate all the possible encryption algorithms since we get back only one encryption algorithm in response. var result = possibleEncryptionAlogrithms.Where(encryptionAlgorithm => { using (var client = new Smb2Client(new TimeSpan(0, 0, defaultTimeoutInSeconds))) { client.ConnectOverTCP(SUTIpAddress); DialectRevision selectedDialect; byte[] gssToken; Packet_Header responseHeader; NEGOTIATE_Response responsePayload; uint status = client.Negotiate( 0, 1, Packet_Header_Flags_Values.NONE, 0, new DialectRevision[] { DialectRevision.Smb311 }, SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, Capabilities_Values.NONE, Guid.NewGuid(), out selectedDialect, out gssToken, out responseHeader, out responsePayload, preauthHashAlgs: new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }, encryptionAlgs: new EncryptionAlgorithm[] { encryptionAlgorithm } ); if (status == Smb2Status.STATUS_SUCCESS && client.SelectedCipherID == encryptionAlgorithm) { logWriter.AddLog(DetectLogLevel.Information, $"Encryption algorithm: {encryptionAlgorithm} is supported by SUT."); return(true); } else { logWriter.AddLog(DetectLogLevel.Information, $"Encryption algorithm: {encryptionAlgorithm} is not supported by SUT."); return(false); } } }); smb2Info.SutSupportedEncryptionAlgorithms = result.ToArray(); }