Exemplo n.º 1
0
    def __init__(self, settings):
        self.settings = settings
        self.mode = None  #'CLIENT'
        self.sspi = None
        self.operator = None
        self.client = None
        self.target = None
        #self.ntlmChallenge = None

        self.session_key = None
        self.ntlm_ctx = NTLMAUTHHandler(NTLMHandlerSettings(None, 'MANUAL'))
Exemplo n.º 2
0
	def __init__(self, settings):
		self.settings = settings
		self.mode = None
		url = '%s://%s:%s' % (self.settings.proto, self.settings.host, self.settings.port)
		self.sspi = SSPIProxyWS(url, self.settings.agent_id)
		self.operator = None
		self.client = None
		self.target = None
		#self.ntlmChallenge = None
		self.iterations = 0
		
		self.session_key = None
		self.ntlm_ctx = NTLMAUTHHandler(NTLMHandlerSettings(None, 'MANUAL'))
Exemplo n.º 3
0
	def to_spnego_cred(creds, target = None):
		if creds.authentication_type == SMBAuthProtocol.NTLM:
			ntlmcred = SMBNTLMCredential()
			ntlmcred.username = creds.username
			ntlmcred.domain = creds.domain if creds.domain is not None else ''
			ntlmcred.workstation = None
			ntlmcred.is_guest = False
			
			if creds.secret is None:
				raise Exception('NTLM authentication requres password!')
			if creds.secret_type == SMBCredentialsSecretType.NT:
				ntlmcred.nt_hash = creds.secret
			elif creds.secret_type == SMBCredentialsSecretType.PASSWORD:
				ntlmcred.password = creds.secret
			
			settings = NTLMHandlerSettings(ntlmcred)
			handler = NTLMAUTHHandler(settings)
			
			#setting up SPNEGO
			spneg = SPNEGO()
			spneg.add_auth_context('NTLMSSP - Microsoft NTLM Security Support Provider', handler)
			
			return spneg
			
		elif creds.authentication_type == SMBAuthProtocol.KERBEROS:
			if target is None:
				raise Exception('Target must be specified with Kerberos!')
				
			if target.hostname is None:
				raise Exception('target must have a domain name or hostname for kerberos!')
				
			if target.dc_ip is None:
				raise Exception('target must have a dc_ip for kerberos!')
			
			kc = KerberosCredential()
			kc.username = creds.username
			kc.domain = creds.domain
			if creds.secret_type == SMBCredentialsSecretType.PASSWORD:
				kc.password = creds.secret
			elif creds.secret_type == SMBCredentialsSecretType.NT:
				kc.nt_hash = creds.secret
				
			elif creds.secret_type == SMBCredentialsSecretType.AES:
				if len(creds.secret) == 32:
					kc.kerberos_key_aes_128 = creds.secret
				elif len(creds.secret) == 64:
					kc.kerberos_key_aes_256 = creds.secret
					
			elif creds.secret_type == SMBCredentialsSecretType.RC4:
				kc.kerberos_key_rc4 = creds.secret
			
			elif creds.secret_type == SMBCredentialsSecretType.RC4:
				kc.ccache = creds.secret
			else:
				raise Exception('No suitable secret type found to set up kerberos!')
			
				
			kcred = SMBKerberosCredential()
			kcred.ccred = kc #KerberosCredential
			kcred.ksoc = KerberosSocketAIO(target.dc_ip) #KerberosSocketAIO
			kcred.target = KerberosTarget.from_target_string(target.to_target_string()) #KerberosTarget
			
			handler = SMBKerberos(kcred)
			
			#setting up SPNEGO
			spneg = SPNEGO()
			spneg.add_auth_context('MS KRB5 - Microsoft Kerberos 5', handler)
			return spneg
			
		elif creds.authentication_type == SMBAuthProtocol.SSPI_KERBEROS:
			if target is None:
				raise Exception('Target must be specified with Kerberos SSPI!')
				
			kerbcred = SMBKerberosSSPICredential()
			kerbcred.client = None #creds.username #here we could submit the domain as well for impersonation? TODO!
			kerbcred.password = creds.secret
			kerbcred.target = target.to_target_string()
			
			handler = SMBKerberosSSPI(kerbcred)
			#setting up SPNEGO
			spneg = SPNEGO()
			spneg.add_auth_context('MS KRB5 - Microsoft Kerberos 5', handler)
			return spneg
		
		elif creds.authentication_type == SMBAuthProtocol.SSPI_NTLM:
			ntlmcred = SMBNTLMSSPICredential()
			ntlmcred.client = creds.username #here we could submit the domain as well for impersonation? TODO!
			ntlmcred.password = creds.secret
			
			handler = SMBNTLMSSPI(ntlmcred)
			#setting up SPNEGO
			spneg = SPNEGO()
			spneg.add_auth_context('NTLMSSP - Microsoft NTLM Security Support Provider', handler)
			return spneg

		elif creds.authentication_type.value.startswith('MULTIPLEXOR'):
			if creds.authentication_type in [SMBAuthProtocol.MULTIPLEXOR_SSL_NTLM, SMBAuthProtocol.MULTIPLEXOR_NTLM]:
				from aiosmb.ntlm.multiplexor import SMBNTLMMultiplexor

				ntlmcred = SMBMultiplexorCredential()
				ntlmcred.type = 'NTLM'
				if creds.username is not None:
					ntlmcred.username = '******'
				if creds.domain is not None:
					ntlmcred.domain = '<CURRENT>'
				if creds.secret is not None:
					ntlmcred.password = '******'
				ntlmcred.is_guest = False
				ntlmcred.is_ssl = True if creds.authentication_type == SMBAuthProtocol.MULTIPLEXOR_SSL_NTLM else False
				ntlmcred.parse_settings(creds.settings)
				
				handler = SMBNTLMMultiplexor(ntlmcred)
				#setting up SPNEGO
				spneg = SPNEGO()
				spneg.add_auth_context('NTLMSSP - Microsoft NTLM Security Support Provider', handler)
				return spneg

			elif creds.authentication_type in [SMBAuthProtocol.MULTIPLEXOR_SSL_KERBEROS, SMBAuthProtocol.MULTIPLEXOR_KERBEROS]:
				from aiosmb.kerberos.multiplexor import SMBKerberosMultiplexor

				ntlmcred = SMBMultiplexorCredential()
				ntlmcred.type = 'KERBEROS'
				ntlmcred.target = creds.target
				if creds.username is not None:
					ntlmcred.username = '******'
				if creds.domain is not None:
					ntlmcred.domain = '<CURRENT>'
				if creds.secret is not None:
					ntlmcred.password = '******'
				ntlmcred.is_guest = False
				ntlmcred.is_ssl = True if creds.authentication_type == SMBAuthProtocol.MULTIPLEXOR_SSL_NTLM else False
				ntlmcred.parse_settings(creds.settings)

				handler = SMBKerberosMultiplexor(ntlmcred)
				#setting up SPNEGO
				spneg = SPNEGO()
				spneg.add_auth_context('MS KRB5 - Microsoft Kerberos 5', handler)
				return spneg
Exemplo n.º 4
0
class SMBWSNetNTLMAuth:
    def __init__(self, settings):
        self.settings = settings
        self.mode = None
        self.sspi = WSNETAuth()
        self.operator = None
        self.client = None
        self.target = None
        #self.ntlmChallenge = None
        self.iterations = 0

        self.session_key = None
        self.ntlm_ctx = NTLMAUTHHandler(NTLMHandlerSettings(None, 'MANUAL'))

    def setup(self):
        return

    @property
    def ntlmChallenge(self):
        return self.ntlm_ctx.ntlmChallenge

    def get_sealkey(self, mode='Client'):
        return self.ntlm_ctx.get_sealkey(mode=mode)

    def get_signkey(self, mode='Client'):
        return self.ntlm_ctx.get_signkey(mode=mode)

    def SEAL(self, signingKey, sealingKey, messageToSign, messageToEncrypt,
             seqNum, cipher_encrypt):
        return self.ntlm_ctx.SEAL(signingKey, sealingKey, messageToSign,
                                  messageToEncrypt, seqNum, cipher_encrypt)

    def SIGN(self, signingKey, message, seqNum, cipher_encrypt):
        return self.ntlm_ctx.SIGN(signingKey, message, seqNum, cipher_encrypt)

    def get_session_key(self):
        return self.session_key

    def get_extra_info(self):
        return self.ntlm_ctx.get_extra_info()

    def is_extended_security(self):
        return self.ntlm_ctx.is_extended_security()

    async def authenticate(self,
                           authData=b'',
                           flags=None,
                           seq_number=0,
                           is_rpc=False):
        try:
            if is_rpc is True and flags is None:
                flags = ISC_REQ.REPLAY_DETECT | ISC_REQ.CONFIDENTIALITY | ISC_REQ.USE_SESSION_KEY | ISC_REQ.INTEGRITY | ISC_REQ.SEQUENCE_DETECT | ISC_REQ.CONNECTION
            elif flags is None:
                flags = ISC_REQ.CONNECTION

            if authData is None:
                status, ctxattr, data, err = await self.sspi.authenticate(
                    'NTLM', '', '', 3, flags.value, authdata=b'')
                if err is not None:
                    raise err
                self.iterations += 1
                self.ntlm_ctx.load_negotiate(data)
                return data, True, None
            else:
                self.ntlm_ctx.load_challenge(authData)
                status, ctxattr, data, err = await self.sspi.authenticate(
                    'NTLM', '', '', 3, flags.value, authdata=authData)
                if err is not None:
                    raise err
                if err is None:
                    self.ntlm_ctx.load_authenticate(data)
                    self.session_key, err = await self.sspi.get_sessionkey()
                    if err is not None:
                        raise err
                    self.ntlm_ctx.load_sessionkey(self.get_session_key())

                await self.sspi.disconnect()
                return data, False, None
        except Exception as e:
            return None, None, e
Exemplo n.º 5
0
class SMBNTLMMultiplexor:
    def __init__(self, settings):
        self.settings = settings
        self.mode = None  #'CLIENT'
        self.sspi = None
        self.operator = None
        self.client = None
        self.target = None
        #self.ntlmChallenge = None

        self.session_key = None
        self.ntlm_ctx = NTLMAUTHHandler(NTLMHandlerSettings(None, 'MANUAL'))

    def setup(self):
        return

    @property
    def ntlmChallenge(self):
        return self.ntlm_ctx.ntlmChallenge

    def get_sealkey(self, mode='Client'):
        return self.ntlm_ctx.get_sealkey(mode=mode)

    def get_signkey(self, mode='Client'):
        return self.ntlm_ctx.get_signkey(mode=mode)

    def SEAL(self, signingKey, sealingKey, messageToSign, messageToEncrypt,
             seqNum, cipher_encrypt):
        return self.ntlm_ctx.SEAL(signingKey, sealingKey, messageToSign,
                                  messageToEncrypt, seqNum, cipher_encrypt)

    def SIGN(self, signingKey, message, seqNum, cipher_encrypt):
        return self.ntlm_ctx.SIGN(signingKey, message, seqNum, cipher_encrypt)

    def get_session_key(self):
        return self.session_key

    def get_extra_info(self):
        return self.ntlm_ctx.get_extra_info()

    def is_extended_security(self):
        return self.ntlm_ctx.is_extended_security()

    #async def encrypt(self, data, message_no):
    #	return self.sspi.encrypt(data, message_no)
    #
    #async def decrypt(self, data, message_no):
    #	return self.sspi.decrypt(data, message_no)

    async def authenticate(self,
                           authData=None,
                           flags=None,
                           seq_number=0,
                           is_rpc=False):
        if self.sspi is None:
            res, err = await self.start_remote_sspi()
            if err is not None:
                return None, None, err

        if is_rpc is True and flags is None:
            flags = ISC_REQ.REPLAY_DETECT | ISC_REQ.CONFIDENTIALITY | ISC_REQ.USE_SESSION_KEY | ISC_REQ.INTEGRITY | ISC_REQ.SEQUENCE_DETECT | ISC_REQ.CONNECTION
            flags = int(flags)

        if self.settings.mode == 'CLIENT':
            if authData is None:
                data, res = await self.sspi.authenticate(flags=flags)
                if res is None:
                    self.ntlm_ctx.load_negotiate(data)
                return data, res, None
            else:
                self.ntlm_ctx.load_challenge(authData)
                data, res = await self.sspi.challenge(authData, flags=flags)
                if res is None:
                    self.ntlm_ctx.load_authenticate(data)
                    self.session_key, res = await self.sspi.get_session_key()
                    if res is None:
                        self.ntlm_ctx.load_sessionkey(self.get_session_key())

                await self.sspi.disconnect()
                return data, res, None

        else:
            return None, None, Exception('Server mode not implemented!')

    async def start_remote_sspi(self):
        try:
            #print(self.settings.get_url())
            self.operator = MultiplexorOperator(self.settings.get_url(),
                                                logging_sink=logger)
            await self.operator.connect()
            #creating virtual sspi server
            server_info = await self.operator.start_sspi(self.settings.agent_id
                                                         )
            #print(server_info)

            sspi_url = 'ws://%s:%s' % (server_info['listen_ip'],
                                       server_info['listen_port'])

            #print(sspi_url)
            self.sspi = SSPINTLMClient(sspi_url)
            await self.sspi.connect()
            return True, None
        except Exception as e:
            import traceback
            traceback.print_exc()
            return None, e
Exemplo n.º 6
0
class SMBNTLMMultiplexor:
    def __init__(self, settings):
        self.settings = settings
        self.mode = None  #'CLIENT'
        self.sspi = None
        self.operator = None
        self.client = None
        self.target = None
        #self.ntlmChallenge = None

        self.session_key = None
        self.ntlm_ctx = NTLMAUTHHandler(NTLMHandlerSettings(None, 'MANUAL'))

    def setup(self):
        return

    @property
    def ntlmChallenge(self):
        return self.ntlm_ctx.ntlmChallenge

    def get_sealkey(self, mode='Client'):
        return self.ntlm_ctx.get_sealkey(mode=mode)

    def get_signkey(self, mode='Client'):
        return self.ntlm_ctx.get_signkey(mode=mode)

    def SEAL(self, signingKey, sealingKey, messageToSign, messageToEncrypt,
             seqNum, cipher_encrypt):
        return self.ntlm_ctx.SEAL(signingKey, sealingKey, messageToSign,
                                  messageToEncrypt, seqNum, cipher_encrypt)

    def SIGN(self, signingKey, message, seqNum, cipher_encrypt):
        return self.ntlm_ctx.SIGN(signingKey, message, seqNum, cipher_encrypt)

    def get_session_key(self):
        return self.session_key

    def get_extra_info(self):
        return self.ntlm_ctx.get_extra_info()

    def is_extended_security(self):
        return self.ntlm_ctx.is_extended_security()

    #async def encrypt(self, data, message_no):
    #	return self.sspi.encrypt(data, message_no)
    #
    #async def decrypt(self, data, message_no):
    #	return self.sspi.decrypt(data, message_no)

    async def authenticate(self,
                           authData=None,
                           flags=None,
                           seq_number=0,
                           is_rpc=False):
        if self.sspi is None:
            await self.start_remote_sspi()

        if self.settings.mode == 'CLIENT':
            if authData is None:
                data, res = await self.sspi.authenticate(is_rpc=is_rpc)
                print('authenticate: %s' % data)
                if res is None:
                    self.ntlm_ctx.load_negotiate(data)
                return data, res
            else:
                self.ntlm_ctx.load_challenge(authData)
                data, res = await self.sspi.challenge(authData, is_rpc=is_rpc)
                print('challenge: %s' % data)
                if res is None:
                    self.ntlm_ctx.load_authenticate(data)
                    self.session_key, res = await self.sspi.get_session_key()
                    print('session_key: %s' % self.session_key)
                    if res is None:
                        self.ntlm_ctx.load_sessionkey(self.get_session_key())
                    else:
                        print(res)

                return data, res

        else:
            raise Exception('Server mode not implemented!')

    async def start_remote_sspi(self):
        try:
            print(self.settings.get_url())
            self.operator = MultiplexorOperator(self.settings.get_url())
            await self.operator.connect()
            #creating virtual sspi server
            server_info = await self.operator.start_sspi(self.settings.agent_id
                                                         )
            #print(server_info)

            sspi_url = 'ws://%s:%s' % (server_info['listen_ip'],
                                       server_info['listen_port'])

            #print(sspi_url)
            self.sspi = SSPINTLMClient(sspi_url)
            await self.sspi.connect()
        except Exception as e:
            import traceback
            traceback.print_exc()
            return None
Exemplo n.º 7
0
    def to_spnego_cred(creds, target=None):
        if creds.authentication_type == SMBAuthProtocol.NTLM:
            ntlmcred = SMBNTLMCredential()
            ntlmcred.username = creds.username
            ntlmcred.domain = creds.domain if creds.domain is not None else ''
            ntlmcred.workstation = None
            ntlmcred.is_guest = False

            if creds.secret is None:
                if creds.username is None and creds.domain is None:
                    ntlmcred.is_guest = True
                else:
                    raise Exception('NTLM authentication requres password!')

            if creds.secret_type == SMBCredentialsSecretType.NT:
                ntlmcred.nt_hash = creds.secret
            elif creds.secret_type == SMBCredentialsSecretType.PASSWORD:
                ntlmcred.password = creds.secret

            settings = NTLMHandlerSettings(ntlmcred)
            handler = NTLMAUTHHandler(settings)

            #setting up SPNEGO
            spneg = SPNEGO()
            spneg.add_auth_context(
                'NTLMSSP - Microsoft NTLM Security Support Provider', handler)

            return spneg

        elif creds.authentication_type == SMBAuthProtocol.KERBEROS:
            if target is None:
                raise Exception('Target must be specified with Kerberos!')

            if target.hostname is None:
                raise Exception(
                    'target must have a domain name or hostname for kerberos!')

            if target.dc_ip is None:
                raise Exception('target must have a dc_ip for kerberos!')

            if creds.secret_type == SMBCredentialsSecretType.KEYTAB:
                filename = creds.secret
                if creds.secret.upper() == 'ENV':
                    filename = os.environ['KRB5KEYTAB']

                kc = KerberosCredential.from_keytab(filename, creds.username,
                                                    creds.domain)

            elif creds.secret_type == SMBCredentialsSecretType.CCACHE:
                filename = creds.secret
                if creds.secret.upper() == 'ENV':
                    try:
                        filename = os.environ['KRB5CCACHE']
                    except:
                        raise Exception(
                            'Kerberos auth missing environment variable KRB5CCACHE'
                        )
                kc = KerberosCredential.from_ccache_file(filename)
                kc.username = creds.username
                kc.domain = creds.domain

            else:
                kc = KerberosCredential()
                kc.username = creds.username
                kc.domain = creds.domain
                if creds.secret_type == SMBCredentialsSecretType.PASSWORD:
                    kc.password = creds.secret
                elif creds.secret_type == SMBCredentialsSecretType.NT:
                    kc.nt_hash = creds.secret

                elif creds.secret_type == SMBCredentialsSecretType.AES:
                    if len(creds.secret) == 32:
                        kc.kerberos_key_aes_128 = creds.secret
                    elif len(creds.secret) == 64:
                        kc.kerberos_key_aes_256 = creds.secret

                elif creds.secret_type == SMBCredentialsSecretType.RC4:
                    kc.kerberos_key_rc4 = creds.secret

            if kc is None:
                raise Exception(
                    'No suitable secret type found to set up kerberos!')

            kcred = SMBKerberosCredential()
            kcred.ccred = kc
            kcred.spn = KerberosSPN.from_target_string(
                target.to_target_string())

            if target.proxy is not None:
                if target.proxy.type in [
                        SMBProxyType.SOCKS5, SMBProxyType.SOCKS5_SSL,
                        SMBProxyType.SOCKS4, SMBProxyType.SOCKS4_SSL
                ]:
                    kcred.target = KerberosTarget(target.dc_ip)
                    kcred.target.proxy = KerberosProxy()
                    kcred.target.proxy.target = copy.deepcopy(
                        target.proxy.target)
                    kcred.target.proxy.target.endpoint_ip = target.dc_ip
                    kcred.target.proxy.target.endpoint_port = 88
                    kcred.target.proxy.creds = copy.deepcopy(target.proxy.auth)

                elif target.proxy.type in [
                        SMBProxyType.MULTIPLEXOR, SMBProxyType.MULTIPLEXOR_SSL
                ]:
                    kcred.target = KerberosTarget(target.dc_ip)
                    kcred.target.proxy = copy.deepcopy(target.proxy)
            else:
                kcred.target = KerberosTarget(target.dc_ip)
            handler = SMBKerberos(kcred)

            #setting up SPNEGO
            spneg = SPNEGO()
            spneg.add_auth_context('MS KRB5 - Microsoft Kerberos 5', handler)
            return spneg

        elif creds.authentication_type == SMBAuthProtocol.SSPI_KERBEROS:
            if target is None:
                raise Exception('Target must be specified with Kerberos SSPI!')

            kerbcred = SMBKerberosSSPICredential()
            kerbcred.client = None  #creds.username #here we could submit the domain as well for impersonation? TODO!
            kerbcred.password = creds.secret
            kerbcred.target = target.to_target_string()

            handler = SMBKerberosSSPI(kerbcred)
            #setting up SPNEGO
            spneg = SPNEGO()
            spneg.add_auth_context('MS KRB5 - Microsoft Kerberos 5', handler)
            return spneg

        elif creds.authentication_type == SMBAuthProtocol.SSPI_NTLM:
            ntlmcred = SMBNTLMSSPICredential()
            ntlmcred.client = creds.username  #here we could submit the domain as well for impersonation? TODO!
            ntlmcred.password = creds.secret

            handler = SMBNTLMSSPI(ntlmcred)
            #setting up SPNEGO
            spneg = SPNEGO()
            spneg.add_auth_context(
                'NTLMSSP - Microsoft NTLM Security Support Provider', handler)
            return spneg

        elif creds.authentication_type.value.startswith('MPN'):
            if creds.authentication_type in [
                    SMBAuthProtocol.MPN_SSL_NTLM, SMBAuthProtocol.MPN_NTLM
            ]:
                from aiosmb.authentication.ntlm.mpn import SMBNTLMMPN
                ntlmcred = SMBMPNCredential()
                ntlmcred.type = 'NTLM'
                ntlmcred.is_ssl = True if creds.authentication_type == SMBAuthProtocol.MPN_SSL_NTLM else False
                ntlmcred.parse_settings(creds.settings)

                handler = SMBNTLMMPN(ntlmcred)
                #setting up SPNEGO
                spneg = SPNEGO()
                spneg.add_auth_context(
                    'NTLMSSP - Microsoft NTLM Security Support Provider',
                    handler)
                return spneg

            elif creds.authentication_type in [
                    SMBAuthProtocol.MPN_SSL_KERBEROS,
                    SMBAuthProtocol.MPN_KERBEROS
            ]:
                from aiosmb.authentication.kerberos.mpn import SMBKerberosMPN

                ntlmcred = SMBMPNCredential()
                ntlmcred.type = 'KERBEROS'
                ntlmcred.target = creds.target
                if creds.username is not None:
                    ntlmcred.username = '******'
                if creds.domain is not None:
                    ntlmcred.domain = '<CURRENT>'
                if creds.secret is not None:
                    ntlmcred.password = '******'
                ntlmcred.is_guest = False
                ntlmcred.is_ssl = True if creds.authentication_type == SMBAuthProtocol.MPN_SSL_KERBEROS else False
                ntlmcred.parse_settings(creds.settings)

                handler = SMBKerberosMPN(ntlmcred)
                #setting up SPNEGO
                spneg = SPNEGO()
                spneg.add_auth_context('MS KRB5 - Microsoft Kerberos 5',
                                       handler)
                return spneg

        elif creds.authentication_type.value.startswith('MULTIPLEXOR'):
            if creds.authentication_type in [
                    SMBAuthProtocol.MULTIPLEXOR_SSL_NTLM,
                    SMBAuthProtocol.MULTIPLEXOR_NTLM
            ]:
                from aiosmb.authentication.ntlm.multiplexor import SMBNTLMMultiplexor

                ntlmcred = SMBMultiplexorCredential()
                ntlmcred.type = 'NTLM'
                if creds.username is not None:
                    ntlmcred.username = '******'
                if creds.domain is not None:
                    ntlmcred.domain = '<CURRENT>'
                if creds.secret is not None:
                    ntlmcred.password = '******'
                ntlmcred.is_guest = False
                ntlmcred.is_ssl = True if creds.authentication_type == SMBAuthProtocol.MULTIPLEXOR_SSL_NTLM else False
                ntlmcred.parse_settings(creds.settings)

                handler = SMBNTLMMultiplexor(ntlmcred)
                #setting up SPNEGO
                spneg = SPNEGO()
                spneg.add_auth_context(
                    'NTLMSSP - Microsoft NTLM Security Support Provider',
                    handler)
                return spneg

            elif creds.authentication_type in [
                    SMBAuthProtocol.MULTIPLEXOR_SSL_KERBEROS,
                    SMBAuthProtocol.MULTIPLEXOR_KERBEROS
            ]:
                from aiosmb.authentication.kerberos.multiplexor import SMBKerberosMultiplexor

                ntlmcred = SMBMultiplexorCredential()
                ntlmcred.type = 'KERBEROS'
                ntlmcred.target = creds.target
                if creds.username is not None:
                    ntlmcred.username = '******'
                if creds.domain is not None:
                    ntlmcred.domain = '<CURRENT>'
                if creds.secret is not None:
                    ntlmcred.password = '******'
                ntlmcred.is_guest = False
                ntlmcred.is_ssl = True if creds.authentication_type == SMBAuthProtocol.MULTIPLEXOR_SSL_NTLM else False
                ntlmcred.parse_settings(creds.settings)

                handler = SMBKerberosMultiplexor(ntlmcred)
                #setting up SPNEGO
                spneg = SPNEGO()
                spneg.add_auth_context('MS KRB5 - Microsoft Kerberos 5',
                                       handler)
                return spneg
Exemplo n.º 8
0
class SMBNTLMMPN:
    def __init__(self, settings):
        self.settings = settings
        self.operator = settings.operator
        self.agent_id = settings.agent_id
        self.mode = None  #'CLIENT'
        self.sspi = None
        self.operator = None
        self.client = None
        self.target = None
        #self.ntlmChallenge = None

        self.session_key = None
        self.ntlm_ctx = NTLMAUTHHandler(NTLMHandlerSettings(None, 'MANUAL'))

    def setup(self):
        return

    @property
    def ntlmChallenge(self):
        return self.ntlm_ctx.ntlmChallenge

    def get_sealkey(self, mode='Client'):
        return self.ntlm_ctx.get_sealkey(mode=mode)

    def get_signkey(self, mode='Client'):
        return self.ntlm_ctx.get_signkey(mode=mode)

    def SEAL(self, signingKey, sealingKey, messageToSign, messageToEncrypt,
             seqNum, cipher_encrypt):
        return self.ntlm_ctx.SEAL(signingKey, sealingKey, messageToSign,
                                  messageToEncrypt, seqNum, cipher_encrypt)

    def SIGN(self, signingKey, message, seqNum, cipher_encrypt):
        return self.ntlm_ctx.SIGN(signingKey, message, seqNum, cipher_encrypt)

    def get_session_key(self):
        return self.session_key

    def get_extra_info(self):
        return self.ntlm_ctx.get_extra_info()

    def is_extended_security(self):
        return self.ntlm_ctx.is_extended_security()

    async def authenticate(self,
                           authData=None,
                           flags=None,
                           seq_number=0,
                           is_rpc=False):
        try:
            if self.operator is None:
                self.operator = MPNOPerator(self.settings.get_url())
                asyncio.create_task(self.operator.run())
                await asyncio.wait_for(self.operator.connected_evt.wait(),
                                       timeout=self.settings.timeout)
            if self.sspi is None:
                self.sspi, err = await self.operator.create_sspi(self.agent_id)
                if err is not None:
                    return None, None, err

            if is_rpc is True and flags is None:
                flags = ISC_REQ.REPLAY_DETECT | ISC_REQ.CONFIDENTIALITY | ISC_REQ.USE_SESSION_KEY | ISC_REQ.INTEGRITY | ISC_REQ.SEQUENCE_DETECT | ISC_REQ.CONNECTION
                flags = int(flags)

            if self.settings.mode == 'CLIENT':
                if authData is None:
                    ctx_attr, data, err = await self.sspi.ntlm_authenticate(
                        context_attributes=flags)
                    if err is not None:
                        raise err

                    self.ntlm_ctx.load_negotiate(data)
                    return data, err, err
                else:
                    self.ntlm_ctx.load_challenge(authData)
                    ctx_attr, data, err = await self.sspi.ntlm_challenge(
                        authData, context_attributes=flags)
                    if err is None:
                        self.ntlm_ctx.load_authenticate(data)
                        self.session_key, err = await self.sspi.get_sessionkey(
                        )
                        if err is None:
                            self.ntlm_ctx.load_sessionkey(
                                self.get_session_key())

                    await self.sspi.disconnect()
                    return data, err, err

            else:
                return None, None, Exception('Server mode not implemented!')
        except Exception as e:
            return None, None, e
Exemplo n.º 9
0
class SMBNTLMSSPI:
	def __init__(self, settings):
		self.settings = settings
		self.mode = None #'CLIENT'
		self.sspi = NTLMSMBSSPI()
		self.client = None
		self.target = None
		#self.ntlmChallenge = None
		
		self.session_key = None
		self.ntlm_ctx = NTLMAUTHHandler(NTLMHandlerSettings(None, 'MANUAL'))
		
		self.setup()
		
	@property
	def ntlmChallenge(self):
		return self.ntlm_ctx.ntlmChallenge
		
	def setup(self):
		self.mode = self.settings.mode.upper()
		self.client = self.settings.client
		self.password = self.settings.password
		
	def get_sealkey(self, mode = 'Client'):
		return self.ntlm_ctx.get_sealkey(mode = mode)
			
	def get_signkey(self, mode = 'Client'):
		return self.ntlm_ctx.get_signkey(mode = mode)
		
		
	def SEAL(self, signingKey, sealingKey, messageToSign, messageToEncrypt, seqNum, cipher_encrypt):
		return self.ntlm_ctx.SEAL(signingKey, sealingKey, messageToSign, messageToEncrypt, seqNum, cipher_encrypt)
		
	def SIGN(self, signingKey, message, seqNum, cipher_encrypt):
		return self.ntlm_ctx.SIGN(signingKey, message, seqNum, cipher_encrypt)
	
	def get_session_key(self):
		if not self.session_key:
			self.session_key = self.sspi.get_session_key()
		
		return self.session_key
		
	def get_extra_info(self):
		return self.ntlm_ctx.get_extra_info()
		
	def is_extended_security(self):
		return self.ntlm_ctx.is_extended_security()
		
	async def encrypt(self, data, message_no):
		return self.sspi.encrypt(data, message_no)
		
	async def decrypt(self, data, message_no):
		return self.sspi.decrypt(data, message_no)
	
	async def authenticate(self, authData = None, flags = None, seq_number = 0, is_rpc = False):
		if self.mode == 'CLIENT':
			if authData is None:
				data, res = self.sspi.negotiate(is_rpc = is_rpc)
				self.ntlm_ctx.load_negotiate(data)
				return data, res
			else:
				self.ntlm_ctx.load_challenge( authData)
				data, res = self.sspi.authenticate(authData, is_rpc = is_rpc)
				self.ntlm_ctx.load_authenticate( data)
				self.ntlm_ctx.load_sessionkey(self.get_session_key())
				
				return data, res
Exemplo n.º 10
0
    def to_spnego_cred(creds, target=None):
        if creds.authentication_type == SMBAuthProtocol.NEGOEX:
            with_certstrore = creds.secret_type == SMBCredentialsSecretType.CERTSTORE
            settings = SPNEGOEXAuthHandlerSettings(
                creds.username,
                creds.secret,
                target,
                dh_params=None,
                with_certstrore=with_certstrore)
            handler = SPNEGOEXAuthHandler(settings)

            #setting up SPNEGO
            spneg = SPNEGO()
            spneg.add_auth_context(
                'NEGOEX - SPNEGO Extended Negotiation Security Mechanism',
                handler)

            return spneg

        elif creds.authentication_type == SMBAuthProtocol.NTLM:
            ntlmcred = SMBNTLMCredential()
            ntlmcred.username = creds.username
            ntlmcred.domain = creds.domain if creds.domain is not None else ''
            ntlmcred.workstation = None
            ntlmcred.is_guest = False

            if creds.secret is None:
                if creds.username is None and creds.domain is None:
                    ntlmcred.is_guest = True
                else:
                    raise Exception('NTLM authentication requres password!')

            if creds.secret_type == SMBCredentialsSecretType.NT:
                ntlmcred.nt_hash = creds.secret
            elif creds.secret_type == SMBCredentialsSecretType.PASSWORD:
                ntlmcred.password = creds.secret

            settings = NTLMHandlerSettings(ntlmcred)
            handler = NTLMAUTHHandler(settings)

            #setting up SPNEGO
            spneg = SPNEGO()
            spneg.add_auth_context(
                'NTLMSSP - Microsoft NTLM Security Support Provider', handler)

            return spneg

        elif creds.authentication_type == SMBAuthProtocol.KERBEROS:
            if target is None:
                raise Exception('Target must be specified with Kerberos!')

            if target.hostname is None:
                raise Exception(
                    'target must have a domain name or hostname for kerberos!')

            if target.dc_ip is None:
                raise Exception('target must have a dc_ip for kerberos!')

            if creds.secret_type == SMBCredentialsSecretType.KEYTAB:
                filename = creds.secret
                if creds.secret.upper() == 'ENV':
                    filename = os.environ['KRB5KEYTAB']

                kc = KerberosCredential.from_keytab(filename, creds.username,
                                                    creds.domain)

            elif creds.secret_type == SMBCredentialsSecretType.CCACHE:
                filename = creds.secret
                if creds.secret.upper() == 'ENV':
                    try:
                        filename = os.environ['KRB5CCACHE']
                    except:
                        raise Exception(
                            'Kerberos auth missing environment variable KRB5CCACHE'
                        )
                kc = KerberosCredential.from_ccache_file(filename)
                kc.username = creds.username
                kc.domain = creds.domain

            elif creds.secret_type == SMBCredentialsSecretType.KIRBI:
                filename = creds.secret
                kc = KerberosCredential.from_kirbi(filename)
                kc.username = creds.username
                kc.domain = creds.domain

            elif creds.secret_type == SMBCredentialsSecretType.PFX:
                kc = KerberosCredential.from_pfx_file(creds.username,
                                                      creds.secret,
                                                      username=creds.altname,
                                                      domain=creds.altdomain)
                creds.username = kc.username
                creds.domain = kc.domain
                target.domain = kc.domain

            elif creds.secret_type == SMBCredentialsSecretType.PFXSTR:
                kc = KerberosCredential.from_pfx_string(creds.username,
                                                        creds.secret,
                                                        username=creds.altname,
                                                        domain=creds.altdomain)
                creds.username = kc.username
                creds.domain = kc.domain
                target.domain = kc.domain

            elif creds.secret_type == SMBCredentialsSecretType.PEM:
                kc = KerberosCredential.from_pem_file(creds.username,
                                                      creds.secret,
                                                      username=creds.altname,
                                                      domain=creds.altdomain)
                creds.username = kc.username
                creds.domain = kc.domain
                target.domain = kc.domain

            elif creds.secret_type == SMBCredentialsSecretType.CERTSTORE:
                # username is the CN of the certificate
                # secret is the name of the certstore, default: MY
                certstore = creds.secret
                if creds.secret is None:
                    certstore = 'MY'
                kc = KerberosCredential.from_windows_certstore(
                    creds.username,
                    certstore,
                    username=creds.altname,
                    domain=creds.altdomain)
                creds.username = kc.username
                creds.domain = kc.domain
                target.domain = kc.domain

            else:
                kc = KerberosCredential()
                kc.username = creds.username
                kc.domain = creds.domain
                if creds.secret_type == SMBCredentialsSecretType.PASSWORD:
                    kc.password = creds.secret
                elif creds.secret_type == SMBCredentialsSecretType.NT:
                    kc.nt_hash = creds.secret

                elif creds.secret_type == SMBCredentialsSecretType.AES:
                    if len(creds.secret) == 32:
                        kc.kerberos_key_aes_128 = creds.secret
                    elif len(creds.secret) == 64:
                        kc.kerberos_key_aes_256 = creds.secret

                elif creds.secret_type == SMBCredentialsSecretType.RC4:
                    kc.kerberos_key_rc4 = creds.secret

            if kc is None:
                raise Exception(
                    'No suitable secret type found to set up kerberos!')

            kcred = SMBKerberosCredential()
            kcred.ccred = kc
            kcred.spn = KerberosSPN.from_target_string(
                target.to_target_string())

            if target.proxy is not None:
                if target.proxy.type in [
                        SMBProxyType.WSNET, SMBProxyType.SOCKS5,
                        SMBProxyType.SOCKS5_SSL, SMBProxyType.SOCKS4,
                        SMBProxyType.SOCKS4_SSL
                ]:
                    kcred.target = KerberosTarget(target.dc_ip)
                    kcred.target.proxy = KerberosProxy()
                    kcred.target.proxy.target = copy.deepcopy(
                        target.proxy.target)
                    kcred.target.proxy.target[-1].endpoint_ip = target.dc_ip
                    kcred.target.proxy.target[-1].endpoint_port = 88

                elif target.proxy.type in [
                        SMBProxyType.MULTIPLEXOR, SMBProxyType.MULTIPLEXOR_SSL
                ]:
                    kcred.target = KerberosTarget(target.dc_ip)
                    kcred.target.proxy = copy.deepcopy(target.proxy)

            else:
                kcred.target = KerberosTarget(target.dc_ip)
            handler = SMBKerberos(kcred)
            #setting up SPNEGO
            spneg = SPNEGO()
            spneg.add_auth_context('MS KRB5 - Microsoft Kerberos 5', handler)
            return spneg

        elif creds.authentication_type == SMBAuthProtocol.SSPI_KERBEROS:
            if target is None:
                raise Exception('Target must be specified with Kerberos SSPI!')

            kerbcred = SMBKerberosSSPICredential()
            kerbcred.client = None  #creds.username #here we could submit the domain as well for impersonation? TODO!
            kerbcred.password = creds.secret
            kerbcred.target = target.to_target_string()

            handler = SMBKerberosSSPI(kerbcred)
            #setting up SPNEGO
            spneg = SPNEGO()
            spneg.add_auth_context('MS KRB5 - Microsoft Kerberos 5', handler)
            return spneg

        elif creds.authentication_type == SMBAuthProtocol.SSPI_NTLM:
            ntlmcred = SMBNTLMSSPICredential()
            ntlmcred.client = creds.username  #here we could submit the domain as well for impersonation? TODO!
            ntlmcred.password = creds.secret

            handler = SMBNTLMSSPI(ntlmcred)
            #setting up SPNEGO
            spneg = SPNEGO()
            spneg.add_auth_context(
                'NTLMSSP - Microsoft NTLM Security Support Provider', handler)
            return spneg

        elif creds.authentication_type.value.startswith('MPN'):
            if creds.authentication_type in [
                    SMBAuthProtocol.MPN_SSL_NTLM, SMBAuthProtocol.MPN_NTLM
            ]:
                from aiosmb.authentication.ntlm.mpn import SMBNTLMMPN
                ntlmcred = SMBMPNCredential()
                ntlmcred.type = 'NTLM'
                ntlmcred.is_ssl = True if creds.authentication_type == SMBAuthProtocol.MPN_SSL_NTLM else False
                ntlmcred.parse_settings(creds.settings)

                handler = SMBNTLMMPN(ntlmcred)
                #setting up SPNEGO
                spneg = SPNEGO()
                spneg.add_auth_context(
                    'NTLMSSP - Microsoft NTLM Security Support Provider',
                    handler)
                return spneg

            elif creds.authentication_type in [
                    SMBAuthProtocol.MPN_SSL_KERBEROS,
                    SMBAuthProtocol.MPN_KERBEROS
            ]:
                from aiosmb.authentication.kerberos.mpn import SMBKerberosMPN

                ntlmcred = SMBMPNCredential()
                ntlmcred.type = 'KERBEROS'
                ntlmcred.target = creds.target
                if creds.username is not None:
                    ntlmcred.username = '******'
                if creds.domain is not None:
                    ntlmcred.domain = '<CURRENT>'
                if creds.secret is not None:
                    ntlmcred.password = '******'
                ntlmcred.is_guest = False
                ntlmcred.is_ssl = True if creds.authentication_type == SMBAuthProtocol.MPN_SSL_KERBEROS else False
                ntlmcred.parse_settings(creds.settings)

                handler = SMBKerberosMPN(ntlmcred)
                #setting up SPNEGO
                spneg = SPNEGO()
                spneg.add_auth_context('MS KRB5 - Microsoft Kerberos 5',
                                       handler)
                return spneg

        elif creds.authentication_type.value.startswith('MULTIPLEXOR'):
            if creds.authentication_type in [
                    SMBAuthProtocol.MULTIPLEXOR_SSL_NTLM,
                    SMBAuthProtocol.MULTIPLEXOR_NTLM
            ]:
                from aiosmb.authentication.ntlm.multiplexor import SMBNTLMMultiplexor

                ntlmcred = SMBMultiplexorCredential()
                ntlmcred.type = 'NTLM'
                if creds.username is not None:
                    ntlmcred.username = '******'
                if creds.domain is not None:
                    ntlmcred.domain = '<CURRENT>'
                if creds.secret is not None:
                    ntlmcred.password = '******'
                ntlmcred.is_guest = False
                ntlmcred.is_ssl = True if creds.authentication_type == SMBAuthProtocol.MULTIPLEXOR_SSL_NTLM else False
                ntlmcred.parse_settings(creds.settings)

                handler = SMBNTLMMultiplexor(ntlmcred)
                #setting up SPNEGO
                spneg = SPNEGO()
                spneg.add_auth_context(
                    'NTLMSSP - Microsoft NTLM Security Support Provider',
                    handler)
                return spneg

            elif creds.authentication_type in [
                    SMBAuthProtocol.MULTIPLEXOR_SSL_KERBEROS,
                    SMBAuthProtocol.MULTIPLEXOR_KERBEROS
            ]:
                from aiosmb.authentication.kerberos.multiplexor import SMBKerberosMultiplexor

                ntlmcred = SMBMultiplexorCredential()
                ntlmcred.type = 'KERBEROS'
                ntlmcred.target = creds.target
                if creds.username is not None:
                    ntlmcred.username = '******'
                if creds.domain is not None:
                    ntlmcred.domain = '<CURRENT>'
                if creds.secret is not None:
                    ntlmcred.password = '******'
                ntlmcred.is_guest = False
                ntlmcred.is_ssl = True if creds.authentication_type == SMBAuthProtocol.MULTIPLEXOR_SSL_NTLM else False
                ntlmcred.parse_settings(creds.settings)

                handler = SMBKerberosMultiplexor(ntlmcred)
                #setting up SPNEGO
                spneg = SPNEGO()
                spneg.add_auth_context('MS KRB5 - Microsoft Kerberos 5',
                                       handler)
                return spneg

        elif creds.authentication_type.value.startswith('WSNET'):
            if creds.authentication_type in [SMBAuthProtocol.WSNET_NTLM]:
                from aiosmb.authentication.ntlm.wsnet import SMBWSNetNTLMAuth

                ntlmcred = SMBWSNETCredential()
                ntlmcred.type = 'NTLM'
                if creds.username is not None:
                    ntlmcred.username = '******'
                if creds.domain is not None:
                    ntlmcred.domain = '<CURRENT>'
                if creds.secret is not None:
                    ntlmcred.password = '******'
                ntlmcred.is_guest = False

                handler = SMBWSNetNTLMAuth(ntlmcred)
                spneg = SPNEGO()
                spneg.add_auth_context(
                    'NTLMSSP - Microsoft NTLM Security Support Provider',
                    handler)
                return spneg

            elif creds.authentication_type in [SMBAuthProtocol.WSNET_KERBEROS]:
                from aiosmb.authentication.kerberos.wsnet import SMBWSNetKerberosAuth

                ntlmcred = SMBWSNETCredential()
                ntlmcred.type = 'KERBEROS'
                ntlmcred.target = creds.target
                if creds.username is not None:
                    ntlmcred.username = '******'
                if creds.domain is not None:
                    ntlmcred.domain = '<CURRENT>'
                if creds.secret is not None:
                    ntlmcred.password = '******'
                ntlmcred.is_guest = False

                handler = SMBWSNetKerberosAuth(ntlmcred)
                #setting up SPNEGO
                spneg = SPNEGO()
                spneg.add_auth_context('MS KRB5 - Microsoft Kerberos 5',
                                       handler)
                return spneg

        elif creds.authentication_type.value.startswith('SSPIPROXY'):
            if creds.authentication_type == SMBAuthProtocol.SSPIPROXY_NTLM:
                from aiosmb.authentication.ntlm.sspiproxy import SMBSSPIProxyNTLMAuth

                ntlmcred = SMBSSPIProxyCredential()
                ntlmcred.type = 'NTLM'
                if creds.username is not None:
                    ntlmcred.username = '******'
                if creds.domain is not None:
                    ntlmcred.domain = '<CURRENT>'
                if creds.secret is not None:
                    ntlmcred.password = '******'
                ntlmcred.is_guest = False
                ntlmcred.host = creds.settings['host'][0]
                ntlmcred.port = int(creds.settings['port'][0])
                ntlmcred.proto = 'ws'
                if 'proto' in creds.settings:
                    ntlmcred.proto = creds.settings['proto'][0]
                if 'agentid' in creds.settings:
                    ntlmcred.agent_id = bytes.fromhex(
                        creds.settings['agentid'][0])

                handler = SMBSSPIProxyNTLMAuth(ntlmcred)
                spneg = SPNEGO()
                spneg.add_auth_context(
                    'NTLMSSP - Microsoft NTLM Security Support Provider',
                    handler)
                return spneg

            elif creds.authentication_type == SMBAuthProtocol.SSPIPROXY_KERBEROS:
                from aiosmb.authentication.kerberos.sspiproxy import SMBSSPIProxyKerberosAuth

                ntlmcred = SMBSSPIProxyCredential()
                ntlmcred.type = 'KERBEROS'
                ntlmcred.target = creds.target
                if creds.username is not None:
                    ntlmcred.username = '******'
                if creds.domain is not None:
                    ntlmcred.domain = '<CURRENT>'
                if creds.secret is not None:
                    ntlmcred.password = '******'
                ntlmcred.is_guest = False
                ntlmcred.host = creds.settings['host'][0]
                ntlmcred.port = int(creds.settings['port'][0])
                ntlmcred.proto = 'ws'
                if 'proto' in creds.settings:
                    ntlmcred.proto = creds.settings['proto'][0]
                if 'agentid' in creds.settings:
                    ntlmcred.agent_id = bytes.fromhex(
                        creds.settings['agentid'][0])

                handler = SMBSSPIProxyKerberosAuth(ntlmcred)
                #setting up SPNEGO
                spneg = SPNEGO()
                spneg.add_auth_context('MS KRB5 - Microsoft Kerberos 5',
                                       handler)
                return spneg