예제 #1
0
        internal static NegotiateResponseExtended GetNegotiateResponseExtended(NegotiateRequest request, Guid serverGuid)
        {
            NegotiateResponseExtended response = new NegotiateResponseExtended();

            response.DialectIndex  = (ushort)request.Dialects.IndexOf(SMBServer.NTLanManagerDialect);
            response.SecurityMode  = SecurityMode.UserSecurityMode | SecurityMode.EncryptPasswords;
            response.MaxMpxCount   = ServerMaxMpxCount;
            response.MaxNumberVcs  = ServerNumberVcs;
            response.MaxBufferSize = ServerMaxBufferSize;
            response.MaxRawSize    = ServerMaxRawSize;
            response.Capabilities  = Capabilities.Unicode |
                                     Capabilities.LargeFiles |
                                     Capabilities.NTSMB |
                                     Capabilities.RpcRemoteApi |
                                     Capabilities.NTStatusCode |
                                     Capabilities.NTFind |
                                     Capabilities.InfoLevelPassthrough |
                                     Capabilities.LargeRead |
                                     Capabilities.LargeWrite |
                                     Capabilities.ExtendedSecurity;
            response.SystemTime     = DateTime.UtcNow;
            response.ServerTimeZone = (short)-TimeZoneInfo.Local.GetUtcOffset(DateTime.Now).TotalMinutes;
            response.ServerGuid     = serverGuid;

            return(response);
        }
예제 #2
0
        internal static NegotiateResponse GetNegotiateResponse(SMB1Header header, NegotiateRequest request, GSSProvider securityProvider, ConnectionState state)
        {
            NegotiateResponse response = new NegotiateResponse();

            response.DialectIndex  = (ushort)request.Dialects.IndexOf(SMBServer.NTLanManagerDialect);
            response.SecurityMode  = SecurityMode.UserSecurityMode | SecurityMode.EncryptPasswords;
            response.MaxMpxCount   = 50;
            response.MaxNumberVcs  = 1;
            response.MaxBufferSize = 16644;
            response.MaxRawSize    = 65536;
            response.Capabilities  = ServerCapabilities.Unicode |
                                     ServerCapabilities.LargeFiles |
                                     ServerCapabilities.NTSMB |
                                     ServerCapabilities.NTStatusCode |
                                     ServerCapabilities.NTFind |
                                     ServerCapabilities.LargeRead |
                                     ServerCapabilities.LargeWrite;
            response.SystemTime     = DateTime.UtcNow;
            response.ServerTimeZone = (short)-TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).TotalMinutes;
            NegotiateMessage negotiateMessage = CreateNegotiateMessage();
            ChallengeMessage challengeMessage;
            NTStatus         status = securityProvider.GetNTLMChallengeMessage(out state.AuthenticationContext, negotiateMessage, out challengeMessage);

            if (status == NTStatus.SEC_I_CONTINUE_NEEDED)
            {
                response.Challenge = challengeMessage.ServerChallenge;
            }
            response.DomainName = String.Empty;
            response.ServerName = String.Empty;

            return(response);
        }
예제 #3
0
        private bool NegotiateNTLanManagerDialect()
        {
            if (m_transport == SMBTransportType.NetBiosOverTCP)
            {
                SessionRequestPacket sessionRequest = new SessionRequestPacket();
                sessionRequest.CalledName  = NetBiosUtils.GetMSNetBiosName("*SMBSERVER", NetBiosSuffix.FileServiceService);;
                sessionRequest.CallingName = NetBiosUtils.GetMSNetBiosName(Environment.MachineName, NetBiosSuffix.WorkstationService);
                TrySendPacket(m_clientSocket, sessionRequest);
            }
            NegotiateRequest request = new NegotiateRequest();

            request.Dialects.Add(NTLanManagerDialect);
            TrySendMessage(m_clientSocket, request);
            SMB1Message reply = WaitForMessage(CommandName.SMB_COM_NEGOTIATE);

            if (reply == null)
            {
                return(false);
            }

            if (reply.Commands[0] is NegotiateResponse)
            {
                NegotiateResponse response = (NegotiateResponse)reply.Commands[0];
                return(true);
            }
            else if (reply.Commands[0] is NegotiateResponseExtended)
            {
                NegotiateResponseExtended response = (NegotiateResponseExtended)reply.Commands[0];
                return(true);
            }
            else
            {
                return(false);
            }
        }
예제 #4
0
        internal static NegotiateResponseNTLM GetNegotiateResponse(SMBHeader header, NegotiateRequest request, byte[] serverChallenge)
        {
            NegotiateResponseNTLM response = new NegotiateResponseNTLM();

            response.DialectIndex  = (ushort)request.Dialects.IndexOf(SMBServer.NTLanManagerDialect);
            response.SecurityMode  = SecurityMode.UserSecurityMode | SecurityMode.EncryptPasswords;
            response.MaxMpxCount   = 50;
            response.MaxNumberVcs  = 1;
            response.MaxBufferSize = 16644;
            response.MaxRawSize    = 65536;
            response.Capabilities  = ServerCapabilities.Unicode |
                                     ServerCapabilities.LargeFiles |
                                     ServerCapabilities.NTSMB |
                                     ServerCapabilities.NTStatusCode |
                                     ServerCapabilities.NTFind |
                                     ServerCapabilities.LargeRead |
                                     ServerCapabilities.LargeWrite;
            response.SystemTime     = DateTime.UtcNow;
            response.ServerTimeZone = (short)-TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).TotalMinutes;
            response.Challenge      = serverChallenge;
            response.DomainName     = String.Empty;
            response.ServerName     = String.Empty;

            return(response);
        }
예제 #5
0
        internal static SMB2Command GetNegotiateResponse(NegotiateRequest request, GSSProvider securityProvider, ConnectionState state, Guid serverGuid, DateTime serverStartTime)
        {
            NegotiateResponse response = new NegotiateResponse();

            if (request.Dialects.Contains(SMB2Dialect.SMB210))
            {
                state.Dialect            = SMBDialect.SMB210;
                response.DialectRevision = SMB2Dialect.SMB210;
            }
            else if (request.Dialects.Contains(SMB2Dialect.SMB202))
            {
                state.Dialect            = SMBDialect.SMB202;
                response.DialectRevision = SMB2Dialect.SMB202;
            }
            else
            {
                return(new ErrorResponse(request.CommandName, NTStatus.STATUS_NOT_SUPPORTED));
            }
            response.SecurityMode    = SecurityMode.SigningEnabled;
            response.ServerGuid      = serverGuid;
            response.MaxTransactSize = 65536;
            response.MaxReadSize     = 65536;
            response.MaxWriteSize    = 65536;
            response.SystemTime      = DateTime.Now;
            response.ServerStartTime = serverStartTime;
            response.SecurityBuffer  = securityProvider.GetSPNEGOTokenInitBytes();
            return(response);
        }
예제 #6
0
        private bool NegotiateDialect()
        {
            NegotiateRequest request = new NegotiateRequest();

            request.SecurityMode    = SecurityMode.SigningEnabled;
            request.ClientGuid      = Guid.NewGuid();
            request.ClientStartTime = DateTime.Now;
            request.Dialects.Add(SMB2Dialect.SMB202);
            request.Dialects.Add(SMB2Dialect.SMB210);

            TrySendCommand(request);
            NegotiateResponse response = WaitForCommand(SMB2CommandName.Negotiate) as NegotiateResponse;

            if (response != null && response.Header.Status == NTStatus.STATUS_SUCCESS)
            {
                m_dialect         = response.DialectRevision;
                m_signingRequired = (response.SecurityMode & SecurityMode.SigningRequired) > 0;
                m_maxTransactSize = Math.Min(response.MaxTransactSize, ClientMaxTransactSize);
                m_maxReadSize     = Math.Min(response.MaxReadSize, ClientMaxReadSize);
                m_maxWriteSize    = Math.Min(response.MaxWriteSize, ClientMaxWriteSize);
                m_securityBlob    = response.SecurityBuffer;
                return(true);
            }
            return(false);
        }
예제 #7
0
        private bool NegotiateDialect(bool forceExtendedSecurity)
        {
            if (m_transport == SMBTransportType.NetBiosOverTCP)
            {
                SessionRequestPacket sessionRequest = new SessionRequestPacket();
                sessionRequest.CalledName  = NetBiosUtils.GetMSNetBiosName("*SMBSERVER", NetBiosSuffix.FileServiceService);;
                sessionRequest.CallingName = NetBiosUtils.GetMSNetBiosName(Environment.MachineName, NetBiosSuffix.WorkstationService);
                TrySendPacket(m_clientSocket, sessionRequest);
            }
            NegotiateRequest request = new NegotiateRequest();

            request.Dialects.Add(NTLanManagerDialect);

            TrySendMessage(request);
            SMB1Message reply = WaitForMessage(CommandName.SMB_COM_NEGOTIATE);

            if (reply == null)
            {
                return(false);
            }

            if (reply.Commands[0] is NegotiateResponse && !forceExtendedSecurity)
            {
                NegotiateResponse response = (NegotiateResponse)reply.Commands[0];
                m_unicode    = ((response.Capabilities & Capabilities.Unicode) > 0);
                m_largeFiles = ((response.Capabilities & Capabilities.LargeFiles) > 0);
                bool ntSMB        = ((response.Capabilities & Capabilities.NTSMB) > 0);
                bool rpc          = ((response.Capabilities & Capabilities.RpcRemoteApi) > 0);
                bool ntStatusCode = ((response.Capabilities & Capabilities.NTStatusCode) > 0);
                m_infoLevelPassthrough = ((response.Capabilities & Capabilities.InfoLevelPassthrough) > 0);
                m_largeRead            = ((response.Capabilities & Capabilities.LargeRead) > 0);
                m_largeWrite           = ((response.Capabilities & Capabilities.LargeWrite) > 0);
                m_serverMaxBufferSize  = response.MaxBufferSize;
                m_maxMpxCount          = Math.Min(response.MaxMpxCount, ClientMaxMpxCount);
                m_serverChallenge      = response.Challenge;
                return(ntSMB && rpc && ntStatusCode);
            }
            else if (reply.Commands[0] is NegotiateResponseExtended)
            {
                NegotiateResponseExtended response = (NegotiateResponseExtended)reply.Commands[0];
                m_unicode    = ((response.Capabilities & Capabilities.Unicode) > 0);
                m_largeFiles = ((response.Capabilities & Capabilities.LargeFiles) > 0);
                bool ntSMB        = ((response.Capabilities & Capabilities.NTSMB) > 0);
                bool rpc          = ((response.Capabilities & Capabilities.RpcRemoteApi) > 0);
                bool ntStatusCode = ((response.Capabilities & Capabilities.NTStatusCode) > 0);
                m_infoLevelPassthrough = ((response.Capabilities & Capabilities.InfoLevelPassthrough) > 0);
                m_largeRead            = ((response.Capabilities & Capabilities.LargeRead) > 0);
                m_largeWrite           = ((response.Capabilities & Capabilities.LargeWrite) > 0);
                m_serverMaxBufferSize  = response.MaxBufferSize;
                m_maxMpxCount          = Math.Min(response.MaxMpxCount, ClientMaxMpxCount);
                m_securityBlob         = response.SecurityBlob;
                return(ntSMB && rpc && ntStatusCode);
            }
            else
            {
                return(false);
            }
        }
        /// <summary>
        /// Update SMB_COM_NEGOTIATE request.
        /// </summary>
        /// <param name="connection">It represents the SMB connection.</param>
        /// <param name="smbRequest">It represents the SMB request.</param>
        public static void UpdateNegotiateRequest(SmbConnection connection, SmbRequest smbRequest)
        {
            NegotiateRequest req = smbRequest as NegotiateRequest;

            connection.SutSendSequenceNumber.Add(smbRequest.messageId);
            connection.sentRequest.Add(smbRequest.messageId, smbRequest);
            connection.clientSignState            = req.signState;
            connection.isNegotiateSent            = true;
            connection.isClientSupportExtSecurity = req.isSupportExtSecurity;
        }
예제 #9
0
        private bool NegotiateDialect(bool forceExtendedSecurity)
        {
            NegotiateRequest request = new NegotiateRequest();

            request.Dialects.Add(NTLanManagerDialect);

            TrySendMessage(request);
            SMB1Message reply = WaitForMessage(CommandName.SMB_COM_NEGOTIATE);

            if (reply == null)
            {
                return(false);
            }

            if (reply.Commands[0] is NegotiateResponse && !forceExtendedSecurity)
            {
                NegotiateResponse response = (NegotiateResponse)reply.Commands[0];
                Domainname = response.DomainName;
                Hostname   = response.ServerName;

                m_unicode    = ((response.Capabilities & Capabilities.Unicode) > 0);
                m_largeFiles = ((response.Capabilities & Capabilities.LargeFiles) > 0);
                bool ntSMB        = ((response.Capabilities & Capabilities.NTSMB) > 0);
                bool rpc          = ((response.Capabilities & Capabilities.RpcRemoteApi) > 0);
                bool ntStatusCode = ((response.Capabilities & Capabilities.NTStatusCode) > 0);
                m_infoLevelPassthrough = ((response.Capabilities & Capabilities.InfoLevelPassthrough) > 0);
                m_largeRead            = ((response.Capabilities & Capabilities.LargeRead) > 0);
                m_largeWrite           = ((response.Capabilities & Capabilities.LargeWrite) > 0);
                m_serverMaxBufferSize  = response.MaxBufferSize;
                m_maxMpxCount          = Math.Min(response.MaxMpxCount, ClientMaxMpxCount);
                m_serverChallenge      = response.Challenge;
                return(ntSMB && rpc && ntStatusCode);
            }
            else if (reply.Commands[0] is NegotiateResponseExtended)
            {
                NegotiateResponseExtended response = (NegotiateResponseExtended)reply.Commands[0];
                m_unicode    = ((response.Capabilities & Capabilities.Unicode) > 0);
                m_largeFiles = ((response.Capabilities & Capabilities.LargeFiles) > 0);
                bool ntSMB        = ((response.Capabilities & Capabilities.NTSMB) > 0);
                bool rpc          = ((response.Capabilities & Capabilities.RpcRemoteApi) > 0);
                bool ntStatusCode = ((response.Capabilities & Capabilities.NTStatusCode) > 0);
                m_infoLevelPassthrough = ((response.Capabilities & Capabilities.InfoLevelPassthrough) > 0);
                m_largeRead            = ((response.Capabilities & Capabilities.LargeRead) > 0);
                m_largeWrite           = ((response.Capabilities & Capabilities.LargeWrite) > 0);
                m_serverMaxBufferSize  = response.MaxBufferSize;
                m_maxMpxCount          = Math.Min(response.MaxMpxCount, ClientMaxMpxCount);
                m_securityBlob         = response.SecurityBlob;
                return(ntSMB && rpc && ntStatusCode);
            }
            else
            {
                return(false);
            }
        }
예제 #10
0
        internal static SMB2Command GetNegotiateResponse(NegotiateRequest request, GSSProvider securityProvider, ConnectionState state, SMBTransportType transportType, Guid serverGuid, DateTime serverStartTime, bool enableSMB3)
        {
            NegotiateResponse response = new NegotiateResponse();

            if (enableSMB3 && request.Dialects.Contains(SMB2Dialect.SMB300))
            {
                state.Dialect            = SMBDialect.SMB300;
                response.DialectRevision = SMB2Dialect.SMB300;
            }
            else if (request.Dialects.Contains(SMB2Dialect.SMB210))
            {
                state.Dialect            = SMBDialect.SMB210;
                response.DialectRevision = SMB2Dialect.SMB210;
            }
            else if (request.Dialects.Contains(SMB2Dialect.SMB202))
            {
                state.Dialect            = SMBDialect.SMB202;
                response.DialectRevision = SMB2Dialect.SMB202;
            }
            else
            {
                state.LogToServer(Severity.Verbose, "Negotiate failure: None of the requested SMB2 dialects is supported");
                return(new ErrorResponse(request.CommandName, NTStatus.STATUS_NOT_SUPPORTED));
            }
            response.SecurityMode = SecurityMode.SigningEnabled;
            response.ServerGuid   = serverGuid;
            if (state.Dialect != SMBDialect.SMB202 && transportType == SMBTransportType.DirectTCPTransport)
            {
                response.Capabilities    = Capabilities.LargeMTU;
                response.MaxTransactSize = ServerMaxTransactSizeLargeMTU;
                response.MaxReadSize     = ServerMaxReadSizeLargeMTU;
                response.MaxWriteSize    = ServerMaxWriteSizeLargeMTU;
                // [MS-SMB2] 3.3.5.2 Receiving Any Message - If the length of the message exceeds Connection.MaxTransactSize + 256, the server MUST disconnect the connection.
                int maxPacketSize = SessionPacket.HeaderLength + (int)ServerMaxTransactSizeLargeMTU + 256;
                if (maxPacketSize > state.ReceiveBuffer.Buffer.Length)
                {
                    state.ReceiveBuffer.IncreaseBufferSize(maxPacketSize);
                }
            }
            else
            {
                response.MaxTransactSize = ServerMaxTransactSize;
                response.MaxReadSize     = ServerMaxReadSize;
                response.MaxWriteSize    = ServerMaxWriteSize;
            }
            response.SystemTime      = DateTime.Now;
            response.ServerStartTime = serverStartTime;
            response.SecurityBuffer  = securityProvider.GetSPNEGOTokenInitBytes();
            return(response);
        }
예제 #11
0
        private bool NegotiateDialect(bool forceExtendedSecurity)
        {
            NegotiateRequest request = new NegotiateRequest();

            request.Dialects.Add(NTLanManagerDialect);

            SendMessage(request);
            SMB1Message reply = WaitForMessage(CommandName.SMB_COM_NEGOTIATE);

            switch (reply.Commands[0])
            {
            case NegotiateResponse negotiateResponse when !forceExtendedSecurity:
            {
                m_unicode    = ((negotiateResponse.Capabilities & Capabilities.Unicode) > 0);
                m_largeFiles = ((negotiateResponse.Capabilities & Capabilities.LargeFiles) > 0);
                bool ntSMB        = ((negotiateResponse.Capabilities & Capabilities.NTSMB) > 0);
                bool rpc          = ((negotiateResponse.Capabilities & Capabilities.RpcRemoteApi) > 0);
                bool ntStatusCode = ((negotiateResponse.Capabilities & Capabilities.NTStatusCode) > 0);
                m_infoLevelPassthrough = ((negotiateResponse.Capabilities & Capabilities.InfoLevelPassthrough) > 0);
                m_largeRead            = ((negotiateResponse.Capabilities & Capabilities.LargeRead) > 0);
                m_largeWrite           = ((negotiateResponse.Capabilities & Capabilities.LargeWrite) > 0);
                m_serverMaxBufferSize  = negotiateResponse.MaxBufferSize;
                m_maxMpxCount          = Math.Min(negotiateResponse.MaxMpxCount, ClientMaxMpxCount);
                m_serverChallenge      = negotiateResponse.Challenge;
                return(ntSMB && rpc && ntStatusCode);
            }

            case NegotiateResponseExtended response:
            {
                m_unicode    = ((response.Capabilities & Capabilities.Unicode) > 0);
                m_largeFiles = ((response.Capabilities & Capabilities.LargeFiles) > 0);
                bool ntSMB        = ((response.Capabilities & Capabilities.NTSMB) > 0);
                bool rpc          = ((response.Capabilities & Capabilities.RpcRemoteApi) > 0);
                bool ntStatusCode = ((response.Capabilities & Capabilities.NTStatusCode) > 0);
                m_infoLevelPassthrough = ((response.Capabilities & Capabilities.InfoLevelPassthrough) > 0);
                m_largeRead            = ((response.Capabilities & Capabilities.LargeRead) > 0);
                m_largeWrite           = ((response.Capabilities & Capabilities.LargeWrite) > 0);
                m_serverMaxBufferSize  = response.MaxBufferSize;
                m_maxMpxCount          = Math.Min(response.MaxMpxCount, ClientMaxMpxCount);
                m_securityBlob         = response.SecurityBlob;
                return(ntSMB && rpc && ntStatusCode);
            }

            default:
                return(false);
            }
        }
예제 #12
0
 /// <summary>
 /// May return an empty list
 /// </summary>
 private List <SMB1Command> ProcessSMB1Command(SMB1Header header, SMB1Command command, ref ConnectionState state)
 {
     if (state.Dialect == SMBDialect.NotSet)
     {
         if (command is NegotiateRequest)
         {
             NegotiateRequest request = (NegotiateRequest)command;
             if (request.Dialects.Contains(SMBServer.NTLanManagerDialect))
             {
                 state         = new SMB1ConnectionState(state);
                 state.Dialect = SMBDialect.NTLM012;
                 m_connectionManager.AddConnection(state);
                 if (EnableExtendedSecurity && header.ExtendedSecurityFlag)
                 {
                     return(NegotiateHelper.GetNegotiateResponseExtended(request, m_serverGuid));
                 }
                 else
                 {
                     return(NegotiateHelper.GetNegotiateResponse(header, request, m_securityProvider, state));
                 }
             }
             else
             {
                 return(new NegotiateResponseNotSupported());
             }
         }
         else
         {
             // [MS-CIFS] An SMB_COM_NEGOTIATE exchange MUST be completed before any other SMB messages are sent to the server
             header.Status = NTStatus.STATUS_INVALID_SMB;
             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_INVALID_SMB;
         return(new ErrorResponse(command.CommandName));
     }
     else
     {
         return(ProcessSMB1Command(header, command, (SMB1ConnectionState)state));
     }
 }
예제 #13
0
        public SMBClient(IPAddress serverAddress, SMBTransportType transport)
        {
            NegotiateRequest request = new NegotiateRequest();

            request.Dialects.Add(NTLanManagerDialect);

            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            if (transport == SMBTransportType.DirectTCPTransport)
            {
                serverSocket.Connect(serverAddress, DirectTCPPort);
            }
            else
            {
                serverSocket.Connect(serverAddress, NetBiosOverTCPPort);
            }
            TrySendMessage(serverSocket, request);
        }
예제 #14
0
 /// <summary>
 /// May return null
 /// </summary>
 private SMB2Command ProcessSMB2Command(SMB2Command command, ref ConnectionState state)
 {
     if (state.Dialect == SMBDialect.NotSet)
     {
         if (command is NegotiateRequest)
         {
             NegotiateRequest request  = (NegotiateRequest)command;
             SMB2Command      response = NegotiateHelper.GetNegotiateResponse(request, m_securityProvider, state, m_transport, m_serverGuid, m_serverStartTime, m_enableSMB3);
             if (state.Dialect != SMBDialect.NotSet)
             {
                 state = new SMB2ConnectionState(state);
                 m_connectionManager.AddConnection(state);
             }
             return(response);
         }
         else
         {
             // [MS-SMB2] If the request being received is not an SMB2 NEGOTIATE Request [..]
             // and Connection.NegotiateDialect is 0xFFFF or 0x02FF, the server MUST
             // disconnect the connection.
             state.LogToServer(Severity.Debug, "Invalid Connection State for command {0}", command.CommandName.ToString());
             state.ClientSocket.Close();
             return(null);
         }
     }
     else if (command is NegotiateRequest)
     {
         // [MS-SMB2] If Connection.NegotiateDialect is 0x0202, 0x0210, 0x0300, 0x0302, or 0x0311,
         // the server MUST disconnect the connection.
         state.LogToServer(Severity.Debug, "Rejecting NegotiateRequest. NegotiateDialect is already set");
         state.ClientSocket.Close();
         return(null);
     }
     else
     {
         return(ProcessSMB2Command(command, (SMB2ConnectionState)state));
     }
 }
예제 #15
0
        internal static NegotiateResponseExtended GetNegotiateResponseExtended(NegotiateRequest request, Guid serverGuid)
        {
            NegotiateResponseExtended response = new NegotiateResponseExtended();

            response.DialectIndex  = (ushort)request.Dialects.IndexOf(SMBServer.NTLanManagerDialect);
            response.SecurityMode  = SecurityMode.UserSecurityMode | SecurityMode.EncryptPasswords;
            response.MaxMpxCount   = 50;
            response.MaxNumberVcs  = 1;
            response.MaxBufferSize = 16644;
            response.MaxRawSize    = 65536;
            response.Capabilities  = ServerCapabilities.Unicode |
                                     ServerCapabilities.LargeFiles |
                                     ServerCapabilities.NTSMB |
                                     ServerCapabilities.NTStatusCode |
                                     ServerCapabilities.NTFind |
                                     ServerCapabilities.LargeRead |
                                     ServerCapabilities.LargeWrite |
                                     ServerCapabilities.ExtendedSecurity;
            response.SystemTime     = DateTime.UtcNow;
            response.ServerTimeZone = (short)-TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).TotalMinutes;
            response.ServerGuid     = serverGuid;

            return(response);
        }
예제 #16
0
        public void Negotiate()
        {
            if (IsConnectd)
            {
                throw new Exception("Repeat Negotiate");
            }
            ulong       mid         = (ulong)Interlocked.Increment(ref MessageId);
            SMB2Header  smb2Header  = new SMB2Header(ESMB2Command.NEGOTIATE, SMB2HeaderFlags.None, mid, 0, 0);
            SMB2Body    smb2Body    = new NegotiateRequest(ESecurityMode.SMB2_NEGOTIATE_SIGNING_ENABLED, Guid.NewGuid());
            SMB2Message smb2Message = new SMB2Message(smb2Header, smb2Body);

            SMBTransport.SendDatas(smb2Message.DumpBinary());

            var sm = GetMessage(mid);

            if (sm.SMB2Header.Status == 0)
            {
                IsConnectd = true;
            }
            else
            {
                throw new Exception("Negotiate Status error:" + sm.SMB2Header.Status);
            }
        }
예제 #17
0
        /// <summary>
        /// May return null
        /// </summary>
        public SMBCommand ProcessCommand(SMBHeader header, SMBCommand command, StateObject state, List <SMBCommand> sendQueue)
        {
            if (command is NegotiateRequest)
            {
                NegotiateRequest request = (NegotiateRequest)command;
                if (request.Dialects.Contains(SMBServer.NTLanManagerDialect))
                {
                    if (EnableExtendedSecurity && header.ExtendedSecurityFlag)
                    {
                        return(NegotiateHelper.GetNegotiateResponseExtended(request, m_serverGuid));
                    }
                    else
                    {
                        return(new NegotiateResponseNotSupported());
                    }
                }
                else
                {
                    return(new NegotiateResponseNotSupported());
                }
            }
            else if (command is SessionSetupAndXRequest)
            {
                SessionSetupAndXRequest request = (SessionSetupAndXRequest)command;
                state.MaxBufferSize = request.MaxBufferSize;
                //this probably won't work
                return(NegotiateHelper.GetSessionSetupResponse(header, request, state));
            }
            else if (command is SessionSetupAndXRequestExtended)
            {
                SessionSetupAndXRequestExtended request = (SessionSetupAndXRequestExtended)command;
                state.MaxBufferSize = request.MaxBufferSize;
                return(NegotiateHelper.GetSessionSetupResponseExtended(header, request, state));
            }
            else if (command is EchoRequest)
            {
                return(ServerResponseHelper.GetEchoResponse((EchoRequest)command, sendQueue));
            }
            else if (state.IsAuthenticated(header.UID))
            {
                if (command is TreeConnectAndXRequest)
                {
                    TreeConnectAndXRequest request = (TreeConnectAndXRequest)command;
                    return(TreeConnectHelper.GetTreeConnectResponse(header, request, state, m_shares));
                }
                else if (command is LogoffAndXRequest)
                {
                    return(new LogoffAndXResponse());
                }
                else if (state.IsTreeConnected(header.TID))
                {
                    string rootPath = state.GetConnectedTreePath(header.TID);
                    object share;
                    if (state.IsIPC(header.TID))
                    {
                        share = m_services;
                    }
                    else
                    {
                        share = m_shares.GetShareFromRelativePath(rootPath);
                    }

                    if (command is CreateDirectoryRequest)
                    {
                        if (!(share is FileSystemShare))
                        {
                            header.Status = NTStatus.STATUS_SMB_BAD_COMMAND;
                            return(new ErrorResponse(command.CommandName));
                        }
                        CreateDirectoryRequest request = (CreateDirectoryRequest)command;
                        return(FileSystemResponseHelper.GetCreateDirectoryResponse(header, request, (FileSystemShare)share, state));
                    }
                    else if (command is DeleteDirectoryRequest)
                    {
                        if (!(share is FileSystemShare))
                        {
                            header.Status = NTStatus.STATUS_SMB_BAD_COMMAND;
                            return(new ErrorResponse(command.CommandName));
                        }
                        DeleteDirectoryRequest request = (DeleteDirectoryRequest)command;
                        return(FileSystemResponseHelper.GetDeleteDirectoryResponse(header, request, (FileSystemShare)share, state));
                    }
                    else if (command is CloseRequest)
                    {
                        CloseRequest request = (CloseRequest)command;
                        return(ServerResponseHelper.GetCloseResponse(header, request, state));
                    }
                    else if (command is FlushRequest)
                    {
                        return(new FlushResponse());
                    }
                    else if (command is DeleteRequest)
                    {
                        if (!(share is FileSystemShare))
                        {
                            header.Status = NTStatus.STATUS_SMB_BAD_COMMAND;
                            return(new ErrorResponse(command.CommandName));
                        }
                        DeleteRequest request = (DeleteRequest)command;
                        return(FileSystemResponseHelper.GetDeleteResponse(header, request, (FileSystemShare)share, state));
                    }
                    else if (command is RenameRequest)
                    {
                        if (!(share is FileSystemShare))
                        {
                            header.Status = NTStatus.STATUS_SMB_BAD_COMMAND;
                            return(new ErrorResponse(command.CommandName));
                        }
                        RenameRequest request = (RenameRequest)command;
                        return(FileSystemResponseHelper.GetRenameResponse(header, request, (FileSystemShare)share, state));
                    }
                    else if (command is QueryInformationRequest)
                    {
                        if (!(share is FileSystemShare))
                        {
                            header.Status = NTStatus.STATUS_SMB_BAD_COMMAND;
                            return(new ErrorResponse(command.CommandName));
                        }
                        QueryInformationRequest request = (QueryInformationRequest)command;
                        return(FileSystemResponseHelper.GetQueryInformationResponse(header, request, (FileSystemShare)share));
                    }
                    else if (command is SetInformationRequest)
                    {
                        if (!(share is FileSystemShare))
                        {
                            header.Status = NTStatus.STATUS_SMB_BAD_COMMAND;
                            return(new ErrorResponse(command.CommandName));
                        }
                        SetInformationRequest request = (SetInformationRequest)command;
                        return(FileSystemResponseHelper.GetSetInformationResponse(header, request, (FileSystemShare)share, state));
                    }
                    else if (command is ReadRequest)
                    {
                        ReadRequest request = (ReadRequest)command;
                        return(ReadWriteResponseHelper.GetReadResponse(header, request, share, state));
                    }
                    else if (command is WriteRequest)
                    {
                        string userName = state.GetConnectedUserName(header.UID);
                        if (share is FileSystemShare && !((FileSystemShare)share).HasWriteAccess(userName))
                        {
                            header.Status = NTStatus.STATUS_ACCESS_DENIED;
                            return(new ErrorResponse(command.CommandName));
                        }
                        WriteRequest request = (WriteRequest)command;
                        return(ReadWriteResponseHelper.GetWriteResponse(header, request, share, state));
                    }
                    else if (command is CheckDirectoryRequest)
                    {
                        if (!(share is FileSystemShare))
                        {
                            header.Status = NTStatus.STATUS_SMB_BAD_COMMAND;
                            return(new ErrorResponse(command.CommandName));
                        }
                        CheckDirectoryRequest request = (CheckDirectoryRequest)command;
                        return(FileSystemResponseHelper.GetCheckDirectoryResponse(header, request, (FileSystemShare)share));
                    }
                    else if (command is WriteRawRequest)
                    {
                        // [MS-CIFS] 3.3.5.26 - Receiving an SMB_COM_WRITE_RAW Request:
                        // the server MUST verify that the Server.Capabilities include CAP_RAW_MODE,
                        // If an error is detected [..] the Write Raw operation MUST fail and
                        // the server MUST return a Final Server Response [..] with the Count field set to zero.
                        return(new WriteRawFinalResponse());
                    }
                    else if (command is SetInformation2Request)
                    {
                        if (!(share is FileSystemShare))
                        {
                            header.Status = NTStatus.STATUS_SMB_BAD_COMMAND;
                            return(new ErrorResponse(command.CommandName));
                        }
                        SetInformation2Request request = (SetInformation2Request)command;
                        return(FileSystemResponseHelper.GetSetInformation2Response(header, request, (FileSystemShare)share, state));
                    }
                    else if (command is LockingAndXRequest)
                    {
                        header.Status = NTStatus.STATUS_ACCESS_DENIED;
                        return(new ErrorResponse(CommandName.SMB_COM_LOCKING_ANDX));
                    }
                    else if (command is OpenAndXRequest)
                    {
                        OpenAndXRequest request = (OpenAndXRequest)command;
                        return(OpenAndXHelper.GetOpenAndXResponse(header, request, share, state));
                    }
                    else if (command is ReadAndXRequest)
                    {
                        ReadAndXRequest request = (ReadAndXRequest)command;
                        return(ReadWriteResponseHelper.GetReadResponse(header, request, share, state));
                    }
                    else if (command is WriteAndXRequest)
                    {
                        string userName = state.GetConnectedUserName(header.UID);
                        if (share is FileSystemShare && !((FileSystemShare)share).HasWriteAccess(userName))
                        {
                            header.Status = NTStatus.STATUS_ACCESS_DENIED;
                            return(new ErrorResponse(command.CommandName));
                        }
                        WriteAndXRequest request = (WriteAndXRequest)command;
                        return(ReadWriteResponseHelper.GetWriteResponse(header, request, share, state));
                    }
                    else if (command is FindClose2Request)
                    {
                        return(ServerResponseHelper.GetFindClose2Request(header, (FindClose2Request)command, state));
                    }
                    else if (command is TreeDisconnectRequest)
                    {
                        TreeDisconnectRequest request = (TreeDisconnectRequest)command;
                        return(TreeConnectHelper.GetTreeDisconnectResponse(header, request, state));
                    }
                    else if (command is TransactionRequest) // Both TransactionRequest and Transaction2Request
                    {
                        TransactionRequest request = (TransactionRequest)command;
                        try
                        {
                            return(TransactionHelper.GetTransactionResponse(header, request, share, state, sendQueue));
                        }
                        catch (UnsupportedInformationLevelException)
                        {
                            header.Status = NTStatus.STATUS_INVALID_PARAMETER;
                            return(new ErrorResponse(command.CommandName));
                        }
                    }
                    else if (command is TransactionSecondaryRequest) // Both TransactionSecondaryRequest and Transaction2SecondaryRequest
                    {
                        TransactionSecondaryRequest request = (TransactionSecondaryRequest)command;
                        try
                        {
                            return(TransactionHelper.GetTransactionResponse(header, request, share, state, sendQueue));
                        }
                        catch (UnsupportedInformationLevelException)
                        {
                            header.Status = NTStatus.STATUS_INVALID_PARAMETER;
                            return(new ErrorResponse(command.CommandName));
                        }
                    }
                    else if (command is NTTransactRequest)
                    {
                        NTTransactRequest request = (NTTransactRequest)command;
                        return(NTTransactHelper.GetNTTransactResponse(header, request, share, state, sendQueue));
                    }
                    else if (command is NTTransactSecondaryRequest)
                    {
                        NTTransactSecondaryRequest request = (NTTransactSecondaryRequest)command;
                        return(NTTransactHelper.GetNTTransactResponse(header, request, share, state, sendQueue));
                    }
                    else if (command is NTCreateAndXRequest)
                    {
                        NTCreateAndXRequest request = (NTCreateAndXRequest)command;
                        return(NTCreateHelper.GetNTCreateResponse(header, request, share, state));
                    }
                }
                else
                {
                    header.Status = NTStatus.STATUS_SMB_BAD_TID;
                    return(new ErrorResponse(command.CommandName));
                }
            }

            header.Status = NTStatus.STATUS_SMB_BAD_COMMAND;
            return(new ErrorResponse(command.CommandName));
        }
예제 #18
0
        public static void NegotiateResponse(ModelSmb2Status status, DialectRevision dialectRevision)
        {
            Condition.IsTrue(State == ModelState.Connected);
            Condition.IsTrue(Request is ModelComNegotiateRequest || Request is NegotiateRequest);

            // Avoid "Microsoft.SpecExplorer.Runtime.Testing.UnboundVariableException: Variable's value cannot be read before it is bound"
            Condition.IsTrue(dialectRevision == DialectRevision.Smb2002 || dialectRevision == DialectRevision.Smb21 ||
                             dialectRevision == DialectRevision.Smb30 || dialectRevision == DialectRevision.Smb302 ||
                             dialectRevision == DialectRevision.Smb2Wildcard ||
                             dialectRevision == DialectRevision.Smb2Unknown);

            if (Request is ModelComNegotiateRequest)
            {
                ModelComNegotiateRequest comNegotiateReq = ModelHelper.RetrieveOutstandingRequest <ModelComNegotiateRequest>(ref Request);

                if (Config.MaxSmbVersionSupported != DialectRevision.Smb21 && !ModelUtility.IsSmb3xFamily(Config.MaxSmbVersionSupported))
                {
                    ModelHelper.Log(
                        LogType.Requirement,
                        "3.3.5.3.1: If the server does not implement the SMB 2.1 or 3.x dialect family, processing MUST continue as specified in 3.3.5.3.2.");

                    ComNegotiateHandleSmb2002InResponse(dialectRevision);
                }
                else
                {
                    ModelHelper.Log(
                        LogType.Requirement,
                        "3.3.5.3.1: Otherwise, the server MUST scan the dialects provided for the dialect string \"SMB 2.???\".");

                    if (comNegotiateReq.Dialects.Contains(SMBDialects.SMB_2_X))
                    {
                        ModelHelper.Log(
                            LogType.Requirement,
                            "3.3.5.3.1: If the string is present, the server MUST respond with an SMB2 NEGOTIATE Response as specified in 2.2.4.");

                        ModelHelper.Log(
                            LogType.Requirement,
                            "3.3.5.3.1: DialectRevision MUST be set to 0x02FF");

                        NegotiateDialect = DialectRevision.Smb2Wildcard;

                        ModelHelper.Log(
                            LogType.Requirement,
                            "3.3.5.3.1: Connection.NegotiateDialect MUST be set to 0x02FF, and the response is sent to the client");

                        Condition.IsTrue(dialectRevision == DialectRevision.Smb2Wildcard);
                    }
                    else
                    {
                        ModelHelper.Log(
                            LogType.Requirement,
                            "3.3.5.3.1: If the string is not present, continue to section 3.3.5.3.2");

                        ComNegotiateHandleSmb2002InResponse(dialectRevision);
                    }
                }
            }
            else
            {
                NegotiateRequest negotiateReq = ModelHelper.RetrieveOutstandingRequest <NegotiateRequest>(ref Request);

                if (negotiateReq.Dialects.Count == 0)
                {
                    ModelHelper.Log(
                        LogType.Requirement,
                        "3.3.5.4: If the DialectCount of the SMB2 NEGOTIATE Request is 0, the server MUST fail the request with STATUS_INVALID_PARAMETER");
                    ModelHelper.Log(
                        LogType.TestInfo,
                        "DialectCount of the SMB2 NEGOTIATE Request is 0");
                    ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedFields);
                    Condition.IsTrue(status == ModelSmb2Status.STATUS_INVALID_PARAMETER);
                    return;
                }

                ModelHelper.Log(
                    LogType.Requirement,
                    "3.3.5.4: The server MUST select the greatest common dialect between the dialects it implements and the Dialects array of the SMB2 NEGOTIATE request");

                DialectRevision commonDialect = SelectCommonDialect(negotiateReq.Dialects);

                ModelHelper.Log(
                    LogType.TestInfo,
                    "Common dialect is {0}", commonDialect);
                if (commonDialect == DialectRevision.Smb2Unknown)
                {
                    ModelHelper.Log(
                        LogType.Requirement,
                        "3.3.5.4: If a common dialect is not found, the server MUST fail the request with STATUS_NOT_SUPPORTED");
                    ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedFields);
                    Condition.IsTrue(status == ModelSmb2Status.STATUS_NOT_SUPPORTED);
                    return;
                }

                ModelHelper.Log(
                    LogType.Requirement,
                    "3.3.5.4: If a common dialect is found, the server MUST set Connection.Dialect to \"2.002\", \"2.100\", \"3.000\", or \"3.002\"," +
                    " and Connection.NegotiateDialect to 0x0202, 0x0210, 0x0300, or 0x0302 accordingly, to reflect the dialect selected");

                NegotiateDialect = commonDialect;

                ModelHelper.Log(
                    LogType.TestInfo,
                    "Connection.Dialect is set to {0}", NegotiateDialect);

                ModelHelper.Log(
                    LogType.Requirement,
                    "3.3.5.4: The server MUST then construct an SMB2 NEGOTIATE Response, as specified in section 2.2.4, with the following specific values, and return STATUS_SUCCESS to the client.");
                ModelHelper.Log(
                    LogType.Requirement,
                    "\tDialectRevision MUST be set to the common dialect");

                Condition.IsTrue(dialectRevision == commonDialect);
            }

            Condition.IsTrue(status == Smb2Status.STATUS_SUCCESS);
        }