Пример #1
0
    def _create_observables(self, msg):
        o = Observables(self.__parse_email_message(msg))

        t = ToolInformation()
        t.name = os.path.basename(__file__)
        t.description = StructuredText("Email to CybOX conversion script")
        t.vendor = "The MITRE Corporation"
        t.version = __version__

        t_list = ToolInformationList()
        t_list.append(t)

        m = MeasureSource()
        m.tools = t_list
        o.observable_package_source = m

        return o
Пример #2
0
    def transform(self, event):
        stix_package = STIXPackage()
        self._add_header(stix_package, "Unauthorized traffic to honeypot",
                         "Describes one or more honeypot incidents")

        incident = Incident(
            id_="%s:%s-%s" %
            (CONPOT_NAMESPACE, 'incident', event['session_id']))
        initial_time = StixTime()
        initial_time.initial_compromise = event['timestamp'].isoformat()
        incident.time = initial_time
        incident.title = "Conpot Event"
        incident.short_description = "Traffic to Conpot ICS honeypot"
        incident.add_category(
            VocabString(value='Scans/Probes/Attempted Access'))

        tool_list = ToolInformationList()
        tool_list.append(
            ToolInformation.from_dict({
                'name':
                "Conpot",
                'vendor':
                "Conpot Team",
                'version':
                conpot.__version__,
                'description':
                textwrap.dedent(
                    'Conpot is a low interactive server side Industrial Control Systems '
                    'honeypot designed to be easy to deploy, modify and extend.'
                )
            }))
        incident.reporter = InformationSource(tools=tool_list)

        incident.add_discovery_method("Monitoring Service")
        incident.confidence = "High"

        # Victim Targeting by Sector
        ciq_identity = CIQIdentity3_0Instance()
        #identity_spec = STIXCIQIdentity3_0()
        #identity_spec.organisation_info = OrganisationInfo(industry_type="Electricity, Industrial Control Systems")
        #ciq_identity.specification = identity_spec
        ttp = TTP(
            title=
            "Victim Targeting: Electricity Sector and Industrial Control System Sector"
        )
        ttp.victim_targeting = VictimTargeting()
        ttp.victim_targeting.identity = ciq_identity

        incident.leveraged_ttps.append(ttp)

        indicator = Indicator(title="Conpot Event")
        indicator.description = "Conpot network event"
        indicator.confidence = "High"
        source_port = Port.from_dict({
            'port_value': event['remote'][1],
            'layer4_protocol': 'tcp'
        })
        dest_port = Port.from_dict({
            'port_value':
            self.protocol_to_port_mapping[event['data_type']],
            'layer4_protocol':
            'tcp'
        })
        source_ip = Address.from_dict({
            'address_value': event['remote'][0],
            'category': Address.CAT_IPV4
        })
        dest_ip = Address.from_dict({
            'address_value': event['public_ip'],
            'category': Address.CAT_IPV4
        })
        source_address = SocketAddress.from_dict({
            'ip_address':
            source_ip.to_dict(),
            'port':
            source_port.to_dict()
        })
        dest_address = SocketAddress.from_dict({
            'ip_address': dest_ip.to_dict(),
            'port': dest_port.to_dict()
        })
        network_connection = NetworkConnection.from_dict({
            'source_socket_address':
            source_address.to_dict(),
            'destination_socket_address':
            dest_address.to_dict(),
            'layer3_protocol':
            "IPv4",
            'layer4_protocol':
            "TCP",
            'layer7_protocol':
            event['data_type'],
            'source_tcp_state':
            "ESTABLISHED",
            'destination_tcp_state':
            "ESTABLISHED",
        })
        indicator.add_observable(Observable(network_connection))

        artifact = Artifact()
        artifact.data = json.dumps(event['data'])
        artifact.packaging.append(ZlibCompression())
        artifact.packaging.append(Base64Encoding())
        indicator.add_observable(Observable(artifact))

        incident.related_indicators.append(indicator)
        stix_package.add_incident(incident)

        stix_package_xml = stix_package.to_xml()
        return stix_package_xml
Пример #3
0
def to_stix(obj, items_to_convert=[], loaded=False, bin_fmt="raw"):
    """
    Converts a CRITs object to a STIX document.

    The resulting document includes standardized representations
    of all related objects noted within items_to_convert.

    :param items_to_convert: The list of items to convert to STIX/CybOX
    :type items_to_convert: Either a list of CRITs objects OR
                            a list of {'_type': CRITS_TYPE, '_id': CRITS_ID} dicts
    :param loaded: Set to True if you've passed a list of CRITs objects as
                    the value for items_to_convert, else leave False.
    :type loaded: bool
    :param bin_fmt: Specifies the format for Sample data encoding.
                    Options: None (don't include binary data in STIX output),
                                "raw" (include binary data as is),
                                "base64" (base64 encode binary data)

    :returns: A dict indicating which items mapped to STIX indicators, ['stix_indicators']
                which items mapped to STIX observables, ['stix_observables']
                which items are included in the resulting STIX doc, ['final_objects']
                and the STIX doc itself ['stix_obj'].
    """

    from cybox.common import Time, ToolInformationList, ToolInformation
    from stix.common import StructuredText, InformationSource
    from stix.core import STIXPackage, STIXHeader
    from stix.common.identity import Identity

    # These lists are used to determine which CRITs objects
    # go in which part of the STIX document.
    ind_list = ['Indicator']
    obs_list = [
        'Certificate', 'Domain', 'Email', 'IP', 'PCAP', 'RawData', 'Sample'
    ]
    actor_list = ['Actor']

    # Store message
    stix_msg = {
        'stix_incidents': [],
        'stix_indicators': [],
        'stix_observables': [],
        'stix_actors': [],
        'final_objects': []
    }

    if not loaded:  # if we have a list of object metadata, load it before processing
        items_to_convert = [
            class_from_id(item['_type'], item['_id'])
            for item in items_to_convert
        ]

    # add self to the list of items to STIXify
    if obj not in items_to_convert:
        items_to_convert.append(obj)

    # add any email attachments
    attachments = []
    for obj in items_to_convert:
        if obj._meta['crits_type'] == 'Email':
            for rel in obj.relationships:
                if rel.relationship == RelationshipTypes.CONTAINS:
                    atch = class_from_id('Sample', rel.object_id)
                    if atch not in items_to_convert:
                        attachments.append(atch)
    items_to_convert.extend(attachments)

    # grab ObjectId of items
    refObjs = {key.id: 0 for key in items_to_convert}

    relationships = {}
    stix = []
    from stix.indicator import Indicator as S_Ind
    for obj in items_to_convert:
        obj_type = obj._meta['crits_type']
        if obj_type == class_from_type('Event')._meta['crits_type']:
            stx, release = to_stix_incident(obj)
            stix_msg['stix_incidents'].append(stx)
        elif obj_type in ind_list:  # convert to STIX indicators
            stx, releas = to_stix_indicator(obj)
            stix_msg['stix_indicators'].append(stx)
            refObjs[obj.id] = S_Ind(idref=stx.id_)
        elif obj_type in obs_list:  # convert to CybOX observable
            if obj_type == class_from_type('Sample')._meta['crits_type']:
                stx, releas = to_cybox_observable(obj, bin_fmt=bin_fmt)
            else:
                stx, releas = to_cybox_observable(obj)

            # wrap in stix Indicator
            ind = S_Ind()
            for ob in stx:
                ind.add_observable(ob)
            ind.title = "CRITs %s Top-Level Object" % obj_type
            ind.description = ("This is simply a CRITs %s top-level "
                               "object, not actually an Indicator. "
                               "The Observable is wrapped in an Indicator"
                               " to facilitate documentation of the "
                               "relationship." % obj_type)
            ind.confidence = 'None'
            stx = ind
            stix_msg['stix_indicators'].append(stx)
            refObjs[obj.id] = S_Ind(idref=stx.id_)
        elif obj_type in actor_list:  # convert to STIX actor
            stx, releas = to_stix_actor(obj)
            stix_msg['stix_actors'].append(stx)

        # get relationships from CRITs objects
        for rel in obj.relationships:
            if rel.object_id in refObjs:
                relationships.setdefault(stx.id_, {})
                relationships[stx.id_][rel.object_id] = (
                    rel.relationship, rel.rel_confidence.capitalize(),
                    rel.rel_type)

        stix_msg['final_objects'].append(obj)
        stix.append(stx)

    # set relationships on STIX objects
    for stix_obj in stix:
        for rel in relationships.get(stix_obj.id_, {}):
            if isinstance(refObjs.get(rel), S_Ind):  # if is STIX Indicator
                stix_obj.related_indicators.append(refObjs[rel])
                rel_meta = relationships.get(stix_obj.id_)[rel]
                stix_obj.related_indicators[-1].relationship = rel_meta[0]
                stix_obj.related_indicators[-1].confidence = rel_meta[1]

                # Add any Email Attachments to CybOX EmailMessage Objects
                if isinstance(stix_obj, S_Ind):
                    if 'EmailMessage' in stix_obj.observable.object_.id_:
                        if rel_meta[0] == 'Contains' and rel_meta[
                                2] == 'Sample':
                            email = stix_obj.observable.object_.properties
                            email.attachments.append(refObjs[rel].idref)

    tool_list = ToolInformationList()
    tool = ToolInformation("CRITs", "MITRE")
    tool.version = settings.CRITS_VERSION
    tool_list.append(tool)
    i_s = InformationSource(time=Time(produced_time=datetime.now()),
                            identity=Identity(name=settings.COMPANY_NAME),
                            tools=tool_list)

    if obj._meta['crits_type'] == "Event":
        stix_desc = obj.description()
        stix_int = obj.event_type()
        stix_title = obj.title()
    else:
        stix_desc = "STIX from %s" % settings.COMPANY_NAME
        stix_int = "Collective Threat Intelligence"
        stix_title = "Threat Intelligence Sharing"
    header = STIXHeader(information_source=i_s,
                        description=StructuredText(value=stix_desc),
                        package_intents=[stix_int],
                        title=stix_title)

    stix_msg['stix_obj'] = STIXPackage(incidents=stix_msg['stix_incidents'],
                                       indicators=stix_msg['stix_indicators'],
                                       threat_actors=stix_msg['stix_actors'],
                                       stix_header=header,
                                       id_=uuid.uuid4())

    return stix_msg
Пример #4
0
    def transform(self, event):
        self._set_namespace(self.config['contact_domain'], self.config['contact_name'])
        stix_package = STIXPackage()
        self._add_header(stix_package, "Unauthorized traffic to honeypot", "Describes one or more honeypot incidents")

        incident = Incident(id_="%s:%s-%s" % (self.config['contact_name'], 'incident', event['session_id']))
        initial_time = StixTime()
        initial_time.initial_compromise = event['timestamp'].isoformat()
        incident.time = initial_time
        incident.title = "Conpot Event"
        incident.short_description = "Traffic to Conpot ICS honeypot"
        incident.add_category(VocabString(value='Scans/Probes/Attempted Access'))

        tool_list = ToolInformationList()
        tool_list.append(ToolInformation.from_dict({
            'name': "Conpot",
            'vendor': "Conpot Team",
            'version': conpot.__version__,
            'description': textwrap.dedent('Conpot is a low interactive server side Industrial Control Systems '
                                           'honeypot designed to be easy to deploy, modify and extend.')
        }))
        incident.reporter = InformationSource(tools=tool_list)

        incident.add_discovery_method("Monitoring Service")
        incident.confidence = "High"

        # Victim Targeting by Sector
        ciq_identity = CIQIdentity3_0Instance()
        #identity_spec = STIXCIQIdentity3_0()
        #identity_spec.organisation_info = OrganisationInfo(industry_type="Electricity, Industrial Control Systems")
        #ciq_identity.specification = identity_spec
        ttp = TTP(title="Victim Targeting: Electricity Sector and Industrial Control System Sector")
        ttp.victim_targeting = VictimTargeting()
        ttp.victim_targeting.identity = ciq_identity

        incident.leveraged_ttps.append(ttp)

        indicator = Indicator(title="Conpot Event")
        indicator.description = "Conpot network event"
        indicator.confidence = "High"
        source_port = Port.from_dict({'port_value': event['remote'][1], 'layer4_protocol': 'tcp'})
        dest_port = Port.from_dict({'port_value': self.protocol_to_port_mapping[event['data_type']],
                                    'layer4_protocol': 'tcp'})
        source_ip = Address.from_dict({'address_value': event['remote'][0], 'category': Address.CAT_IPV4})
        dest_ip = Address.from_dict({'address_value': event['public_ip'], 'category': Address.CAT_IPV4})
        source_address = SocketAddress.from_dict({'ip_address': source_ip.to_dict(), 'port': source_port.to_dict()})
        dest_address = SocketAddress.from_dict({'ip_address': dest_ip.to_dict(), 'port': dest_port.to_dict()})
        network_connection = NetworkConnection.from_dict(
            {'source_socket_address': source_address.to_dict(),
             'destination_socket_address': dest_address.to_dict(),
             'layer3_protocol': u"IPv4",
             'layer4_protocol': u"TCP",
             'layer7_protocol': event['data_type'],
             'source_tcp_state': u"ESTABLISHED",
             'destination_tcp_state': u"ESTABLISHED",
             }
        )
        indicator.add_observable(Observable(network_connection))

        artifact = Artifact()
        artifact.data = json.dumps(event['data'])
        artifact.packaging.append(ZlibCompression())
        artifact.packaging.append(Base64Encoding())
        indicator.add_observable(Observable(artifact))

        incident.related_indicators.append(indicator)
        stix_package.add_incident(incident)

        stix_package_xml = stix_package.to_xml()
        return stix_package_xml
Пример #5
0
def to_stix(obj, items_to_convert=[], loaded=False, bin_fmt="raw"):
    """
    Converts a CRITs object to a STIX document.

    The resulting document includes standardized representations
    of all related objects noted within items_to_convert.

    :param items_to_convert: The list of items to convert to STIX/CybOX
    :type items_to_convert: Either a list of CRITs objects OR
                            a list of {'_type': CRITS_TYPE, '_id': CRITS_ID} dicts
    :param loaded: Set to True if you've passed a list of CRITs objects as
                    the value for items_to_convert, else leave False.
    :type loaded: bool
    :param bin_fmt: Specifies the format for Sample data encoding.
                    Options: None (don't include binary data in STIX output),
                                "raw" (include binary data as is),
                                "base64" (base64 encode binary data)

    :returns: A dict indicating which items mapped to STIX indicators, ['stix_indicators']
                which items mapped to STIX observables, ['stix_observables']
                which items are included in the resulting STIX doc, ['final_objects']
                and the STIX doc itself ['stix_obj'].
    """

    from cybox.common import Time, ToolInformationList, ToolInformation
    from stix.common import StructuredText, InformationSource
    from stix.core import STIXPackage, STIXHeader
    from stix.common.identity import Identity

    # These lists are used to determine which CRITs objects
    # go in which part of the STIX document.
    ind_list = ['Indicator']
    obs_list = ['Certificate',
                'Domain',
                'Email',
                'IP',
                'PCAP',
                'RawData',
                'Sample']
    actor_list = ['Actor']

    # Store message
    stix_msg = {
                    'stix_incidents': [],
                    'stix_indicators': [],
                    'stix_observables': [],
                    'stix_actors': [],
                    'final_objects': []
                }

    if not loaded: # if we have a list of object metadata, load it before processing
        items_to_convert = [class_from_id(item['_type'], item['_id'])
                                for item in items_to_convert]

    # add self to the list of items to STIXify
    if obj not in items_to_convert:
        items_to_convert.append(obj)

    # add any email attachments
    attachments = []
    for obj in items_to_convert:
        if obj._meta['crits_type'] == 'Email':
            for rel in obj.relationships:
                if rel.relationship == RelationshipTypes.CONTAINS:
                    atch = class_from_id('Sample', rel.object_id)
                    if atch not in items_to_convert:
                        attachments.append(atch)
    items_to_convert.extend(attachments)

    # grab ObjectId of items
    refObjs = {key.id: 0 for key in items_to_convert}

    relationships = {}
    stix = []
    from stix.indicator import Indicator as S_Ind
    for obj in items_to_convert:
        obj_type = obj._meta['crits_type']
        if obj_type == class_from_type('Event')._meta['crits_type']:
            stx, release = to_stix_incident(obj)
            stix_msg['stix_incidents'].append(stx)
        elif obj_type in ind_list: # convert to STIX indicators
            stx, releas = to_stix_indicator(obj)
            stix_msg['stix_indicators'].append(stx)
            refObjs[obj.id] = S_Ind(idref=stx.id_)
        elif obj_type in obs_list: # convert to CybOX observable
            if obj_type == class_from_type('Sample')._meta['crits_type']:
                stx, releas = to_cybox_observable(obj, bin_fmt=bin_fmt)
            else:
                stx, releas = to_cybox_observable(obj)

            # wrap in stix Indicator
            ind = S_Ind()
            for ob in stx:
                ind.add_observable(ob)
            ind.title = "CRITs %s Top-Level Object" % obj_type
            ind.description = ("This is simply a CRITs %s top-level "
                                "object, not actually an Indicator. "
                                "The Observable is wrapped in an Indicator"
                                " to facilitate documentation of the "
                                "relationship." % obj_type)
            ind.confidence = 'None'
            stx = ind
            stix_msg['stix_indicators'].append(stx)
            refObjs[obj.id] = S_Ind(idref=stx.id_)
        elif obj_type in actor_list: # convert to STIX actor
            stx, releas = to_stix_actor(obj)
            stix_msg['stix_actors'].append(stx)

        # get relationships from CRITs objects
        for rel in obj.relationships:
            if rel.object_id in refObjs:
                relationships.setdefault(stx.id_, {})
                relationships[stx.id_][rel.object_id] = (rel.relationship,
                                                            rel.rel_confidence.capitalize(),
                                                            rel.rel_type)

        stix_msg['final_objects'].append(obj)
        stix.append(stx)

    # set relationships on STIX objects
    for stix_obj in stix:
        for rel in relationships.get(stix_obj.id_, {}):
            if isinstance(refObjs.get(rel), S_Ind): # if is STIX Indicator
                stix_obj.related_indicators.append(refObjs[rel])
                rel_meta = relationships.get(stix_obj.id_)[rel]
                stix_obj.related_indicators[-1].relationship = rel_meta[0]
                stix_obj.related_indicators[-1].confidence = rel_meta[1]

                # Add any Email Attachments to CybOX EmailMessage Objects
                if isinstance(stix_obj, S_Ind):
                    if 'EmailMessage' in stix_obj.observable.object_.id_:
                        if rel_meta[0] == 'Contains' and rel_meta[2] == 'Sample':
                            email = stix_obj.observable.object_.properties
                            email.attachments.append(refObjs[rel].idref)

    tool_list = ToolInformationList()
    tool = ToolInformation("CRITs", "MITRE")
    tool.version = settings.CRITS_VERSION
    tool_list.append(tool)
    i_s = InformationSource(
        time=Time(produced_time= datetime.now()),
        identity=Identity(name=settings.COMPANY_NAME),
        tools=tool_list)

    if obj._meta['crits_type'] == "Event":
        stix_desc = obj.description()
        stix_int = obj.event_type()
        stix_title = obj.title()
    else:
        stix_desc = "STIX from %s" % settings.COMPANY_NAME
        stix_int = "Collective Threat Intelligence"
        stix_title = "Threat Intelligence Sharing"
    header = STIXHeader(information_source=i_s,
                        description=StructuredText(value=stix_desc),
                        package_intents=[stix_int],
                        title=stix_title)

    stix_msg['stix_obj'] = STIXPackage(incidents=stix_msg['stix_incidents'],
                    indicators=stix_msg['stix_indicators'],
                    threat_actors=stix_msg['stix_actors'],
                    stix_header=header,
                    id_=uuid.uuid4())

    return stix_msg
Пример #6
0
    def to_stix(self, username=None):
        """
        Converts a CRITs event to a STIX document.

        The resulting document includes all related emails, samples, and
        indicators converted to CybOX Observable objects.
        Returns the STIX document and releasability constraints.

        (NOTE: the following statement is untrue until the
        releasability checking is finished, which includes setting
        releasability on all CRITs objects.)
        Raises UnreleasableEventError if the releasability on the
        relationships and the event do not share any common releasability
        sources.
        """

        from crits.emails.email import Email
        from crits.samples.sample import Sample
        from crits.indicators.indicator import Indicator

        from cybox.common import Time, ToolInformationList, ToolInformation
        from cybox.core import Observables
        from stix.common import StructuredText
        from stix.core import STIXPackage, STIXHeader
        from stix.common import InformationSource
        from stix.common.identity import Identity

        stix_indicators = []
        stix_observables = []
        final_objects = []

        # create a list of sources to send as part of the results.
        # list should be limited to the sources this user is allowed to use.
        # this list should be used along with the list of objects to set the
        # appropriate source's 'released' key to True for each object.
        final_sources = []
        user_source_list = user_sources(username)
        for f in self.releasability:
            if f.name in user_source_list:
                final_sources.append(f.name)
        final_sources = set(final_sources)

        # TODO: eventually we can use class_from_id instead of the if block
        #       but only once we support all CRITs types.
        for r in self.relationships:
            obj = None
            if r.rel_type == Email._meta['crits_type']:
                obj = Email.objects(id=r.object_id,
                                    source__name__in=user_source_list).first()
                if obj:
                    ind, releas = obj.to_cybox()
                    stix_observables.append(ind[0])
            elif r.rel_type == Sample._meta['crits_type']:
                obj = Sample.objects(id=r.object_id,
                                    source__name__in=user_source_list).first()
                if obj:
                    ind, releas = obj.to_cybox()
                    for i in ind:
                        stix_observables.append(i)
            elif r.rel_type == Indicator._meta['crits_type']:
                #NOTE: Currently this will raise an exception if there
                #   are multiple indicators with the same value.
                #   Should be fixed automatically once we transition
                #   indicators to be related based on ObjectId rather
                #   than value.
                obj = Indicator.objects(id=r.object_id,
                                    source__name__in=user_source_list).first()
                if obj:
                    ind, releas = obj.to_stix_indicator()
                    stix_indicators.append(ind)
            else:
                continue
            #Create a releasability list that is the intersection of
            #   each related item's releasability with the event's
            #   releasability. If the resulting set is empty, raise exception
            #TODO: Set releasability on all objects so that we actually
            #   get results here instead of always raising an exception.
            if obj:
                releas_sources = set([rel.name for rel in releas])
                final_sources = final_sources.intersection(releas_sources)
                #TODO: uncomment the following lines when objects have
                #   releasability set.
                #if not final_sources:
                #    raise UnreleasableEventError(r.value)

                # add to the final_objects list to send as part of the results
                final_objects.append(obj)

        tool_list = ToolInformationList()
        tool = ToolInformation("CRITs", "MITRE")
        tool.version = settings.CRITS_VERSION
        tool_list.append(tool)
        i_s = InformationSource(
                time=Time(produced_time= datetime.datetime.now()),
                identity = Identity(name=settings.COMPANY_NAME),
                tools = tool_list
        )
        description = StructuredText(value=self.description)
        header = STIXHeader(information_source=i_s,
                            description=description,
                            package_intent=self.event_type,
                            title=self.title)

        return (STIXPackage(indicators=stix_indicators,
                            observables=Observables(stix_observables),
                            stix_header=header,
                            id_=self.event_id),
                final_sources,
                final_objects)