Ejemplo n.º 1
0
def op_for_event_logs(operation_agent, operation_adversary, executor, ability,
                      operation_link, encoded_command):
    op = Operation(name='test',
                   agents=[operation_agent],
                   adversary=operation_adversary)
    op.set_start_details()
    command_1 = 'whoami'
    command_2 = 'hostname'
    executor_1 = executor(name='psh', platform='windows', command=command_1)
    executor_2 = executor(name='psh', platform='windows', command=command_2)
    ability_1 = ability(ability_id='123',
                        tactic='test tactic',
                        technique_id='T0000',
                        technique_name='test technique',
                        name='test ability',
                        description='test ability desc',
                        executors=[executor_1])
    ability_2 = ability(ability_id='456',
                        tactic='test tactic',
                        technique_id='T0000',
                        technique_name='test technique',
                        name='test ability 2',
                        description='test ability 2 desc',
                        executors=[executor_2])
    link_1 = operation_link(ability=ability_1,
                            paw=operation_agent.paw,
                            executor=executor_1,
                            command=encoded_command(command_1),
                            status=0,
                            host=operation_agent.host,
                            pid=789,
                            decide=datetime.strptime('2021-01-01 08:00:00',
                                                     '%Y-%m-%d %H:%M:%S'),
                            collect=datetime.strptime('2021-01-01 08:01:00',
                                                      '%Y-%m-%d %H:%M:%S'),
                            finish='2021-01-01 08:02:00')
    link_2 = operation_link(ability=ability_2,
                            paw=operation_agent.paw,
                            executor=executor_2,
                            command=encoded_command(command_2),
                            status=0,
                            host=operation_agent.host,
                            pid=7890,
                            decide=datetime.strptime('2021-01-01 09:00:00',
                                                     '%Y-%m-%d %H:%M:%S'),
                            collect=datetime.strptime('2021-01-01 09:01:00',
                                                      '%Y-%m-%d %H:%M:%S'),
                            finish='2021-01-01 09:02:00')
    discarded_link = operation_link(ability=ability_2,
                                    paw=operation_agent.paw,
                                    executor=executor_2,
                                    command=encoded_command(command_2),
                                    status=-2,
                                    host=operation_agent.host,
                                    pid=7891,
                                    decide=datetime.strptime(
                                        '2021-01-01 10:00:00',
                                        '%Y-%m-%d %H:%M:%S'))
    op.chain = [link_1, link_2, discarded_link]
    return op
Ejemplo n.º 2
0
def op_for_event_logs(operation_agent, operation_adversary, executor, ability,
                      operation_link, encoded_command, parse_datestring):
    op = Operation(name='test',
                   agents=[operation_agent],
                   adversary=operation_adversary)
    op.set_start_details()
    command_1 = 'whoami'
    command_2 = 'hostname'
    executor_1 = executor(name='psh', platform='windows', command=command_1)
    executor_2 = executor(name='psh', platform='windows', command=command_2)
    ability_1 = ability(ability_id='123',
                        tactic='test tactic',
                        technique_id='T0000',
                        technique_name='test technique',
                        name='test ability',
                        description='test ability desc',
                        executors=[executor_1])
    ability_2 = ability(ability_id='456',
                        tactic='test tactic',
                        technique_id='T0000',
                        technique_name='test technique',
                        name='test ability 2',
                        description='test ability 2 desc',
                        executors=[executor_2])
    link_1 = operation_link(ability=ability_1,
                            paw=operation_agent.paw,
                            executor=executor_1,
                            command=encoded_command(command_1),
                            status=0,
                            host=operation_agent.host,
                            pid=789,
                            decide=parse_datestring(LINK1_DECIDE_TIME),
                            collect=parse_datestring(LINK1_COLLECT_TIME),
                            finish=LINK1_FINISH_TIME)
    link_2 = operation_link(ability=ability_2,
                            paw=operation_agent.paw,
                            executor=executor_2,
                            command=encoded_command(command_2),
                            status=0,
                            host=operation_agent.host,
                            pid=7890,
                            decide=parse_datestring(LINK2_DECIDE_TIME),
                            collect=parse_datestring(LINK2_COLLECT_TIME),
                            finish=LINK2_FINISH_TIME)
    discarded_link = operation_link(
        ability=ability_2,
        paw=operation_agent.paw,
        executor=executor_2,
        command=encoded_command(command_2),
        status=-2,
        host=operation_agent.host,
        pid=7891,
        decide=parse_datestring('2021-01-01T10:00:00Z'))
    op.chain = [link_1, link_2, discarded_link]
    return op
Ejemplo n.º 3
0
 async def _create_detection_operation(self, red_op_name, red_op_id,
                                       red_op_access):
     planner = (await self.get_service('data_svc').locate(
         'planners', match=dict(name='atomic')))[0]
     adversary_id = self.get_config(prop='adversary', name='gameboard')
     adversary = (await self.data_svc.locate(
         'adversaries', match=dict(adversary_id=adversary_id)))[0]
     obj = (await self.data_svc.locate('objectives',
                                       match=dict(name='default')))[0]
     agent = Agent(0, 0, 0, paw='gameboard_detection')
     access = self.Access.BLUE
     detection_operation = Operation(name=red_op_name + '_' +
                                     str(red_op_id) +
                                     self.blue_op_name_modifier,
                                     agents=[agent],
                                     adversary=adversary,
                                     access=access,
                                     planner=planner,
                                     group='blue')
     detection_operation.objective = obj
     detection_operation.set_start_details()
     return [await self.data_svc.store(detection_operation)]
Ejemplo n.º 4
0
class ResponseService(BaseService):
    def __init__(self, services):
        self.log = self.add_service('response_svc', self)
        self.data_svc = services.get('data_svc')
        self.rest_svc = services.get('rest_svc')
        self.agents = []
        self.adversary = None
        self.abilities = []
        self.op = None

    @template('response.html')
    async def splash(self, request):
        abilities = [
            a for a in await self.data_svc.locate('abilities')
            if await a.which_plugin() == 'response'
        ]
        adversaries = [
            a for a in await self.data_svc.locate('adversaries')
            if await a.which_plugin() == 'response'
        ]
        return dict(abilities=abilities, adversaries=adversaries)

    @staticmethod
    async def register_handler(event_svc):
        await event_svc.observe_event('link/completed', handle_link_completed)

    async def respond_to_pid(self, pid, agent):
        available_agents = await self.get_available_agents(agent)
        if not available_agents:
            return
        total_facts = []
        total_links = []

        for blue_agent in available_agents:
            agent_facts, agent_links = await self.run_abilities_on_agent(
                blue_agent, pid)
            total_facts.extend(agent_facts)
            total_links.extend(agent_links)

        await self.save_to_operation(total_facts, total_links)

    async def get_available_agents(self, agent_to_match):
        await self.refresh_blue_agents_abilities()
        available_agents = [
            a for a in self.agents if a.host == agent_to_match.host
        ]

        if not available_agents:
            self.log.debug('No available blue agents to respond to red action')
            return []

        return available_agents

    async def refresh_blue_agents_abilities(self):
        self.agents = await self.data_svc.locate(
            'agents', match=dict(access=self.Access.BLUE))
        self.adversary = (await self.data_svc.locate(
            'adversaries', match=dict(adversary_id=BLUE_ADVERSARY)))[0]

        self.abilities = []
        for a in self.adversary.atomic_ordering:
            if a not in self.abilities:
                self.abilities.append(a)

    async def run_abilities_on_agent(self, blue_agent, original_pid):
        facts = [Fact(trait='host.process.id', value=original_pid)]
        links = []
        for ability_id in self.abilities:
            ability_facts, ability_links = await self.run_ability_on_agent(
                blue_agent, ability_id, facts, original_pid)
            links.extend(ability_links)
            facts.extend(ability_facts)
        return facts, links

    async def run_ability_on_agent(self, blue_agent, ability_id, agent_facts,
                                   original_pid):
        links = await self.rest_svc.task_agent_with_ability(
            blue_agent.paw, ability_id, agent_facts)
        await self.wait_for_link_completion(links, blue_agent)
        ability_facts = []
        for link in links:
            link.pin = int(original_pid)
            unique_facts = link.facts[1:]
            ability_facts.extend(unique_facts)
        return ability_facts, links

    @staticmethod
    async def wait_for_link_completion(links, agent):
        for link in links:
            while not link.finish or link.can_ignore():
                await asyncio.sleep(3)
                if not agent.trusted:
                    break

    async def create_fact_source(self, facts):
        source_id = str(uuid.uuid4())
        source_name = 'blue-pid-{}'.format(source_id)
        return Source(id=source_id, name=source_name, facts=facts)

    async def save_to_operation(self, facts, links):
        if not self.op or await self.op.is_finished():
            source = await self.create_fact_source(facts)
            await self.create_operation(links=links, source=source)
        else:
            await self.update_operation(links)
        await self.get_service('data_svc').store(self.op)

    async def create_operation(self, links, source):
        planner = (await self.get_service('data_svc').locate(
            'planners', match=dict(name='sequential')))[0]
        await self.get_service('data_svc').store(source)
        self.op = Operation(name=BLUE_OP_NAME,
                            agents=self.agents,
                            adversary=self.adversary,
                            source=source,
                            access=self.Access.BLUE,
                            planner=planner,
                            state='running',
                            auto_close=False,
                            jitter='1/4')
        self.op.set_start_details()
        await self.update_operation(links)

    async def update_operation(self, links):
        for link in links:
            link.operation = self.op.id
            self.op.add_link(link)