From 30ce7ff79c49ed9df5ac851733deaee340b75168 Mon Sep 17 00:00:00 2001 From: Tal Aloni Date: Tue, 17 Jan 2017 21:54:49 +0200 Subject: [PATCH] Properly handle NegotiateRequest --- .../Server/ConnectionState/ConnectionState.cs | 9 ++++++ SMBLibrary/Server/SMBServer.SMB1.cs | 31 ++++++++++++++----- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/SMBLibrary/Server/ConnectionState/ConnectionState.cs b/SMBLibrary/Server/ConnectionState/ConnectionState.cs index bddbc08..1aa4be9 100644 --- a/SMBLibrary/Server/ConnectionState/ConnectionState.cs +++ b/SMBLibrary/Server/ConnectionState/ConnectionState.cs @@ -15,17 +15,25 @@ namespace SMBLibrary.Server { public delegate void LogDelegate(Severity severity, string message); + public enum SMBDialect + { + NotSet, + NTLM012, // NT LM 0.12 + } + public class ConnectionState { public Socket ClientSocket; public IPEndPoint ClientEndPoint; public NBTConnectionReceiveBuffer ReceiveBuffer; protected LogDelegate LogToServerHandler; + public SMBDialect ServerDialect; public ConnectionState(LogDelegate logToServerHandler) { ReceiveBuffer = new NBTConnectionReceiveBuffer(); LogToServerHandler = logToServerHandler; + ServerDialect = SMBDialect.NotSet; } public ConnectionState(ConnectionState state) @@ -34,6 +42,7 @@ namespace SMBLibrary.Server ClientEndPoint = state.ClientEndPoint; ReceiveBuffer = state.ReceiveBuffer; LogToServerHandler = state.LogToServerHandler; + ServerDialect = state.ServerDialect; } public void LogToServer(Severity severity, string message) diff --git a/SMBLibrary/Server/SMBServer.SMB1.cs b/SMBLibrary/Server/SMBServer.SMB1.cs index 3bf3932..e8de18a 100644 --- a/SMBLibrary/Server/SMBServer.SMB1.cs +++ b/SMBLibrary/Server/SMBServer.SMB1.cs @@ -53,25 +53,42 @@ namespace SMBLibrary.Server /// public SMB1Command ProcessSMB1Command(SMB1Header header, SMB1Command command, SMB1ConnectionState state, List sendQueue) { - if (command is NegotiateRequest) + if (state.ServerDialect == SMBDialect.NotSet) { - NegotiateRequest request = (NegotiateRequest)command; - if (request.Dialects.Contains(SMBServer.NTLanManagerDialect)) + if (command is NegotiateRequest) { - if (EnableExtendedSecurity && header.ExtendedSecurityFlag) + NegotiateRequest request = (NegotiateRequest)command; + if (request.Dialects.Contains(SMBServer.NTLanManagerDialect)) { - return NegotiateHelper.GetNegotiateResponseExtended(request, m_serverGuid); + state.ServerDialect = SMBDialect.NTLM012; + if (EnableExtendedSecurity && header.ExtendedSecurityFlag) + { + return NegotiateHelper.GetNegotiateResponseExtended(request, m_serverGuid); + } + else + { + return NegotiateHelper.GetNegotiateResponse(header, request, m_users); + } } else { - return NegotiateHelper.GetNegotiateResponse(header, request, m_users); + return new NegotiateResponseNotSupported(); } } else { - return new NegotiateResponseNotSupported(); + // [MS-CIFS] An SMB_COM_NEGOTIATE exchange MUST be completed before any other SMB messages are sent to the server + header.Status = NTStatus.STATUS_SMB_BAD_COMMAND; + return new ErrorResponse(command.CommandName); } } + else if (command is NegotiateRequest) + { + // There MUST be only one SMB_COM_NEGOTIATE exchange per SMB connection. + // Subsequent SMB_COM_NEGOTIATE requests received by the server MUST be rejected with error responses. + header.Status = NTStatus.STATUS_SMB_BAD_COMMAND; + return new ErrorResponse(command.CommandName); + } else if (command is SessionSetupAndXRequest) { SessionSetupAndXRequest request = (SessionSetupAndXRequest)command;