def test_check_repeatable_abilities(self, repeatable_ability):
     test_adversary = Adversary(adversary_id='123',
                                name='test',
                                description='',
                                atomic_ordering=['456'])
     ram = dict(adversaries=[test_adversary],
                abilities=[repeatable_ability])
     assert test_adversary.check_repeatable_abilities(ram['abilities'])
 def test_store_existing(self, unrepeatable_ability, repeatable_ability):
     test_adversary = Adversary(adversary_id='123',
                                name='test',
                                description='',
                                atomic_ordering=['123'])
     ram = dict(adversaries=[test_adversary],
                abilities=[unrepeatable_ability, repeatable_ability])
     test_adversary.atomic_ordering = ['456']
     test_adversary.store(ram)
     assert ram['adversaries'][0].has_repeatable_abilities
     assert ram['adversaries'][0].atomic_ordering[0] == '456'
Exemple #3
0
    def test_adversary(self):
        self.run_async(self.data_svc.store(
            Adversary(adversary_id='123', name='test', description='test adversary', phases=dict())
        ))
        self.run_async(self.data_svc.store(
            Adversary(adversary_id='123', name='test', description='test adversary', phases=dict())
        ))
        adversaries = self.run_async(self.data_svc.locate('adversaries'))

        self.assertEqual(1, len(adversaries))
        for x in adversaries:
            json.dumps(x.display)
Exemple #4
0
 async def _load_adversaries(self, plugin):
     for filename in glob.iglob('%s/adversaries/**/*.yml' % plugin.data_dir, recursive=True):
         for adv in self.strip_yml(filename):
             if adv.get('phases'):
                 ordering = await self._load_phase_adversary_variant(adv)
             else:
                 ordering = adv.get('atomic_ordering', list())
             atomic_ordering = await self._link_abilities(ordering, adv)
             adversary = Adversary(adversary_id=adv['id'], name=adv['name'], description=adv['description'],
                                   atomic_ordering=atomic_ordering)
             adversary.access = plugin.access
             await self.store(adversary)
Exemple #5
0
 async def _load_adversaries(self, plugin):
     for filename in glob.iglob('%s/adversaries/**/*.yml' % plugin.data_dir, recursive=True):
         for adv in self.strip_yml(filename):
             phases = adv.get('phases', dict())
             for p in adv.get('packs', []):
                 adv_pack = await self._add_adversary_packs(p)
                 if adv_pack:
                     await self._merge_phases(phases, adv_pack)
             sorted_phases = [phases[x] for x in sorted(phases.keys())]
             phases = await self._add_phases(sorted_phases, adv)
             adversary = Adversary(adversary_id=adv['id'], name=adv['name'], description=adv['description'],
                                   phases=phases)
             adversary.access = plugin.access
             await self.store(adversary)
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=[])))
Exemple #7
0
def setup_planning_test(loop, ability, agent, operation, data_svc,
                        init_base_world):
    tability = ability(ability_id='123',
                       executor='sh',
                       platform='darwin',
                       test=BaseWorld.encode_string('mkdir test'),
                       cleanup=BaseWorld.encode_string('rm -rf test'),
                       variations=[])
    tagent = agent(sleep_min=1,
                   sleep_max=2,
                   watchdog=0,
                   executors=['sh'],
                   platform='darwin')
    tsource = Source(id='123', name='test', facts=[], adjustments=[])
    toperation = operation(name='test1',
                           agents=tagent,
                           adversary=Adversary(name='test',
                                               description='test',
                                               atomic_ordering=[],
                                               adversary_id='XYZ'),
                           source=tsource)

    loop.run_until_complete(data_svc.store(tability))

    loop.run_until_complete(
        data_svc.store(
            Obfuscator(
                name='plain-text',
                description=
                'Does no obfuscation to any command, instead running it in plain text',
                module='plugins.stockpile.app.obfuscators.plain_text')))

    yield tability, tagent, toperation
Exemple #8
0
 async def _load_adversaries(self, directory):
     for filename in glob.iglob('%s/*.yml' % directory, recursive=True):
         for adv in self.strip_yml(filename):
             phases = [
                 dict(phase=k, id=i)
                 for k, v in adv.get('phases', dict()).items() for i in v
             ]
             ps = []
             for p in adv.get('packs', []):
                 ps.append(await self._add_adversary_packs(p))
             for pack in ps:
                 phases += pack
             if adv.get('visible', True):
                 pp = defaultdict(list)
                 for phase in phases:
                     matching_abilities = await self.locate(
                         'abilities', match=dict(ability_id=phase['id']))
                     if not len(matching_abilities):
                         self.log.error(
                             'Missing Ability (%s) for adversary: %s' %
                             (phase['id'], adv['name']))
                     for ability in matching_abilities:
                         pp[phase['phase']].append(ability)
                 phases = dict(pp)
                 await self.store(
                     Adversary(adversary_id=adv['id'],
                               name=adv['name'],
                               description=adv['description'],
                               phases=phases))
def setup_learning_service(loop, data_svc, ability, operation, link):
    tability = ability(tactic='discovery',
                       technique_id='T1033',
                       technique='Find',
                       name='test',
                       test='d2hvYW1pCg==',
                       description='find active user',
                       cleanup='',
                       executor='sh',
                       platform='darwin',
                       payloads=['wifi.sh'],
                       parsers=[],
                       requirements=[],
                       privilege=None,
                       variations=[])
    loop.run_until_complete(data_svc.store(tability))
    toperation = operation(name='sample',
                           agents=None,
                           adversary=Adversary(name='sample',
                                               adversary_id='XYZ',
                                               atomic_ordering=[],
                                               description='test'))
    loop.run_until_complete(data_svc.store(toperation))
    tlink = link(ability=tability, command='', paw='')
    yield toperation, tlink
Exemple #10
0
 async def _load_adversaries(self, directory):
     total = 0
     for filename in glob.iglob('%s/*.yml' % directory, recursive=True):
         for adv in self.strip_yml(filename):
             phases = [
                 dict(phase=k, id=i)
                 for k, v in adv.get('phases', dict()).items() for i in v
             ]
             for pack in [
                     await self._add_adversary_packs(p)
                     for p in adv.get('packs', [])
             ]:
                 phases += pack
             if adv.get('visible', True):
                 pp = defaultdict(list)
                 for phase in phases:
                     for ability in await self.locate(
                             'abilities',
                             match=dict(ability_id=phase['id'])):
                         pp[phase['phase']].append(ability)
                 phases = dict(pp)
                 await self.store(
                     Adversary(adversary_id=adv['id'],
                               name=adv['name'],
                               description=adv['description'],
                               phases=phases))
                 total += 1
     self.log.debug('Loaded %s adversaries' % total)
Exemple #11
0
def setup_planning_test(loop, executor, ability, agent, operation, data_svc, event_svc, init_base_world):
    texecutor = executor(name='sh', platform='darwin', command='mkdir test', cleanup='rm -rf test')
    tability = ability(ability_id='123', executors=[texecutor], repeatable=True, buckets=['test'], name='test1')
    tagent = agent(sleep_min=1, sleep_max=2, watchdog=0, executors=['sh'], platform='darwin',
                   server='http://127.0.0.1:8000')
    tsource = Source(id='123', name='test', facts=[], adjustments=[])
    toperation = operation(name='test1', agents=[tagent],
                           adversary=Adversary(name='test', description='test',
                                               atomic_ordering=[],
                                               adversary_id='XYZ'),
                           source=tsource)

    cexecutor = executor(name='sh', platform='darwin', command=test_string, cleanup='whoami')
    cability = ability(ability_id='321', executors=[cexecutor], singleton=True, name='test2')

    loop.run_until_complete(data_svc.store(tability))
    loop.run_until_complete(data_svc.store(cability))

    loop.run_until_complete(data_svc.store(
        Obfuscator(name='plain-text',
                   description='Does no obfuscation to any command, instead running it in plain text',
                   module='plugins.stockpile.app.obfuscators.plain_text')
    ))

    yield tability, tagent, toperation, cability
Exemple #12
0
    def test_save_discover_seeded_fact_not_in_command(self, event_loop,
                                                      ability, executor,
                                                      operation,
                                                      knowledge_svc):
        test_executor = executor(name='psh', platform='windows')
        test_ability = ability(ability_id='123', executors=[test_executor])
        fact1 = Fact(trait='remote.host.fqdn', value='dc')
        fact2 = Fact(trait='domain.user.name', value='Bob')
        relationship = Relationship(source=fact1,
                                    edge='has_user',
                                    target=fact2)
        link = Link(command='net user',
                    paw='123456',
                    ability=test_ability,
                    id='111111',
                    executor=test_executor)
        operation = operation(name='test-op',
                              agents=[],
                              adversary=Adversary(name='sample',
                                                  adversary_id='XYZ',
                                                  atomic_ordering=[],
                                                  description='test'),
                              source=Source(id='test-source',
                                            facts=[fact1, fact2]))
        event_loop.run_until_complete(operation._init_source())
        event_loop.run_until_complete(
            link.save_fact(operation, fact2, 1, relationship))

        assert fact2.origin_type == OriginType.SEEDED
        assert '123456' in fact2.collected_by
Exemple #13
0
 async def _load_adversaries(self, plugin):
     for filename in glob.iglob('%s/adversaries/**/*.yml' % plugin.data_dir,
                                recursive=True):
         for adv in self.strip_yml(filename):
             adversary = Adversary.load(adv)
             adversary.access = plugin.access
             await self.store(adversary)
Exemple #14
0
 async def _adjust_adversary_phases(self):
     if not self.phases_enabled:
         return Adversary(adversary_id=(self.adversary.adversary_id + "_phases_disabled"),
                          name=(self.adversary.name + " - with phases disabled"),
                          description=(self.adversary.name + " with phases disabled"),
                          phases={1: [i for phase, ab in self.adversary.phases.items() for i in ab]})
     else:
         return self.adversary
Exemple #15
0
 async def _construct_adversary_for_op(self, adversary_id):
     adv = await self.get_service('data_svc').locate(
         'adversaries', match=dict(adversary_id=adversary_id))
     if adv:
         return copy.deepcopy(adv[0])
     return Adversary(adversary_id=0,
                      name='ad-hoc',
                      description='an empty adversary profile',
                      phases={'1': []})
Exemple #16
0
    def test_no_duplicate_adversary(self, loop, data_svc):
        loop.run_until_complete(
            data_svc.store(
                Adversary(adversary_id='123',
                          name='test',
                          description='test adversary',
                          phases=dict())))
        loop.run_until_complete(
            data_svc.store(
                Adversary(adversary_id='123',
                          name='test',
                          description='test adversary',
                          phases=dict())))
        adversaries = loop.run_until_complete(data_svc.locate('adversaries'))

        assert len(adversaries) == 1
        for x in adversaries:
            json.dumps(x.display)
Exemple #17
0
def setup_rest_svc_test(loop, data_svc):
    BaseWorld.apply_config(name='main',
                           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=[],
                    executor='psh',
                    platform='windows')))
    adversary = Adversary(adversary_id='123',
                          name='test',
                          description='test',
                          atomic_ordering=[])
    loop.run_until_complete(data_svc.store(adversary))

    agent = Agent(paw='123',
                  sleep_min=2,
                  sleep_max=8,
                  watchdog=0,
                  executors=['pwsh', 'psh'],
                  platform='windows')
    loop.run_until_complete(data_svc.store(agent))

    loop.run_until_complete(
        data_svc.store(
            Planner(planner_id='123',
                    name='test',
                    module='test',
                    params=dict())))

    source = Source(id='123', name='test', facts=[], adjustments=[])
    loop.run_until_complete(data_svc.store(source))

    loop.run_until_complete(
        data_svc.store(
            Operation(name='test',
                      agents=[agent],
                      adversary=adversary,
                      id='123',
                      source=source)))

    loop.run_until_complete(
        data_svc.store(
            Obfuscator(
                name='plain-text',
                description=
                'Does no obfuscation to any command, instead running it in plain text',
                module='plugins.stockpile.app.obfuscators.plain_text')))
Exemple #18
0
 def _generate_adversary(adversary_id=None, name=None, description=None, phases=None):
     if not adversary_id:
         adversary_id = uuid.uuid4()
     if not name:
         name = ''.join(random.choice(string.ascii_uppercase) for _ in range(10))
     if not description:
         description = "description"
     if not phases:
         phases = dict()
     return Adversary(adversary_id=adversary_id, name=name, description=description, atomic_ordering=phases)
Exemple #19
0
    def test_no_duplicate_adversary(self, event_loop, data_svc):
        event_loop.run_until_complete(
            data_svc.store(
                Adversary(adversary_id='123',
                          name='test',
                          description='test adversary',
                          atomic_ordering=list())))
        event_loop.run_until_complete(
            data_svc.store(
                Adversary(adversary_id='123',
                          name='test',
                          description='test adversary',
                          atomic_ordering=list())))
        adversaries = event_loop.run_until_complete(
            data_svc.locate('adversaries'))

        assert len(adversaries) == 1
        for x in adversaries:
            json.dumps(x.display)
Exemple #20
0
 async def _construct_adversary_for_op(self, adversary_id):
     adv = await self.get_service('data_svc').locate(
         'adversaries', match=dict(adversary_id=adversary_id))
     if adv:
         return copy.deepcopy(adv[0])
     return Adversary.load(
         dict(adversary_id='ad-hoc',
              name='ad-hoc',
              description='an empty adversary profile',
              atomic_ordering=[]))
Exemple #21
0
    def test_operation(self):
        adversary = self.run_async(self.data_svc.store(
            Adversary(adversary_id='123', name='test', description='test adversary', phases=dict())
        ))
        self.run_async(self.data_svc.store(Operation(name='my first op', agents=[], adversary=adversary)))

        operations = self.run_async(self.data_svc.locate('operations'))
        self.assertEqual(1, len(operations))
        for x in operations:
            json.dumps(x.display)
 async def _construct_and_dump_adversary(self, adversary_id: str):
     adv = await self.services['data_svc'].locate(
         'adversaries', match=dict(adversary_id=adversary_id))
     if not adv:
         adv = Adversary.load(
             dict(adversary_id='ad-hoc',
                  name='ad-hoc',
                  description='an empty adversary profile',
                  atomic_ordering=[]))
     else:
         adv = adv[0]
     return AdversarySchema().dump(adv)
Exemple #23
0
 async def _adjust_adversary_phases(operation):
     """If an operation has phases disabled, replace operation
     adversary with new adversary whose phases are collapsed.
     Modified adversary is temporary and not stored, just used
     for the operation.
     """
     if not operation.phases_enabled:
         return Adversary(adversary_id=(operation.adversary.adversary_id + "_phases_disabled"),
                          name=(operation.adversary.name + " - with phases disabled"),
                          description=(operation.adversary.name + " with phases disabled"),
                          phases={1: [i for phase, ab in operation.adversary.phases.items() for i in ab]})
     else:
         return operation.adversary
Exemple #24
0
 async def _load_adversaries(self, directory):
     for filename in glob.iglob('%s/*.yml' % directory, recursive=True):
         for adv in self.strip_yml(filename):
             phases = adv.get('phases', dict())
             for p in adv.get('packs', []):
                 adv_pack = await self._add_adversary_packs(p)
                 if adv_pack:
                     await self._merge_phases(phases, adv_pack)
             if adv.get('visible', True):
                 sorted_phases = [phases[x] for x in sorted(phases.keys())]
                 phases = await self._add_phases(sorted_phases, adv)
                 await self.store(
                     Adversary(adversary_id=adv['id'], name=adv['name'], description=adv['description'],
                               phases=phases)
                 )
Exemple #25
0
    def test_operation(self, loop, data_svc):
        adversary = loop.run_until_complete(
            data_svc.store(
                Adversary(adversary_id='123',
                          name='test',
                          description='test adversary',
                          phases=dict())))
        loop.run_until_complete(
            data_svc.store(
                Operation(name='my first op', agents=[], adversary=adversary)))

        operations = loop.run_until_complete(data_svc.locate('operations'))
        assert len(operations) == 1
        for x in operations:
            json.dumps(x.display)
Exemple #26
0
def setup_rest_svc_test(loop, data_svc):
    BaseWorld.apply_config(name='main', 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', name='testA', executors=[
            Executor(name='psh', platform='windows', command='curl #{app.contact.http}')
        ])
    ))
    loop.run_until_complete(data_svc.store(
        Ability(ability_id='456', name='testB', executors=[
            Executor(name='sh', platform='linux', command='whoami')
        ])
    ))
    loop.run_until_complete(data_svc.store(
        Ability(ability_id='789', name='testC', executors=[
            Executor(name='sh', platform='linux', command='hostname')
        ])
    ))
    adversary = Adversary(adversary_id='123', name='test', description='test', atomic_ordering=[])
    loop.run_until_complete(data_svc.store(adversary))

    agent = Agent(paw='123', sleep_min=2, sleep_max=8, watchdog=0, executors=['pwsh', 'psh'], platform='windows')
    loop.run_until_complete(data_svc.store(agent))

    loop.run_until_complete(data_svc.store(
        Objective(id='495a9828-cab1-44dd-a0ca-66e58177d8cc', name='default', goals=[Goal()])
    ))

    loop.run_until_complete(data_svc.store(
        Planner(planner_id='123', name='test', module='test', params=dict())
    ))

    source = Source(id='123', name='test', facts=[], adjustments=[])
    loop.run_until_complete(data_svc.store(source))

    loop.run_until_complete(data_svc.store(
        Operation(name='test', agents=[agent], adversary=adversary, id='123', source=source)
    ))

    loop.run_until_complete(data_svc.store(
        Obfuscator(name='plain-text',
                   description='Does no obfuscation to any command, instead running it in plain text',
                   module='plugins.stockpile.app.obfuscators.plain_text')
    ))
Exemple #27
0
 async def _load_adversaries(self, directory):
     for filename in glob.iglob('%s/*.yml' % directory, recursive=True):
         for adv in self.strip_yml(filename):
             phases = [dict(phase=k, id=i) for k, v in adv.get('phases', dict()).items() for i in v]
             ps = []
             for p in adv.get('packs', []):
                 adv_pack = await self._add_adversary_packs(p)
                 if adv_pack:
                     ps.append(adv_pack)
             for pack in ps:
                 phases += pack
             if adv.get('visible', True):
                 phases = await self._add_phases(phases, adv)
                 await self.store(
                     Adversary(adversary_id=adv['id'], name=adv['name'], description=adv['description'],
                               phases=phases)
                 )
Exemple #28
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',
                               '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=[])))
Exemple #29
0
    def test_create_relationship_source_fact(self, event_loop, ability,
                                             executor, operation,
                                             knowledge_svc):
        test_executor = executor(name='psh', platform='windows')
        test_ability = ability(ability_id='123', executors=[test_executor])
        fact1 = Fact(trait='remote.host.fqdn', value='dc')
        fact2 = Fact(trait='domain.user.name', value='Bob')
        relationship = Relationship(source=fact1,
                                    edge='has_admin',
                                    target=fact2)
        link1 = Link(command='echo "Bob"',
                     paw='123456',
                     ability=test_ability,
                     id='111111',
                     executor=test_executor)
        operation = operation(name='test-op',
                              agents=[],
                              adversary=Adversary(name='sample',
                                                  adversary_id='XYZ',
                                                  atomic_ordering=[],
                                                  description='test'),
                              source=Source(id='test-source', facts=[fact1]))
        event_loop.run_until_complete(operation._init_source())
        event_loop.run_until_complete(
            link1.create_relationships([relationship], operation))

        link2 = Link(command='echo "Bob"',
                     paw='789100',
                     ability=test_ability,
                     id='222222',
                     executor=test_executor)
        event_loop.run_until_complete(
            link2.create_relationships([relationship], operation))

        fact_store_operation_source = event_loop.run_until_complete(
            knowledge_svc.get_facts(dict(source=operation.source.id)))
        fact_store_operation = event_loop.run_until_complete(
            knowledge_svc.get_facts(dict(source=operation.id)))
        assert len(fact_store_operation_source) == 1
        assert len(fact_store_operation) == 1
        assert len(fact_store_operation_source[0].collected_by) == 2
Exemple #30
0
async def setup_learning_service(data_svc, ability, operation, link):
    texecutor = Executor(name='sh',
                         platform='darwin',
                         command='whoami',
                         payloads=['wifi.sh'])
    tability = ability(tactic='discovery',
                       technique_id='T1033',
                       technique_name='Find',
                       name='test',
                       description='find active user',
                       privilege=None,
                       executors=[texecutor])
    await data_svc.store(tability)
    toperation = operation(name='sample',
                           agents=None,
                           adversary=Adversary(name='sample',
                                               adversary_id='XYZ',
                                               atomic_ordering=[],
                                               description='test'))
    await data_svc.store(toperation)
    tlink1 = link(ability=tability, command='', paw='1234', executor=texecutor)
    tlink2 = link(ability=tability, command='', paw='5678', executor=texecutor)
    yield toperation, tlink1, tlink2