Example #1
0
def main():
    NAMESPACE = {"https://www.ncsc.gov.uk/": "ncscuk"}
    idgen.set_id_namespace(NAMESPACE)
    pkg = STIXPackage()
    coa = CourseOfAction()

    obj = file_to_obj('out.json')
    if obj.type == 'bundle':
        for _dict in obj.objects:
            object = dict_to_obj(_dict)
            if object.type == 'indicator':
                ind = Indicator()
                id_str = object.id.replace('--', '-')
                print id_str
                #ind.id_ = object.id
                pattern_type = object.pattern.split(':')[0]
                _value = re.sub("'", '', object.pattern.split(' = ')[1])
                if pattern_type == 'ipv4-addr':
                    obs = Observable(
                        Address(address_value=_value,
                                category=Address.CAT_IPV4))
                elif pattern_type == 'url':
                    obs = Observable(URI(value=_value, type_=URI.TYPE_URL))
                pkg.add_observable(obs)
                obs_ref = Observable()
                obs_ref.id_ = None
                obs_ref.idref = obs.id_
                ind.add_observable(obs_ref)

    pkg.add_indicator(ind)
    print pkg.to_xml()
Example #2
0
    def test_observble_init(self):
        obj = Object()
        dobj = ObjectProperties()
        a = Address()
        oc = ObservableComposition()
        e = Event()

        obs1 = Observable(obj)
        self.assertTrue(obs1.object_ is obj)
        self.assertFalse(obs1.observable_composition)
        self.assertFalse(obs1.event)

        obs2 = Observable(dobj)
        self.assertTrue(obs2.object_)
        self.assertTrue(obs2.object_.properties is dobj)
        self.assertFalse(obs2.observable_composition)
        self.assertFalse(obs2.event)

        obs3 = Observable(a)
        self.assertTrue(obs3.object_)
        self.assertTrue(obs3.object_.properties is a)
        self.assertFalse(obs3.event)
        self.assertFalse(obs3.observable_composition)

        obs4 = Observable(oc)
        self.assertFalse(obs4.object_)
        self.assertFalse(obs4.event)
        self.assertTrue(obs4.observable_composition is oc)

        obs5 = Observable(e)
        self.assertFalse(obs5.object_)
        self.assertTrue(obs5.event is e)
        self.assertFalse(obs5.observable_composition)
Example #3
0
def main():
    pkg = STIXPackage()
    file_object1 = File()
    file_object1.file_name = "readme.doc.exe"
    file_object1.size_in_bytes = 40891
    file_object1.add_hash(
        Hash("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
             ))
    observable1 = Observable(file_object1)

    file_object2 = File()
    file_object2.file_name = "readme.doc.exe"
    file_object2.size_in_bytes = 40891
    file_object2.add_hash(
        Hash("d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592"
             ))
    observable2 = Observable(file_object2)

    incident = Incident(title="Malicious files detected")

    related_observable1 = RelatedObservable(
        observable1, relationship="Malicious Artifact Detected")
    related_observable2 = RelatedObservable(
        observable2, relationship="Malicious Artifact Detected")
    incident.related_observables.append(related_observable1)
    incident.related_observables.append(related_observable2)

    pkg.add_incident(incident)

    print(pkg.to_xml(encoding=None))
Example #4
0
def generateIPObservable(indicator, attribute):
    indicator.add_indicator_type("IP Watchlist")
    address_object = resolveIPType(attribute["value"], attribute["type"])
    address_object.parent.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":AddressObject-" + attribute[
        "uuid"]
    if ("|" in attribute["value"]):
        port = attribute["value"].split('|')[1]
        address_observable = Observable(address_object)
        address_observable.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":Address-" + attribute[
            "uuid"]
        port_object = Port()
        port_object.port_value = attribute["value"].split('|')[1]
        port_object.port_value.condition = "Equals"
        port_object.parent.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":PortObject-" + attribute[
            "uuid"]
        port_observable = Observable(port_object)
        port_observable.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":Port-" + attribute[
            "uuid"]
        compositeObject = ObservableComposition(
            observables=[address_observable, port_observable])
        compositeObject.operator = "AND"
        observable = Observable(
            id_=cybox.utils.idgen.__generator.namespace.prefix +
            ":ObservableComposition-" + attribute["uuid"])
        observable.observable_composition = compositeObject
        return observable
    else:
        return address_object
Example #5
0
def returnAttachmentComposition(attribute):
    file_object = File()
    file_object.file_name = attribute["value"]
    file_object.parent.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":FileObject-" + attribute[
        "uuid"]
    observable = Observable()
    if "data" in attribute:
        artifact = Artifact(data=attribute["data"])
        artifact.parent.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":ArtifactObject-" + attribute[
            "uuid"]
        observable_artifact = Observable(artifact)
        observable_artifact.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":observable-artifact-" + attribute[
            "uuid"]
        observable_file = Observable(file_object)
        observable_file.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":observable-file-" + attribute[
            "uuid"]
        composition = ObservableComposition(
            observables=[observable_artifact, observable_file])
        observable.observable_composition = composition
    else:
        observable = Observable(file_object)
    observable.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":observable-" + attribute[
        "uuid"]
    if attribute["comment"] != "":
        observable.description = attribute["comment"]
    return observable
Example #6
0
    def test_is_empty_observable(self):
        # Check to see if the cybox.core.Observable object is empty by calling `is_empty_observable`

        # Empty Observable
        test = Observable()
        self.assertTrue(utils.is_empty_observable(test))

        # Observable is None
        test = None
        self.assertTrue(utils.is_empty_observable(test))

        # Non empty Observable with Object
        test = Observable(MockObject())
        self.assertFalse(utils.is_empty_observable(test))

        # Non empty Observable with Event
        test = Observable(Event())
        self.assertFalse(utils.is_empty_observable(test))

        # Checks non empty observable_composition and observable_composition.observables
        test = Observable()
        obs = ObservableComposition()
        test.observable_composition = obs
        test.observable_composition.observables = [Observable()]
        self.assertFalse(utils.is_empty_observable(test))
Example #7
0
    def to_cybox(self, exclude=None):
        if exclude == None:
            exclude = []

        observables = []
        f = File()
        for attr in ['md5', 'sha1', 'sha256']:
            if attr not in exclude:
                val = getattr(self, attr, None)
                if val:
                    setattr(f, attr, val)
        if self.ssdeep and 'ssdeep' not in exclude:
            f.add_hash(Hash(self.ssdeep, Hash.TYPE_SSDEEP))
        if 'size' not in exclude and 'size_in_bytes' not in exclude:
            f.size_in_bytes = UnsignedLong(self.size)
        if 'filename' not in exclude and 'file_name' not in exclude:
            f.file_name = self.filename
        # create an Artifact object for the binary if it exists
        if 'filedata' not in exclude:
            data = self.filedata.read()
            if data:
                data = base64.b64encode(data)
                a = Artifact(data=data, type_=Artifact.TYPE_FILE)
                observables.append(Observable(a))
        #if 'filetype' not in exclude and 'file_format' not in exclude:
        #NOTE: this doesn't work because the CybOX File object does not
        #   have any support built in for setting the filetype to a
        #   CybOX-binding friendly object (e.g., calling .to_dict() on
        #   the resulting CybOX object fails on this field.
        #f.file_format = self.filetype
        observables.append(Observable(f))
        return (observables, self.releasability)
Example #8
0
def main():

    data = json.load(open("data.json"))

    stix_package = STIXPackage(stix_header=STIXHeader(
        title=data['title'], package_intents='Incident'))

    ttps = {}

    for info in data['ips']:
        if info['bot'] not in ttps:
            ttps[info['bot']] = TTP(title=info['bot'])
            stix_package.add_ttp(ttps[info['bot']])

        incident = Incident(title=info['ip'])
        incident.time = Time()
        incident.time.first_malicious_action = info['first_seen']

        addr = Address(address_value=info['ip'], category=Address.CAT_IPV4)
        observable = Observable(item=addr)
        stix_package.add_observable(observable)

        related_ttp = RelatedTTP(TTP(idref=ttps[info['bot']].id_),
                                 relationship="Used Malware")
        incident.leveraged_ttps.append(related_ttp)

        related_observable = RelatedObservable(
            Observable(idref=observable.id_))
        incident.related_observables.append(related_observable)

        stix_package.add_incident(incident)

    print(stix_package.to_xml(encoding=None))
Example #9
0
def generateDomainIPObservable(indicator, attribute):
    indicator.add_indicator_type("Domain Watchlist")
    domain = attribute["value"].split('|')[0]
    ip = attribute["value"].split('|')[1]
    address_object = resolveIPType(ip, attribute["type"])
    address_object.parent.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":AddressObject-" + attribute[
        "uuid"]
    address_observable = Observable(address_object)
    address_observable.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":Address-" + attribute[
        "uuid"]
    domain_object = DomainName()
    domain_object.value = domain
    domain_object.value.condition = "Equals"
    domain_object.parent.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":DomainNameObject-" + attribute[
        "uuid"]
    domain_observable = Observable(domain_object)
    domain_observable.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":DomainName-" + attribute[
        "uuid"]
    compositeObject = ObservableComposition(
        observables=[address_observable, domain_observable])
    compositeObject.operator = "AND"
    observable = Observable(
        id_=cybox.utils.idgen.__generator.namespace.prefix +
        ":ObservableComposition-" + attribute["uuid"])
    observable.observable_composition = compositeObject
    return observable
Example #10
0
    def test_set_indicator_observables_to_list_of_one_observable(self):
        # https://github.com/STIXProject/python-stix/issues/325
        i = Indicator()
        o1 = Observable()
        o2 = Observable()

        i.observables = [o1]
        self.assertEqual(type([]), type(i.observables))
        self.assertEqual(1, len(i.observables))
Example #11
0
    def test_set_indicator_observables_to_list_of_two_observables(self):
        # https://github.com/STIXProject/python-stix/issues/325
        i = Indicator()
        o1 = Observable()
        o2 = Observable()

        i.observables = [o1, o2]
        self.assertEqual(mixbox.typedlist.TypedList, type(i.observables))
        self.assertEqual(2, len(i.observables))
Example #12
0
def returnAttachmentComposition(attribute):
    file_object = File()
    file_object.file_name = attribute["value"]
    observable = Observable()
    if "data" in attribute:
        artifact = Artifact(data=attribute["data"])
        composition = ObservableComposition(
            observables=[artifact, file_object])
        observable.observable_composition = composition
    else:
        observable = Observable(file_object)
    return observable
Example #13
0
    def test_observables_property_composition(self):
        f1 = File()
        f1.file_name = "README.txt"
        f2 = File()
        f2.file_name = "README2.txt"
        obs1 = Observable(f1)
        obs2 = Observable(f2)

        comp = Observable(ObservableComposition('AND', [obs1, obs2]))

        ind = Indicator()
        ind.observable = comp
        ind2 = Indicator.from_dict(ind.to_dict())
        self.assertEqual([obs1.to_dict(), obs2.to_dict()],
                         [x.to_dict() for x in ind2.observables])
Example #14
0
def create_url_observable(url):
    url_object = URI.from_dict({'value': url, 'type': URI.TYPE_URL})
    url_observable = Observable(url_object)
    url_observable.title = "Malware Artifact - URL"
    url_observable.description = "URL derived from sandboxed malware sample."
    url_observable.short_description = "URL from malware."
    return url_observable
Example #15
0
def process_sighting(o):
    if indicator_ref(o["sighting_of_ref"]):
        indicator_of_sighting = _ID_OBJECT_MAPPING[o["sighting_of_ref"]]
        if not indicator_of_sighting:
            warn("%s is not in this bundle.  Referenced from %s", 308,
                 o["sighting_of_ref"], o["id"])
            return
        if not indicator_of_sighting.sightings:
            indicator_of_sighting.sightings = Sightings()
        if "where_sighted_refs" in o:
            for ref in o["where_sighted_refs"]:
                s = Sighting()
                indicator_of_sighting.sightings.append(s)
                if ref in _IDENTITIES:
                    identity20_tuple = _IDENTITIES[ref]
                    s.information_source = create_information_source(
                        identity20_tuple)
                if "observed_data_refs" in o:
                    # reference, regardless of whether its in the bundle or not
                    s.related_observables = RelatedObservables()
                    for od_ref in o["observed_data_refs"]:
                        ro = RelatedObservable()
                        s.related_observables.append(ro)
                        ro.item = Observable(idref=convert_id20(od_ref))
                        # TODO: first_seen
                        # TODO: last_seen
    else:
        warn(
            "Unable to convert STIX 2.0 sighting %s because it doesn't refer to an indicator",
            508, o["sighings_of_ref"])
Example #16
0
def create_stix_hash_observable(namespace, indicator):
    """
    Create STIX file observable.
    Args:
        namespace: The XML namespace.
        indicator: The Demisto File indicator.

    Returns:
        STIX File observable.
    """

    id_ = f'{namespace}:observable-{uuid.uuid4()}'
    value = indicator.get('value', '')
    type_ = indicator.get('indicator_type', '')

    file_object = cybox.objects.file_object.File()
    file_object.add_hash(indicator)

    observable = Observable(
        title=f'{value}: {type_}',
        id_=id_,
        item=file_object
    )

    return [observable]
Example #17
0
def create_stix_email_observable(namespace: str, indicator: dict) -> List[Observable]:
    """
    Create STIX Email observable.
    Args:
        namespace: The XML namespace.
        indicator: The Demisto Email indicator.

    Returns:
        STIX Email observable.
    """
    category = cybox.objects.address_object.Address.CAT_EMAIL
    type_ = indicator.get('indicator_type', '')
    value = indicator.get('value', '')
    id_ = f'{namespace}:observable-{uuid.uuid4()}'

    email_object = cybox.objects.address_object.Address(
        address_value=indicator.get('value', ''),
        category=category
    )

    observable = Observable(
        title=f'{type_}: {value}',
        id_=id_,
        item=email_object
    )

    return [observable]
Example #18
0
    def to_cybox_observable(self):
        """
            Convert a Certificate to a CybOX Observables.
            Returns a tuple of (CybOX object, releasability list).

            To get the cybox object as xml or json, call to_xml() or
            to_json(), respectively, on the resulting CybOX object.
        """
        custom_prop = Property(
        )  # make a custom property so CRITs import can identify Certificate exports
        custom_prop.name = "crits_type"
        custom_prop.description = "Indicates the CRITs type of the object this CybOX object represents"
        custom_prop._value = "Certificate"
        obj = File()  # represent cert information as file
        obj.md5 = self.md5
        obj.file_name = self.filename
        obj.file_format = self.filetype
        obj.size_in_bytes = self.size
        obj.custom_properties = CustomProperties()
        obj.custom_properties.append(custom_prop)
        obs = Observable(obj)
        obs.description = self.description
        data = self.filedata.read()
        if data:  # if cert data available
            a = Artifact(data, Artifact.TYPE_FILE)  # create artifact w/data
            a.packaging.append(Base64Encoding())
            obj.add_related(a, "Child_Of")  # relate artifact to file
        return ([obs], self.releasability)
def _dostix(hashes):
    '''This function creates a STIX packages containing hashes.'''
    print("[+] Creating STIX Package")
    title = SETTINGS['stix']['ind_title'] + " " + str(datetime.datetime.now())
    _custom_namespace(SETTINGS['stix']['ns'], SETTINGS['stix']['ns_prefix'])
    stix_package = STIXPackage()
    stix_package.stix_header = STIXHeader()
    stix_package.stix_header.title = title
    stix_package.stix_header.handling = _marking()
    try:
        indicator = Indicator()
        indicator.set_producer_identity(SETTINGS['stix']['producer'])
        indicator.set_produced_time(indicator.timestamp)
        indicator.set_received_time(indicator.timestamp)
        indicator.add_kill_chain_phase(PHASE_DELIVERY)
        indicator.confidence = "Low"

        indicator.title = title
        indicator.add_indicator_type("File Hash Watchlist")
        indicator.description = SETTINGS['stix']['ind_desc']

        try:
            indicator.add_indicated_ttp(
                TTP(idref=SETTINGS['indicated_ttp'],
                    timestamp=indicator.timestamp))
            indicator.suggested_coas.append(
                CourseOfAction(idref=SETTINGS['suggested_coa'],
                               timestamp=indicator.timestamp))
        except KeyError:
            pass

        for info in hashes:
            try:
                file_name = info['filename']
                file_object = File()
                file_object.file_name = file_name
                file_object.file_name.condition = "Equals"
                file_object.file_extension = "." + file_name.split('.')[-1]
                file_object.file_extension.condition = "Equals"
                file_object.size_in_bytes = info['filesize']
                file_object.size_in_bytes.condition = "Equals"
                file_object.file_format = info['fileformat']
                file_object.file_format.condition = "Equals"
                file_object.add_hash(Hash(info['md5']))
                file_object.add_hash(Hash(info['sha1']))
                file_object.add_hash(Hash(info['sha256']))
                file_object.add_hash(Hash(info['sha512']))
                file_object.add_hash(Hash(info['ssdeep'], Hash.TYPE_SSDEEP))
                for hashobj in file_object.hashes:
                    hashobj.simple_hash_value.condition = "Equals"
                    hashobj.type_.condition = "Equals"
                file_obs = Observable(file_object)
                file_obs.title = "File: " + file_name
                indicator.add_observable(file_obs)
            except TypeError:
                pass
        stix_package.add_indicator(indicator)
        return stix_package
    except KeyError:
        pass
Example #20
0
def create_file_hash_observable(fn, hash_value):
    '''Create a CybOX Observable representing a file hash.'''
    hash_ = Hash(hash_value)
    file_ = File()
    file_.file_name = fn
    file_.add_hash(hash_)
    return Observable(file_)
Example #21
0
    def to_cybox_observable(self):
        """
            Convert an IP to a CybOX Observables.
            Returns a tuple of (CybOX object, releasability list).

            To get the cybox object as xml or json, call to_xml() or
            to_json(), respectively, on the resulting CybOX object.
        """
        obj = Address()
        obj.address_value = self.ip

        temp_type = self.ip_type.replace("-", "")
        if temp_type.find(Address.CAT_ASN.replace("-", "")) >= 0:
            obj.category = Address.CAT_ASN
        elif temp_type.find(Address.CAT_ATM.replace("-", "")) >= 0:
            obj.category = Address.CAT_ATM
        elif temp_type.find(Address.CAT_CIDR.replace("-", "")) >= 0:
            obj.category = Address.CAT_CIDR
        elif temp_type.find(Address.CAT_MAC.replace("-", "")) >= 0:
            obj.category = Address.CAT_MAC
        elif temp_type.find(Address.CAT_IPV4_NETMASK.replace("-", "")) >= 0:
            obj.category = Address.CAT_IPV4_NETMASK
        elif temp_type.find(Address.CAT_IPV4_NET.replace("-", "")) >= 0:
            obj.category = Address.CAT_IPV4_NET
        elif temp_type.find(Address.CAT_IPV4.replace("-", "")) >= 0:
            obj.category = Address.CAT_IPV4
        elif temp_type.find(Address.CAT_IPV6_NETMASK.replace("-", "")) >= 0:
            obj.category = Address.CAT_IPV6_NETMASK
        elif temp_type.find(Address.CAT_IPV6_NET.replace("-", "")) >= 0:
            obj.category = Address.CAT_IPV6_NET
        elif temp_type.find(Address.CAT_IPV6.replace("-", "")) >= 0:
            obj.category = Address.CAT_IPV6

        return ([Observable(obj)], self.releasability)
Example #22
0
def create_email_address_observable(email_address):
    '''Create a CybOX Observable representing an IPv4 address'''
    email_address_object = Address.from_dict({
        'address_value': email_address,
        'category': Address.CAT_EMAIL
    })
    return Observable(email_address_object)
Example #23
0
def create_domain_name_observable(domain_name):
    '''Create a CybOX Observable representing a domain name.'''
    domain_name_object = URI.from_dict({
        'value': domain_name,
        'type': URI.TYPE_DOMAIN
    })
    return Observable(domain_name_object)
Example #24
0
def create_ipv4_observable(ipv4_address):
    '''Create a CybOX Observable representing an IPv4 address'''
    ipv4_object = Address.from_dict({
        'address_value': ipv4_address,
        'category': Address.CAT_IPV4
    })
    return Observable(ipv4_object)
Example #25
0
    def add_object(self, object_):
        """Adds a python-cybox Object instance to the ``observables`` list
        property.

        This is the same as calling ``indicator.add_observable(object_)``.

        Note:
            If the `object` param is not an instance of ``cybox.core.Object``
            an attempt will be made to to convert it into one before wrapping
            it in an ``cybox.core.Observable`` layer.

        Args:
            object_: An instance of ``cybox.core.Object`` or an object
                that can be converted into an instance of
                ``cybox.core.Observable``

        Raises:
            ValueError: if the `object_` param cannot be converted to an
                instance of ``cybox.core.Observable``.
        """
        if not object_:
            return

        observable = Observable(object_)
        self.add_observable(observable)
Example #26
0
def create_stix_url_observable(namespace, indicator):
    """
    Create STIX URL observable.
    Args:
        namespace: The XML namespace.
        indicator: The Demisto URL indicator.

    Returns:
        STIX URL observable.
    """
    id_ = f'{namespace}:observable-{uuid.uuid4()}'
    value = indicator.get('value', '')

    uri_object = cybox.objects.uri_object.URI(
        value=value,
        type_=cybox.objects.uri_object.URI.TYPE_URL
    )

    observable = Observable(
        title=f'URL: {value}',
        id_=id_,
        item=uri_object
    )

    return [observable]
Example #27
0
    def test_add_related_observable(self):
        from cybox.core import Observable
        from stix.common.related import RelatedObservable

        i = self.klass()

        self.assertEqual(0, len(i.related_observables))
        i.add_related_observable(Observable())
        self.assertEqual(1, len(i.related_observables))

        related = RelatedObservable(Observable())
        i.add_related_observable(related)
        self.assertEqual(2, len(i.related_observables))

        # Test that this fails
        self.assertRaises(TypeError, i.add_related_observable,
                          "THIS SHOULD FAIL")
Example #28
0
    def test_id_idref_exclusive(self):
        o = Observable()
        self.assertTrue(o.id_ is not None)
        self.assertTrue(o.idref is None)

        o.idref = "foo"
        self.assertTrue(o.idref is not None)
        self.assertTrue(o.id_ is None)
Example #29
0
 def return_attachment_composition(self, attribute):
     file_object = File()
     file_object.file_name = attribute.value
     file_object.parent.id_ = "{}:FileObject-{}".format(self.namespace_prefix, attribute.uuid)
     if 'data' in attribute:
         observable_artifact = self.create_artifact_object(attribute, artifact="a")
         observable_file = Observable(file_object)
         observable_file.id_ = "{}:observable-file-{}".format(self.namespace_prefix, attribute.uuid)
         observable = Observable()
         composition = ObservableComposition(observables=[observable_artifact, observable_file])
         observable.observable_composition = composition
     else:
         observable = Observable(file_object)
     observable.id_ = "{}:observable-{}".format(self.namespace_prefix, attribute.uuid)
     if attribute.comment:
         observable.description = attribute.comment
     return observable
Example #30
0
def createArtifactObject(indicator, attribute):
    artifact = Artifact(data=attribute["data"])
    artifact.parent.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":ArtifactObject-" + attribute[
        "uuid"]
    observable = Observable(artifact)
    observable.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":observable-artifact-" + attribute[
        "uuid"]
    indicator.add_observable(observable)