def from_cybox(cls, cybox_object): """ Convert a Cybox DefinedObject to a MongoEngine Indicator object. :param cybox_object: The cybox object to create the indicator from. :type cybox_object: :class:`cybox.core.Observable`` :returns: :class:`crits.indicators.indicator.Indicator` """ obj = make_crits_object(cybox_object) if obj.name and obj.name != obj.object_type: ind_type = "%s - %s" % (obj.object_type, obj.name) else: ind_type = obj.object_type db_indicator = Indicator.objects(Q(ind_type=ind_type) & Q(value=obj.value)).first() if db_indicator: indicator = db_indicator else: indicator = cls() indicator.value = obj.value indicator.created = obj.date indicator.modified = obj.date return indicator
def parse_indicators(self, indicators): """ Parse list of indicators. :param indicators: List of STIX indicators. :type indicators: List of STIX indicators. """ analyst = self.source_instance.analyst for indicator in indicators: # for each STIX indicator # store relationships for rel in getattr(indicator, 'related_indicators', ()): self.relationships.append( (indicator.id_, rel.relationship.value, rel.item.idref, rel.confidence.value.value)) # handled indicator-wrapped observable if getattr(indicator, 'title', ""): if "Top-Level Object" in indicator.title: self.parse_observables(indicator.observables) result = self.imported.pop(indicator.observables[0].id_, None) if result: self.imported[indicator.id_] = result continue for observable in indicator.observables: # get each observable from indicator (expecting only 1) try: # create CRITs Indicator from observable item = observable.object_.properties obj = make_crits_object(item) if obj.name and obj.name != obj.object_type: ind_type = "%s - %s" % (obj.object_type, obj.name) else: ind_type = obj.object_type for value in obj.value: if value and ind_type: res = handle_indicator_ind(value.strip(), self.source, ind_type, analyst, add_domain=True, add_relationship=True) if res['success']: self.imported[indicator.id_] = ( Indicator._meta['crits_type'], res['object']) else: self.failed.append(( res['message'], type(item).__name__, item.parent.id_)) # note for display in UI except Exception, e: # probably caused by cybox object we don't handle self.failed.append( (e.message, type(item).__name__, item.parent.id_)) # note for display in UI
def parse_indicators(self, indicators): """ Parse list of indicators. :param indicators: List of STIX indicators. :type indicators: List of STIX indicators. """ analyst = self.source_instance.analyst for indicator in indicators: # for each STIX indicator # store relationships for rel in getattr(indicator, "related_indicators", ()): self.relationships.append( (indicator.id_, rel.relationship.value, rel.item.idref, rel.confidence.value.value) ) # handled indicator-wrapped observable if getattr(indicator, "title", ""): if "Top-Level Object" in indicator.title: self.parse_observables(indicator.observables) result = self.imported.pop(indicator.observables[0].id_, None) if result: self.imported[indicator.id_] = result continue for observable in indicator.observables: # get each observable from indicator (expecting only 1) try: # create CRITs Indicator from observable item = observable.object_.properties obj = make_crits_object(item) if obj.name and obj.name != obj.object_type: ind_type = "%s - %s" % (obj.object_type, obj.name) else: ind_type = obj.object_type for value in obj.value: if value and ind_type: res = handle_indicator_ind( value.strip(), self.source, ind_type, analyst, add_domain=True, add_relationship=True ) if res["success"]: self.imported[indicator.id_] = (Indicator._meta["crits_type"], res["object"]) else: self.failed.append( (res["message"], type(item).__name__, item.parent.id_) ) # note for display in UI except Exception, e: # probably caused by cybox object we don't handle self.failed.append((e.message, type(item).__name__, item.parent.id_)) # note for display in UI
def from_cybox(cls, cybox_object, source): """ Convert a Cybox DefinedObject to a MongoEngine Indicator object. :param cybox_object: The cybox object to create the indicator from. :type cybox_object: :class:`cybox.core.Observable`` :param source: The source list for the Indicator. :type source: list :returns: :class:`crits.indicators.indicator.Indicator` """ indicator = cls(source=source) obj = make_crits_object(cybox_object) indicator.created = obj.date if obj.name and obj.name != obj.object_type: indicator.ind_type = "%s - %s" % (obj.object_type, obj.name) else: indicator.ind_type = obj.object_type indicator.modified = obj.date indicator.value = obj.value return indicator
def parse_indicators(self, indicators): """ Parse list of indicators. :param indicators: List of STIX indicators. :type indicators: List of STIX indicators. """ analyst = self.source_instance.analyst for indicator in indicators: # for each STIX indicator for observable in indicator.observables: # get each observable from indicator (expecting only 1) try: # create CRITs Indicator from observable item = observable.object_.properties obj = make_crits_object(item) if obj.name and obj.name != obj.object_type: ind_type = "%s - %s" % (obj.object_type, obj.name) else: ind_type = obj.object_type for value in obj.value: if value and ind_type: res = handle_indicator_ind(value.strip(), self.source, None, ind_type, analyst, add_domain=True, add_relationship=True) if res['success']: self.imported.append( (Indicator._meta['crits_type'], res['object'])) else: self.failed.append(( res['message'], type(item).__name__, item.parent.id_)) # note for display in UI except Exception, e: # probably caused by cybox object we don't handle self.failed.append( (e.message, type(item).__name__, item.parent.id_)) # note for display in UI
def parse_indicators(self, indicators): """ Parse list of indicators. :param indicators: List of STIX indicators. :type indicators: List of STIX indicators. """ analyst = self.source_instance.analyst for indicator in indicators: # for each STIX indicator for observable in indicator.observables: # get each observable from indicator (expecting only 1) try: # create CRITs Indicator from observable item = observable.object_.properties obj = make_crits_object(item) if obj.name and obj.name != obj.object_type: ind_type = "%s - %s" % (obj.object_type, obj.name) else: ind_type = obj.object_type for value in obj.value: if value and ind_type: res = handle_indicator_ind( value.strip(), self.source, None, ind_type, analyst, add_domain=True, add_relationship=True, ) if res["success"]: self.imported.append((Indicator._meta["crits_type"], res["object"])) else: self.failed.append( (res["message"], type(item).__name__, item.parent.id_) ) # note for display in UI except Exception, e: # probably caused by cybox object we don't handle self.failed.append((e.message, type(item).__name__, item.parent.id_)) # note for display in UI
def parse_observables(self, observables): """ Parse list of observables in STIX doc. :param observables: List of STIX observables. :type observables: List of STIX observables. """ analyst = self.source_instance.analyst for obs in observables: # for each STIX observable if not obs.object_ or not obs.object_.properties: self.failed.append(("No valid object_properties was found!", type(obs).__name__, obs.id_)) # note for display in UI continue try: # try to create CRITs object from observable item = obs.object_.properties if isinstance(item, Address): if item.category in ('cidr', 'ipv4-addr', 'ipv4-net', 'ipv4-netmask', 'ipv6-addr', 'ipv6-net', 'ipv6-netmask'): imp_type = "IP" for value in item.address_value.values: ip = str(value).strip() iptype = "Address - %s" % item.category res = ip_add_update(ip, iptype, [self.source], analyst=analyst, is_add_indicator=True) self.parse_res(imp_type, obs, res) if isinstance(item, DomainName): imp_type = "Domain" for value in item.value.values: (sdomain, domain) = get_domain(str(value.strip())) res = upsert_domain(sdomain, domain, [self.source], username=analyst) self.parse_res(imp_type, obs, res) elif isinstance(item, Artifact): # Not sure if this is right, and I believe these can be # encoded in a couple different ways. imp_type = "RawData" rawdata = item.data.decode('utf-8') description = "None" # TODO: find out proper ways to determine title, datatype, # tool_name, tool_version title = "Artifact for Event: STIX Document %s" % self.package.id_ res = handle_raw_data_file(rawdata, self.source.name, user=analyst, description=description, title=title, data_type="Text", tool_name="STIX", tool_version=None, method=self.source_instance.method, reference=self.source_instance.reference) self.parse_res(imp_type, obs, res) elif (isinstance(item, File) and item.custom_properties and item.custom_properties[0].name == "crits_type" and item.custom_properties[0]._value == "Certificate"): imp_type = "Certificate" description = "None" filename = str(item.file_name) data = None for obj in item.parent.related_objects: if isinstance(obj.properties, Artifact): data = obj.properties.data res = handle_cert_file(filename, data, self.source, user=analyst, description=description) self.parse_res(imp_type, obs, res) elif isinstance(item, File) and self.has_network_artifact(item): imp_type = "PCAP" description = "None" filename = str(item.file_name) data = None for obj in item.parent.related_objects: if (isinstance(obj.properties, Artifact) and obj.properties.type_ == Artifact.TYPE_NETWORK): data = obj.properties.data res = handle_pcap_file(filename, data, self.source, user=analyst, description=description) self.parse_res(imp_type, obs, res) elif isinstance(item, File): imp_type = "Sample" filename = str(item.file_name) md5 = item.md5 data = None for obj in item.parent.related_objects: if (isinstance(obj.properties, Artifact) and obj.properties.type_ == Artifact.TYPE_FILE): data = obj.properties.data res = handle_file(filename, data, self.source, user=analyst, md5_digest=md5, is_return_only_md5=False) self.parse_res(imp_type, obs, res) elif isinstance(item, EmailMessage): imp_type = "Email" data = {} data['source'] = self.source.name data['source_method'] = self.source_instance.method data['source_reference'] = self.source_instance.reference data['raw_body'] = str(item.raw_body) data['raw_header'] = str(item.raw_header) data['helo'] = str(item.email_server) if item.header: data['message_id'] = str(item.header.message_id) data['subject'] = str(item.header.subject) data['sender'] = str(item.header.sender) data['reply_to'] = str(item.header.reply_to) data['x_originating_ip'] = str(item.header.x_originating_ip) data['x_mailer'] = str(item.header.x_mailer) data['boundary'] = str(item.header.boundary) data['from_address'] = str(item.header.from_) data['date'] = item.header.date.value if item.header.to: data['to'] = [str(r) for r in item.header.to.to_list()] res = handle_email_fields(data, analyst, "STIX") # Should check for attachments and add them here. self.parse_res(imp_type, obs, res) else: # try to parse all other possibilities as Indicator imp_type = "Indicator" obj = make_crits_object(item) if (obj.object_type == 'Address' and obj.name in ('cidr', 'ipv4-addr', 'ipv4-net', 'ipv4-netmask', 'ipv6-addr', 'ipv6-net', 'ipv6-netmask')): # This was already caught above continue else: if obj.name and obj.name != obj.object_type: ind_type = "%s - %s" % (obj.object_type, obj.name) else: ind_type = obj.object_type for value in obj.value: if value and ind_type: res = handle_indicator_ind(value.strip(), self.source, None, ind_type, analyst, add_domain=True, add_relationship=True) self.parse_res(imp_type, obs, res) except Exception, e: # probably caused by cybox object we don't handle self.failed.append((e.message, type(item).__name__, item.parent.id_)) # note for display in UI