def test_for_enum_has_value_functionality(): # Test if the has_value function works as intended assert StixCyberObservableTypes.has_value("url") is True assert StixCyberObservableTypes.has_value("LRU") is False assert LocationTypes.has_value("CITY") is True assert LocationTypes.has_value("YTIC") is False assert IdentityTypes.has_value("SECTOR") is True assert IdentityTypes.has_value("RECTOS") is False assert ContainerTypes.has_value("Note") is True assert ContainerTypes.has_value("ETON") is False
def add_kill_chain_phases(self, entity_type, id, kill_chain_phases, version=2): for kill_chain_phase in kill_chain_phases: if version == 2: kill_chain_phase = kill_chain_phase["value"] kill_chain_phase_id = self.opencti.kill_chain_phase.create( kill_chain_name=kill_chain_phase["kill_chain_name"], phase_name=kill_chain_phase["phase_name"], phase_order=kill_chain_phase["x_opencti_order"] if "x_opencti_order" in kill_chain_phase else 0, stix_id=kill_chain_phase["id"] if "id" in kill_chain_phase else None, )["id"] if entity_type == "relationship": self.opencti.stix_core_relationship.add_kill_chain_phase( id=id, kill_chain_phase_id=kill_chain_phase_id) elif StixCyberObservableTypes.has_value(entity_type): self.opencti.stix_cyber_observable.add_kill_chain_phase( id=id, kill_chain_phase_id=kill_chain_phase_id) else: self.opencti.stix_domain_object.add_kill_chain_phase( id=id, kill_chain_phase_id=kill_chain_phase_id)
def add_external_references(self, entity_type, id, external_references, version=2): for external_reference in external_references: if version == 2: external_reference = external_reference["value"] if "url" in external_reference and "source_name" in external_reference: url = external_reference["url"] source_name = external_reference["source_name"] else: continue external_reference_id = self.opencti.external_reference.create( source_name=source_name, url=url, external_id=external_reference["external_id"] if "external_id" in external_reference else None, description=external_reference["description"] if "description" in external_reference else None, )["id"] if entity_type == "relationship": self.opencti.stix_core_relationship.add_external_reference( id=id, external_reference_id=external_reference_id) elif StixCyberObservableTypes.has_value(entity_type): self.opencti.stix_cyber_observable.add_external_reference( id=id, external_reference_id=external_reference_id) else: self.opencti.stix_domain_object.add_external_reference( id=id, external_reference_id=external_reference_id)
def replace_created_by_ref(self, entity_type, id, created_by_ref): if entity_type == "relationship": self.opencti.stix_core_relationship.update_created_by( id=id, identity_id=created_by_ref) elif StixCyberObservableTypes.has_value(entity_type): self.opencti.stix_cyber_observable.update_created_by( id=id, identity_id=created_by_ref) else: self.opencti.stix_domain_object.update_created_by( id=id, identity_id=created_by_ref)
def remove_kill_chain_phases(self, entity_type, id, kill_chain_phases): for kill_chain_phase in kill_chain_phases: if entity_type == "relationship": self.opencti.stix_core_relationship.remove_kill_chain_phase( id=id, kill_chain_phase_id=kill_chain_phase["id"]) elif StixCyberObservableTypes.has_value(entity_type): self.opencti.stix_cyber_observable.remove_kill_chain_phase( id=id, kill_chain_phase_id=kill_chain_phase["id"]) else: self.opencti.stix_domain_object.remove_kill_chain_phase( id=id, kill_chain_phase_id=kill_chain_phase["id"])
def remove_external_references(self, entity_type, id, external_references): for external_reference in external_references: if entity_type == "relationship": self.opencti.stix_core_relationship.remove_external_reference( id=id, external_reference_id=external_reference["id"]) elif StixCyberObservableTypes.has_value(entity_type): self.opencti.stix_cyber_observable.remove_external_reference( id=id, external_reference_id=external_reference["id"]) else: self.opencti.stix_domain_object.remove_external_reference( id=id, external_reference_id=external_reference["id"])
def remove_object_marking_refs(self, entity_type, id, object_marking_refs): for object_marking_ref in object_marking_refs: if entity_type == "relationship": self.opencti.stix_core_relationship.remove_marking_definition( id=id, marking_definition_id=object_marking_ref) elif StixCyberObservableTypes.has_value(entity_type): self.opencti.stix_cyber_observable.remove_marking_definition( id=id, marking_definition_id=object_marking_ref) else: self.opencti.stix_domain_object.remove_marking_definition( id=id, marking_definition_id=object_marking_ref)
def remove_labels(self, entity_type, id, labels): for label in labels: if entity_type == "relationship": self.opencti.stix_core_relationship.remove_label( id=id, label_name=label) elif StixCyberObservableTypes.has_value(entity_type): self.opencti.stix_cyber_observable.remove_label( id=id, label_name=label) else: self.opencti.stix_domain_object.remove_label(id=id, label_name=label)
def update_attribute(self, entity_type, id, operation, key, value): if entity_type == "relationship": self.opencti.stix_core_relationship.update_field( id=id, key=key, value=value, operation=operation) elif StixCyberObservableTypes.has_value(entity_type): self.opencti.stix_cyber_observable.update_field( id=id, key=key, value=value, operation=operation) else: self.opencti.stix_domain_object.update_field(id=id, key=key, value=value, operation=operation)
def add_labels(self, entity_type, id, labels, version=2): for label in labels: if version == 2: label = label["value"] if entity_type == "relationship": self.opencti.stix_core_relationship.add_label(id=id, label_name=label) elif StixCyberObservableTypes.has_value(entity_type): self.opencti.stix_cyber_observable.add_label(id=id, label_name=label) else: self.opencti.stix_domain_object.add_label(id=id, label_name=label)
def replace_created_by_ref(self, entity_type, id, created_by_ref, version=2): if version == 2: created_by_ref = (created_by_ref[0]["value"] if created_by_ref is not None else None) if entity_type == "relationship": self.opencti.stix_core_relationship.update_created_by( id=id, identity_id=created_by_ref) elif StixCyberObservableTypes.has_value(entity_type): self.opencti.stix_cyber_observable.update_created_by( id=id, identity_id=created_by_ref) else: self.opencti.stix_domain_object.update_created_by( id=id, identity_id=created_by_ref)
def add_object_marking_refs(self, entity_type, id, object_marking_refs, version=2): for object_marking_ref in object_marking_refs: if version == 2: object_marking_ref = object_marking_ref["value"] if entity_type == "relationship": self.opencti.stix_core_relationship.add_marking_definition( id=id, marking_definition_id=object_marking_ref) elif StixCyberObservableTypes.has_value(entity_type): self.opencti.stix_cyber_observable.add_marking_definition( id=id, marking_definition_id=object_marking_ref) else: self.opencti.stix_domain_object.add_marking_definition( id=id, marking_definition_id=object_marking_ref)
def update_attribute(self, entity_type, id, input): # Relations if entity_type == "relationship": self.opencti.stix_core_relationship.update_field(id=id, input=input) elif entity_type == "sighting": self.opencti.stix_sighting_relationship.update_field(id=id, input=input) # Observables elif StixCyberObservableTypes.has_value(entity_type): self.opencti.stix_cyber_observable.update_field(id=id, input=input) # Meta elif entity_type == "marking-definition": self.opencti.marking_definition.update_field(id=id, input=input) elif entity_type == "label": self.opencti.label.update_field(id=id, input=input) elif entity_type == "kill-chain-phase": self.opencti.kill_chain_phase.update_field(id=id, input=input) elif entity_type == "external-reference": self.opencti.external_reference.update_field(id=id, input=input) # Remaining stix domain else: self.opencti.stix_domain_object.update_field(id=id, input=input)
def _process_message(self, data): file_name = data["file_name"] # TODO this can be implemented to filter every entity and observable # max_marking = data["max_marking"] entity_type = data["entity_type"] if entity_type != "Report": raise ValueError( f'This Connector can only process entities of type "Report" and not of type "{entity_type}".' ) # Get the Report report_dict = self.helper.api.report.read(id=data["entity_id"]) # Extract values for inclusion in output pdf report_marking = report_dict.get("objectMarking", None) if report_marking: report_marking = report_marking[-1]["definition"] report_name = report_dict["name"] report_description = report_dict.get("description", "No description available.") report_confidence = report_dict["confidence"] report_id = report_dict["id"] report_external_refs = [ external_ref_dict["url"] for external_ref_dict in report_dict["externalReferences"] ] report_objs = report_dict["objects"] report_date = datetime.datetime.now().strftime("%b %d %Y") context = { "report_name": report_name, "report_description": report_description, "report_marking": report_marking, "report_confidence": report_confidence, "report_external_refs": report_external_refs, "report_date": report_date, "company_address_line_1": self.company_address_line_1, "company_address_line_2": self.company_address_line_2, "company_address_line_3": self.company_address_line_3, "company_phone_number": self.company_phone_number, "company_email": self.company_email, "company_website": self.company_website, "entities": {}, "observables": {}, } # Process each STIX Object for report_obj in report_objs: obj_entity_type = report_obj["entity_type"] obj_id = report_obj["standard_id"] # Handle StixCyberObservables entities if obj_entity_type == "StixFile" or StixCyberObservableTypes.has_value( obj_entity_type): observable_dict = self.helper.api.stix_cyber_observable.read( id=obj_id) # If only include indicators and # the observable doesn't have an indicator, skip it if self.indicators_only and not observable_dict["indicators"]: self.helper.log_info( f"Skipping {obj_entity_type} observable with value {observable_dict['observable_value']} as it was not an Indicator." ) continue if obj_entity_type not in context["observables"]: context["observables"][obj_entity_type] = [] # Defang urls if self.defang_urls and obj_entity_type == "Url": observable_dict["observable_value"] = observable_dict[ "observable_value"].replace("http", "hxxp", 1) context["observables"][obj_entity_type].append(observable_dict) # Handle all other entities else: reader_func = self.get_reader(obj_entity_type) if reader_func is None: self.helper.log_error( f'Could not find a function to read entity with type "{obj_entity_type}"' ) continue entity_dict = reader_func(id=obj_id) if obj_entity_type not in context["entities"]: context["entities"][obj_entity_type] = [] context["entities"][obj_entity_type].append(entity_dict) # Render html with input variables env = Environment( loader=FileSystemLoader(os.path.abspath(os.getcwd()))) template = env.get_template("src/resources/report.html") html_string = template.render(context) # Generate pdf from html string pdf_contents = HTML(string=html_string, base_url="src/resources").write_pdf() # Upload the output pdf self.helper.log_info(f"Uploading: {file_name}") self.helper.api.stix_domain_object.add_file( id=report_id, file_name=file_name, data=pdf_contents, mime_type="application/pdf", ) return "Export done"
def _process_message(self, data): file_name = data["file_name"] export_scope = data["export_scope"] # single or list export_type = data["export_type"] # Simple or Full # max_marking = data["max_marking"] # TODO Implement marking restriction entity_type = data["entity_type"] if export_scope == "single": entity_id = data["entity_id"] self.helper.log_info("Exporting: " + entity_type + "/" + export_type + "(" + entity_id + ") to " + file_name) entity_data = self.helper.api.stix_domain_object.read(id=entity_id) entities_list = [] if "objectsIds" in entity_data: for id in entity_data["objectsIds"]: entity = self.helper.api.stix_domain_object.read(id=id) if entity is None: entity = self.helper.api.stix_cyber_observable.read( id=id) if entity is not None: del entity["objectLabelIds"] entities_list.append(entity) del entity_data["objectLabelIds"] del entity_data["objectsIds"] entities_list.append(entity_data) csv_data = self.export_dict_list_to_csv(entities_list) self.helper.log_info("Uploading: " + entity_type + "/" + export_type + "(" + entity_id + ") to " + file_name) self.helper.api.stix_domain_object.push_entity_export( entity_id, file_name, csv_data) self.helper.log_info("Export done: " + entity_type + "/" + export_type + "(" + entity_id + ") to " + file_name) else: list_params = data["list_params"] self.helper.log_info("Exporting list: " + entity_type + "/" + export_type + " to " + file_name) final_entity_type = entity_type if IdentityTypes.has_value(entity_type): if list_params["filters"] is not None: list_params["filters"].append({ "key": "entity_type", "values": [entity_type] }) else: list_params["filters"] = [{ "key": "entity_type", "values": [entity_type] }] final_entity_type = "Identity" if LocationTypes.has_value(entity_type): if list_params["filters"] is not None: list_params["filters"].append({ "key": "entity_type", "values": [entity_type] }) else: list_params["filters"] = [{ "key": "entity_type", "values": [entity_type] }] final_entity_type = "Location" if StixCyberObservableTypes.has_value(entity_type): if list_params["filters"] is not None: list_params["filters"].append({ "key": "entity_type", "values": [entity_type] }) else: list_params["filters"] = [{ "key": "entity_type", "values": [entity_type] }] final_entity_type = "Stix-Cyber-Observable" # List lister = { "Attack-Pattern": self.helper.api.attack_pattern.list, "Campaign": self.helper.api.campaign.list, "Note": self.helper.api.note.list, "Observed-Data": self.helper.api.observed_data.list, "Opinion": self.helper.api.opinion.list, "Report": self.helper.api.report.list, "Course-Of-Action": self.helper.api.course_of_action.list, "Identity": self.helper.api.identity.list, "Indicator": self.helper.api.indicator.list, "Infrastructure": self.helper.api.infrastructure.list, "Intrusion-Set": self.helper.api.intrusion_set.list, "Location": self.helper.api.location.list, "Malware": self.helper.api.malware.list, "Threat-Actor": self.helper.api.threat_actor.list, "Tool": self.helper.api.tool.list, "Vulnerability": self.helper.api.vulnerability.list, "X-OpenCTI-Incident": self.helper.api.x_opencti_incident.list, "Stix-Cyber-Observable": self.helper.api.stix_cyber_observable.list, } do_list = lister.get( final_entity_type, lambda **kwargs: self.helper. log_error('Unknown object type "' + final_entity_type + '", doing nothing...'), ) entities_list = do_list( search=list_params["search"], filters=list_params["filters"], orderBy=list_params["orderBy"], orderMode=list_params["orderMode"], types=list_params["types"] if "types" in list_params else None, getAll=True, ) csv_data = self.export_dict_list_to_csv(entities_list) self.helper.log_info("Uploading: " + entity_type + "/" + export_type + " to " + file_name) if entity_type != "Stix-Cyber-Observable": self.helper.api.stix_domain_object.push_list_export( entity_type, file_name, csv_data, json.dumps(list_params)) else: self.helper.api.stix_cyber_observable.push_list_export( file_name, csv_data, json.dumps(list_params)) self.helper.log_info("Export done: " + entity_type + "/" + export_type + " to " + file_name) return "Export done"
def _process_message(self, data): file_name = data["file_name"] # max_marking = data["max_marking"] # TODO Implement marking restriction entity_type = data["entity_type"] list_params = data["list_params"] self.helper.log_info(data) final_entity_type = entity_type if StixCyberObservableTypes.has_value(entity_type): if list_params["filters"] is not None: list_params["filters"].append( {"key": "entity_type", "values": [entity_type]} ) else: list_params["filters"] = [ {"key": "entity_type", "values": [entity_type]} ] final_entity_type = "Stix-Cyber-Observable" # List lister = { "Stix-Domain-Object": self.helper.api.stix_domain_object.list, "Attack-Pattern": self.helper.api.attack_pattern.list, "Campaign": self.helper.api.campaign.list, "Note": self.helper.api.note.list, "Observed-Data": self.helper.api.observed_data.list, "Opinion": self.helper.api.opinion.list, "Report": self.helper.api.report.list, "Course-Of-Action": self.helper.api.course_of_action.list, "Identity": self.helper.api.identity.list, "Indicator": self.helper.api.indicator.list, "Infrastructure": self.helper.api.infrastructure.list, "Intrusion-Set": self.helper.api.intrusion_set.list, "Location": self.helper.api.location.list, "Malware": self.helper.api.malware.list, "Threat-Actor": self.helper.api.threat_actor.list, "Tool": self.helper.api.tool.list, "Vulnerability": self.helper.api.vulnerability.list, "Incident": self.helper.api.incident.list, "Stix-Cyber-Observable": self.helper.api.stix_cyber_observable.list, } do_list = lister.get( final_entity_type, lambda **kwargs: self.helper.log_error( 'Unknown object type "' + final_entity_type + '", doing nothing...' ), ) entities_list = do_list( search=list_params["search"], filters=list_params["filters"], orderBy=list_params["orderBy"], orderMode=list_params["orderMode"], types=list_params["types"] if "types" in list_params else None, getAll=True, ) observable_values = [f["observable_value"] for f in entities_list] observable_values_bytes = "\n".join(observable_values) self.helper.log_info("Uploading: " + entity_type + " to " + file_name) if entity_type != "Stix-Cyber-Observable": self.helper.api.stix_domain_object.push_list_export( entity_type, file_name, observable_values_bytes, json.dumps(list_params) ) else: self.helper.api.stix_cyber_observable.push_list_export( file_name, observable_values_bytes, json.dumps(list_params) ) self.helper.log_info("Export done: " + entity_type + " to " + file_name) return "Export done"