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
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()
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
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
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
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)
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
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
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
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
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()
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()