Example #1
0
    async def tree_disconnect(self, tree_id):
        """
		Disconnects from tree, removes all file entries associated to the tree
		"""
        if self.session_closed == True:
            return

        command = TREE_DISCONNECT_REQ()

        header = SMB2Header_SYNC()
        header.Command = SMB2Command.TREE_DISCONNECT
        header.TreeId = tree_id
        msg = SMB2Message(header, command)
        message_id = await self.sendSMB(msg)

        rply = await self.recvSMB(message_id)

        if rply.header.Status == NTStatus.SUCCESS:
            del_file_ids = []
            share_name = self.TreeConnectTable_id[tree_id].share_name
            for fe in self.FileHandleTable:
                if self.FileHandleTable[fe].tree_id == tree_id:
                    del_file_ids.append(self.FileHandleTable[fe].file_id)

            for file_id in del_file_ids:
                del self.FileHandleTable[file_id]

            del self.TreeConnectTable_id[tree_id]
            del self.TreeConnectTable_share[share_name]
Example #2
0
    async def echo(self):
        """
		Issues an ECHO request to the server. Server will reply with and ECHO response, if it's still alive
		"""
        command = ECHO_REQ()
        header = SMB2Header_SYNC()
        header.Command = SMB2Command.ECHO
        msg = SMB2Message(header, command)
        message_id = await self.sendSMB(msg)
        rply = await self.recvSMB(message_id)
Example #3
0
    async def cancel(self, message_id):
        """
		Issues a CANCEL command for the given message_id
		"""
        command = CANCEL_REQ()
        header = SMB2Header_SYNC()
        header.Command = SMB2Command.CANCEL
        msg.header.MessageId = message_id
        msg = SMB2Message(header, command)
        message_id = await self.sendSMB(msg)
        rply = await self.recvSMB(message_id)
Example #4
0
    async def query_directory(
            self,
            tree_id,
            file_id,
            search_pattern='*',
            resume_index=0,
            information_class=FileInfoClass.FileFullDirectoryInformation,
            maxBufferSize=None,
            flags=0):
        """
		
		IMPORTANT: in case you are requesting big amounts of data, the result will arrive in chunks. You will need to invoke this function until None is returned to get the full data!!!
		"""
        if self.session_closed == True:
            return

        if tree_id not in self.TreeConnectTable_id:
            raise Exception('Unknown Tree ID!')
        if file_id not in self.FileHandleTable:
            raise Exception('Unknown File ID!')

        command = QUERY_DIRECTORY_REQ()
        command.FileInformationClass = information_class
        command.Flags = 0
        if resume_index != 0:
            command.Flags |= QueryDirectoryFlag.SMB2_INDEX_SPECIFIED
        command.FileIndex = resume_index
        command.FileId = file_id
        command.FileName = search_pattern

        header = SMB2Header_SYNC()
        header.Command = SMB2Command.QUERY_DIRECTORY
        header.TreeId = tree_id

        msg = SMB2Message(header, command)
        message_id = await self.sendSMB(msg)

        rply = await self.recvSMB(message_id)

        if rply.header.Status == NTStatus.SUCCESS:
            if information_class == FileInfoClass.FileFullDirectoryInformation:
                return FileFullDirectoryInformationList.from_bytes(
                    rply.command.Data)

            else:
                return rply.command.Data

        elif rply.header.Status == NTStatus.NO_MORE_FILES:
            return None
        else:
            raise Exception('query_directory reply: %s' % rply.header.Status)
Example #5
0
    async def logoff(self):
        """
		Logs off from the server, effectively terminates the session. 
		The underlying connection will still be active, so please either clean it up manually or dont touch this function
		For proper closing of the connection use the terminate function
		"""
        command = LOGOFF_REQ()

        header = SMB2Header_SYNC()
        header.Command = SMB2Command.LOGOFF
        msg = SMB2Message(header, command)
        message_id = await self.sendSMB(msg)

        rply = await self.recvSMB(message_id)
Example #6
0
    async def flush(tree_id, file_id):
        """
		Flushes all cached data that may be on the server for the given file.
		"""
        command = FLUSH_REQ()
        command.FileId = file_id

        header = SMB2Header_SYNC()
        header.Command = SMB2Command.FLUSH
        header.TreeId = tree_id
        msg = SMB2Message(header, command)
        message_id = await self.sendSMB(msg)

        rply = await self.recvSMB(message_id)
Example #7
0
    async def close(self, tree_id, file_id, flags=CloseFlag.NONE):
        """
		Closes the file/directory/pipe/whatever based on file_id. It will automatically remove all traces of the file handle.
		"""
        command = CLOSE_REQ()
        command.Flags = flags
        command.FileId = file_id

        header = SMB2Header_SYNC()
        header.Command = SMB2Command.CLOSE
        header.TreeId = tree_id
        msg = SMB2Message(header, command)
        message_id = await self.sendSMB(msg)

        rply = await self.recvSMB(message_id)
        if rply.header.Status == NTStatus.SUCCESS:
            del self.FileHandleTable[file_id]
Example #8
0
    async def negotiate(self):
        """
		Initiates protocol negotiation.
		First we send an SMB_COM_NEGOTIATE_REQ with our supported dialects
		"""

        #let's construct an SMBv1 SMB_COM_NEGOTIATE_REQ packet
        header = SMBHeader()
        header.Command = SMBCommand.SMB_COM_NEGOTIATE
        header.Status = NTStatus.SUCCESS
        header.Flags = 0
        header.Flags2 = SMBHeaderFlags2Enum.SMB_FLAGS2_UNICODE

        command = SMB_COM_NEGOTIATE_REQ()
        command.Dialects = ['SMB 2.???']

        msg = SMBMessage(header, command)
        message_id = await self.sendSMB(msg)
        #recieveing reply, should be version2, because currently we dont support v1 :(
        rply = await self.recvSMB(message_id)  #negotiate MessageId should be 1
        if rply.header.Status == NTStatus.SUCCESS:
            if isinstance(rply, SMB2Message):
                if rply.command.DialectRevision == NegotiateDialects.WILDCARD:
                    command = NEGOTIATE_REQ()
                    command.SecurityMode = NegotiateSecurityMode.SMB2_NEGOTIATE_SIGNING_ENABLED | NegotiateSecurityMode.SMB2_NEGOTIATE_SIGNING_REQUIRED
                    command.Capabilities = 0
                    command.ClientGuid = self.ClientGUID
                    command.Dialects = self.dialects

                    header = SMB2Header_SYNC()
                    header.Command = SMB2Command.NEGOTIATE
                    header.CreditReq = 0

                    msg = SMB2Message(header, command)
                    message_id = await self.sendSMB(msg)
                    rply = await self.recvSMB(
                        message_id)  #negotiate MessageId should be 1
                    if rply.header.Status != NTStatus.SUCCESS:
                        print('session got reply!')
                        print(rply)
                        raise Exception(
                            'session_setup_1 (authentication probably failed) reply: %s'
                            % rply.header.Status)

                if rply.command.DialectRevision not in self.supported_dialects:
                    raise SMBUnsupportedDialectSelected()

                self.selected_dialect = rply.command.DialectRevision
                self.signing_required = NegotiateSecurityMode.SMB2_NEGOTIATE_SIGNING_ENABLED in rply.command.SecurityMode
                logger.log(
                    1, 'Server selected dialect: %s' % self.selected_dialect)

                self.MaxTransactSize = min(0x100000,
                                           rply.command.MaxTransactSize)
                self.MaxReadSize = min(0x100000, rply.command.MaxReadSize)
                self.MaxWriteSize = min(0x100000, rply.command.MaxWriteSize)
                self.ServerGuid = rply.command.ServerGuid
                self.SupportsMultiChannel = NegotiateCapabilities.MULTI_CHANNEL in rply.command.Capabilities

            else:
                logger.error(
                    'Server choose SMB v1 which is not supported currently')
                raise SMBUnsupportedSMBVersion()

        else:
            print('session got reply!')
            print(rply)
            raise Exception(
                'session_setup_1 (authentication probably failed) reply: %s' %
                rply.header.Status)

        self.status = SMBConnectionStatus.SESSIONSETUP