Example #1
0
    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
Example #2
0
    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
Example #3
0
    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
Example #4
0
    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
Example #5
0
    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
Example #6
0
    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
Example #7
0
    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
Example #8
0
    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