async def _create_ability(self, ability_id, tactic=None, technique_name=None, technique_id=None, name=None, test=None, description=None, executor=None, platform=None, cleanup=None, payloads=None, parsers=None, requirements=None, privilege=None, timeout=60, access=None, buckets=None, repeatable=False, code=None, language=None, build_target=None, variations=None): ps = [] for module in parsers: pcs = [(ParserConfig(**m)) for m in parsers[module]] ps.append(Parser(module=module, parserconfigs=pcs)) rs = [] for requirement in requirements: for module in requirement: relation = [ Relationship(source=r['source'], edge=r.get('edge'), target=r.get('target')) for r in requirement[module] ] rs.append(Requirement(module=module, relationships=relation)) ability = Ability(ability_id=ability_id, name=name, test=test, tactic=tactic, technique_id=technique_id, technique=technique_name, code=code, language=language, executor=executor, platform=platform, description=description, build_target=build_target, cleanup=cleanup, payloads=payloads, parsers=ps, requirements=rs, privilege=privilege, timeout=timeout, repeatable=repeatable, variations=variations, buckets=buckets) ability.access = access return await self.store(ability)
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
async def _create_ability(self, ability_id, tactic, technique_name, technique_id, name, test, description, executor, platform, cleanup=None, payload=None, parsers=None, requirements=None, privilege=None, timeout=60): ps = [] for module in parsers: pcs = [(ParserConfig(**m)) for m in parsers[module]] ps.append(Parser(module=module, parserconfigs=pcs)) rs = [] for requirement in requirements: for module in requirement: relation = [ Relationship(source=r['source'], edge=r.get('edge'), target=r.get('target')) for r in requirement[module] ] rs.append(Requirement(module=module, relationships=relation)) return await self.store( Ability(ability_id=ability_id, name=name, test=test, tactic=tactic, technique_id=technique_id, technique=technique_name, executor=executor, platform=platform, description=description, cleanup=cleanup, payload=payload, parsers=ps, requirements=rs, privilege=privilege, timeout=timeout))
def replaced_ability_payload(test_ability): ability_data = test_ability.schema.dump(test_ability) test_executor_linux = Executor(name='sh', platform='linux', command='whoami') test_requirement = Requirement( module='plugins.stockpile.app.requirements.paw_provenance', relationship_match=[{ 'source': 'host.user.name' }]) ability_data.update( dict(name='replaced test ability', tactic='collection', technique_name='discovery', technique_id='2', executors=[ExecutorSchema().dump(test_executor_linux)], plugin='', requirements=[RequirementSchema().dump(test_requirement)])) return ability_data