def _create_observable_file( properties: ObservableProperties, hashes: Optional[Mapping[str, str]] = None, name: Optional[str] = None, ) -> File: return File( hashes=hashes, name=name, object_marking_refs=properties.object_markings, custom_properties=_get_custom_properties(properties), )
def create_file(content): files = [] value = get(get(content, 'dynamic_analysis'), 'open_files') if value != -1: files = value file_list = [] file_ref = [] for file in files: file_obj = File(name=file) file_list.append(file_obj) file_ref.append(file_obj['id']) return (file_list, file_ref)
def _create_observable_file( hashes: Optional[Mapping[str, str]] = None, name: Optional[str] = None, created_by: Optional[Identity] = None, labels: Optional[List[str]] = None, object_markings: Optional[List[MarkingDefinition]] = None, ) -> File: return File( hashes=hashes, name=name, object_marking_refs=object_markings, custom_properties=_get_default_custom_properties(created_by=created_by, labels=labels), )
def _create_observable_file( hashes: Optional[Mapping[str, str]] = None, name: Optional[str] = None, object_markings: Optional[List[MarkingDefinition]] = None, custom_properties: Optional[Mapping[str, Any]] = None, ) -> File: if custom_properties is None: custom_properties = {} return File( hashes=hashes, name=name, object_marking_refs=object_markings, custom_properties=custom_properties, )
def stixer(vulns, path): for vuln in vulns: timestamp = datetime.now() vuln_name = vuln['name'] vuln_description = vuln['description'] if args.mitigations: mitigation_description = get_mitigation(vuln['name']) else: mitigation_description = "" snippet_android = vuln['code'] coa_name = vuln_name + "_coa" file_path = PurePath(vuln['file']) target = f"{str(file_path)}:{vuln['line']}" coa = CourseOfAction(type="course-of-action", name=coa_name, description=mitigation_description, x_actions=[{ "mitigation_android": "No snippet avaliable" }], allow_custom=True) vuln = Vulnerability(type="vulnerability", name=vuln_name, description=vuln_description, vulnerable_snippet=snippet_android, allow_custom=True) mitigates = Relationship(coa, 'mitigates', vuln) observed_object = File(name=target) observed_data = ObservedData(first_observed=timestamp, last_observed=timestamp, number_observed=1, objects={0: observed_object}) sight = Sighting(vuln, observed_data_refs=[observed_data]) bundle = Bundle(coa, mitigates, vuln, sight, observed_data, observed_object) with open(f"{path}/{vuln_name}.json", "w") as f: f.write(str(bundle) + "\n")
def _send_knowledge(self, observable, report): bundle_objects = [] final_observable = observable if observable["entity_type"] in ["StixFile", "Artifact"]: final_observable = self.helper.api.stix_cyber_observable.update_field( id=final_observable["id"], key="hashes.MD5", value=report["md5"]) final_observable = self.helper.api.stix_cyber_observable.update_field( id=final_observable["id"], key="hashes.SHA-1", value=report["sha1"]) final_observable = self.helper.api.stix_cyber_observable.update_field( id=final_observable["id"], key="hashes.SHA-256", value=report["sha256"], ) if "name" not in final_observable or final_observable[ "name"] is None: self.helper.api.stix_cyber_observable.update_field( id=final_observable["id"], key="x_opencti_additional_names", value=report["submit_name"], operation="add", ) if final_observable["entity_type"] == "StixFile": self.helper.api.stix_cyber_observable.update_field( id=final_observable["id"], key="size", value=str(report["size"]), ) self.helper.api.stix_cyber_observable.update_field( id=final_observable["id"], key="x_opencti_score", value=str(report["threat_score"]), ) # Create external reference external_reference = self.helper.api.external_reference.create( source_name="Hybrid Analysis", url="https://www.hybrid-analysis.com/sample/" + report["sha256"], description="Hybrid Analysis Report", ) self.helper.api.stix_cyber_observable.add_external_reference( id=final_observable["id"], external_reference_id=external_reference["id"], ) # Create tags for tag in report["type_short"]: tag_ha = self.helper.api.label.create(value=tag, color="#0059f7") self.helper.api.stix_cyber_observable.add_label( id=final_observable["id"], label_id=tag_ha["id"]) # Attach the TTPs for tactic in report["mitre_attcks"]: if (tactic["malicious_identifiers_count"] > 0 or tactic["suspicious_identifiers_count"] > 0): attack_pattern = AttackPattern( id=OpenCTIStix2Utils.generate_random_stix_id( "attack-pattern"), created_by_ref=self.identity, name=tactic["technique"], custom_properties={ "x_mitre_id": tactic["attck_id"], }, object_marking_refs=[TLP_WHITE], ) relationship = Relationship( id=OpenCTIStix2Utils.generate_random_stix_id( "relationship"), relationship_type="uses", created_by_ref=self.identity, source_ref=final_observable["standard_id"], target_ref=attack_pattern.id, object_marking_refs=[TLP_WHITE], ) bundle_objects.append(attack_pattern) bundle_objects.append(relationship) # Attach the domains for domain in report["domains"]: domain_stix = SimpleObservable( id=OpenCTIStix2Utils.generate_random_stix_id( "x-opencti-simple-observable"), key="Domain-Name.value", value=domain, created_by_ref=self.identity, object_marking_refs=[TLP_WHITE], ) relationship = Relationship( id=OpenCTIStix2Utils.generate_random_stix_id("relationship"), relationship_type="communicates-with", created_by_ref=self.identity, source_ref=final_observable["standard_id"], target_ref=domain_stix.id, object_marking_refs=[TLP_WHITE], ) bundle_objects.append(domain_stix) bundle_objects.append(relationship) # Attach the IP addresses for host in report["hosts"]: host_stix = SimpleObservable( id=OpenCTIStix2Utils.generate_random_stix_id( "x-opencti-simple-observable"), key=self.detect_ip_version(host) + ".value", value=host, created_by_ref=self.identity, object_marking_refs=[TLP_WHITE], ) relationship = Relationship( id=OpenCTIStix2Utils.generate_random_stix_id("relationship"), relationship_type="communicates-with", created_by_ref=self.identity, source_ref=final_observable["standard_id"], target_ref=host_stix.id, object_marking_refs=[TLP_WHITE], ) bundle_objects.append(host_stix) bundle_objects.append(relationship) # Attach other files for file in report["extracted_files"]: if file["threat_level"] > 0: file_stix = File( id=OpenCTIStix2Utils.generate_random_stix_id("file"), hashes={ "MD5": file["md5"], "SHA-1": file["sha1"], "SHA-256": file["sha256"], }, size=file["size"], name=file["name"], custom_properties={"x_opencti_labels": file["type_tags"]}, created_by_ref=self.identity, object_marking_refs=[TLP_WHITE], ) relationship = Relationship( id=OpenCTIStix2Utils.generate_random_stix_id( "relationship"), relationship_type="drops", created_by_ref=self.identity, source_ref=final_observable["standard_id"], target_ref=file_stix.id, ) bundle_objects.append(file_stix) bundle_objects.append(relationship) for tactic in report["mitre_attcks"]: if (tactic["malicious_identifiers_count"] > 0 or tactic["suspicious_identifiers_count"] > 0): attack_pattern = AttackPattern( id=OpenCTIStix2Utils.generate_random_stix_id( "attack-pattern"), created_by_ref=self.identity, name=tactic["technique"], custom_properties={ "x_mitre_id": tactic["attck_id"], }, ) relationship = Relationship( id=OpenCTIStix2Utils.generate_random_stix_id( "relationship"), relationship_type="uses", created_by_ref=self.identity, source_ref=final_observable["standard_id"], target_ref=attack_pattern.id, ) bundle_objects.append(attack_pattern) bundle_objects.append(relationship) if len(bundle_objects) > 0: bundle = Bundle(objects=bundle_objects).serialize() bundles_sent = self.helper.send_stix2_bundle(bundle) return ("Sent " + str(len(bundles_sent)) + " stix bundle(s) for worker import") else: return "Nothing to attach"
def parse_line_to_stix_object(self, classifier, line, regex): if self.is_on_whitelist(classifier["prepare"](re.search( regex, line).group(1))): return "" if classifier["name"] == "processes_created": process = Process( type="process", id="process--" + str(uuid1()), command_line=classifier["prepare"](re.search(regex, line).group(1)), custom_properties={ "container_id": Stix2.get_containerid(line), "timestamp": line[:24], "full_output": line, "executable_path": Stix2.get_executable_path(line), }, allow_custom=True, ) self.processes.append(process) self.all_stix_objects.append(process) if classifier["name"].startswith("files_"): name = classifier["prepare"](re.search( regex, line).group(1)).split("/")[-1] dir_str = "/".join(classifier["prepare"](re.search( regex, line).group(1)).split("/")[:-1]) or "/" if not name: name = classifier["prepare"](re.search( regex, line).group(1)).split("/")[-2] dir_str = "/".join(classifier["prepare"](re.search( regex, line).group(1)).split("/")[:-2]) or "/" file = File( type="file", id="file--" + str(uuid1()), name=name, custom_properties={ "parent_directory_str": dir_str, "container_id": Stix2.get_containerid(line), "timestamp": line[:24], "full_output": line, }, allow_custom=True, ) self.all_stix_objects.append(file) if classifier["name"] == "files_removed": self.files_removed.append(file) if classifier["name"] == "files_written": self.files_written.append(file) if classifier["name"] == "files_read": self.files_read.append(file) if classifier["name"] == "hosts_connected": ipv4_regex = r"([0-9]{1,3}\.){3}[0-9]{1,3}" if re.search(ipv4_regex, line): ipv4 = IPv4Address( type="ipv4-addr", id="ipv4-addr--" + str(uuid1()), value=classifier["prepare"](re.search(regex, line).group(1)), custom_properties={ "container_id": Stix2.get_containerid(line), "timestamp": line[:24], "full_output": line, }, allow_custom=True, ) self.ipv4.append(ipv4) self.all_stix_objects.append(ipv4) else: ipv6 = IPv6Address( type="ipv6-addr", id="ipv6-addr--" + str(uuid1()), value=classifier["prepare"](re.search(regex, line).group(1)), custom_properties={ "container_id": Stix2.get_containerid(line), "timestamp": line[:24], "full_output": line, }, allow_custom=True, ) self.ipv6.append(ipv6) self.all_stix_objects.append(ipv6) if classifier["name"] == "domains": ip = re.search(regex, line).group(1) domain_name = classifier["prepare"](ip) if domain_name != ip: domain = DomainName( type="domain-name", id="domain-name--" + str(uuid1()), value=domain_name, resolves_to_refs=[ self.get_ip_stix_object_for_domain(line, ip) ], custom_properties={ "container_id": Stix2.get_containerid(line), "timestamp": line[:24], "full_output": line, "resolves_to_str": ip, }, allow_custom=True, ) self.domains.append(domain) self.all_stix_objects.append(domain) else: # reverse dns failed, only save ipv4 / ipv6 object self.get_ip_stix_object_for_domain(line, ip)
def _process_indicator(self, indicator: Indicator) -> list[_Observable]: """ Process the indicator depending on its type. Parameters ---------- indicator : Indicator One indicator from an article. Returns ------- List of Observable A list of Observable depending on the indicator type. """ indicator_type = indicator["type"] values = indicator["values"] tlp_marking = TLP_WHITE if indicator[ "source"] == "public" else TLP_AMBER if indicator_type == "hash_md5": return [ File( type="file", hashes={"MD5": v}, object_marking_refs=tlp_marking, ) for v in values ] if indicator_type in ["hash_sha1", "sha1"]: return [ File( type="file", hashes={"SHA-1": v}, object_marking_refs=tlp_marking, ) for v in values ] if indicator_type in ["sha256", "hash_sha256"]: return [ File( type="file", hashes={"SHA-256": v}, object_marking_refs=tlp_marking, ) for v in values ] if indicator_type == "domain": return [ DomainName(type="domain-name", value=v, object_marking_refs=tlp_marking) for v in values ] if indicator_type in ["email", "emails"]: return [ EmailAddress(type="email-addr", value=v, object_marking_refs=tlp_marking) for v in values ] if indicator_type in ["filename", "filepath"]: return [ File(type="file", name=v, object_marking_refs=tlp_marking) for v in values ] if indicator_type == "ip": return [ IPv4Address(type="ipv4-addr", value=v, object_marking_refs=tlp_marking) for v in values ] if indicator_type in ["proces_mutex", "process_mutex", "mutex"]: return [ Mutex(type="mutex", name=v, object_marking_refs=tlp_marking) for v in values ] if indicator_type == "url": return [ URL(type="url", value=v, object_marking_refs=tlp_marking, defanged=False) for v in values ] if indicator_type == "certificate_sha1": return [ X509Certificate( type="x509-certificate", hashes={"SHA-1": v}, object_marking_refs=tlp_marking, ) for v in values ] if indicator_type in [ "certificate_issuerorganizationname", "certificate_issuercommonname", ]: return [ X509Certificate(type="x509-certificate", issuer=v, object_marking_refs=tlp_marking) for v in values ] if indicator_type in [ "certificate_subjectorganizationname", "certificate_subjectcountry", "certificate_subjectcommonname", ]: return [ X509Certificate(type="x509-certificate", subject=v, object_marking_refs=tlp_marking) for v in values ] if indicator_type in [ "certificate_serialnumber", "code_certificate_serial" ]: return [ X509Certificate( type="x509-certificate", serial_number=v, object_marking_refs=tlp_marking, ) for v in values ] self.helper.log_warning( f"[RiskIQ] indicator with key {indicator_type} not supported. (Values: {values})" ) return []