def test_properties_not_in_inline(self): # https://github.com/CybOXProject/python-cybox/issues/287 o1 = Object(self.domain) o2 = Object(self.ip) o1.add_related(self.ip, "Resolved_To", inline=False) xml = o1.to_xml(encoding=None) print(xml) self.assertTrue(o1.id_ in xml) self.assertTrue(o2.id_ in xml) self.assertFalse(str(self.ip.address_value) in xml)
def test_round_trip(self): o = Object() o.idref = "example:a1" o.properties = Address("1.2.3.4", Address.CAT_IPV4) o2 = round_trip(o) self.assertEqual(o.to_dict(), o2.to_dict())
def test_obj_oc_mutally_exclusive(self): obj = Object() oc = ObservableComposition() e = Event() o1 = Observable(obj) self.assertRaises(ValueError, _set_event, o1, e) self.assertRaises(ValueError, _set_oc, o1, oc) o5 = Observable(e) self.assertRaises(ValueError, _set_obj, o5, obj) self.assertRaises(ValueError, _set_oc, o5, oc) o2 = Observable(oc) self.assertRaises(ValueError, _set_obj, o2, obj) self.assertRaises(ValueError, _set_event, o2, e) o3 = Observable() _set_obj(o3, obj) self.assertRaises(ValueError, _set_event, o3, e) self.assertRaises(ValueError, _set_oc, o3, oc) o6 = Observable() _set_event(o6, e) self.assertRaises(ValueError, _set_obj, o6, obj) self.assertRaises(ValueError, _set_oc, o6, oc) o4 = Observable() _set_oc(o4, oc) self.assertRaises(ValueError, _set_obj, o4, obj) self.assertRaises(ValueError, _set_event, o4, e)
def test_add_collections(self): o = Bundle() o.add_named_action_collection("Actions") ma = MalwareAction() o.add_action(ma, "Actions") self.assertTrue( o.collections.action_collections.has_collection("Actions")) o.add_named_object_collection("Objects") obj = Object() o.add_object(obj, "Objects") self.assertTrue( o.collections.object_collections.has_collection("Objects")) o.add_named_behavior_collection("Behaviors") b = Behavior() o.add_behavior(b, "Behaviors") self.assertTrue( o.collections.behavior_collections.has_collection("Behaviors")) o.add_named_candidate_indicator_collection("Indicators") ci = CandidateIndicator() o.add_candidate_indicator(ci, "Indicators") self.assertTrue( o.collections.candidate_indicator_collections.has_collection( "Indicators"))
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)
def create_file(file_name=None, md5=None, sha1=None, sha256=None): file_ = File() file_.file_name = file_name file_.md5 = md5 file_.sha1 = sha1 file_.sha256 = sha256 api_object = ApiObject(ty='obs', apiobj=Observable(item=Object(file_))) api_object.api_object = api_object return api_object
def create_maec(self, url_indicator): package = Package() ms = MalwareSubject() ms.malware_instance_object_attributes = Object() ms.malware_instance_object_attributes.properties = URI( type_=URI.TYPE_URL) ms.malware_instance_object_attributes.properties.value = url_indicator package.add_malware_subject(ms) return package
def test_round_trip(self): o = Observable() o.title = "An observable" o.description = "some text" o.description.structuring_format = "plain" o.id_ = "abc123" o.object_ = Object() o2 = cybox.test.round_trip(o) self.assertEqual(o.to_dict(), o2.to_dict())
def test_invalid_arguments(self): obj = Object() e = Event() oc = ObservableComposition() o1 = Observable() self.assertRaises(TypeError, _set_event, o1, obj) self.assertRaises(TypeError, _set_oc, o1, obj) self.assertRaises(TypeError, _set_obj, o1, e) self.assertRaises(TypeError, _set_oc, o1, e) self.assertRaises(TypeError, _set_obj, o1, oc) self.assertRaises(TypeError, _set_event, o1, oc)
def __init__(self, item=None, id_=None, idref=None, title=None, description=None): """Create an Observable out of 'item'. `item` can be any of: - an Object - an Event - an ObservableComposition - any subclass of ObjectProperties. In the first three cases, the appropriate property of the Observable will be set. In the last cases, an Object will be built automatically to ensure the correct hierarchy is created. """ super(Observable, self).__init__() if not id_ and not idref: id_ = cybox.utils.create_id(prefix="Observable") self.id_ = id_ self.title = title self.description = description self.object_ = None self.event = None self.observable_composition = None self.idref = idref self.sighting_count = None self.observable_source = [] self.keywords = Keywords() self.pattern_fidelity = None if item is None: return elif isinstance(item, Object): self.object_ = item elif isinstance(item, ObservableComposition): self.observable_composition = item elif isinstance(item, Event): self.event = item elif isinstance(item, ObjectProperties): if item.parent: self.object_ = item.parent else: self.object_ = Object(item) else: msg = ("item must be an Object, Event, ObservableComposition, or " "subclass of ObjectProperties. Received an %s" % type(item)) raise TypeError(msg)
def __init__(self, item=None, id_=None, idref=None, title=None, description=None): """Create an Observable out of 'item'. `item` can be any of: - an Object - an Event - an ObservableComposition - any subclass of ObjectProperties. In the first three cases, the appropriate property of the Observable will be set. In the last cases, an Object will be built automatically to ensure the correct hierarchy is created. """ super(Observable, self).__init__() if not id_ and not idref: id_ = cybox.utils.create_id(prefix="Observable") self.id_ = id_ self.title = title self.description = description self.object_ = None self.event = None self.observable_composition = None self.idref = idref self.sighting_count = None self.observable_source = [] if not item: return if isinstance(item, Object): self.object_ = item elif isinstance(item, ObservableComposition): self.observable_composition = item elif isinstance(item, Event): self.event = item elif isinstance(item, ObjectProperties): if item.parent: self.object_ = item.parent else: self.object_ = Object(item)
def generateObservable(indicator, attribute): if (attribute["type"] in ("snort", "yara")): generateTM(indicator, attribute) else: observable = None if (attribute["type"] in simple_type_to_method.keys()): action = getattr(this_module, simple_type_to_method[attribute["type"]], None) if (action != None): property = action(attribute) object = Object(property) object.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":" + property.__class__.__name__ + "-" + attribute[ "uuid"] observable = Observable(object) observable.id_ = cybox.utils.idgen.__generator.namespace.prefix + ":observable-" + attribute[ "uuid"] indicator.add_observable(observable)
def test_round_trip(self): o = Observable() o.title = "An observable" o.description = "some text" o.description.structuring_format = "plain" o.id_ = "abc123" o.object_ = Object() pf = PatternFidelity() ot = ObfuscationTechnique() ot.description = "X0Rz" pf.evasion_techniques = ObfuscationTechniques() pf.evasion_techniques.append(ot) o.pattern_fidelity = pf o2 = round_trip(o) self.assertEqual(o.to_dict(), o2.to_dict())
def generate_observable(self, indicator, attribute): attribute_type = attribute.type if attribute_type in ('snort', 'yara'): self.generate_TM(indicator, attribute) else: observable = None # if attribute_type in self.simple_type_to_method: try: observable_property = self.simple_type_to_method[attribute_type](indicator, attribute) except KeyError: return False if isinstance(observable_property, Observable): return indicator.add_observable(observable_property) observable_property.condition = "Equals" observable_object = Object(observable_property) observable_object.id_ = "{}:{}-{}".format(self.namespace_prefix, observable_property.__class__.__name__, attribute.uuid) observable = Observable(observable_object) observable.id_ = "{}:observable-{}".format(self.namespace_prefix, attribute.uuid) indicator.add_observable(observable)
def prune_objects(self, candidate_indicator_objects): """Perform contraindicator and required property checking and prune un-wanted properties from the input list of candidate Indicator CybOX Objects. Args: candidate_indicator_objects: a list of ``maec.bundle.object_history.ObjectHistoryEntry`` objects representing the initial list of CybOX Objects that may be used in the STIX Indicators. Returns: A list of ``maec.bundle.object_history.ObjectHistoryEntry`` objects representing the final list of checked and pruned CybOX Objects that will be used for the STIX Indicators. """ final_indicator_objects = [] # Prune any unwanted properties from Objects for entry in candidate_indicator_objects: object = entry.object xsi_type = object.properties._XSI_TYPE # Do the contraindicator check if xsi_type in self.config.supported_objects and not self._contraindicator_check( entry): object_type_conf = self.config.supported_objects[xsi_type] # Prune the properties of the Object to correspond to the input config file # First, test for the presence of only the required properties if self._required_property_check( object, self.config.supported_objects[xsi_type]): # If the required properties are found, prune based on the full set (optional + required) full_properties = {} full_properties.update(object_type_conf["required"]) full_properties.update(object_type_conf["optional"]) full_properties.update( object_type_conf["mutually_exclusive"]) full_pruned_properties = self._prune_object_properties( object.properties.to_dict(), full_properties) full_pruned_properties["xsi:type"] = xsi_type # Create a new Object with the pruned ObjectProperties pruned_object = Object() pruned_object.properties = ObjectProperties.from_dict( full_pruned_properties) entry.object = pruned_object # Add the updated Object History entry to the final list of Indicators final_indicator_objects.append(entry) return final_indicator_objects
def test_observable_init(self): # Can pass an Object into the Observable constructor o = Object() obs = Observable(o) # Can pass an Event into the Observable constructor e = Event() obs = Observable(e) # Can pass an ObservableComposition into the Observable constructor oc = ObservableComposition() obs = Observable(oc) # Can pass an ObjectProperties subclass into the Observable constructor a = Address() obs = Observable(a) # Cannot pass a String into the Observable constructor. s = String() self.assertRaises(TypeError, Observable, s)
# - A single Action embedded in the Bundle # - A single Capability embedded in the Bundle from cybox.core import AssociatedObjects, AssociatedObject, Object, AssociationType from cybox.common import Hash, HashList, VocabString from cybox.objects.file_object import File from maec.bundle import Bundle, MalwareAction, Capability from maec.package import Analysis, MalwareSubject, Package # Instantiate the Bundle, Package, MalwareSubject, and Analysis classes bundle = Bundle(defined_subject=False) package = Package() subject = MalwareSubject() analysis = Analysis() # Create the Object for use in the Malware Instance Object Attributes subject_object = Object() subject_object.properties = File() subject_object.properties.name = 'foobar.exe' subject_object.properties.size_in_bytes = '35532' subject_object.properties.hashes = HashList() subject_object.properties.hashes.append( Hash("8743b52063cd84097a65d1633f5c74f5")) # Set the Malware Instance Object Attributes with an Object constructed from the dictionary subject.set_malware_instance_object_attributes(subject_object) # Create the Associated Object Dictionary for use in the Action associated_object = AssociatedObject() associated_object.properties = File() associated_object.properties.file_name = 'abcd.dll' associated_object.properties.size_in_bytes = '123456' associated_object.association_type = VocabString() associated_object.association_type.value = 'output'
from maec.package.package import Package from maec.package.malware_subject import (MalwareSubject, MalwareSubjectRelationship, MalwareSubjectRelationshipList, MalwareSubjectReference) from cybox.common import VocabString from cybox.core import Object from cybox.objects.file_object import File # Set up the necessary Package and Malware Subject instances p = Package() ms1 = MalwareSubject() ms2 = MalwareSubject() ms3 = MalwareSubject() ms4 = MalwareSubject() # Set the Malware_Instance_Object_Attributes on the first Malware Subject ms1.malware_instance_object_attributes = Object() ms1.malware_instance_object_attributes.properties = File() ms1.malware_instance_object_attributes.properties.file_name = "dg003_improve_8080_V132.exe" ms1.malware_instance_object_attributes.properties.size_in_bytes = "196608" ms1.malware_instance_object_attributes.properties.add_hash("4EC0027BEF4D7E1786A04D021FA8A67F") # Set the Malware_Instance_Object_Attributes on the second Malware Subject ms2.malware_instance_object_attributes = Object() ms2.malware_instance_object_attributes.properties = File() ms2.malware_instance_object_attributes.properties.file_name = "msvcr.dll" # Set the Malware_Instance_Object_Attributes on the third Malware Subject ms3.malware_instance_object_attributes = Object() ms3.malware_instance_object_attributes.properties = File() ms3.malware_instance_object_attributes.properties.file_name = "fvcwin32.exe"
def publish_indicator(self, indicator_data, user): indicator = DBIndicator( id_=indicator_data['id'], title=indicator_data.get('title'), description=indicator_data.get('description'), short_description=indicator_data.get('short_description'), ) indicator.add_indicator_type(indicator_data.get('indicatorType')) indicator.confidence = indicator_data.get('confidence', '') indicator.id_ns = indicator_data.get('id_ns', '') ident = EdgeIdentity(name=indicator_data.get('producer', '')) indicator.producer = EdgeInformationSource(identity=ident) indicator.handling = handling_from_draft('ind', indicator_data) if 'test_mechanisms' in indicator_data: for test_mechanism in indicator_data['test_mechanisms']: indicator.test_mechanisms.append( IndicatorBuilderPatch.test_mechanism_from_draft( test_mechanism)) api_objects = {} observable_composition = ObservableComposition( operator=indicator_data.get('composition_type')) # If this is an Update rather than a create, # we only need to copy the id and ns to the composition reedit_flag = 0 # New Observables via Build or Edit for data in indicator_data['observables']: observable_id = data.get('id') if observable_id is None: # No id for this observable, therefore it is new and must be created: object_type = data['objectType'] object_type_info = self.observable_object_generator.get_object_type_information( object_type) observable_object = self.observable_object_generator.generate_observable_object_from_data( object_type, data) object_container = Object(observable_object) object_container.id_ = self.generate_id( object_type_info['id_prefix']) # Create the observable, and store it in a collection so they can be saved to the database later on: observable_id = self.generate_id('observable') observable = Observable(title=data['title'], description=data.get( 'description', ''), item=object_container, id_=observable_id) observable.id_ns = indicator_data['id_ns'] api_objects[observable.id_] = ApiObject('obs', observable) elif reedit_flag == 0 and self._is_re_edit_mode(data): reedit_flag = 1 # Create a reference to the observable, and add it to the observable composition. # The observable composition will be added to the indicator. # Adding references to the composition saves duplication of data. observable_reference = Observable(idref=observable_id, idref_ns=indicator_data['id_ns']) observable_composition.add(observable_reference) # For some reason, the observable composition must be wrapped up in another observable. # So to clarify, at this point, we have an observable that contains an observable composition. This composition # contains a collection of references to the actual observables. # We only want a new ID for the observable composition (obs) if it is first-time Build # otherwise, get it from...?the database? if reedit_flag: user_action_log = logging.getLogger('user_actions') user_action_log.info( "%s updated STIX item %s (%s)" % (user.username, indicator.id_, indicator.title)) # EOIndicator = self.edge_object_loader.load(indicator.id_) # Get the parent indicator # find_ob_comp = lambda edges: [x.fetch() for x in edges if x.ty == 'obs'][0] # # Find the observable composition among it's edges and return only the first hit. # # The call to fetch() resolves the idref into an instance of the object itself # existing_obs_comp = find_ob_comp(EOIndicator.edges) # parent_observable = Observable(item=observable_composition, id_=existing_obs_comp.id_) # else: parent_observable = Observable(item=observable_composition, id_=self.generate_id('observable')) parent_observable.id_ns = indicator.id_ns parent_observable.timestamp = datetime.utcnow( ) # needed for versioning Observable Composition # ...and store this observable so we can actually write its contents to the database later... api_objects[parent_observable.id_] = ApiObject('obs', parent_observable) # Add a reference of the 'parent' observable to the indicator parent_observable_reference = Observable(idref=parent_observable.id_, idref_ns=indicator.id_ns) indicator.add_observable(parent_observable_reference) indicator_api_object = ApiObject('ind', indicator) # Process related items/correlations [ relate.correlateIndtoTtp(indicator_api_object, item['idref']) for item in indicator_data.get('indicated_ttps', []) ] [ relate.correlateIndtoInd(indicator_api_object, item['idref']) for item in indicator_data.get('related_indicators', []) ] [ relate.correlateIndtoCoa(indicator_api_object, item['idref']) for item in indicator_data.get('suggested_coas', []) ] # Store the indicator so we can write it to the database later api_objects[indicator_api_object.id_] = indicator_api_object # Finally lets add everything to our Mongo collection... tlp = (indicator_data.get('tlp') or 'NULL').upper() esms = lines2list(indicator_data.get('markings', "")) inbox_processor = InboxProcessorForBuilders( user=user, trustgroups=indicator_data.get('trustgroups', []), ) for api_obj in api_objects.itervalues(): inbox_processor.add( InboxItem(api_object=api_obj, etlp=tlp, esms=esms)) inbox_processor.run() self.delete_draft(user, indicator_data['id'])
def test_id_autoset(self): o = Object() self.assertNotEqual(o.id_, None)
from maec.package.analysis import Analysis from maec.bundle.bundle import Bundle from maec.bundle.malware_action import MalwareAction from cybox.core import Object, AssociatedObject, AssociatedObjects from cybox.objects.win_executable_file_object import WinExecutableFile from cybox.objects.win_mutex_object import WinMutex from cybox.common import ToolInformation, VocabString # Set up the necessary Package, Malware Subject, Analysis Bundle Instances p = Package() ms = MalwareSubject() b = Bundle() a = Analysis() # Set the Malware_Instance_Object_Attributes on the Malware Subject ms.malware_instance_object_attributes = Object() ms.malware_instance_object_attributes.properties = WinExecutableFile() ms.malware_instance_object_attributes.properties.size_in_bytes = "210564" ms.malware_instance_object_attributes.properties.add_hash( "B6C39FF68346DCC8B67AA060DEFE40C2") ms.malware_instance_object_attributes.properties.add_hash( "D55B0FB96FAD96D203D10850469489FC03E6F2F7") # Populate the Analysis with the metadata relating to the Analysis that was performed a.method = "dynamic" a.type_ = "triage" a.set_findings_bundle(b.id_) t = ToolInformation() t.name = "ThreatExpert" t.vendor = "ThreatExpert" a.add_tool(t)
def test_id_prefix(self): a = Address() o = Object(a) self.assertTrue("Address" in o.id_)