예제 #1
0
	async def authenticate(self, authData = None, flags = ISC_REQ.CONNECTION, seq_number = 0, is_rpc = False):
		try:
			if is_rpc == True:
				if self.iterations == 0:
					flags = ISC_REQ.CONFIDENTIALITY | \
							ISC_REQ.INTEGRITY | \
							ISC_REQ.MUTUAL_AUTH | \
							ISC_REQ.REPLAY_DETECT | \
							ISC_REQ.SEQUENCE_DETECT|\
							ISC_REQ.USE_DCE_STYLE
					
					
					status, ctxattr, apreq, err = await self.ksspi.authenticate('KERBEROS', '', 'cifs/%s' % self.settings.target, 3, flags.value, authdata = b'')
					if err is not None:
						raise err
					self.iterations += 1
					return apreq, True, None
				
				elif self.iterations == 1:
					status, ctxattr, data, err = await self.ksspi.authenticate('KERBEROS', '','cifs/%s' % self.settings.target, 3, flags.value, authdata = authData)
					if err is not None:
						return None, None, err
					self.session_key, err = await self.ksspi.get_sessionkey()
					if err is not None:
						return None, None, err
						
					aprep = AP_REP.load(data).native
					subkey = Key(aprep['enc-part']['etype'], self.session_key)
					self.gssapi = get_gssapi(subkey)

					if aprep['enc-part']['etype'] != 23: #no need for seq number in rc4
						raw_seq_data, err = await self.ksspi.get_sequenceno()
						if err is not None:
							return None, None, err
						self.seq_number = GSSWrapToken.from_bytes(raw_seq_data[16:]).SND_SEQ
					
					self.iterations += 1
					await self.ksspi.disconnect()
					return data, False, None
					
				else:
					raise Exception('SSPI Kerberos -RPC - auth encountered too many calls for authenticate.')
			
				
			else:
				status, ctxattr, apreq, err = await self.ksspi.authenticate('KERBEROS', '','cifs/%s' % self.settings.target, 3, flags.value, authdata = b'')
				if err is not None:
					return None, None, err
				
				self.session_key, err = await self.ksspi.get_sessionkey()
				if err is not None:
					raise err
				await self.ksspi.disconnect()

				return apreq, False, None
		except Exception as e:
			return None, None, e
예제 #2
0
	async def authenticate(self, authData = None, flags = None, seq_number = 0, is_rpc = False):
		#authdata is only for api compatibility reasons
		if self.ksspi is None:
			await self.start_remote_kerberos()
		try:
			if is_rpc == True:
				if self.iterations == 0:
					flags = ISC_REQ.CONFIDENTIALITY | \
							ISC_REQ.INTEGRITY | \
							ISC_REQ.MUTUAL_AUTH | \
							ISC_REQ.REPLAY_DETECT | \
							ISC_REQ.SEQUENCE_DETECT|\
							ISC_REQ.USE_DCE_STYLE
					
					apreq, res = await self.ksspi.authenticate('cifs/%s' % self.settings.target, flags = str(flags.value))

					self.iterations += 1
					return apreq, True, None
				
				elif self.iterations == 1:
					data, err = await self.ksspi.authenticate('cifs/%s' % self.settings.target, flags = str(flags.value), token_data = authData)
					if err is not None:
						return None, None, err
					self.session_key, err = await self.ksspi.get_session_key()
					if err is not None:
						return None, None, err
						
					aprep = AP_REP.load(data).native
					subkey = Key(aprep['enc-part']['etype'], self.session_key)
					self.gssapi = get_gssapi(subkey)

					if aprep['enc-part']['etype'] != 23: #no need for seq number in rc4
						raw_seq_data, err = await self.ksspi.get_seq_number()
						if err is not None:
							return None, None, err
						self.seq_number = GSSWrapToken.from_bytes(raw_seq_data[16:]).SND_SEQ
					
					self.iterations += 1
					await self.ksspi.disconnect()
					return data, False, None
					
				else:
					raise Exception('SSPI Kerberos -RPC - auth encountered too many calls for authenticate.')
			
				
			else:
				apreq, res = await self.ksspi.authenticate('cifs/%s' % self.settings.target)
				#print('MULTIPLEXOR KERBEROS SSPI, APREQ: %s ERROR: %s' % (apreq, res))
				if res is None:
					self.session_key, res = await self.ksspi.get_session_key()
					await self.ksspi.disconnect()

				return apreq, res, None
		except Exception as e:
			return None, None, err
예제 #3
0
파일: sspi.py 프로젝트: Red-infosec/aiosmb
    async def authenticate(self,
                           authData=None,
                           flags=None,
                           seq_number=0,
                           is_rpc=False):
        #authdata is only for api compatibility reasons
        if is_rpc == True:
            if self.iterations == 0:
                flags = ISC_REQ.CONFIDENTIALITY | \
                  ISC_REQ.INTEGRITY | \
                  ISC_REQ.MUTUAL_AUTH | \
                  ISC_REQ.REPLAY_DETECT | \
                  ISC_REQ.SEQUENCE_DETECT|\
                  ISC_REQ.USE_DCE_STYLE

                token = self.ksspi.get_ticket_for_spn(self.target,
                                                      flags=flags,
                                                      is_rpc=True,
                                                      token_data=authData)
                #print(token.hex())
                self.iterations += 1
                return token, True

            elif self.iterations == 1:
                flags = ISC_REQ.USE_DCE_STYLE

                token = self.ksspi.get_ticket_for_spn(self.target,
                                                      flags=flags,
                                                      is_rpc=True,
                                                      token_data=authData)
                #print(token.hex())

                aprep = AP_REP.load(token).native

                subkey = Key(aprep['enc-part']['etype'],
                             self.get_session_key())

                cipher_text = aprep['enc-part']['cipher']
                cipher = _enctype_table[aprep['enc-part']['etype']]()

                plaintext = cipher.decrypt(subkey, 12, cipher_text)

                self.gssapi = get_gssapi(subkey)

                self.iterations += 1
                return token, False

            else:
                raise Exception(
                    'SSPI Kerberos -RPC - auth encountered too many calls for authenticate.'
                )

        else:
            apreq = self.ksspi.get_ticket_for_spn(self.target)
            return apreq, False
예제 #4
0
    async def authenticate(self,
                           authData,
                           flags=None,
                           seq_number=0,
                           is_rpc=False):

        if self.iterations == 0:
            #tgt = await self.kc.get_TGT(override_etype=[18])
            tgt = await self.kc.get_TGT()
            tgs, encpart, self.session_key = await self.kc.get_TGS(self.spn)
        ap_opts = []
        if is_rpc == True:
            if self.iterations == 0:
                ap_opts.append('mutual-required')
                flags = ChecksumFlags.GSS_C_CONF_FLAG | ChecksumFlags.GSS_C_INTEG_FLAG | ChecksumFlags.GSS_C_SEQUENCE_FLAG|\
                  ChecksumFlags.GSS_C_REPLAY_FLAG | ChecksumFlags.GSS_C_MUTUAL_FLAG | ChecksumFlags.GSS_C_DCE_STYLE

                apreq = self.kc.construct_apreq(tgs,
                                                encpart,
                                                self.session_key,
                                                flags=flags,
                                                seq_number=seq_number,
                                                ap_opts=ap_opts)
                self.iterations += 1
                return apreq, False

            else:
                #mutual authentication part here
                aprep = AP_REP.load(authData).native
                cipher = _enctype_table[int(aprep['enc-part']['etype'])]()
                cipher_text = aprep['enc-part']['cipher']
                temp = cipher.decrypt(self.session_key, 12, cipher_text)

                enc_part = EncAPRepPart.load(temp).native
                cipher = _enctype_table[int(enc_part['subkey']['keytype'])]()

                now = datetime.datetime.now(datetime.timezone.utc)
                apreppart_data = {}
                apreppart_data['cusec'] = now.microsecond
                apreppart_data['ctime'] = now.replace(microsecond=0)
                apreppart_data['seq-number'] = enc_part['seq-number']

                apreppart_data_enc = cipher.encrypt(
                    self.session_key, 12,
                    EncAPRepPart(apreppart_data).dump(), None)

                #overriding current session key
                self.session_key = Key(cipher.enctype,
                                       enc_part['subkey']['keyvalue'])

                ap_rep = {}
                ap_rep['pvno'] = 5
                ap_rep['msg-type'] = MESSAGE_TYPE.KRB_AP_REP.value
                ap_rep['enc-part'] = EncryptedData({
                    'etype': self.session_key.enctype,
                    'cipher': apreppart_data_enc
                })

                token = AP_REP(ap_rep).dump()
                self.gssapi = get_gssapi(self.session_key)
                self.iterations += 1

                return token, False
        else:
            apreq = self.kc.construct_apreq(tgs,
                                            encpart,
                                            self.session_key,
                                            flags=flags,
                                            seq_number=seq_number,
                                            ap_opts=ap_opts)
            return apreq, False
예제 #5
0
    async def authenticate(self,
                           authData=None,
                           flags=None,
                           seq_number=0,
                           is_rpc=False):
        #authdata is only for api compatibility reasons
        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.ksspi is None:
            self.ksspi, err = await self.operator.create_sspi(self.agent_id)
            if err is not None:
                return None, None, err
        try:
            if is_rpc == True:
                if self.iterations == 0:
                    flags = ISC_REQ.CONFIDENTIALITY | \
                      ISC_REQ.INTEGRITY | \
                      ISC_REQ.MUTUAL_AUTH | \
                      ISC_REQ.REPLAY_DETECT | \
                      ISC_REQ.SEQUENCE_DETECT|\
                      ISC_REQ.USE_DCE_STYLE

                    context_attributes, apreq, err = await self.ksspi.kerberos(
                        'cifs/%s' % self.settings.target,
                        context_attributes=flags.value)
                    if err is not None:
                        raise err

                    self.iterations += 1
                    return apreq, True, None

                elif self.iterations == 1:
                    context_attributes, data, err = await self.ksspi.kerberos(
                        target_name='cifs/%s' % self.settings.target,
                        context_attributes=flags.value,
                        token_data=authData)
                    if err is not None:
                        return None, None, err
                    self.session_key, err = await self.ksspi.get_sessionkey()
                    if err is not None:
                        return None, None, err

                    aprep = AP_REP.load(data).native
                    subkey = Key(aprep['enc-part']['etype'], self.session_key)
                    self.gssapi = get_gssapi(subkey)

                    if aprep['enc-part'][
                            'etype'] != 23:  #no need for seq number in rc4
                        raw_seq_data, err = await self.ksspi.get_sequenceno()
                        if err is not None:
                            return None, None, err
                        self.seq_number = GSSWrapToken.from_bytes(
                            raw_seq_data[16:]).SND_SEQ

                    self.iterations += 1
                    await self.ksspi.disconnect()
                    return data, False, None

                else:
                    raise Exception(
                        'SSPI Kerberos -RPC - auth encountered too many calls for authenticate.'
                    )

            else:
                context_attributes, apreq, err = await self.ksspi.kerberos(
                    target_name='cifs/%s' % self.settings.target)
                #print('MULTIPLEXOR KERBEROS SSPI, APREQ: %s ERROR: %s' % (apreq, res))
                if err is not None:
                    raise err

                self.session_key, err = await self.ksspi.get_sessionkey()
                if err is not None:
                    raise err
                await self.ksspi.disconnect()

                return apreq, False, None
        except Exception as e:
            return None, None, err