Example #1
0
    def parse_stix(self, reference=None, make_event=False, source=''):
        """
        Parse the document.

        :param reference: The reference to the data.
        :type reference: str
        :param make_event: Whether or not to create an Event for this document.
        :type make_event: bool
        :param source: The source of this document.
        :type source: str
        :raises: :class:`crits.standards.parsers.STIXParserException`

        Until we have a way to map source strings in a STIX document to
        a source in CRITs, we are being safe and using the source provided
        as the true source.
        """

        f = StringIO(self.data)
        self.package = STIXPackage.from_xml(f)
        f.close()
        if not self.package:
            raise STIXParserException("STIX package failure")

        stix_header = self.package.stix_header
        if stix_header and stix_header.information_source and stix_header.information_source.identity:
            self.information_source = stix_header.information_source.identity.name
            if self.information_source:
                info_src = "STIX Source: %s" % self.information_source
                if not reference:
                    reference = ''
                else:
                    reference += ", "
                reference += info_src
        if does_source_exist(source):
            self.source.name = source
        elif does_source_exist(self.information_source):
            self.source.name = self.information_source
        else:
            raise STIXParserException("No source to attribute data to.")

        self.source_instance.reference = reference
        self.source.instances.append(self.source_instance)

        if make_event:
            event = Event.from_stix(stix_package=self.package,
                                    source=[self.source])
            try:
                event.save(username=self.source_instance.analyst)
                self.imported.append((Event._meta['crits_type'], event))
            except Exception, e:
                self.failed.append(
                    (e.message, type(event).__name__, event.id_))
Example #2
0
    def parse_stix(self, reference=None, make_event=False, source=''):
        """
        Parse the document.

        :param reference: The reference to the data.
        :type reference: str
        :param make_event: Whether or not to create an Event for this document.
        :type make_event: bool
        :param source: The source of this document.
        :type source: str
        :raises: :class:`crits.standards.parsers.STIXParserException`

        Until we have a way to map source strings in a STIX document to
        a source in CRITs, we are being safe and using the source provided
        as the true source.
        """

        f = StringIO(self.data)
        self.package = STIXPackage.from_xml(f)
        f.close()
        if not self.package:
            raise STIXParserException("STIX package failure")

        stix_header = self.package.stix_header
        if stix_header and stix_header.information_source and stix_header.information_source.identity:
            self.information_source = stix_header.information_source.identity.name
            if self.information_source:
                info_src = "STIX Source: %s" % self.information_source
                if not reference:
                    reference = ''
                else:
                    reference += ", "
                reference += info_src
        if does_source_exist(source):
            self.source.name = source
        elif does_source_exist(self.information_source):
            self.source.name = self.information_source
        else:
            raise STIXParserException("No source to attribute data to.")

        self.source_instance.reference = reference
        self.source.instances.append(self.source_instance)

        if make_event:
            event = Event.from_stix(stix_package=self.package)
            try:
                event.add_source(self.source)
                event.save(username=self.source_instance.analyst)
                self.imported.append((Event._meta['crits_type'], event))
            except Exception, e:
                self.failed.append((e.message, type(event).__name__, event.id_))
Example #3
0
 def _validate(cls, config):
     hostname = config.get("hostname", "").strip()
     keyfile = config.get("keyfile", "").strip()
     certfile = config.get("certfile", "").strip()
     data_feed = config.get("data_feed", "").strip()
     certfiles = config.get("certfiles", "")
     if not hostname:
         raise ServiceConfigError("You must specify a TAXII Server.")
     if not keyfile:
         raise ServiceConfigError("You must specify a keyfile location.")
     if  not os.path.isfile(keyfile):
         raise ServiceConfigError("keyfile does not exist.")
     if not certfile:
         raise ServiceConfigError("You must specify a certfile location.")
     if  not os.path.isfile(certfile):
         raise ServiceConfigError("certfile does not exist.")
     if not data_feed:
         raise ServiceConfigError("You must specify a TAXII Data Feed.")
     if not certfiles:
         raise ServiceConfigError("You must specify at least one certfile.")
     for crtfile in certfiles:
         try:
             (source, feed, filepath) = crtfile.split(',')
         except ValueError:
             raise ServiceConfigError("You must specify a source, feed name"
                                      ", and certificate path for each source.")
         source.strip()
         feed.strip()
         filepath.strip()
         if not does_source_exist(source):
             raise ServiceConfigError("Invalid source: %s" % source)
         if  not os.path.isfile(filepath):
             raise ServiceConfigError("certfile does not exist: %s" % filepath)
Example #4
0
 def parse_feed_config(config):
     srv_name = config.get("srv_name", "").strip()
     feedname = config.get("feedname", "").strip()
     source = config.get("source", "").strip()
     subID = config.get("subID", "").strip()
     fcert = config.get("fcert", "").strip()
     fkey = config.get("fkey", "").strip()
     errors = []
     if not srv_name:
         errors.append("No server name to which to relate this feed")
     if not re.match("^[\w ]+$", srv_name):
         errors.append("Provided server name is invalid")
     if not feedname:
         errors.append("You must specify a Feed Name")
     if not source:
         errors.append("You must specify a CRITs source")
     else:
         if not does_source_exist(source):
             errors.append("Provided CRITs source is invalid")
     if fcert and not os.path.isfile(fcert):
         errors.append("Encryption Certificate does not exist at given location")
     if fkey and not os.path.isfile(fkey):
         errors.append("Decryption Key does not exist at given location")
     if errors:
         raise ServiceConfigError("<br>".join(errors))
Example #5
0
 def parse_feed_config(config):
     srv_name = config.get("srv_name", "").strip()
     feedname = config.get("feedname", "").strip()
     source = config.get("source", "").strip()
     subID = config.get("subID", "").strip()
     fcert = config.get("fcert", "").strip()
     fkey = config.get("fkey", "").strip()
     errors = []
     if not srv_name:
         errors.append("No server name to which to relate this feed")
     if not re.match("^[\w ]+$", srv_name):
         errors.append("Provided server name is invalid")
     if not feedname:
         errors.append("You must specify a Feed Name")
     if not source:
         errors.append("You must specify a CRITs source")
     else:
         if not does_source_exist(source):
             errors.append("Provided CRITs source is invalid")
     if fcert and not os.path.isfile(fcert):
         errors.append(
             "Encryption Certificate does not exist at given location")
     if fkey and not os.path.isfile(fkey):
         errors.append("Decryption Key does not exist at given location")
     if errors:
         raise ServiceConfigError("<br>".join(errors))
Example #6
0
 def _validate(cls, config):
     hostname = config.get("hostname", "").strip()
     keyfile = config.get("keyfile", "").strip()
     certfile = config.get("certfile", "").strip()
     data_feed = config.get("data_feed", "").strip()
     certfiles = config.get("certfiles", "")
     if not hostname:
         raise ServiceConfigError("You must specify a TAXII Server.")
     if not keyfile:
         raise ServiceConfigError("You must specify a keyfile location.")
     if not os.path.isfile(keyfile):
         raise ServiceConfigError("keyfile does not exist.")
     if not certfile:
         raise ServiceConfigError("You must specify a certfile location.")
     if not os.path.isfile(certfile):
         raise ServiceConfigError("certfile does not exist.")
     if not data_feed:
         raise ServiceConfigError("You must specify a TAXII Data Feed.")
     if not certfiles:
         raise ServiceConfigError("You must specify at least one certfile.")
     for crtfile in certfiles:
         try:
             (source, feed, filepath) = crtfile.split(',')
         except ValueError:
             raise ServiceConfigError(
                 ("You must specify a source, feed name"
                  ", and certificate path for each source."))
         source.strip()
         feed.strip()
         filepath.strip()
         if not does_source_exist(source):
             raise ServiceConfigError("Invalid source: %s" % source)
         if not os.path.isfile(filepath):
             raise ServiceConfigError("certfile does not exist: %s" %
                                      filepath)
Example #7
0
    def parse_config(config):
        # When editing a config we are given a string.
        # When validating an existing config it will be a list.
        # Convert it to a list of strings.
        certfiles = config.get('certfiles', [])
        if isinstance(certfiles, basestring):
            config['certfiles'] = [cf for cf in certfiles.split('\r\n')]

        hostname = config.get("hostname", "").strip()
        keyfile = config.get("keyfile", "").strip()
        certfile = config.get("certfile", "").strip()
        data_feed = config.get("data_feed", "").strip()
        errors = []
        if not hostname:
            errors.append("You must specify a TAXII Server.")
        if not keyfile:
            errors.append("You must specify a keyfile location.")
        if not os.path.isfile(keyfile):
            errors.append("keyfile does not exist.")
        if not certfile:
            errors.append("You must specify a certfile location.")
        if not os.path.isfile(certfile):
            errors.append("certfile does not exist.")
        if not data_feed:
            errors.append("You must specify a TAXII Data Feed.")
        if not certfiles:
            errors.append("You must specify at least one certfile.")
        if not config.get('polling_time', "").strip().isdigit():
            errors.append("Polling time must be an integer.")
        if not config.get('inbox_time', "").strip().isdigit():
            errors.append("Inbox time must be an integer.")
        for crtfile in config['certfiles']:
            try:
                (source, feed, polling, inbox) = crtfile.split(',')
            except ValueError as e:
                errors.append(
                    "You must specify a source, feed name, "
                    " true/false polling, and true/false inbox for each source. (%s)"
                    % str(e))
                break
            source.strip()
            feed.strip()
            if not does_source_exist(source):
                errors.append("Invalid source: %s" % source)
        if errors:
            raise ServiceConfigError("\n".join(errors))
Example #8
0
    def parse_config(config):
        # When editing a config we are given a string.
        # When validating an existing config it will be a list.
        # Convert it to a list of strings.
        certfiles = config.get('certfiles', [])
        if isinstance(certfiles, basestring):
            config['certfiles'] = [cf for cf in certfiles.split('\r\n')]

        hostname = config.get("hostname", "").strip()
        keyfile = config.get("keyfile", "").strip()
        certfile = config.get("certfile", "").strip()
        data_feed = config.get("data_feed", "").strip()
        errors = []
        if not hostname:
            errors.append("You must specify a TAXII Server.")
        if not keyfile:
            errors.append("You must specify a keyfile location.")
        if  not os.path.isfile(keyfile):
            errors.append("keyfile does not exist.")
        if not certfile:
            errors.append("You must specify a certfile location.")
        if  not os.path.isfile(certfile):
            errors.append("certfile does not exist.")
        if not data_feed:
            errors.append("You must specify a TAXII Data Feed.")
        if not certfiles:
            errors.append("You must specify at least one certfile.")
        for crtfile in config['certfiles']:
            try:
                (source, feed, filepath) = crtfile.split(',')
            except ValueError as e:
                errors.append("You must specify a source, feed name, and "
                              "certificate path for each source. (%s)" % str(e))
                break
            source.strip()
            feed.strip()
            filepath.strip()
            if not does_source_exist(source):
                errors.append("Invalid source: %s" % source)
            if  not os.path.isfile(filepath):
                errors.append("certfile does not exist: %s" % filepath)
        if errors:
            raise ServiceConfigError("\n".join(errors))
Example #9
0
    def parse_stix(self, reference='', make_event=False, source=''):
        """
        Parse the document.

        :param reference: The reference to the data.
        :type reference: str
        :param make_event: Whether or not to create an Event for this document.
        :type make_event: bool
        :param source: The source of this document.
        :type source: str
        :raises: :class:`taxii_service.parsers.STIXParserException`

        Until we have a way to map source strings in a STIX document to
        a source in CRITs, we are being safe and using the source provided
        as the true source.
        """

        f = BytesIO(self.data)
        self.package = STIXPackage.from_xml(f)
        f.close()
        if not self.package:
            raise STIXParserException("STIX package failure")

        stix_header = self.package.stix_header
        if stix_header and stix_header.information_source and stix_header.information_source.identity:
            self.information_source = stix_header.information_source.identity.name

            if self.information_source:
                info_src = "STIX Source: %s" % self.information_source
                if not reference:
                    reference = ''
                else:
                    reference += ", "
                reference += info_src
        if does_source_exist(source):
            self.source.name = source
        elif does_source_exist(self.information_source):
            self.source.name = self.information_source
        else:
            raise STIXParserException("No source to attribute data to.")

        self.source_instance.reference = reference
        self.source.instances.append(self.source_instance)

        if make_event:
            title = "STIX Document %s" % self.package.id_
            event_type = EventTypes.INTEL_SHARING
            date = datetime.datetime.now()
            description = str(date)
            header = self.package.stix_header
            if isinstance(header, STIXHeader):
                if header.title:
                    title = header.title
                if hasattr(header, 'package_intents'):
                    try:
                        stix_type = str(header.package_intents[0])
                        event_type = get_crits_event_type(stix_type)
                    except:
                        pass
                if header.description:
                    description = header.description
                    if isinstance(description, StructuredText):
                        try:
                            description = description.to_dict()
                        except:
                            pass
            res = add_new_event(title, description, event_type,
                                self.source.name, self.source_instance.method,
                                self.source_instance.reference, date,
                                self.source_instance.analyst)
            if res['success']:
                self.event = res['object']
                self.imported[self.package.id_] = ('Event', res['object'])

                # Get relationships to the Event
                if self.package.incidents:
                    incdnts = self.package.incidents
                    for rel in getattr(incdnts[0], 'related_indicators', ()):
                        self.event_rels[rel.item.idref] = (
                            rel.relationship.value, rel.confidence.value.value)
            else:
                self.failed.append((res['message'], "STIX Event", ""))

        if self.package.indicators:
            res = self.parse_indicators(self.package.indicators)
            if res == False:
                self.parse_campaigns(self.package.indicators,
                                     self.package.campaigns)
                self.parse_ttps(self.package.indicators)
                self.parse_aliases(self.package.indicators)
            self.parse_comments(self.package.indicators)
            self.parse_relationship(self.package.indicators)
            self.parse_sources(self.package.indicators)
            self.parse_sectors(self.package.indicators)
            self.parse_sightings(self.package.indicators)
            self.parse_kill_chain(self.package.indicators)
            self.parse_rfi(self.package.indicators)
            if self.package.campaigns:
                self.parse_related_campaigns(self.package.indicators,
                                             self.package.campaigns)
            if self.package.stix_header:
                self.parse_tlp(self.package.indicators,
                               self.package.stix_header)
            self.set_releasability(self.package.indicators, source)

        if self.package.observables and self.package.observables.observables:
            self.parse_observables(self.package.observables.observables)

        if self.package.threat_actors:
            self.parse_threat_actors(self.package.threat_actors)
Example #10
0
    def parse_stix(self, reference=None, make_event=False, source=''):
        """
        Parse the document.

        :param reference: The reference to the data.
        :type reference: str
        :param make_event: Whether or not to create an Event for this document.
        :type make_event: bool
        :param source: The source of this document.
        :type source: str
        :raises: :class:`crits.standards.parsers.STIXParserException`

        Until we have a way to map source strings in a STIX document to
        a source in CRITs, we are being safe and using the source provided
        as the true source.
        """

        f = StringIO(self.data)
        (self.package, self.binding) = STIXPackage.from_xml(f)
        f.close()
        if not self.package and not self.binding:
            raise STIXParserException("STIX package failure")

        stix_header = self.package.stix_header
        if stix_header and stix_header.information_source and stix_header.information_source.identity:
            self.information_source = stix_header.information_source.identity.name
            if self.information_source:
                info_src = "STIX Source: %s" % self.information_source
                if not reference:
                    reference = ''
                else:
                    reference += ", "
                reference += info_src
        if does_source_exist(source):
            self.source.name = source

        self.source_instance.reference = reference
        self.source.instances.append(self.source_instance)

        if make_event:
            event = Event.from_stix(stix_package=self.package,
                                    source=[self.source])
            event.save(username=self.source_instance.analyst)
            self.events.append(('Event', str(event.id)))

        # Walk STIX indicators and pull out CybOX observables.
        # stix.(indicators|observables) is a list of CybOX observables
        if self.package.indicators:
            for indicator in self.package.indicators:
                if not indicator:
                    continue
                for observable in indicator.observables:
                    self.__parse_observable(observable)

        # Also walk STIX observables and pull out CybOX observables.
        # At some point the standard will allow stix_package.observables to be
        # an iterable object and we can collapse this with indicators.
        if self.package.observables:
            if self.package.observables.observables:
                for observable in self.package.observables.observables:
                    if not observable:
                        continue
                    self.__parse_observable(observable)
Example #11
0
    def parse_stix(self, reference='', make_event=False, source=''):
        """
        Parse the document.

        :param reference: The reference to the data.
        :type reference: str
        :param make_event: Whether or not to create an Event for this document.
        :type make_event: bool
        :param source: The source of this document.
        :type source: str
        :raises: :class:`taxii_service.parsers.STIXParserException`

        Until we have a way to map source strings in a STIX document to
        a source in CRITs, we are being safe and using the source provided
        as the true source.
        """

        f = BytesIO(self.data)
        self.package = STIXPackage.from_xml(f)
        f.close()
        if not self.package:
            raise STIXParserException("STIX package failure")

        stix_header = self.package.stix_header
        if stix_header and stix_header.information_source and stix_header.information_source.identity:
            self.information_source = stix_header.information_source.identity.name
            if self.information_source:
                info_src = "STIX Source: %s" % self.information_source
                if not reference:
                    reference = ''
                else:
                    reference += ", "
                reference += info_src
        if does_source_exist(source):
            self.source.name = source
        elif does_source_exist(self.information_source):
            self.source.name = self.information_source
        else:
            raise STIXParserException("No source to attribute data to.")

        self.source_instance.reference = reference
        self.source.instances.append(self.source_instance)

        if make_event:
            title = "STIX Document %s" % self.package.id_
            event_type = EventTypes.INTEL_SHARING
            date = datetime.datetime.now()
            description = str(date)
            header = self.package.stix_header
            if isinstance(header, STIXHeader):
                if header.title:
                    title = header.title
                if hasattr(header, 'package_intents'):
                    try:
                        stix_type = str(header.package_intents[0])
                        event_type = get_crits_event_type(stix_type)
                    except:
                        pass
                if header.description:
                    description = header.description
                    if isinstance(description, StructuredText):
                        try:
                            description = description.to_dict()
                        except:
                            pass
            res = add_new_event(title,
                                description,
                                event_type,
                                self.source.name,
                                self.source_instance.method,
                                self.source_instance.reference,
                                date,
                                self.source_instance.analyst)
            if res['success']:
                self.event = res['object']
                self.imported[self.package.id_] = ('Event', res['object'])

                # Get relationships to the Event
                if self.package.incidents:
                    incdnts = self.package.incidents
                    for rel in getattr(incdnts[0], 'related_indicators', ()):
                        self.event_rels[rel.item.idref] = (rel.relationship.value,
                                                           rel.confidence.value.value)
            else:
                self.failed.append((res['message'],
                                    "STIX Event",
                                    ""))

        if self.package.indicators:
            self.parse_indicators(self.package.indicators)

        if self.package.observables and self.package.observables.observables:
            self.parse_observables(self.package.observables.observables)

        if self.package.threat_actors:
            self.parse_threat_actors(self.package.threat_actors)
Example #12
0
    def parse_stix(self, reference=None, make_event=False, source=''):
        """
        Parse the document.

        :param reference: The reference to the data.
        :type reference: str
        :param make_event: Whether or not to create an Event for this document.
        :type make_event: bool
        :param source: The source of this document.
        :type source: str
        :raises: :class:`crits.standards.parsers.STIXParserException`

        Until we have a way to map source strings in a STIX document to
        a source in CRITs, we are being safe and using the source provided
        as the true source.
        """

        f = StringIO(self.data)
        self.package = STIXPackage.from_xml(f)
        f.close()
        if not self.package:
            raise STIXParserException("STIX package failure")

        stix_header = self.package.stix_header
        if stix_header and stix_header.information_source and stix_header.information_source.identity:
            self.information_source = stix_header.information_source.identity.name
            if self.information_source:
                info_src = "STIX Source: %s" % self.information_source
                if not reference:
                    reference = ''
                else:
                    reference += ", "
                reference += info_src
        if does_source_exist(source):
            self.source.name = source
        elif does_source_exist(self.information_source):
            self.source.name = self.information_source
        else:
            raise STIXParserException("No source to attribute data to.")

        self.source_instance.reference = reference
        self.source.instances.append(self.source_instance)

        if make_event:
            title = "STIX Document %s" % self.package.id_
            event_type = "Collective Threat Intelligence"
            date = datetime.datetime.now()
            description = str(date)
            header = self.package.stix_header
            if isinstance(header, STIXHeader):
                if header.title:
                    title = header.title
                if hasattr(header, 'package_intents'):
                    event_type = str(header.package_intents[0])
                if header.description:
                    description = header.description
                    if isinstance(description, StructuredText):
                        try:
                            description = description.to_dict()
                        except:
                            pass
            res = add_new_event(title,
                                description,
                                event_type,
                                self.source.name,
                                self.source_instance.method,
                                self.source_instance.reference,
                                date,
                                self.source_instance.analyst)
            if res['success']:
                self.imported.append(('Event',
                                      res['object']))
            else:
                self.failed.append((res['message'],
                                    "STIX Event",
                                    ""))

        if self.package.indicators:
            self.parse_indicators(self.package.indicators)

        if self.package.observables and self.package.observables.observables:
            self.parse_observables(self.package.observables.observables)

        if self.package.threat_actors:
            self.parse_threat_actors(self.package.threat_actors)
Example #13
0
    def parse_stix(self, reference='', make_event=False, source=''):
        """
        Parse the document.

        :param reference: The reference to the data.
        :type reference: str
        :param make_event: Whether or not to create an Event for this document.
        :type make_event: bool
        :param source: The source of this document.
        :type source: str
        :raises: :class:`taxii_service.parsers.STIXParserException`

        Until we have a way to map source strings in a STIX document to
        a source in CRITs, we are being safe and using the source provided
        as the true source.
        """

        with closing(StringIO(self.data)) as f:
            try:
                try:
                    self.package = STIXPackage.from_xml(f)
                    if not self.package:
                        raise STIXParserException("STIX package failure")
                except UnsupportedVersionError:
                    v = stix.__version__
                    v = v[0:-2] if len(v.split('.')) > 3 else v
                    updated = ramrod.update(f, to_=v)
                    doc = updated.document.as_stringio()
                    self.package = STIXPackage.from_xml(doc)
            except Exception as e:
                msg = "Failed to create STIX/CybOX from XML"
                self.failed.append((e.message, "STIX Package (%s)" % msg,
                                    ''))  # note for display in UI
                return

        if not self.preview:
            self.stix_version = self.package.version
            stix_header = self.package.stix_header
            if stix_header and stix_header.information_source and stix_header.information_source.identity:
                self.information_source = stix_header.information_source.identity.name
                if self.information_source:
                    info_src = "STIX Source: %s" % self.information_source
                    if not reference:
                        reference = ''
                    else:
                        reference += ", "
                    reference += info_src
            if source:
                if does_source_exist(source):
                    self.source.name = source
                else:
                    raise STIXParserException(
                        'Source "%s" does not exist in CRITs.' % source)
            elif does_source_exist(self.information_source):
                self.source.name = self.information_source
            else:
                raise STIXParserException("No source to attribute data to.")

            self.source_instance.reference = reference
            self.source.instances.append(self.source_instance)

        if make_event:
            title = "STIX Document %s" % self.package.id_
            event_type = EventTypes.INTEL_SHARING
            date = datetime.datetime.now()
            description = str(date)
            if self.package.incidents:
                incdnt = self.package.incidents[0]
                title = incdnt.title
                if incdnt.description:
                    description = incdnt.description
                    if isinstance(description, StructuredText):
                        try:
                            description = description.to_dict()
                        except:
                            pass
                if incdnt.short_description in EventTypes.values():
                    event_type = incdnt.short_description
                elif incdnt.categories and incdnt.categories[0].value:
                    event_type = get_crits_event_type(
                        incdnt.categories[0].value)
            else:  #package contains no incidents
                header = self.package.stix_header
                if isinstance(header, STIXHeader):
                    if header.title:
                        title = header.title
                    if header.package_intents:
                        try:
                            stix_type = str(header.package_intents[0])
                            event_type = get_crits_event_type(stix_type)
                        except:
                            pass
                    if header.description:
                        description = header.description
                        if isinstance(description, StructuredText):
                            try:
                                description = description.to_dict()
                            except:
                                pass
            if self.preview:
                self.imported[self.package.id_] = ('Event', None, title)
            else:
                res = add_new_event(title, description, event_type,
                                    self.source.name,
                                    self.source_instance.method,
                                    self.source_instance.reference, date,
                                    self.source_instance.analyst)
                self.parsed.append(self.package.id_)
                if res['success']:
                    self.event = res['object']
                    self.imported[self.package.id_] = ('Event',
                                                       res['object'].id, title
                                                       or res['object'].id)
                    self.updates[res['object'].id] = res['object']

                    # Get relationships to the Event
                    if self.package.incidents:
                        incdnts = self.package.incidents
                        for rel in getattr(incdnts[0], 'related_indicators',
                                           ()):
                            if rel.relationship or rel.confidence:
                                r = rel.relationship.value or RelationshipTypes.RELATED_TO
                                c = getattr(rel.confidence.value, 'value',
                                            'Unknown')
                                self.event_rels[rel.item.idref] = (r, c)
                else:
                    self.failed.append((res['message'], "Event (%s)" % title,
                                        self.package.id_))

        if self.package.indicators:
            self.parse_indicators(self.package.indicators)

        if self.package.observables and self.package.observables.observables:
            self.parse_observables(self.package.observables.observables)

        if self.package.threat_actors:
            self.parse_threat_actors(self.package.threat_actors)
Example #14
0
    def parse_stix(self, reference=None, make_event=False, source=''):
        """
        Parse the document.

        :param reference: The reference to the data.
        :type reference: str
        :param make_event: Whether or not to create an Event for this document.
        :type make_event: bool
        :param source: The source of this document.
        :type source: str
        :raises: :class:`crits.standards.parsers.STIXParserException`

        Until we have a way to map source strings in a STIX document to
        a source in CRITs, we are being safe and using the source provided
        as the true source.
        """

        f = StringIO(self.data)
        (self.package, self.binding) = STIXPackage.from_xml(f)
        f.close()
        if not self.package and not self.binding:
            raise STIXParserException("STIX package failure")

        stix_header = self.package.stix_header
        if stix_header and stix_header.information_source and stix_header.information_source.identity:
            self.information_source = stix_header.information_source.identity.name
            if self.information_source:
                info_src = "STIX Source: %s" % self.information_source
                if not reference:
                    reference = ''
                else:
                    reference += ", "
                reference += info_src
        if does_source_exist(source):
            self.source.name = source

        self.source_instance.reference = reference
        self.source.instances.append(self.source_instance)

        if make_event:
            event = Event.from_stix(stix_package=self.package, source=[self.source])
            event.save(username=self.source_instance.analyst)
            self.events.append(('Event', str(event.id)))

        # Walk STIX indicators and pull out CybOX observables.
        # stix.(indicators|observables) is a list of CybOX observables
        if self.package.indicators:
            for indicator in self.package.indicators:
                if not indicator:
                    continue
                for observable in indicator.observables:
                    self.__parse_observable(observable)

        # Also walk STIX observables and pull out CybOX observables.
        # At some point the standard will allow stix_package.observables to be
        # an iterable object and we can collapse this with indicators.
        if self.package.observables:
            if self.package.observables.observables:
                for observable in self.package.observables.observables:
                    if not observable:
                        continue
                    self.__parse_observable(observable)
Example #15
0
    def parse_stix(self, reference='', make_event=False, source=''):
        """
        Parse the document.

        :param reference: The reference to the data.
        :type reference: str
        :param make_event: Whether or not to create an Event for this document.
        :type make_event: bool
        :param source: The source of this document.
        :type source: str
        :raises: :class:`taxii_service.parsers.STIXParserException`

        Until we have a way to map source strings in a STIX document to
        a source in CRITs, we are being safe and using the source provided
        as the true source.
        """

        with closing(StringIO(self.data)) as f:
            try:
                try:
                    self.package = STIXPackage.from_xml(f)
                    if not self.package:
                        raise STIXParserException("STIX package failure")
                except UnsupportedVersionError:
                    v = stix.__version__
                    v = v[0:-2] if len(v.split('.')) > 3 else v
                    updated = ramrod.update(f, to_=v)
                    doc = updated.document.as_stringio()
                    self.package = STIXPackage.from_xml(doc)
            except Exception as e:
                msg = "Failed to create STIX/CybOX from XML"
                self.failed.append((e.message,
                                    "STIX Package (%s)" % msg,
                                    '')) # note for display in UI
                return

        if not self.preview:
            self.stix_version = self.package.version
            stix_header = self.package.stix_header
            if stix_header and stix_header.information_source and stix_header.information_source.identity:
                self.information_source = stix_header.information_source.identity.name
                if self.information_source:
                    info_src = "STIX Source: %s" % self.information_source
                    if not reference:
                        reference = ''
                    else:
                        reference += ", "
                    reference += info_src
            if source:
                if does_source_exist(source):
                    self.source.name = source
                else:
                    raise STIXParserException('Source "%s" does not exist in CRITs.' % source)
            elif does_source_exist(self.information_source):
                self.source.name = self.information_source
            else:
                raise STIXParserException("No source to attribute data to.")

            self.source_instance.reference = reference
            self.source.instances.append(self.source_instance)

        if make_event:
            title = "STIX Document %s" % self.package.id_
            event_type = EventTypes.INTEL_SHARING
            date = datetime.datetime.now()
            description = str(date)
            if self.package.incidents:
                incdnt = self.package.incidents[0]
                title = incdnt.title
                if incdnt.description:
                    description = incdnt.description
                    if isinstance(description, StructuredText):
                        try:
                            description = description.to_dict()
                        except:
                            pass
                if incdnt.short_description in EventTypes.values():
                    event_type = incdnt.short_description
                elif incdnt.categories and incdnt.categories[0].value:
                    event_type = get_crits_event_type(incdnt.categories[0].value)
            else: #package contains no incidents
                header = self.package.stix_header
                if isinstance(header, STIXHeader):
                    if header.title:
                        title = header.title
                    if header.package_intents:
                        try:
                            stix_type = str(header.package_intents[0])
                            event_type = get_crits_event_type(stix_type)
                        except:
                            pass
                    if header.description:
                        description = header.description
                        if isinstance(description, StructuredText):
                            try:
                                description = description.to_dict()
                            except:
                                pass
            if self.preview:
                self.imported[self.package.id_] = ('Event',
                                                   None,
                                                   title)
            else:
                res = add_new_event(title,
                                    description,
                                    event_type,
                                    self.source.name,
                                    self.source_instance.method,
                                    self.source_instance.reference,
                                    date,
                                    self.source_instance.analyst)
                self.parsed.append(self.package.id_)
                if res['success']:
                    self.event = res['object']
                    self.imported[self.package.id_] = ('Event',
                                                       res['object'].id,
                                                       title or res['object'].id)
                    self.updates[res['object'].id] = res['object']

                    # Get relationships to the Event
                    if self.package.incidents:
                        incdnts = self.package.incidents
                        for rel in getattr(incdnts[0], 'related_indicators', ()):
                            if rel.relationship or rel.confidence:
                                r = rel.relationship.value or RelationshipTypes.RELATED_TO
                                c = getattr(rel.confidence.value, 'value', 'Unknown')
                                self.event_rels[rel.item.idref] = (r, c)
                else:
                    self.failed.append((res['message'],
                                        "Event (%s)" % title,
                                        self.package.id_))

        if self.package.indicators:
            self.parse_indicators(self.package.indicators)

        if self.package.observables and self.package.observables.observables:
            self.parse_observables(self.package.observables.observables)

        if self.package.threat_actors:
            self.parse_threat_actors(self.package.threat_actors)