def _mitre_groups_technique_intersection_function(self, event, *args, **kwargs): """Function: For given Techniques return the Groups that are know to use all of them.""" try: # Get the wf_instance_id of the workflow this Function was called in wf_instance_id = event.message["workflow_instance"][ "workflow_instance_id"] # Get the function parameters: mitre_technique_name = kwargs.get("mitre_technique_name") # text mitre_technique_id = kwargs.get("mitre_technique_id") # text log = logging.getLogger(__name__) log.info("mitre_technique_name: %s", mitre_technique_name) log.info("mitre_technique_id: %s", mitre_technique_id) result_payload = ResultPayload( "fn_mitre_integration", mitre_technique_name=mitre_technique_name, mitre_technique_id=mitre_technique_id) if not mitre_technique_id and not mitre_technique_name: raise ValueError( "At least one of the inputs(mitre_technique_name or mitre_technique_id) " "should be provided.") yield StatusMessage("Getting technique information...") mitre_conn = mitre_attack.MitreAttackConnection() techniques = mitre_attack_utils.get_multiple_techniques( mitre_conn, mitre_technique_ids=mitre_technique_id, mitre_technique_names=mitre_technique_name) intersection_query = ",".join([t.id for t in techniques]) yield StatusMessage("Getting group intersection information...") groups = mitre_attack.MitreAttackGroup.get_by_technique_intersection( mitre_conn, techniques) if len(groups) == 0: yield StatusMessage( "No groups were found using all of the given techniques. Done" ) else: yield StatusMessage("Done. Returning results.") # Storing the techniques specified to query this group for group in groups: group.technique_id = intersection_query groups = [x.dict_form() for x in groups] # prepare the data for viewing results = {"mitre_groups": groups} # Produce a FunctionResult with the results yield FunctionResult(result_payload.done(True, results)) except Exception as e: yield FunctionError(e)
def test_ids_precede_names(self): """ Since 2 techniques are returned and not 3, we know that it used ids. """ techniques = get_multiple_techniques( self.mitre_attack, mitre_technique_ids="T1213, T1483", mitre_technique_names="Port Knocking, Domain Generation Algorithms" ) assert len(techniques) == 2
def test_multiple_techniques_works_by_name(self): """ In mocked data, for these names there's more than one technique. """ techniques = get_multiple_techniques( self.mitre_attack, mitre_technique_ids=None, mitre_technique_names="Port Knocking, Domain Generation Algorithms" ) assert len(techniques) > 2
def _mitre_groups_using_technique_function(self, event, *args, **kwargs): """Function: Get a list of groups that are using the given technique(s).""" try: mitre_technique_name = kwargs.get("mitre_technique_name") # text mitre_technique_id = kwargs.get("mitre_technique_id") # text log = logging.getLogger(__name__) log.info("mitre_technique_name: %s", mitre_technique_name) log.info("mitre_technique_id: %s", mitre_technique_id) result_payload = ResultPayload( "fn_mitre_integration", mitre_technique_name=mitre_technique_name, mitre_technique_id=mitre_technique_id) if not mitre_technique_id and not mitre_technique_name: raise ValueError( "At least one of the inputs(mitre_technique_name or mitre_technique_id) " "should be provided.") yield StatusMessage("Getting technique information...") mitre_conn = mitre_attack.MitreAttackConnection( self.opts, self.options) techniques = mitre_attack_utils.get_multiple_techniques( mitre_conn, mitre_technique_ids=mitre_technique_id, mitre_technique_names=mitre_technique_name) yield StatusMessage("Getting group information...") groups = [] for technique in techniques: groups.extend( mitre_attack.MitreAttackGroup.get_by_technique( mitre_conn, technique)) if len(groups) == 0: yield StatusMessage( "No groups were found using any of the given techniques. Done." ) else: yield StatusMessage("Done. Returning results.") groups = [x.dict_form() for x in groups] # prepare the data for viewing results = {"mitre_groups": groups} # Produce a FunctionResult with the results yield FunctionResult(result_payload.done(True, results)) except Exception as e: log.exception(str(e)) yield FunctionError()
def test_unknown_names_fail(self): with pytest.raises(ValueError): techniques = get_multiple_techniques( self.mitre_attack, mitre_technique_ids=None, mitre_technique_names="Made up technique")
def test_unknown_ids_fail(self): with pytest.raises(ValueError): techniques = get_multiple_techniques( self.mitre_attack, mitre_technique_ids="T1205, T1213, T007", mitre_technique_names=None)
def test_multiple_techniques_works_by_id(self): techniques = get_multiple_techniques( self.mitre_attack, mitre_technique_ids="T1213, T1483", mitre_technique_names=None) assert len(techniques) == 2