Beispiel #1
0
        public static SMB2Body CreateSMB2Body(byte[] vs, int offset, ESMB2Command eSMB2Command, SMB2HeaderFlags smb2HeaderFlags, NTStateType ntState)
        {
            SMB2Body sMB2Body = null;

            if (smb2HeaderFlags.HasFlag(SMB2HeaderFlags.ServerToRedir))
            {
                if (ntState == NTStateType.Success || ntState == NTStateType.MoreProcessingRequired || ntState == NTStateType.LogonFailure)
                {
                    switch (eSMB2Command)
                    {
                    case ESMB2Command.NEGOTIATE: sMB2Body = NegotiateResponse.Parser(vs, offset); break;

                    case ESMB2Command.SESSION_SETUP: sMB2Body = SessionSetupResponse.Parser(vs, offset); break;

                    case ESMB2Command.TREE_CONNECT: sMB2Body = TreeConnectResponse.Parser(vs, offset); break;

                    case ESMB2Command.LOGOFF:
                    case ESMB2Command.TREE_DISCONNECT: sMB2Body = LogoffAndTreeDisconnect.Parser(vs, offset); break;

                    case ESMB2Command.CREATE: sMB2Body = CreateResponse.Parser(vs, offset); break;

                    case ESMB2Command.CLOSE: sMB2Body = CloseResponse.Parser(vs, offset); break;

                    case ESMB2Command.WRITE: sMB2Body = WriteResponse.Parser(vs, offset); break;

                    case ESMB2Command.READ: sMB2Body = ReadResponse.Parser(vs, offset); break;

                    case ESMB2Command.IOCTL: sMB2Body = IOCTLResponse.Parser(vs, offset); break;

                    default: throw new Exception("UnKnow SMB2 Command");
                    }
                }
                else
                {
                    sMB2Body = ErrorResponse.Parser(vs, offset);
                }
            }
            else
            {
                throw new NotImplementedException();
            }
            return(sMB2Body);
        }
        internal static SMB2Command GetSessionSetupResponse(SessionSetupRequest request, GSSProvider securityProvider, SMB2ConnectionState state)
        {
            // [MS-SMB2] Windows [..] will also accept raw Kerberos messages and implicit NTLM messages as part of GSS authentication.
            SessionSetupResponse response = new SessionSetupResponse();

            byte[]   outputToken;
            NTStatus status = securityProvider.AcceptSecurityContext(ref state.AuthenticationContext, request.SecurityBuffer, out outputToken);

            if (status != NTStatus.STATUS_SUCCESS && status != NTStatus.SEC_I_CONTINUE_NEEDED)
            {
                string userName    = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.UserName) as string;
                string domainName  = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.DomainName) as string;
                string machineName = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.MachineName) as string;
                string osVersion   = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.OSVersion) as string;
                state.LogToServer(Severity.Information, "Session Setup: User '{0}' failed authentication (Domain: '{1}', Workstation: '{2}', OS version: '{3}'), NTStatus: {4}", userName, domainName, machineName, osVersion, status);
                return(new ErrorResponse(request.CommandName, status));
            }

            if (outputToken != null)
            {
                response.SecurityBuffer = outputToken;
            }

            // According to [MS-SMB2] 3.3.5.5.3, response.Header.SessionID must be allocated if the server returns STATUS_MORE_PROCESSING_REQUIRED
            if (request.Header.SessionID == 0)
            {
                ulong?sessionID = state.AllocateSessionID();
                if (!sessionID.HasValue)
                {
                    return(new ErrorResponse(request.CommandName, NTStatus.STATUS_TOO_MANY_SESSIONS));
                }
                response.Header.SessionID = sessionID.Value;
            }

            if (status == NTStatus.SEC_I_CONTINUE_NEEDED)
            {
                response.Header.Status = NTStatus.STATUS_MORE_PROCESSING_REQUIRED;
            }
            else // status == STATUS_SUCCESS
            {
                string userName    = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.UserName) as string;
                string domainName  = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.DomainName) as string;
                string machineName = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.MachineName) as string;
                string osVersion   = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.OSVersion) as string;
                byte[] sessionKey  = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.SessionKey) as byte[];
                object accessToken = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.AccessToken);
                bool?  isGuest     = securityProvider.GetContextAttribute(state.AuthenticationContext, GSSAttributeName.IsGuest) as bool?;
                if (!isGuest.HasValue || !isGuest.Value)
                {
                    state.LogToServer(Severity.Information, "Session Setup: User '{0}' authenticated successfully (Domain: '{1}', Workstation: '{2}', OS version: '{3}').", userName, domainName, machineName, osVersion);
                    bool        signingRequired = (request.SecurityMode & SecurityMode.SigningRequired) > 0;
                    SMB2Dialect smb2Dialect     = SMBServer.ToSMB2Dialect(state.Dialect);
                    byte[]      signingKey      = SMB2Cryptography.GenerateSigningKey(sessionKey, smb2Dialect, null);
                    state.CreateSession(request.Header.SessionID, userName, machineName, sessionKey, accessToken, signingRequired, signingKey);
                }
                else
                {
                    state.LogToServer(Severity.Information, "Session Setup: User '{0}' failed authentication (Domain: '{1}', Workstation: '{2}', OS version: '{3}'), logged in as guest.", userName, domainName, machineName, osVersion);
                    state.CreateSession(request.Header.SessionID, "Guest", machineName, sessionKey, accessToken, false, null);
                    response.SessionFlags = SessionFlags.IsGuest;
                }
            }
            return(response);
        }