async def handle_heartbeat(self, **kwargs): results = kwargs.pop('results', []) for agent in await self.get_service('data_svc').locate( 'agents', dict(paw=kwargs.get('paw', None))): await agent.heartbeat_modification(**kwargs) self.log.debug('Incoming %s beacon from %s' % (agent.contact, agent.paw)) for result in results: await self._save(Result(**result)) await self.get_service('event_svc').fire_event( 'link/completed', agent=agent.display, pid=result['pid']) return agent, await self._get_instructions(agent) agent = await self.get_service('data_svc').store( Agent.load( dict(sleep_min=self.get_config(name='agents', prop='sleep_min'), sleep_max=self.get_config(name='agents', prop='sleep_max'), watchdog=self.get_config(name='agents', prop='watchdog'), **kwargs))) await self._add_agent_to_operation(agent) self.log.debug('First time %s beacon from %s' % (agent.contact, agent.paw)) await agent.bootstrap(self.get_service('data_svc')) return agent, await self._get_instructions(agent)
async def handle_heartbeat(self, **kwargs): """ Accept all components of an agent profile and save a new agent or register an updated heartbeat. :param kwargs: key/value pairs :return: the agent object, instructions to execute """ result = kwargs.pop('result', dict()) for agent in await self.get_service('data_svc').locate( 'agents', dict(paw=kwargs.get('paw', None))): await agent.heartbeat_modification(**kwargs) self.log.debug('Incoming %s beacon from %s' % (agent.contact, agent.paw)) if result: await self._save(Result(**result)) return agent, await self._get_instructions(agent.paw) agent = await self.get_service('data_svc').store( Agent(sleep_min=self.sleep_min, sleep_max=self.sleep_max, watchdog=self.watchdog, **kwargs)) await self._add_agent_to_operation(agent) self.log.debug('First time %s beacon from %s' % (agent.contact, agent.paw)) return agent, await self._get_instructions( agent.paw) + await self._get_bootstrap_instructions(agent)
async def handle_heartbeat(self, **kwargs): results = kwargs.pop('results', []) old_paw = kwargs.get('paw') if old_paw: kwargs['paw'] = await self._sanitize_paw(old_paw) for agent in await self.get_service('data_svc').locate('agents', dict(paw=kwargs.get('paw', None))): await agent.heartbeat_modification(**kwargs) self.log.debug('Incoming %s beacon from %s' % (agent.contact, agent.paw)) for result in results: self.log.debug('Received result for link %s from agent %s via contact %s' % (result['id'], agent.paw, agent.contact)) await self._save(Result(**result)) operation = await self.get_service('app_svc').find_op_with_link(result['id']) access = operation.access if operation else self.Access.RED await self.get_service('event_svc').fire_event(exchange='link', queue='completed', agent=agent.display, pid=result['pid'], link_id=result['id'], access=access.value) if results: return agent, [] return agent, await self._get_instructions(agent) agent = await self.get_service('data_svc').store( Agent.load(dict(sleep_min=self.get_config(name='agents', prop='sleep_min'), sleep_max=self.get_config(name='agents', prop='sleep_max'), watchdog=self.get_config(name='agents', prop='watchdog'), **kwargs)) ) await self._add_agent_to_operation(agent) self.log.debug('First time %s beacon from %s' % (agent.contact, agent.paw)) data_svc = self.get_service('data_svc') await agent.bootstrap(data_svc) if agent.deadman_enabled: self.log.debug("Agent %s can accept deadman abilities. Will return any available deadman abilities." % agent.paw) await agent.deadman(data_svc) return agent, await self._get_instructions(agent)
def _make_result(link_id): result = dict(id=link_id, output=str( base64.b64encode( '10.10.10.10'.encode('utf-8')).decode('utf-8')), pid=0, status=0) return Result(**result)
async def operation_loop(self): while True: await self.tcp_handler.refresh() for session in self.tcp_handler.sessions: _, instructions = await self.contact_svc.handle_heartbeat(paw=session.paw) for instruction in instructions: try: self.log.debug('TCP instruction: %s' % instruction.id) status, _, response = await self.tcp_handler.send(session.id, self.decode_bytes(instruction.command)) result = Result(id=instruction.id, output=self.encode_string(response), status=status) await self.contact_svc.handle_heartbeat(paw=session.paw, result=result) await asyncio.sleep(instruction.sleep) except Exception as e: self.log.debug('[-] operation exception: %s' % e) await asyncio.sleep(20)
async def test_save_ability_hooks(self, setup_contact_service, contact_svc): test_string = b'test_string' link = setup_contact_service rest_svc = RestService() result = dict(id=link.id, output=str( base64.b64encode(base64.b64encode(test_string)), 'utf-8'), pid=0, status=0) await contact_svc._save(Result(**result)) result = await rest_svc.display_result(dict(link_id=link.id)) assert base64.b64decode(result['output']) == test_string # cleanup test try: os.remove(os.path.join('data', 'results', link.id)) except FileNotFoundError: print('Unable to cleanup test_save_ability_hooks result file')
async def process_elasticsearch_results(self, operation, link): file_svc = self.get_service('file_svc') contact_svc = self.get_service('contact_svc') link_output = BaseService.decode_bytes( file_svc.read_result_file(link.id)) loaded_output = json.loads(link_output) for result in loaded_output: # Add link new_link = deepcopy(link) new_link.facts = [] new_link.relationships = [] new_link.apply_id(new_link.host) operation.chain.append(new_link) await self.data_svc.store(operation) # Add result for new link new_result = Result(id=new_link.id, output=BaseService.encode_string( json.dumps(result, indent=4)), pid=str(link.pid), status=str(link.status)) await contact_svc._save(new_result)