Example #1
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 #2
0
def strip_observables(pkg_path):
    '''Strips observable from a package, support multiple structures'''
    result = Observables()
    pkg = STIXPackage.from_xml(pkg_path)
    processed = []
    for ind in pkg.indicators:
        if ind.composite_indicator_expression:
            """The indicator is a compsite structure, this references other indicators, which reference the observables..."""
            cyboxobject = ObservableComposition()
            cyboxobject.operator = str(ind.observable_composition_operator)
            for x in ind.composite_indicator_expression:
                """For every indicator in the composite list, get referenced indicator"""
                ref_ind = getindicator_by_id(pkg, str(x._idref))
                if ref_ind.observables:
                    for y in ref_ind.observables:
                        """For every referenced observable, get the object"""
                        ref_obs = getobservable_by_id(pkg, y._idref)
                        if ref_obs:
                            cyboxobject.add(ref_obs)
                            processed.append(ref_obs.id_)
            result.add(cyboxobject)
        if ind.observables:
            for x in ind.observables:
                if x is not None:
                    if x.id_ not in processed:
                        result.add(x)
                        processed.append(x.id_)
    if pkg.observables:
        for x in pkg.observables:
            if x is not None:
                if x.id_ not in processed:
                    result.add(x)
    scanfile = open(os.path.join(iocname,"scan.json"),'w')
    scanfile.write(json.dumps(walkobservables(result).to_dict(), indent=4))
    scanfile.close()
Example #3
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 #4
0
 def _merge_observables(self, observables, operator='AND'):
     observable_composition = ObservableComposition()
     observable_composition.operator = operator
     
     for observable_ in observables:
         observable_composition.add(observable_)
     
     root_observable = Observable()
     root_observable.observable_composition = observable_composition
     
     return root_observable
Example #5
0
    def _merge_observables(self, observables):
        observable_composition = ObservableComposition()
        observable_composition.operator = self.observable_composition_operator

        for observable in observables:
            observable_composition.add(observable)

        root_observable = Observable()
        root_observable.observable_composition = observable_composition

        return root_observable
Example #6
0
    def _merge_observables(self, observables):
        observable_composition = ObservableComposition()
        observable_composition.operator = self.observable_composition_operator

        for observable in observables:
            observable_composition.add(observable)

        root_observable = Observable()
        root_observable.observable_composition = observable_composition

        return root_observable
Example #7
0
    def _merge_observables(self, observables, operator='AND'):
        observable_composition = ObservableComposition()
        observable_composition.operator = operator

        for observable_ in observables:
            observable_composition.add(observable_)

        root_observable = Observable()
        root_observable.observable_composition = observable_composition

        return root_observable
Example #8
0
    def add_observable(self, observable):
        """Adds an observable to the ``observable`` property of the
        :class:`Indicator`.

        If the `observable` parameter is ``None``, no item will be added
        to the ``observable`` property.

        Note:
            The STIX Language dictates that an :class:`Indicator` can have only
            one ``Observable`` under it. Because of this, when a user adds
            another ``Observable`` a new, empty ``Observable`` will be crated
            and append the existing and new ``observable`` using the
            ``ObservableComposition`` property. To access the top level
            ``Observable`` can be achieved by the ``observable`` property .By
            default, the ``operator`` of the composition layer will be set to
            ``"OR"``. The ``operator`` value can be changed via the
            ``observable_composition_operator`` property.

            Setting ``observable`` or ``observables`` with re-initialize the
            property and lose all ``Observable`` in the composition layer.

        Args:
            observable: An instance of ``cybox.core.Observable`` or an object
                type that can be converted into one.


        Raises:
            ValueError: If the `observable` param cannot be converted into an
                instance of ``cybox.core.Observable``.

        """
        if not observable:
            return

        # Sets the first observable.
        elif not self.observable:
            self.observable = observable

        # When another is inserted. A "root" Observable is created and the
        # user's Observables are appended to the composition.
        elif not self.observable.observable_composition:
            observable_comp = ObservableComposition()
            observable_comp.operator = self.observable_composition_operator

            observable_comp.add(self.observable)
            observable_comp.add(observable)

            self.observable = Observable()
            self.observable.observable_composition = observable_comp

        # Keep appending to "root" Observable.
        else:
            self.observable.observable_composition.add(observable)
Example #9
0
def generateDomainIPObservable(indicator, attribute):
    indicator.add_indicator_type("Domain Watchlist")
    compositeObject = ObservableComposition()
    compositeObject.operator = "AND"
    domain = attribute["value"].split('|')[0]
    ip = attribute["value"].split('|')[1]
    address_object = resolveIPType(ip, attribute["type"])
    domain_object = DomainName()
    domain_object.value = domain
    compositeObject.add(address_object)
    compositeObject.add(domain_object)
    return compositeObject
Example #10
0
    def add_observable(self, observable):
        """Adds an observable to the ``observable`` property of the
        :class:`Indicator`.

        If the `observable` parameter is ``None``, no item will be added
        to the ``observable`` property.

        Note:
            The STIX Language dictates that an :class:`Indicator` can have only
            one ``Observable`` under it. Because of this, when a user adds
            another ``Observable`` a new, empty ``Observable`` will be crated
            and append the existing and new ``observable`` using the
            ``ObservableComposition`` property. To access the top level
            ``Observable`` can be achieved by the ``observable`` property .By
            default, the ``operator`` of the composition layer will be set to
            ``"OR"``. The ``operator`` value can be changed via the
            ``observable_composition_operator`` property.

            Setting ``observable`` or ``observables`` with re-initialize the
            property and lose all ``Observable`` in the composition layer.

        Args:
            observable: An instance of ``cybox.core.Observable`` or an object
                type that can be converted into one.


        Raises:
            ValueError: If the `observable` param cannot be converted into an
                instance of ``cybox.core.Observable``.

        """
        if not observable:
            return

        # Sets the first observable.
        elif not self.observable:
            self.observable = observable

        # When another is inserted. A "root" Observable is created and the
        # user's Observables are appended to the composition.
        elif not self.observable.observable_composition:
            observable_comp = ObservableComposition()
            observable_comp.operator = self.observable_composition_operator

            observable_comp.add(self.observable)
            observable_comp.add(observable)

            self.observable = Observable()
            self.observable.observable_composition = observable_comp

        # Keep appending to "root" Observable.
        else:
            self.observable.observable_composition.add(observable)
Example #11
0
 def generate_domain_ip_observable(self, indicator, attribute):
     indicator.add_indicator_type("Domain Watchlist")
     domain, ip = attribute.value.split('|')
     address_object = self.resolve_ip_type(attribute.type, ip)
     address_object.parent.id_ = "{}:AddressObject-{}".format(self.namespace_prefix, attribute.uuid)
     address_observable = Observable(address_object)
     address_observable.id_ = "{}:Address-{}".format(self.namespace_prefix, attribute.uuid)
     domain_object = DomainName()
     domain_object.value = domain
     domain_object.value.condition = "Equals"
     domain_object.parent.id_ = "{}:DomainNameObject-{}".format(self.namespace_prefix, attribute.uuid)
     domain_observable = Observable(domain_object)
     domain_observable.id_ = "{}:DomainName-{}".format(self.namespace_prefix, attribute.uuid)
     composite_object = ObservableComposition(observables=[address_observable, domain_observable])
     composite_object.operator = "AND"
     observable = Observable(id_="{}:ObservableComposition-{}".format(self.namespace_prefix, attribute.uuid))
     observable.observable_composition = composite_object
     return observable
Example #12
0
 def generate_ip_observable(self, indicator, attribute):
     indicator.add_indicator_type("IP Watchlist")
     address_object = self.resolve_ip_type(attribute.type, attribute.value)
     address_object.parent.id_ = "{}:AddressObject-{}".format(self.namespace_prefix, attribute.uuid)
     if '|' in attribute.value:
         port = attribute.value.split('|')[1]
         address_observable = Observable(address_object)
         address_observable.id_ = "{}:Address-{}".format(self.namespace_prefix, attribute.uuid)
         port_object = Port()
         port_object.port_value = port
         port_object.port_value.condition = "Equals"
         port_object.parent.id_ = "{}:PortObject-{}".format(self.namespace_prefix, attribute.uuid)
         port_observable = Observable(port_object)
         port_observable.id_ = "{}:Port-{}".format(self.namespace_prefix, attribute.uuid)
         compositeObject = ObservableComposition(observables=[address_observable, port_observable])
         compositeObject.operator = "AND"
         observable = Observable(id_ = "{}:ObservableComposition-{}".format(self.namespace_prefix, attribute.uuid))
         observable.observable_composition = compositeObject
         return observable
     else:
         return address_object
Example #13
0
    def observables(self, value):
        """
        The method will automatically create a top ``cybox.core.Observable`` and
        append all ``cybox.core.Observable`` using ``observable_composition``
        property when a ``list`` is given with length greater than 1.

        Note:
            The top level ``cybox.core.Observable`` will set the ``operator``
            property for the ``cybox.core.ObservableComposition`` via the
            ``observable_composition_operator`` property. The value of
            ``operator`` can be changed via ``observable_composition_operator``
            property. By default, the composition layer will be set to ``"OR"``.

        Args:
            value: A ``list`` of ``cybox.core.Observable`` instances or a single
                ``cybox.core.Observable`` instance.

        Raises:
            ValueError: If set to a value that cannot be converted to an
                instance of ``cybox.core.Observable``.
        """
        if not value:
            return

        if isinstance(value, Observable):
            self.observable = value

        elif utils.is_sequence(value):
            if len(value) == 1:
                self.observable = value
                return

            observable_comp = ObservableComposition()
            observable_comp.operator = self.observable_composition_operator

            for element in value:
                observable_comp.add(element)

            self.observable = Observable()
            self.observable.observable_composition = observable_comp
Example #14
0
    def observables(self, value):
        """
        The method will automatically create a top ``cybox.core.Observable`` and
        append all ``cybox.core.Observable`` using ``observable_composition``
        property when a ``list`` is given with length greater than 1.

        Note:
            The top level ``cybox.core.Observable`` will set the ``operator``
            property for the ``cybox.core.ObservableComposition`` via the
            ``observable_composition_operator`` property. The value of
            ``operator`` can be changed via ``observable_composition_operator``
            property. By default, the composition layer will be set to ``"OR"``.

        Args:
            value: A ``list`` of ``cybox.core.Observable`` instances or a single
                ``cybox.core.Observable`` instance.

        Raises:
            ValueError: If set to a value that cannot be converted to an
                instance of ``cybox.core.Observable``.
        """
        if not value:
            return

        if isinstance(value, Observable):
            self.observable = value

        elif utils.is_sequence(value):
            if len(value) == 1:
                self.add_observable(value[0])
                return

            observable_comp = ObservableComposition()
            observable_comp.operator = self.observable_composition_operator

            for element in value:
                observable_comp.add(element)

            self.observable = Observable()
            self.observable.observable_composition = observable_comp
def main():
    # NOTE: ID values will differ due to being regenerated on each script execution
    pkg = STIXPackage()
    pkg.title="Examples of Observable Composition"


    
    # USE CASE: single obj with single condition
    obs = File()
    obs.file_name = "foo.exe"
    obs.file_name.condition = "Contains"
    pkg.add_observable(obs)
    
    # USE CASE: single obj with multiple conditions
    obs = File()
    obs.file_name = "foo"
    obs.file_name.condition = "Contains"
    obs.size_in_bytes = '1896000'
    obs.size_in_bytes.condition = "Equals"
    pkg.add_observable(obs)

    # USE CASE: multiple obj with individual conditions
    obs = EmailMessage()

    obs.subject = "Syria strategic plans leaked"
    obs.subject.condition= "Equals"
    file_obj = File()
    file_obj.file_name = "bombISIS.pdf"
    file_obj.file_name.condition = "Equals"
    obs.add_related(file_obj, "Contains")
    
    pkg.add_observable(obs)

    
    # USE CASE: multiple objects  with complex condition like (A OR B) AND C
    
    # orcomp = either of a mutex or file are present
    
    orcomp = ObservableComposition()
    orcomp.operator = "OR"
    obs = Mutex()
    obs.name = 'foo'
    obs.name.condition= "Contains"
    
    orcomp.add(obs)
    
    obs = File()
    obs.file_name = "barfoobar"
    obs.file_name.condition = "Equals"
    
    orcomp.add(obs)
    
    # andcomp = the above is true AND a network connection is present
    andcomp = ObservableComposition()
    andcomp.operator = "AND"
    
    andcomp.add(orcomp)
    
    obs = NetworkConnection()
    sock = SocketAddress()
    sock.ip_address = "46.123.99.25"
    sock.ip_address.category = "ipv4-addr"
    sock.ip_address.condition = "Equals"
    obs.destination_socket_address = sock
    andcomp.add (obs)
    
    pkg.add_observable(andcomp) 
    
    # USE CASE:  single object, one property with multiple values 
    obs = SocketAddress()
    obs.ip_address = ['10.0.0.0','10.0.0.1','10.0.0.2'] # comma delimiter automagically added
    obs.ip_address.condition = "Equals"
    obs.ip_address.apply_condition = "ANY"
    
    pkg.add_observable(obs)

    print pkg.to_xml() 
Example #16
0
def main():
    # NOTE: ID values will differ due to being regenerated on each script execution
    pkg = STIXPackage()
    pkg.title = "Examples of Observable Composition"

    # USE CASE: single obj with single condition
    obs = File()
    obs.file_name = "foo.exe"
    obs.file_name.condition = "Contains"
    pkg.add_observable(obs)

    # USE CASE: single obj with multiple conditions
    obs = File()
    obs.file_name = "foo"
    obs.file_name.condition = "Contains"
    obs.size_in_bytes = '1896000'
    obs.size_in_bytes.condition = "Equals"
    pkg.add_observable(obs)

    # USE CASE: multiple obj with individual conditions
    obs = EmailMessage()

    obs.subject = "Syria strategic plans leaked"
    obs.subject.condition = "Equals"
    file_obj = File()
    file_obj.file_name = "bombISIS.pdf"
    file_obj.file_name.condition = "Equals"
    obs.add_related(file_obj, "Contains")

    pkg.add_observable(obs)

    # USE CASE: multiple objects  with complex condition like (A OR B) AND C

    # orcomp = either of a mutex or file are present

    orcomp = ObservableComposition()
    orcomp.operator = "OR"
    obs = Mutex()
    obs.name = 'foo'
    obs.name.condition = "Contains"

    orcomp.add(obs)

    obs = File()
    obs.file_name = "barfoobar"
    obs.file_name.condition = "Equals"

    orcomp.add(obs)

    # andcomp = the above is true AND a network connection is present
    andcomp = ObservableComposition()
    andcomp.operator = "AND"

    andcomp.add(orcomp)

    obs = NetworkConnection()
    sock = SocketAddress()
    sock.ip_address = "46.123.99.25"
    sock.ip_address.category = "ipv4-addr"
    sock.ip_address.condition = "Equals"
    obs.destination_socket_address = sock
    andcomp.add(obs)

    pkg.add_observable(andcomp)

    # USE CASE:  single object, one property with multiple values
    obs = SocketAddress()
    obs.ip_address = ['10.0.0.0', '10.0.0.1', '10.0.0.2']  # comma delimiter automagically added
    obs.ip_address.condition = "Equals"
    obs.ip_address.apply_condition = "ANY"

    pkg.add_observable(obs)

    print pkg.to_xml()