Ejemplo n.º 1
0
    def negotiateSession(self, preferredDialect=None, negSessionResponse=None):
        # We DON'T want to sign
        self._Connection['ClientSecurityMode'] = 0

        if self.RequireMessageSigning is True:
            LOG.error('Signing is required, attack won\'t work!')
            return

        self._Connection['Capabilities'] = SMB2_GLOBAL_CAP_ENCRYPTION
        currentDialect = SMB2_DIALECT_WILDCARD

        # Do we have a negSessionPacket already?
        if negSessionResponse is not None:
            # Yes, let's store the dialect answered back
            negResp = SMB2Negotiate_Response(negSessionResponse['Data'])
            currentDialect = negResp['DialectRevision']

        if currentDialect == SMB2_DIALECT_WILDCARD:
            # Still don't know the chosen dialect, let's send our options

            packet = self.SMB_PACKET()
            packet['Command'] = SMB2_NEGOTIATE
            negSession = SMB2Negotiate()

            negSession['SecurityMode'] = self._Connection['ClientSecurityMode']
            negSession['Capabilities'] = self._Connection['Capabilities']
            negSession['ClientGuid'] = self.ClientGuid
            if preferredDialect is not None:
                negSession['Dialects'] = [preferredDialect]
            else:
                negSession['Dialects'] = [
                    SMB2_DIALECT_002, SMB2_DIALECT_21, SMB2_DIALECT_30
                ]
            negSession['DialectCount'] = len(negSession['Dialects'])
            packet['Data'] = negSession

            packetID = self.sendSMB(packet)
            ans = self.recvSMB(packetID)
            if ans.isValidAnswer(STATUS_SUCCESS):
                negResp = SMB2Negotiate_Response(ans['Data'])

        self._Connection['MaxTransactSize'] = min(0x100000,
                                                  negResp['MaxTransactSize'])
        self._Connection['MaxReadSize'] = min(0x100000, negResp['MaxReadSize'])
        self._Connection['MaxWriteSize'] = min(0x100000,
                                               negResp['MaxWriteSize'])
        self._Connection['ServerGuid'] = negResp['ServerGuid']
        self._Connection['GSSNegotiateToken'] = negResp['Buffer']
        self._Connection['Dialect'] = negResp['DialectRevision']
        if (negResp['SecurityMode'] & SMB2_NEGOTIATE_SIGNING_REQUIRED
            ) == SMB2_NEGOTIATE_SIGNING_REQUIRED:
            LOG.error('Signing is required, attack won\'t work!')
            return
        if (negResp['Capabilities']
                & SMB2_GLOBAL_CAP_LEASING) == SMB2_GLOBAL_CAP_LEASING:
            self._Connection['SupportsFileLeasing'] = True
        if (negResp['Capabilities']
                & SMB2_GLOBAL_CAP_LARGE_MTU) == SMB2_GLOBAL_CAP_LARGE_MTU:
            self._Connection['SupportsMultiCredit'] = True

        if self._Connection['Dialect'] == SMB2_DIALECT_30:
            # Switching to the right packet format
            self.SMB_PACKET = SMB3Packet
            if (negResp['Capabilities'] & SMB2_GLOBAL_CAP_DIRECTORY_LEASING
                ) == SMB2_GLOBAL_CAP_DIRECTORY_LEASING:
                self._Connection['SupportsDirectoryLeasing'] = True
            if (negResp['Capabilities'] & SMB2_GLOBAL_CAP_MULTI_CHANNEL
                ) == SMB2_GLOBAL_CAP_MULTI_CHANNEL:
                self._Connection['SupportsMultiChannel'] = True
            if (negResp['Capabilities'] & SMB2_GLOBAL_CAP_PERSISTENT_HANDLES
                ) == SMB2_GLOBAL_CAP_PERSISTENT_HANDLES:
                self._Connection['SupportsPersistentHandles'] = True
            if (negResp['Capabilities'] &
                    SMB2_GLOBAL_CAP_ENCRYPTION) == SMB2_GLOBAL_CAP_ENCRYPTION:
                self._Connection['SupportsEncryption'] = True

            self._Connection['ServerCapabilities'] = negResp['Capabilities']
            self._Connection['ServerSecurityMode'] = negResp['SecurityMode']
Ejemplo n.º 2
0
    def negotiateSession(self, preferredDialect=None, negSessionResponse=None):
        # Let's store some data for later use
        self._Connection['ClientSecurityMode'] = SMB2_NEGOTIATE_SIGNING_ENABLED
        if self.RequireMessageSigning is True:
            self._Connection[
                'ClientSecurityMode'] |= SMB2_NEGOTIATE_SIGNING_REQUIRED
        self._Connection['Capabilities'] = SMB2_GLOBAL_CAP_ENCRYPTION
        currentDialect = SMB2_DIALECT_WILDCARD

        # Do we have a negSessionPacket already?
        if negSessionResponse is not None:
            # Yes, let's store the dialect answered back
            negResp = SMB2Negotiate_Response(negSessionResponse['Data'])
            currentDialect = negResp['DialectRevision']

        if currentDialect == SMB2_DIALECT_WILDCARD:
            # Still don't know the chosen dialect, let's send our options

            packet = self.SMB_PACKET()
            packet['Command'] = SMB2_NEGOTIATE
            negSession = SMB2Negotiate()

            negSession['SecurityMode'] = self._Connection['ClientSecurityMode']
            negSession['Capabilities'] = self._Connection['Capabilities']
            negSession['ClientGuid'] = self.ClientGuid
            if preferredDialect is not None:
                negSession['Dialects'] = [preferredDialect]
                if preferredDialect == SMB2_DIALECT_311:
                    # Build the Contexts
                    contextData = SMB311ContextData()
                    contextData['NegotiateContextOffset'] = 64 + 38 + 2
                    contextData['NegotiateContextCount'] = 0
                    # Add an SMB2_NEGOTIATE_CONTEXT with ContextType as SMB2_PREAUTH_INTEGRITY_CAPABILITIES
                    # to the negotiate request as specified in section 2.2.3.1:
                    negotiateContext = SMB2NegotiateContext()
                    negotiateContext[
                        'ContextType'] = SMB2_PREAUTH_INTEGRITY_CAPABILITIES

                    preAuthIntegrityCapabilities = SMB2PreAuthIntegrityCapabilities(
                    )
                    preAuthIntegrityCapabilities['HashAlgorithmCount'] = 1
                    preAuthIntegrityCapabilities['SaltLength'] = 32
                    preAuthIntegrityCapabilities[
                        'HashAlgorithms'] = b'\x01\x00'
                    preAuthIntegrityCapabilities['Salt'] = ''.join([
                        rand.choice(string.ascii_letters) for _ in range(
                            preAuthIntegrityCapabilities['SaltLength'])
                    ])

                    negotiateContext[
                        'Data'] = preAuthIntegrityCapabilities.getData()
                    negotiateContext['DataLength'] = len(
                        negotiateContext['Data'])
                    contextData['NegotiateContextCount'] += 1
                    pad = b'\xFF' * (8 - (negotiateContext['DataLength'] % 8))

                    negotiateContext2 = SMB2NegotiateContext()
                    negotiateContext2[
                        'ContextType'] = SMB2_COMPRESSION_CAPABILITIES

                    compressionCapabilities = SMB2CompressionCapabilities()
                    compressionCapabilities['CompressionAlgorithmCount'] = 1
                    compressionCapabilities['Padding'] = 0
                    compressionCapabilities['Flags'] = 0
                    compressionCapabilities[
                        'CompressionAlgorithms'] = b'\x01\x00'

                    negotiateContext2[
                        'Data'] = compressionCapabilities.getData()
                    negotiateContext2['DataLength'] = len(
                        negotiateContext2['Data'])
                    contextData['NegotiateContextCount'] += 1

                    negSession['ClientStartTime'] = contextData.getData()
                    negSession['Padding'] = b'\xFF\xFF'
                    # Subsequent negotiate contexts MUST appear at the first 8-byte aligned offset following the
                    # previous negotiate context.
                    negSession[
                        'NegotiateContextList'] = negotiateContext.getData(
                        ) + pad + negotiateContext2.getData()

            else:
                negSession['Dialects'] = [
                    SMB2_DIALECT_002, SMB2_DIALECT_21, SMB2_DIALECT_30
                ]
            negSession['DialectCount'] = len(negSession['Dialects'])
            packet['Data'] = negSession

            packetID = self.sendSMB(packet)
            ans = self.recvSMB(packetID)
            if ans.isValidAnswer(STATUS_SUCCESS):
                negResp = SMB2Negotiate_Response(ans['Data'])

        self._Connection['MaxTransactSize'] = min(0x100000,
                                                  negResp['MaxTransactSize'])
        self._Connection['MaxReadSize'] = min(0x100000, negResp['MaxReadSize'])
        self._Connection['MaxWriteSize'] = min(0x100000,
                                               negResp['MaxWriteSize'])
        self._Connection['ServerGuid'] = negResp['ServerGuid']
        self._Connection['GSSNegotiateToken'] = negResp['Buffer']
        self._Connection['Dialect'] = negResp['DialectRevision']
        if (negResp['SecurityMode'] & SMB2_NEGOTIATE_SIGNING_REQUIRED) == SMB2_NEGOTIATE_SIGNING_REQUIRED or \
                self._Connection['Dialect'] == SMB2_DIALECT_311:
            self._Connection['RequireSigning'] = True
        if self._Connection['Dialect'] == SMB2_DIALECT_311:
            # Always Sign
            self._Connection['RequireSigning'] = True

        if (negResp['Capabilities']
                & SMB2_GLOBAL_CAP_LEASING) == SMB2_GLOBAL_CAP_LEASING:
            self._Connection['SupportsFileLeasing'] = True
        if (negResp['Capabilities']
                & SMB2_GLOBAL_CAP_LARGE_MTU) == SMB2_GLOBAL_CAP_LARGE_MTU:
            self._Connection['SupportsMultiCredit'] = True

        if self._Connection['Dialect'] >= SMB2_DIALECT_30:
            # Switching to the right packet format
            self.SMB_PACKET = SMB3Packet
            if (negResp['Capabilities'] & SMB2_GLOBAL_CAP_DIRECTORY_LEASING
                ) == SMB2_GLOBAL_CAP_DIRECTORY_LEASING:
                self._Connection['SupportsDirectoryLeasing'] = True
            if (negResp['Capabilities'] & SMB2_GLOBAL_CAP_MULTI_CHANNEL
                ) == SMB2_GLOBAL_CAP_MULTI_CHANNEL:
                self._Connection['SupportsMultiChannel'] = True
            if (negResp['Capabilities'] & SMB2_GLOBAL_CAP_PERSISTENT_HANDLES
                ) == SMB2_GLOBAL_CAP_PERSISTENT_HANDLES:
                self._Connection['SupportsPersistentHandles'] = True
            if (negResp['Capabilities'] &
                    SMB2_GLOBAL_CAP_ENCRYPTION) == SMB2_GLOBAL_CAP_ENCRYPTION:
                self._Connection['SupportsEncryption'] = True

            self._Connection['ServerCapabilities'] = negResp['Capabilities']
            self._Connection['ServerSecurityMode'] = negResp['SecurityMode']