コード例 #1
0
    async def test_trim_links(self, setup_planning_test, planning_svc):
        """
        This test covers both remove_links_with_unset_variables and remove_links_missing_requirements.
        It uses a fact set that causes add_test_variants to create three links. One of which is the original
        that has not been populated with facts, this one gets pruned off by remove_links_with_unset_variables.
        Of the remaining two links that are populated, one is pruned off by a requirement that requires that
        the character 0 is in the link's command. The tests show that only one link is returned by trim_links
        and that the returned link is the one that is populated and adheres to the requirement.
        """
        ability, agent, operation, _ = setup_planning_test

        link = Link.load(dict(command=BaseWorld.encode_string(test_string), paw=agent.paw, ability=ability,
                              executor=next(ability.executors), status=0))
        facts = [
            Fact(trait='1_2_3', value='0'),
            Fact(trait='1_2_3', value='4'),
            Fact(trait='a.b.c', value='1'),
            Fact(trait='a.b.d', value='2'),
            Fact(trait='a.b.e', value='3'),
        ]

        operation.all_facts = async_wrapper(facts)
        operation.planner = MagicMock()
        planning_svc.load_module = async_wrapper(RequirementFake())
        link.ability.requirements = [Requirement('fake_requirement', [{'fake': 'relationship'}])]

        trimmed_links = await planning_svc.trim_links(operation, [link], agent)

        assert len(trimmed_links) == 1
        assert BaseWorld.decode_bytes(trimmed_links[0].display['command']) == target_string
コード例 #2
0
ファイル: test_planning_svc.py プロジェクト: malached/caldera
    def test_filter_bs(self, loop, setup_planning_test, planning_svc):
        _, agent, operation, ability = setup_planning_test
        link = Link.load(
            dict(command=BaseWorld.encode_string(test_string),
                 paw=agent.paw,
                 ability=ability,
                 executor=next(ability.executors),
                 status=0))

        f0 = Fact(trait='1_2_3', value='0')
        f1 = Fact(trait='a.b.c', value='1')
        f2 = Fact(trait='a.b.d', value='2')
        f3 = Fact(trait='a.b.e', value='3')
        f4 = Fact(trait='a.b.e', value='4')
        f5 = Fact(trait='a.b.e', value='5')
        f6 = Fact(trait='a.b.e', value='6')

        gen = loop.run_until_complete(
            planning_svc.add_test_variants([link],
                                           agent,
                                           facts=[f0, f1, f2, f3, f4, f5, f6]))

        assert len(gen) == 4
        assert BaseWorld.decode_bytes(
            gen[1].display['command']) == target_string
コード例 #3
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='hunter',
                           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)
コード例 #4
0
def dns_c2(loop, app_svc, contact_svc, data_svc, obfuscator):
    BaseWorld.apply_config(name='main',
                           config={
                               'app.contact.dns.domain': 'mycaldera.caldera',
                               'app.contact.dns.socket': '0.0.0.0:53',
                               'plugins': ['sandcat', 'stockpile'],
                               'crypt_salt': 'BLAH',
                               'api_key': 'ADMIN123',
                               'encryption_key': 'ADMIN123',
                               'exfil_dir': '/tmp'
                           })
    BaseWorld.apply_config(name='agents',
                           config={
                               'sleep_max':
                               5,
                               'sleep_min':
                               5,
                               'untrusted_timer':
                               90,
                               'watchdog':
                               0,
                               'implant_name':
                               'splunkd',
                               'bootstrap_abilities':
                               ['43b3754c-def4-4699-a673-1d85648fda6a']
                           })
    services = app_svc(loop).get_services()
    dns_c2 = DnsContact(services)
    return dns_c2
コード例 #5
0
ファイル: test_planning_svc.py プロジェクト: russhaun/caldera
    async def test_trait_with_multiple_variations_of_parts(
            self, setup_planning_test, planning_svc):
        _, agent, operation, ability = setup_planning_test
        encoded_command = BaseWorld.encode_string('#{a} #{a.b} #{a.b.c}')
        link = Link.load(
            dict(command=encoded_command,
                 paw=agent.paw,
                 ability=ability,
                 executor=next(ability.executors),
                 status=0))

        input_facts = [
            Fact(trait='a', value='1'),
            Fact(trait='a.b', value='2'),
            Fact(trait='a.b.c', value='3'),
            Fact(trait='server', value='5')
        ]

        new_links = await planning_svc.add_test_variants([link],
                                                         agent,
                                                         facts=input_facts)
        assert len(new_links) == 2

        found_commands = set(x.command for x in new_links)
        assert len(found_commands) == 2  # the original and the replaced
        assert encoded_command in found_commands
        assert BaseWorld.encode_string('1 2 3') in found_commands
コード例 #6
0
    async def initialize():
        with open(Path(__file__).parents[2] / 'conf' / 'default.yml',
                  'r') as fle:
            BaseWorld.apply_config('main', yaml.safe_load(fle))
        with open(Path(__file__).parents[2] / 'conf' / 'payloads.yml',
                  'r') as fle:
            BaseWorld.apply_config('payloads', yaml.safe_load(fle))

        app_svc = AppService(web.Application())
        _ = DataService()
        _ = RestService()
        _ = PlanningService()
        _ = LearningService()
        auth_svc = AuthService()
        _ = ContactService()
        _ = FileSvc()
        services = app_svc.get_services()
        os.chdir(str(Path(__file__).parents[2]))

        await app_svc.register_contacts()
        await app_svc.load_plugins(['sandcat', 'ssl'])
        _ = await RestApi(services).enable()
        await auth_svc.apply(app_svc.application, auth_svc.get_config('users'))
        await auth_svc.set_login_handlers(services)
        return app_svc.application
コード例 #7
0
def ssh_contact_base_world():
    BaseWorld.apply_config(name='main',
                           config={
                               'app.contact.tunnel.ssh.user_name': 'sandcat',
                               'app.contact.tunnel.ssh.user_password':
                               '******',
                               'app.contact.tunnel.ssh.socket': '0.0.0.0:8122',
                               'app.contact.tunnel.ssh.host_key_file':
                               'REPLACE_WITH_KEY_FILE_PATH,',
                               'app.contact.tunnel.ssh.host_key_passphrase':
                               'REPLACE_WITH_KEY_FILE_PASSPHRASE',
                               'plugins': ['sandcat', 'stockpile'],
                               'crypt_salt': 'BLAH',
                               'api_key': 'ADMIN123',
                               'encryption_key': 'ADMIN123',
                               'exfil_dir': '/tmp'
                           })
    BaseWorld.apply_config(name='agents',
                           config={
                               'sleep_max':
                               5,
                               'sleep_min':
                               5,
                               'untrusted_timer':
                               90,
                               'watchdog':
                               0,
                               'implant_name':
                               'splunkd',
                               'bootstrap_abilities':
                               ['43b3754c-def4-4699-a673-1d85648fda6a']
                           })
コード例 #8
0
ファイル: test_rest_svc.py プロジェクト: superzerosec/caldera
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=[])))
コード例 #9
0
def dns_contact_base_world():
    BaseWorld.apply_config(name='main',
                           config={
                               'app.contact.dns.domain': 'mycaldera.caldera',
                               'app.contact.dns.socket': '0.0.0.0:53',
                               'plugins': ['sandcat', 'stockpile'],
                               'crypt_salt': 'BLAH',
                               'api_key': 'ADMIN123',
                               'encryption_key': 'ADMIN123',
                               'exfil_dir': '/tmp'
                           })
    BaseWorld.apply_config(name='agents',
                           config={
                               'sleep_max':
                               5,
                               'sleep_min':
                               5,
                               'untrusted_timer':
                               90,
                               'watchdog':
                               0,
                               'implant_name':
                               'splunkd',
                               'bootstrap_abilities':
                               ['43b3754c-def4-4699-a673-1d85648fda6a']
                           })
コード例 #10
0
    async def test_same_fact_different_agents(self, setup_learning_service,
                                              learning_svc, knowledge_svc):
        operation, link1, link2 = setup_learning_service
        link1.id = 'link1'
        link2.id = 'link2'
        operation.add_link(link1)
        all_facts = await operation.all_facts()
        await learning_svc.learn(
            facts=all_facts,
            link=link1,
            blob=BaseWorld.encode_string(
                'i contain 1 ip address 192.168.0.1 and one file /etc/host.txt. that is all.'
            ),
            operation=operation)
        operation.add_link(link2)
        all_facts = await operation.all_facts()
        await learning_svc.learn(
            facts=all_facts,
            link=link2,
            blob=BaseWorld.encode_string(
                'i contain 1 ip address 192.168.0.1 and one file /etc/host.txt. that is all.'
            ),
            operation=operation)

        knowledge_facts = await knowledge_svc.get_facts(
            dict(source=operation.id))
        assert len(link1.facts) == 2
        assert len(link2.facts) == 2
        assert len(knowledge_facts) == 2
        assert len(knowledge_facts[0].collected_by) == 2
コード例 #11
0
ファイル: test_rest_svc.py プロジェクト: satyendra22/caldera
 def test_update_config_plugin(self):
     # update plugin property
     self.assertEqual(['sandcat', 'stockpile'],
                      BaseWorld.get_config('plugins'))
     self.run_async(
         self.rest_svc.update_config(data=dict(prop='plugin', value='ssl')))
     self.assertEqual(['sandcat', 'stockpile', 'ssl'],
                      BaseWorld.get_config('plugins'))
コード例 #12
0
ファイル: server.py プロジェクト: deacon-mp/caldera
async def start_server():
    await auth_svc.apply(app_svc.application, BaseWorld.get_config('users'))
    app_svc.application.router.add_static('/docs/',
                                          'docs/_build/html',
                                          append_version=True)
    runner = web.AppRunner(app_svc.application)
    await runner.setup()
    await web.TCPSite(runner, '0.0.0.0', BaseWorld.get_config('port')).start()
コード例 #13
0
ファイル: hook.py プロジェクト: emmanvg/response
def _register_agent(ability_id):
    """
    Registers an agent with caldera -- the agent's launch commands and variations
     will be displayed in the 'Deploy Agent' modal of the web interface.
    """
    agents = set(BaseWorld.get_config(name='agents', prop='deployments'))
    agents.add(ability_id)
    BaseWorld.set_config(name='agents', prop='deployments', value=list(agents))
コード例 #14
0
    def test_apply_and_retrieve_config(self):
        new_config = dict(name='newconfig',
                          config={
                              'app.unit.test': 'abcd12345',
                              'plugins': ['stockpile']
                          })
        BaseWorld.apply_config(**new_config)

        assert BaseWorld.get_config(name='newconfig') == new_config['config']
コード例 #15
0
    def test_encode_and_decode_string(self):
        plaintext = 'unit testing string'
        encoded_text = 'dW5pdCB0ZXN0aW5nIHN0cmluZw=='
        encoded_str = BaseWorld.encode_string(plaintext)

        assert encoded_str == encoded_text

        decoded_str = BaseWorld.decode_bytes(encoded_text)
        assert decoded_str == plaintext
コード例 #16
0
ファイル: test_rest_svc.py プロジェクト: asdfasadfasfa/Albert
 def test_update_config_plugin(self, loop, rest_svc):
     internal_rest_svc = rest_svc(loop)
     # update plugin property
     assert ['sandcat', 'stockpile'] == BaseWorld.get_config('plugins')
     loop.run_until_complete(
         internal_rest_svc.update_config(
             data=dict(prop='plugin', value='ssl')))
     assert ['sandcat', 'stockpile',
             'ssl'] == BaseWorld.get_config('plugins')
コード例 #17
0
 async def wrapper(*args, **kwargs):
     agent, instructions = await func(*args, **kwargs)
     log = dict(paw=agent.paw,
                instructions=[
                    BaseWorld.decode_bytes(i.command) for i in instructions
                ],
                date=BaseWorld.get_current_timestamp())
     args[0].report[agent.contact.upper()].append(log)
     return agent, instructions
コード例 #18
0
ファイル: test_rest_svc.py プロジェクト: asdfasadfasfa/Albert
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')))
コード例 #19
0
 def test_retrieve_config(self, loop, app_svc):
     BaseWorld.apply_config(name='main', config={'app.contact.gist': 'arandomkeythatisusedtoconnecttogithubapi',
                                                 'plugins': ['sandcat', 'stockpile'],
                                                 'crypt_salt': 'BLAH',
                                                 'api_key': 'ADMIN123',
                                                 'encryption_key': 'ADMIN123',
                                                 'exfil_dir': '/tmp'})
     gist_c2 = Gist(app_svc(loop).get_services())
     loop.run_until_complete(gist_c2.start())
     assert gist_c2.retrieve_config() == 'arandomkeythatisusedtoconnecttogithubapi'
コード例 #20
0
ファイル: test_planning_svc.py プロジェクト: zaphodef/caldera
def setup_planning_test(loop, ability, agent, operation, data_svc):
    tability = ability(ability_id='123',
                       executor='sh',
                       test=BaseWorld.encode_string('mkdir test'),
                       cleanup=BaseWorld.encode_string('rm -rf test'),
                       variations=[])
    tagent = agent(sleep_min=1, sleep_max=2, watchdog=0)
    toperation = operation(name='test1', agents=tagent, adversary='hunter')
    loop.run_until_complete(data_svc.store(tability))
    yield (tability, tagent, toperation)
コード例 #21
0
ファイル: hook.py プロジェクト: mitre/gameboard
async def enable(services):
    BaseWorld.apply_config('gameboard', BaseWorld.strip_yml('plugins/gameboard/conf/gameboard.yml')[0])
    gameboard_svc = GameboardService(services)
    gameboard_api = GameboardApi(services)
    app = services.get('app_svc').application
    app.router.add_route('GET', '/plugin/gameboard/gui', gameboard_api.splash)
    app.router.add_route('POST', '/plugin/gameboard/pieces', gameboard_api.get_pieces)
    app.router.add_route('POST', '/plugin/gameboard/pin', gameboard_api.update_pin)
    app.router.add_route('POST', '/plugin/gameboard/analytic', gameboard_api.analytic)
    app.router.add_route('POST', '/plugin/gameboard/detection', gameboard_api.verify_detection)
コード例 #22
0
async def enable(services):
    BaseWorld.apply_config('response', BaseWorld.strip_yml('plugins/response/conf/response.yml')[0])
    response_svc = ResponseService(services)
    app = services.get('app_svc').application
    app.router.add_route('GET', '/plugin/responder/gui', response_svc.splash)
    app.router.add_route('POST', '/plugin/responder/update', response_svc.update_responder)

    _register_agent('1837b43e-4fff-46b2-a604-a602f7540469')  # Elasticat agent

    await response_svc.register_handler(services.get('event_svc'))
コード例 #23
0
ファイル: hook.py プロジェクト: zaphodef/atomic
async def _prepare_executor(test):
    command = _use_default_inputs(test, test['executor']['command'])
    command = _handle_multiline_commands(command)
    cleanup = _use_default_inputs(test,
                                  test['executor'].get('cleanup_command', ''))
    cleanup = _handle_multiline_commands(cleanup)

    encoded_command = BaseWorld.encode_string(command)
    encoded_cleanup = BaseWorld.encode_string(cleanup)

    return (encoded_command, encoded_cleanup)
コード例 #24
0
    def test_link_fact_coverage(self, loop, setup_planning_test, planning_svc):
        _, agent, operation, ability = setup_planning_test
        link = Link.load(dict(command=BaseWorld.encode_string(test_string), paw=agent.paw, ability=ability, status=0))
        f1 = Fact(trait='a.b.c', value='1')
        f2 = Fact(trait='a.b.d', value='2')
        f3 = Fact(trait='a.b.e', value='3')

        gen = loop.run_until_complete(planning_svc.add_test_variants([link], agent, facts=[f1, f2, f3]))

        assert len(gen) == 2
        assert BaseWorld.decode_bytes(gen[1].display['command']) == target_string
コード例 #25
0
async def enable(services):
    environments = BaseWorld.strip_yml(
        'plugins/builder/conf/environments.yml')[0]
    BaseWorld.apply_config('build', environments)
    build_svc = BuildService(services)
    await build_svc.stage_enabled_dockers()

    envs = environments['enabled']
    builder_gui = BuilderGUI(services, name, description, envs)
    app = services.get('app_svc').application
    app.router.add_route('GET', '/plugin/builder/gui', builder_gui.splash)
コード例 #26
0
 def setUp(self):
     self.initialize()
     self.ability = Ability(ability_id='123',
                            executor='sh',
                            test=BaseWorld.encode_string('mkdir test'),
                            cleanup=BaseWorld.encode_string('rm -rf test'))
     self.agent = Agent(sleep_min=1, sleep_max=2, watchdog=0)
     self.operation = Operation(name='test1',
                                agents=self.agent,
                                adversary='hunter')
     self.run_async(self.data_svc.store(self.ability))
コード例 #27
0
ファイル: test_rest_svc.py プロジェクト: satyendra22/caldera
 def setUp(self):
     self.initialize()
     BaseWorld.apply_config({
         'app.contact.http': '0.0.0.0',
         'plugins': ['sandcat', 'stockpile']
     })
     self.run_async(
         self.data_svc.store(
             Ability(
                 ability_id='123',
                 test=BaseWorld.encode_string('curl #{app.contact.http}'))))
コード例 #28
0
def base_world():
    BaseWorld.apply_config(
        name='main',
        config={
            'app.foo': 'foo',
            'app.bar': 'bar',
            'auth.baz': 'not an app. item'
        }
    )

    yield BaseWorld

    BaseWorld.clear_config()
コード例 #29
0
    def test_update_config(self):
        # check that an ability reflects the value in app. property
        pre_ability = self.run_async(self.data_svc.locate('abilities', dict(ability_id='123')))
        self.assertEqual('0.0.0.0', BaseWorld.get_config('app.contact.http'))
        self.assertEqual('curl 0.0.0.0', BaseWorld.decode_bytes(pre_ability[0].test))

        # update property
        self.run_async(self.rest_svc.update_config(data=dict(prop='app.contact.http', value='127.0.0.1')))

        # verify ability reflects new value
        post_ability = self.run_async(self.data_svc.locate('abilities', dict(ability_id='123')))
        self.assertEqual('127.0.0.1', BaseWorld.get_config('app.contact.http'))
        self.assertEqual('curl 127.0.0.1', BaseWorld.decode_bytes(post_ability[0].test))
コード例 #30
0
async def enable(services):
    BaseWorld.apply_config('debrief', BaseWorld.strip_yml('plugins/debrief/conf/default.yml')[0])
    app = services.get('app_svc').application
    debrief_gui = DebriefGui(services)
    app.router.add_static('/debrief', 'plugins/debrief/static/', append_version=True)
    app.router.add_static('/logodebrief', 'plugins/debrief/uploads/', append_version=True)
    app.router.add_route('GET', '/plugin/debrief/gui', debrief_gui.splash)
    app.router.add_route('POST', '/plugin/debrief/report', debrief_gui.report)
    app.router.add_route('*', '/plugin/debrief/graph', debrief_gui.graph)
    app.router.add_route('POST', '/plugin/debrief/pdf', debrief_gui.download_pdf)
    app.router.add_route('POST', '/plugin/debrief/json', debrief_gui.download_json)
    app.router.add_route('GET', '/plugin/debrief/logos', debrief_gui.all_logos)
    app.router.add_route('POST', '/plugin/debrief/logo', debrief_gui.upload_logo)