示例#1
0
 def test_set_pending_executor_removal(self):
     agent = Agent(paw='123', sleep_min=2, sleep_max=8, watchdog=0, executors=['cmd', 'test'], platform='windows')
     executor_to_remove = 'test'
     want = dict(executor=executor_to_remove, action='remove')
     agent.set_pending_executor_removal(executor_to_remove)
     assert agent.executor_change_to_assign == want
     assert agent.executors == ['cmd']
示例#2
0
 async def handle_heartbeat(self, paw, platform, server, group, host, username, executors, architecture, location,
                            pid, ppid, sleep, privilege, c2):
     """
     Accept all components of an agent profile and save a new agent or register an updated heartbeat.
     :param paw:
     :param platform:
     :param server:
     :param group:
     :param host:
     :param username:
     :param executors:
     :param architecture:
     :param location:
     :param pid:
     :param ppid:
     :param sleep:
     :param privilege:
     :return: the agent object from explode
     """
     self.log.debug('HEARTBEAT (%s) (%s)' % (c2, paw))
     agent = Agent(paw=paw, host=host, username=username, platform=platform, server=server, location=location,
                   executors=executors, architecture=architecture, pid=pid, ppid=ppid, privilege=privilege, c2=c2)
     if await self.data_svc.locate('agents', dict(paw=paw)):
         return await self.data_svc.store(agent)
     agent.sleep_min = agent.sleep_max = sleep
     agent.group = group
     agent.trusted = True
     return await self.data_svc.store(agent)
示例#3
0
 def test_builtin_fact_replacement_with_upstream_dest(
         self, loop, obfuscator, init_base_world):
     executor = Executor(
         name='psh',
         platform='windows',
         command=
         'echo #{paw} #{server} #{group} #{location} #{exe_name} #{upstream_dest}'
     )
     ability = Ability(ability_id='123', executors=[executor])
     agent = Agent(paw='123',
                   sleep_min=2,
                   sleep_max=8,
                   watchdog=0,
                   executors=['pwsh', 'psh'],
                   platform='windows',
                   group='my_group',
                   server='http://10.10.10.10:8888',
                   location='testlocation',
                   exe_name='testexe',
                   upstream_dest='http://127.0.0.1:12345')
     loop.run_until_complete(agent.task([ability], 'plain-text', []))
     assert 1 == len(agent.links)
     link = agent.links[0]
     decoded_command = b64decode(link.command).decode('utf-8')
     want = 'echo 123 http://10.10.10.10:8888 my_group testlocation testexe http://127.0.0.1:12345'
     assert want == decoded_command
示例#4
0
 async def handle_heartbeat(self, paw, platform, server, group, executors, architecture, location, pid, ppid, sleep, privilege):
     """
     Accept all components of an agent profile and save a new agent or register an updated heartbeat.
     :param paw:
     :param platform:
     :param server:
     :param group:
     :param executors:
     :param architecture:
     :param location:
     :param pid:
     :param ppid:
     :param privilege:
     :return: the agent object from explode
     """
     self.log.debug('HEARTBEAT (%s)' % paw)
     now = self.get_current_timestamp()
     agent = Agent(last_seen=now, paw=paw, platform=platform, server=server, location=location, executors=executors,
                   architecture=architecture, pid=pid, ppid=ppid, trusted=True, last_trusted_seen=now,
                   privilege=privilege)
     if await self.data_svc.locate('agents', dict(paw=paw)):
         return await self.data_svc.store(agent)
     agent.sleep_min = agent.sleep_max = sleep
     agent.group = group
     return await self.data_svc.store(agent)
示例#5
0
    async def handle_heartbeat(self, paw, platform, server, group, host, username, executors, architecture, location,
                               pid, ppid, sleep, privilege, c2, exe_name):
        """
        Accept all components of an agent profile and save a new agent or register an updated heartbeat.

        :param paw:
        :param platform:
        :param server:
        :param group:
        :param host:
        :param username:
        :param executors:
        :param architecture:
        :param location:
        :param pid:
        :param ppid:
        :param sleep:
        :param privilege:
        :return: the agent object from explode
        """
        agent = Agent(paw=paw, host=host, username=username, platform=platform, server=server, location=location,
                      executors=executors, architecture=architecture, pid=pid, ppid=ppid, privilege=privilege, c2=c2,
                      exe_name=exe_name)
        if await self.get_service('data_svc').locate('agents', dict(paw=paw)):
            new_agent = await self.get_service('data_svc').store(agent)
            await self._add_agent_to_operation(new_agent)
            return new_agent
        agent.sleep_min = agent.sleep_max = sleep
        agent.group = group
        agent.trusted = True
        new_agent = await self.get_service('data_svc').store(agent)
        await self._add_agent_to_operation(new_agent)
        return new_agent
示例#6
0
    def test_task_with_facts(self, event_loop, obfuscator, init_base_world, knowledge_svc):
        executor = Executor(name='psh', platform='windows', command='net user #{domain.user.name} /domain')
        ability = Ability(ability_id='123', executors=[executor])
        agent = Agent(paw='123', sleep_min=2, sleep_max=8, watchdog=0, executors=['pwsh', 'psh'], platform='windows')
        fact = Fact(trait='domain.user.name', value='bob')

        event_loop.run_until_complete(agent.task([ability], 'plain-text', [fact]))
        assert 1 == len(agent.links)
示例#7
0
    def test_agent(self):
        self.run_async(self.data_svc.store(Agent(paw='123$abc')))
        self.run_async(self.data_svc.store(Agent(paw='123$abc')))
        agents = self.run_async(self.data_svc.locate('agents'))

        self.assertEqual(1, len(agents))
        for x in agents:
            json.dumps(x.display)
示例#8
0
    def test_agent(self):
        self.run_async(self.data_svc.store(Agent(sleep_min=2, sleep_max=8, watchdog=0)))
        self.run_async(self.data_svc.store(Agent(sleep_min=2, sleep_max=8, watchdog=0)))
        agents = self.run_async(self.data_svc.locate('agents'))

        self.assertEqual(2, len(agents))
        for x in agents:
            json.dumps(x.display)
示例#9
0
 def test_assign_executor_change(self):
     agent = Agent(paw='123', sleep_min=2, sleep_max=8, watchdog=0, executors=['cmd', 'test'], platform='windows')
     executor_to_change = 'test'
     new_path = 'new_path'
     want = dict(action='update_path', executor=executor_to_change, value=new_path)
     agent.set_pending_executor_path_update(executor_to_change, new_path)
     assert agent.assign_pending_executor_change() == want
     assert agent.executor_change_to_assign is None
示例#10
0
    def test_task_with_facts(self, loop, obfuscator, init_base_world):
        ability = Ability(ability_id='123', test=BaseWorld.encode_string('net user #{domain.user.name} /domain'),
                          variations=[], executor='psh', platform='windows')
        agent = Agent(paw='123', sleep_min=2, sleep_max=8, watchdog=0, executors=['pwsh', 'psh'], platform='windows')
        fact = Fact(trait='domain.user.name', value='bob')

        loop.run_until_complete(agent.task([ability], 'plain-text', [fact]))
        assert 1 == len(agent.links)
示例#11
0
 def test_updating_nonexistent_executor(self):
     agent = Agent(paw='123',
                   sleep_min=2,
                   sleep_max=8,
                   watchdog=0,
                   executors=['cmd', 'test'],
                   platform='windows')
     agent.set_pending_executor_path_update('idontexist', 'fakepath')
     assert agent.executor_change_to_assign is None
示例#12
0
    def test_multiple_agents(self, loop, data_svc):
        loop.run_until_complete(
            data_svc.store(Agent(sleep_min=2, sleep_max=8, watchdog=0)))
        loop.run_until_complete(
            data_svc.store(Agent(sleep_min=2, sleep_max=8, watchdog=0)))
        agents = loop.run_until_complete(data_svc.locate('agents'))

        assert len(agents) == 2
        for x in agents:
            json.dumps(x.display)
示例#13
0
    def test_preferred_executor_from_agent_executor(self, event_loop, ability, executor):
        executor_test = executor(name='test', platform='windows')
        executor_cmd = executor(name='cmd', platform='windows')
        executor_psh = executor(name='psh', platform='windows')
        test_ability = ability(ability_id='123', executors=[executor_test, executor_cmd, executor_psh])

        agent = Agent(paw='123', sleep_min=2, sleep_max=8, watchdog=0, executors=['cmd', 'test'], platform='windows')

        preferred_executor = event_loop.run_until_complete(agent.get_preferred_executor(test_ability))
        assert preferred_executor is executor_cmd  # prefer agent's first executor, not ability's
示例#14
0
    def test_preferred_executor_psh(self, loop, ability, executor):
        executor_test = executor(name='test', platform='windows')
        executor_cmd = executor(name='cmd', platform='windows')
        executor_psh = executor(name='psh', platform='windows')
        test_ability = ability(ability_id='123', executors=[executor_test, executor_cmd, executor_psh])

        agent = Agent(paw='123', sleep_min=2, sleep_max=8, watchdog=0, executors=['psh', 'cmd'], platform='windows')

        preferred_executor = loop.run_until_complete(agent.get_preferred_executor(test_ability))
        assert preferred_executor is executor_psh  # 'psh' preferred if available
示例#15
0
 def test_removing_nonexistent_executor(self):
     original_executors = ['cmd', 'test']
     agent = Agent(paw='123',
                   sleep_min=2,
                   sleep_max=8,
                   watchdog=0,
                   executors=original_executors,
                   platform='windows')
     agent.set_pending_executor_removal('idontexist')
     assert agent.executor_change_to_assign is None
     assert agent.executors == original_executors
示例#16
0
 def test_task_no_facts(self, loop, data_svc, obfuscator, init_base_world):
     executor = Executor(name='psh', platform='windows', command='whoami')
     ability = Ability(ability_id='123', executors=[executor])
     agent = Agent(paw='123',
                   sleep_min=2,
                   sleep_max=8,
                   watchdog=0,
                   executors=['pwsh', 'psh'],
                   platform='windows')
     loop.run_until_complete(agent.task([ability], obfuscator='plain-text'))
     assert 1 == len(agent.links)
示例#17
0
 def test_store_new_agent(self, data_svc):
     agent = Agent(paw='123',
                   sleep_min=2,
                   sleep_max=8,
                   watchdog=0,
                   executors=['cmd', 'test'],
                   platform='windows')
     stored_agent = agent.store(data_svc.ram)
     assert len(data_svc.ram['agents']) == 1
     assert agent in data_svc.ram['agents']
     assert stored_agent == agent
示例#18
0
 def test_task_missing_fact(self, loop, obfuscator, init_base_world):
     executor = Executor(name='psh',
                         platform='windows',
                         command='net user #{domain.user.name} /domain')
     ability = Ability(ability_id='123', executors=[executor])
     agent = Agent(paw='123',
                   sleep_min=2,
                   sleep_max=8,
                   watchdog=0,
                   executors=['pwsh', 'psh'],
                   platform='windows')
     loop.run_until_complete(agent.task([ability], obfuscator='plain-text'))
     assert 0 == len(agent.links)
示例#19
0
 def test_heartbeat_modification_during_pending_executor_removal(
         self, loop):
     original_executors = ['cmd', 'test']
     agent = Agent(paw='123',
                   sleep_min=2,
                   sleep_max=8,
                   watchdog=0,
                   executors=original_executors,
                   platform='windows')
     agent.set_pending_executor_removal('test')
     loop.run_until_complete(
         agent.heartbeat_modification(executors=original_executors))
     assert agent.executors == ['cmd']
示例#20
0
 def test_task_no_facts(self, loop, data_svc, obfuscator, init_base_world):
     ability = Ability(ability_id='123',
                       test=BaseWorld.encode_string('whoami'),
                       variations=[],
                       executor='psh',
                       platform='windows')
     agent = Agent(paw='123',
                   sleep_min=2,
                   sleep_max=8,
                   watchdog=0,
                   executors=['pwsh', 'psh'],
                   platform='windows')
     loop.run_until_complete(agent.task([ability], obfuscator='plain-text'))
     assert 1 == len(agent.links)
示例#21
0
 def test_task_missing_fact(self, loop, init_base_world):
     ability = Ability(ability_id='123',
                       test=BaseWorld.encode_string(
                           'net user #{domain.user.name} /domain'),
                       variations=[],
                       executor='psh',
                       platform='windows')
     agent = Agent(paw='123',
                   sleep_min=2,
                   sleep_max=8,
                   watchdog=0,
                   executors=['pwsh', 'psh'],
                   platform='windows')
     loop.run_until_complete(agent.task([ability]))
     assert 0 == len(agent.links)
示例#22
0
 async def start_sniffer_untrusted_agents(self):
     """
     Cyclic function that repeatedly checks if there are agents to be marked as untrusted
     :return: None
     """
     next_check = self.config['untrusted_timer']
     try:
         while True:
             await asyncio.sleep(next_check + 1)
             trusted_agents = await self.get_service('data_svc').locate(
                 'agents', match=dict(trusted=1))
             next_check = self.config['untrusted_timer']
             for a in trusted_agents:
                 last_trusted_seen = datetime.strptime(
                     a.last_trusted_seen, '%Y-%m-%d %H:%M:%S')
                 silence_time = (datetime.now() -
                                 last_trusted_seen).total_seconds()
                 if silence_time > (self.config['untrusted_timer'] +
                                    int(a.sleep_max)):
                     await self.get_service('data_svc').store(
                         Agent(paw=a.paw, trusted=0))
                 else:
                     trust_time_left = self.config[
                         'untrusted_timer'] - silence_time
                     if trust_time_left < next_check:
                         next_check = trust_time_left
     except Exception as e:
         self.log.error('[!] start_sniffer_untrusted_agents: %s' % e)
示例#23
0
 def test_remove(self):
     a1 = self.run_async(self.data_svc.store(Agent(sleep_min=2, sleep_max=8, watchdog=0)))
     agents = self.run_async(self.data_svc.locate('agents', match=dict(paw=a1.paw)))
     self.assertEqual(1, len(agents))
     self.run_async(self.data_svc.remove('agents', match=dict(paw=a1.paw)))
     agents = self.run_async(self.data_svc.locate('agents', match=dict(paw=a1.paw)))
     self.assertEqual(0, len(agents))
示例#24
0
 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)
示例#25
0
 async def save_results(self, id, output, status, pid):
     """
     Save the results from a single executed link
     :param id:
     :param output:
     :param status:
     :param pid:
     :return: a JSON status message
     """
     try:
         loop = asyncio.get_event_loop()
         for op in await self.data_svc.locate('operations', match=dict(finish=None)):
             link = next((l for l in op.chain if l.unique == id), None)
             if link:
                 link.pid = int(pid)
                 link.finish = self.data_svc.get_current_timestamp()
                 link.status = int(status)
                 if output:
                     with open('data/results/%s' % id, 'w') as out:
                         out.write(output)
                     loop.create_task(link.parse(op))
                 await self.data_svc.store(Agent(paw=link.paw))
                 return json.dumps(dict(status=True))
     except Exception as e:
         self.log.error('[!] save_results: %s' % e)
示例#26
0
 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)
示例#27
0
def setup_rest_svc_test(loop, data_svc):
    BaseWorld.apply_config(name='default',
                           config={
                               'app.contact.http': '0.0.0.0',
                               'plugins': ['sandcat', 'stockpile'],
                               'crypt_salt': 'BLAH',
                               'api_key': 'ADMIN123',
                               'encryption_key': 'ADMIN123',
                               'exfil_dir': '/tmp'
                           })
    loop.run_until_complete(
        data_svc.store(
            Ability(ability_id='123',
                    test=BaseWorld.encode_string('curl #{app.contact.http}'),
                    variations=[])))
    loop.run_until_complete(
        data_svc.store(
            Adversary(adversary_id='123',
                      name='test',
                      description='test',
                      phases=[])))
    loop.run_until_complete(
        data_svc.store(Agent(paw='123', sleep_min=2, sleep_max=8, watchdog=0)))
    loop.run_until_complete(
        data_svc.store(
            Planner(planner_id='123',
                    name='test',
                    module='test',
                    params=dict())))
    loop.run_until_complete(
        data_svc.store(Source(identifier='123', name='test', facts=[])))
示例#28
0
 def test_privileged_to_run__1(self, event_loop, data_svc):
     """ Test ability.privilege == None """
     agent = event_loop.run_until_complete(
         data_svc.store(Agent(sleep_min=1, sleep_max=2, watchdog=0)))
     ability = event_loop.run_until_complete(
         data_svc.store(Ability(ability_id='123', privilege=None)))
     assert agent.privileged_to_run(ability)
示例#29
0
def test_agent(event_loop, mocker, mock_time):
    with mocker.patch('app.objects.c_agent.datetime') as mock_datetime:
        mock_datetime.return_value = mock_datetime
        mock_datetime.now.return_value = mock_time
        test_agent = Agent(paw='123', sleep_min=2, sleep_max=8, watchdog=0, executors=['sh'], platform='linux')
        event_loop.run_until_complete(BaseService.get_service('data_svc').store(test_agent))
        return test_agent
示例#30
0
 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)