Beispiel #1
0
    def obj_create(self, bundle, **kwargs):
        """
        Handles creating Events through the API.

        :param bundle: Bundle containing the information to create the Event.
        :type bundle: Tastypie Bundle object.
        :returns: Bundle object.
        :raises BadRequest: If a campaign name is not provided or creation fails.
        """

        analyst = bundle.request.user.username
        title = bundle.data.get('title', None)
        description = bundle.data.get('description', None)
        event_type = bundle.data.get('event_type', None)
        source = bundle.data.get('source', None)
        method = bundle.data.get('method', None)
        reference = bundle.data.get('reference', None)
        date = bundle.data.get('date', None)
        bucket_list = bundle.data.get('bucket_list', None)
        ticket = bundle.data.get('ticket', None)

        if not title and not event_type and not source:
            raise BadRequest('Must provide a title, event_type, and source.')
        et = EventType.objects(name=event_type).first()
        if not et:
            raise BadRequest('Not a valid Event Type.')

        result = add_new_event(title, description, event_type, source, method,
                               reference, date, analyst, bucket_list, ticket)
        if result['success']:
            return bundle
        else:
            raise BadRequest(str(result['message']))
Beispiel #2
0
def add_event(request):
    """
    Add an event to CRITs. Should be an AJAX POST.

    :param request: Django request object (Required)
    :type request: :class:`django.http.HttpRequest`
    :returns: :class:`django.http.HttpResponse`
    """

    if request.method == "POST" and request.is_ajax():
        event_form = EventForm(request.user, request.POST)
        if event_form.is_valid():
            data = event_form.cleaned_data
            result = add_new_event(title=data['title'],
                                   description=data['description'],
                                   event_type=data['event_type'],
                                   source=data['source'],
                                   method=data['method'],
                                   reference=data['reference'],
                                   date=data['occurrence_date'],
                                   bucket_list=data[form_consts.Common.BUCKET_LIST_VARIABLE_NAME],
                                   ticket=data[form_consts.Common.TICKET_VARIABLE_NAME],
                                   analyst=request.user.username)
            if 'object' in result:
                del result['object']
            return HttpResponse(json.dumps(result), mimetype="application/json")
        else:
            return HttpResponse(json.dumps({'form': event_form.as_table(),
                                            'success': False}),
                                mimetype="application/json")
    else:
        return render_to_response("error.html",
                                  {"error": "Expected AJAX POST"},
                                  RequestContext(request))
Beispiel #3
0
def add_event(request):
    """
    Add an event to CRITs. Should be an AJAX POST.

    :param request: Django request object (Required)
    :type request: :class:`django.http.HttpRequest`
    :returns: :class:`django.http.HttpResponse`
    """

    if request.method == "POST" and request.is_ajax():
        event_form = EventForm(request.user, request.POST)
        if event_form.is_valid():
            data = event_form.cleaned_data
            result = add_new_event(title=data['title'],
                                   description=data['description'],
                                   event_type=data['event_type'],
                                   source=data['source'],
                                   method=data['method'],
                                   reference=data['reference'],
                                   date=data['occurrence_date'],
                                   bucket_list=data[form_consts.Common.BUCKET_LIST_VARIABLE_NAME],
                                   ticket=data[form_consts.Common.TICKET_VARIABLE_NAME],
                                   analyst=request.user.username)
            if 'object' in result:
                del result['object']
            return HttpResponse(json.dumps(result), mimetype="application/json")
        else:
            return HttpResponse(json.dumps({'form': event_form.as_table(),
                                            'success': False}),
                                mimetype="application/json")
    else:
        return render_to_response("error.html",
                                  {"error": "Expected AJAX POST"},
                                  RequestContext(request))
Beispiel #4
0
    def obj_create(self, bundle, **kwargs):
        """
        Handles creating Events through the API.

        :param bundle: Bundle containing the information to create the Event.
        :type bundle: Tastypie Bundle object.
        :returns: HttpResponse.
        """

        user = bundle.request.user
        title = bundle.data.get('title', None)
        description = bundle.data.get('description', None)
        event_type = bundle.data.get('event_type', None)
        source = bundle.data.get('source', None)
        method = bundle.data.get('method', None)
        reference = bundle.data.get('reference', None)
        tlp = bundle.data.get('tlp', 'amber')
        date = bundle.data.get('date', None)
        bucket_list = bundle.data.get('bucket_list', None)
        ticket = bundle.data.get('ticket', None)
        campaign = bundle.data.get('campaign', None)
        campaign_confidence = bundle.data.get('campaign_confidence', None)

        content = {'return_code': 0, 'type': 'Event'}
        if not title or not event_type or not source or not description:
            content[
                'message'] = 'Must provide a title, event_type, source, and description.'
            self.crits_response(content)
        if event_type not in EventTypes.values():
            content['message'] = 'Not a valid Event Type.'
            self.crits_response(content)

        if user.has_access_to(EventACL.WRITE):
            result = add_new_event(title, description, event_type, source,
                                   method, reference, tlp, date, user,
                                   bucket_list, ticket, campaign,
                                   campaign_confidence)
        else:
            result = {
                'success': False,
                'message': 'User does not have permission to create Object.'
            }

        if result.get('message'):
            content['message'] = result.get('message')
        content['id'] = result.get('id', '')
        if result.get('id'):
            url = reverse('api_dispatch_detail',
                          kwargs={
                              'resource_name': 'events',
                              'api_name': 'v1',
                              'pk': result.get('id')
                          })
            content['url'] = url
        if result['success']:
            content['return_code'] = 0
        else:
            content['return_code'] = 1
        self.crits_response(content)
Beispiel #5
0
    def obj_create(self, bundle, **kwargs):
        """
        Handles creating Events through the API.

        :param bundle: Bundle containing the information to create the Event.
        :type bundle: Tastypie Bundle object.
        :returns: HttpResponse.
        """

        analyst = bundle.request.user.username
        title = bundle.data.get('title', None)
        description = bundle.data.get('description', None)
        event_type = bundle.data.get('event_type', None)
        source = bundle.data.get('source', None)
        method = bundle.data.get('method', None)
        reference = bundle.data.get('reference', None)
        date = bundle.data.get('date', None)
        bucket_list = bundle.data.get('bucket_list', None)
        ticket = bundle.data.get('ticket', None)
        campaign = bundle.data.get('campaign', None)
        campaign_confidence = bundle.data.get('campaign_confidence', None)

        content = {'return_code': 0,
                   'type': 'Event'}
        if not title or not event_type or not source or not description:
            content['message'] = 'Must provide a title, event_type, source, and description.'
            self.crits_response(content)
        if event_type not in EventTypes.values():
            content['message'] = 'Not a valid Event Type.'
            self.crits_response(content)

        result = add_new_event(title,
                               description,
                               event_type,
                               source,
                               method,
                               reference,
                               date,
                               analyst,
                               bucket_list,
                               ticket,
                               campaign,
                               campaign_confidence)

        if result.get('message'):
            content['message'] = result.get('message')
        content['id'] = result.get('id', '')
        if result.get('id'):
            url = reverse('api_dispatch_detail',
                          kwargs={'resource_name': 'events',
                                  'api_name': 'v1',
                                  'pk': result.get('id')})
            content['url'] = url
        if result['success']:
            content['return_code'] = 0
        else:
            content['return_code'] = 1
        self.crits_response(content)
Beispiel #6
0
def add_event(request):
    """
    Add an event to CRITs. Should be an AJAX POST.

    :param request: Django request object (Required)
    :type request: :class:`django.http.HttpRequest`
    :returns: :class:`django.http.HttpResponse`
    """

    user = request.user

    if request.method == "POST" and request.is_ajax():
        if user.has_access_to(EventACL.WRITE):
            event_form = EventForm(request.user, request.POST)
            if event_form.is_valid():
                data = event_form.cleaned_data
                result = add_new_event(
                    title=data['title'],
                    description=data['description'],
                    event_type=data['event_type'],
                    source_name=data['source_name'],
                    source_method=data['source_method'],
                    source_reference=data['source_reference'],
                    source_tlp=data['source_tlp'],
                    date=data['occurrence_date'],
                    bucket_list=data[
                        form_consts.Common.BUCKET_LIST_VARIABLE_NAME],
                    ticket=data[form_consts.Common.TICKET_VARIABLE_NAME],
                    user=request.user,
                    campaign=data['campaign'],
                    campaign_confidence=data['campaign_confidence'],
                    related_id=data['related_id'],
                    related_type=data['related_type'],
                    relationship_type=data['relationship_type'])
                if 'object' in result:
                    del result['object']
                return HttpResponse(json.dumps(result),
                                    content_type="application/json")
            else:
                return HttpResponse(json.dumps({
                    'form': event_form.as_table(),
                    'success': False
                }),
                                    content_type="application/json")
        else:
            return HttpResponse(
                json.dumps({
                    'success':
                    False,
                    'message':
                    'User does not have permission to add event.'
                }))
    else:
        return render_to_response("error.html",
                                  {"error": "Expected AJAX POST"},
                                  RequestContext(request))
Beispiel #7
0
    def obj_create(self, bundle, **kwargs):
        """
        Handles creating Events through the API.

        :param bundle: Bundle containing the information to create the Event.
        :type bundle: Tastypie Bundle object.
        :returns: HttpResponse.
        """

        analyst = bundle.request.user.username
        title = bundle.data.get('title', None)
        description = bundle.data.get('description', None)
        event_type = bundle.data.get('event_type', None)
        source = bundle.data.get('source', None)
        method = bundle.data.get('method', None)
        reference = bundle.data.get('reference', None)
        date = bundle.data.get('date', None)
        bucket_list = bundle.data.get('bucket_list', None)
        ticket = bundle.data.get('ticket', None)

        content = {'return_code': 0, 'type': 'Event'}
        if not title or not event_type or not source or not description:
            content[
                'message'] = 'Must provide a title, event_type, source, and description.'
            self.crits_response(content)
        et = EventType.objects(name=event_type).first()
        if not et:
            content['message'] = 'Not a valid Event Type.'
            self.crits_response(content)

        result = add_new_event(title, description, event_type, source, method,
                               reference, date, analyst, bucket_list, ticket)

        if result.get('message'):
            content['message'] = result.get('message')
        content['id'] = result.get('id', '')
        if result.get('id'):
            url = reverse('api_dispatch_detail',
                          kwargs={
                              'resource_name': 'events',
                              'api_name': 'v1',
                              'pk': result.get('id')
                          })
            content['url'] = url
        if result['success']:
            content['return_code'] = 0
        self.crits_response(content)
Beispiel #8
0
def add_event(request):
    """
    Add an event to CRITs. Should be an AJAX POST.

    :param request: Django request object (Required)
    :type request: :class:`django.http.HttpRequest`
    :returns: :class:`django.http.HttpResponse`
    """

    user = request.user

    if request.method == "POST" and request.is_ajax():
        if user.has_access_to(EventACL.WRITE):
            event_form = EventForm(request.user, request.POST)
            if event_form.is_valid():
                data = event_form.cleaned_data
                result = add_new_event(title=data['title'],
                                       description=data['description'],
                                       event_type=data['event_type'],
                                       source_name=data['source_name'],
                                       source_method=data['source_method'],
                                       source_reference=data['source_reference'],
                                       source_tlp=data['source_tlp'],
                                       date=data['occurrence_date'],
                                       bucket_list=data[form_consts.Common.BUCKET_LIST_VARIABLE_NAME],
                                       ticket=data[form_consts.Common.TICKET_VARIABLE_NAME],
                                       user=request.user,
                                       campaign=data['campaign'],
                                       campaign_confidence=data['campaign_confidence'],
                                       related_id=data['related_id'],
                                       related_type=data['related_type'],
                                       relationship_type=data['relationship_type'])
                if 'object' in result:
                    del result['object']
                return HttpResponse(json.dumps(result), content_type="application/json")
            else:
                return HttpResponse(json.dumps({'form': event_form.as_table(),
                                                'success': False}),
                                    content_type="application/json")
        else:
            return HttpResponse(json.dumps({'success':False,
                                            'message':'User does not have permission to add event.'}))
    else:
        return render_to_response("error.html",
                                  {"error": "Expected AJAX POST"},
                                  RequestContext(request))
Beispiel #9
0
    def obj_create(self, bundle, **kwargs):
        """
        Handles creating Events through the API.

        :param bundle: Bundle containing the information to create the Event.
        :type bundle: Tastypie Bundle object.
        :returns: Bundle object.
        :raises BadRequest: If a campaign name is not provided or creation fails.
        """

        analyst = bundle.request.user.username
        title = bundle.data.get('title', None)
        description = bundle.data.get('description', None)
        event_type = bundle.data.get('event_type', None)
        source = bundle.data.get('source', None)
        method = bundle.data.get('method', None)
        reference = bundle.data.get('reference', None)
        date = bundle.data.get('date', None)
        bucket_list = bundle.data.get('bucket_list', None)
        ticket = bundle.data.get('ticket', None)

        if not title and not event_type and not source:
            raise BadRequest('Must provide a title, event_type, and source.')
        et = EventType.objects(name=event_type).first()
        if not et:
            raise BadRequest('Not a valid Event Type.')

        result = add_new_event(title,
                               description,
                               event_type,
                               source,
                               method,
                               reference,
                               date,
                               analyst,
                               bucket_list,
                               ticket)
        if result['success']:
            return bundle
        else:
            raise BadRequest(str(result['message']))
Beispiel #10
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)
Beispiel #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)
Beispiel #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)
Beispiel #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)
Beispiel #14
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)