Exemplo n.º 1
0
    async def __handle_smb_in(self):
        """
		Waits from SMB messages from the NetBIOSTransport in_queue, and fills the connection table.
		This function started automatically when calling connect.
		"""
        while not self.shutdown_evt.is_set():
            msg = await self.netbios_transport.in_queue.get()

            logger.log(
                1, '__handle_smb_in got new message with Id %s' %
                msg.header.MessageId)

            if isinstance(msg, SMB2Transform):
                #message is encrypted
                #this point we should decrypt it and only store the decrypted part in the OutstandingResponses table
                #but for now we just thropw exception bc encryption is not implemented
                raise Exception(
                    'Encrypted SMBv2 message recieved, but encryption is not yet supported!'
                )

            self.OutstandingResponses[msg.header.MessageId] = msg
            if msg.header.MessageId in self.OutstandingResponsesEvent:
                self.OutstandingResponsesEvent[msg.header.MessageId].set()
            else:
                #here we are loosing messages, the functionality for "PENDING" and "SHARING_VIOLATION" should be written
                continue
Exemplo n.º 2
0
    async def __handle_smb_in(self):
        """
		Waits from SMB messages from the NetBIOSTransport in_queue, and fills the connection table.
		This function started automatically when calling connect.
		"""
        try:
            while True:
                msg, err = await self.netbios_transport.in_queue.get()
                self.activity_at = datetime.datetime.utcnow()
                if err is not None:
                    logger.error(
                        '__handle_smb_in got error from transport layer %s' %
                        err)
                    #setting all outstanding events to finished
                    for mid in self.OutstandingResponsesEvent:
                        self.OutstandingResponses[mid] = None
                        self.OutstandingResponsesEvent[mid].set()

                    await self.terminate()
                    return

                logger.log(
                    1, '__handle_smb_in got new message with Id %s' %
                    msg.header.MessageId)

                if isinstance(msg, SMB2Transform):
                    #message is encrypted
                    #this point we should decrypt it and only store the decrypted part in the OutstandingResponses table
                    #but for now we just thropw exception bc encryption is not implemented
                    raise Exception(
                        'Encrypted SMBv2 message recieved, but encryption is not yet supported!'
                    )

                if msg.header.Status == NTStatus.PENDING:
                    self.pending_table[msg.header.MessageId] = SMBPendingMsg(
                        msg.header.MessageId, self.OutstandingResponses,
                        self.OutstandingResponsesEvent)
                    await self.pending_table[msg.header.MessageId].run()
                    continue

                if msg.header.MessageId in self.pending_table:
                    await self.pending_table[msg.header.MessageId].stop()
                    del self.pending_table[msg.header.MessageId]

                self.OutstandingResponses[msg.header.MessageId] = msg
                if msg.header.MessageId in self.OutstandingResponsesEvent:
                    self.OutstandingResponsesEvent[msg.header.MessageId].set()
                else:

                    #here we are loosing messages, the functionality for "PENDING" and "SHARING_VIOLATION" should be implemented
                    continue
        except asyncio.CancelledError:
            #the SMB connection is terminating
            return
        except:
            logger.exception('__handle_smb_in')
Exemplo n.º 3
0
    async def recvSMB(self, message_id):
        """
		Returns an SMB message from the outstandingresponse dict, OR waits until the expected message_id appears.
		"""
        if message_id not in self.OutstandingResponses:
            logger.log(1, 'Waiting on messageID : %s' % message_id)
            await self.OutstandingResponsesEvent[message_id].wait()

        msg = self.OutstandingResponses.pop(message_id)

        if msg.header.Status != NTStatus.PENDING:
            if message_id in self.OutstandingResponsesEvent:
                del self.OutstandingResponsesEvent[message_id]
        else:
            self.OutstandingResponsesEvent[message_id].clear()

        return msg
Exemplo n.º 4
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