Exemple #1
0
 def from_obj(bundle_obj):
     if not bundle_obj:
         return None
     bundle_ = Bundle(None, None)
     bundle_.id = bundle_obj.get_id()
     bundle_.schema_version = bundle_obj.get_schema_version()
     bundle_.defined_subject = bundle_obj.get_defined_subject()
     bundle_.content_type = bundle_obj.get_content_type()
     bundle_.timestamp = bundle_obj.get_timestamp()
     bundle_.malware_instance_object_attributes = Object.from_obj(
         bundle_obj.get_Malware_Instance_Object_Attributes()
     )
     if bundle_obj.get_AV_Classifications() is not None:
         bundle_.av_classifications = AVClassifications.from_obj(bundle_obj.get_AV_Classifications())
     bundle_.process_tree = ProcessTree.from_obj(bundle_obj.get_Process_Tree())
     if bundle_obj.get_Behaviors() is not None:
         bundle_.behaviors = BehaviorList.from_obj(bundle_obj.get_Behaviors())
     if bundle_obj.get_Capabilities() is not None:
         bundle_.capabilities = CapabilityList.from_obj(bundle_obj.get_Capabilities())
     if bundle_obj.get_Actions() is not None:
         bundle_.actions = ActionList.from_obj(bundle_obj.get_Actions())
     if bundle_obj.get_Objects() is not None:
         bundle_.objects = ObjectList.from_obj(bundle_obj.get_Objects())
     if bundle_obj.get_Candidate_Indicators() is not None:
         bundle_.candidate_indicators = CandidateIndicatorList.from_obj(bundle_obj.get_Candidate_Indicators())
     bundle_.collections = Collections.from_obj(bundle_obj.get_Collections())
     return bundle_
Exemple #2
0
 def __init__(self, id, defined_subject, schema_version = 4.0, content_type = None, malware_instance_object = None):
     self.id = id
     self.schema_version = schema_version
     self.defined_subject = defined_subject
     self.content_type = content_type
     self.timestamp = None
     self.malware_instance_object_attributes = malware_instance_object
     #Add all of the top-level containers
     self.av_classifications = AVClassifications()
     self.actions = ActionList()
     self.process_tree = None
     self.behaviors = BehaviorList()
     self.objects = ObjectList()
     self.candidate_indicators = CandidateIndicatorList()
     self.collections = Collections()
Exemple #3
0
 def from_dict(bundle_dict):
     if not bundle_dict:
         return None
     bundle_ = Bundle(None, None)
     bundle_.id = bundle_dict.get('id')
     bundle_.schema_version = bundle_dict.get('schema_version')
     bundle_.defined_subject = bundle_dict.get('defined_subject')
     bundle_.content_type = bundle_dict.get('content_type')
     bundle_.timestamp = datetime.datetime.strptime(bundle_dict.get('timestamp'), "%Y-%m-%dT%H:%M:%S.%f")
     bundle_.malware_instance_object_attributes = Object.from_dict(bundle_dict.get('malware_instance_object_attributes'))
     bundle_.av_classifications = AVClassifications.from_list(bundle_dict.get('av_classifications'))
     bundle_.process_tree = ProcessTree.from_dict(bundle_dict.get('process_tree'))
     bundle_.behaviors = BehaviorList.from_list(bundle_dict.get('behaviors'))
     bundle_.actions = ActionList.from_list(bundle_dict.get('actions'))
     bundle_.candidate_indicators = CandidateIndicatorList.from_list(bundle_dict.get('candidate_indicators'))
     bundle_.collections = Collections.from_dict(bundle_dict.get('collections'))
     return bundle_
Exemple #4
0
 def __init__(self, id = None, defined_subject = "False", schema_version = "4.1", content_type = None, malware_instance_object = None):
     super(Bundle, self).__init__()
     if id:
         self.id = id
     else:
         self.id = maec.utils.idgen.create_id(prefix="bundle")
     self.schema_version = schema_version
     self.defined_subject = defined_subject
     self.content_type = content_type
     self.timestamp = None
     self.malware_instance_object_attributes = malware_instance_object
     #Add all of the top-level containers
     self.av_classifications = AVClassifications()
     self.actions = ActionList()
     self.process_tree = None
     self.behaviors = BehaviorList()
     self.capabilities = CapabilityList()
     self.objects = ObjectList()
     self.candidate_indicators = CandidateIndicatorList()
     self.collections = Collections()
Exemple #5
0
 def from_dict(bundle_dict):
     if not bundle_dict:
         return None
     bundle_ = Bundle(None, None)
     bundle_.id = bundle_dict.get("id")
     bundle_.schema_version = bundle_dict.get("schema_version")
     bundle_.defined_subject = bundle_dict.get("defined_subject")
     bundle_.content_type = bundle_dict.get("content_type")
     bundle_.timestamp = datetime.datetime.strptime(bundle_dict.get("timestamp"), "%Y-%m-%dT%H:%M:%S.%f")
     bundle_.malware_instance_object_attributes = Object.from_dict(
         bundle_dict.get("malware_instance_object_attributes")
     )
     bundle_.av_classifications = AVClassifications.from_list(bundle_dict.get("av_classifications"))
     bundle_.process_tree = ProcessTree.from_dict(bundle_dict.get("process_tree"))
     bundle_.behaviors = BehaviorList.from_list(bundle_dict.get("behaviors", []))
     bundle_.capabilities = CapabilityList.from_dict(bundle_dict.get("capabilities"))
     bundle_.actions = ActionList.from_list(bundle_dict.get("actions", []))
     bundle_.objects = ObjectList.from_list(bundle_dict.get("objects", []))
     bundle_.candidate_indicators = CandidateIndicatorList.from_list(bundle_dict.get("candidate_indicators", []))
     bundle_.collections = Collections.from_dict(bundle_dict.get("collections"))
     return bundle_
Exemple #6
0
class Bundle(maec.Entity):
    _namespace = maec.bundle._namespace

    def __init__(
        self, id=None, defined_subject="False", schema_version="4.1", content_type=None, malware_instance_object=None
    ):
        super(Bundle, self).__init__()
        if id:
            self.id = id
        else:
            self.id = maec.utils.idgen.create_id(prefix="bundle")
        self.schema_version = schema_version
        self.defined_subject = defined_subject
        self.content_type = content_type
        self.timestamp = None
        self.malware_instance_object_attributes = malware_instance_object
        # Add all of the top-level containers
        self.av_classifications = AVClassifications()
        self.actions = ActionList()
        self.process_tree = None
        self.behaviors = BehaviorList()
        self.capabilities = CapabilityList()
        self.objects = ObjectList()
        self.candidate_indicators = CandidateIndicatorList()
        self.collections = Collections()

    # Set the Malware Instance Object Attributes
    def set_malware_instance_object_atttributes(self, malware_instance_object):
        self.malware_instance_object_attributes = malware_instance_object

    # Add an AV classification
    def add_av_classification(self, av_classification):
        self.av_classifications.append(av_classification)

    # Add a Capability
    def add_capability(self, capability):
        capabilities = None
        if self.capabilities:
            capabilities = self.capabilities
        else:
            capabilities = CapabilityList()
        capabilities.capability.append(capability)

    # Set the Process Tree, in the top-level <Process_Tree> element
    def set_process_tree(self, process_tree):
        self.process_tree = process_tree

    # Add a new Named Action Collection
    def add_named_action_collection(self, collection_name, collection_id=None):
        if not self.collections:
            self.collections = Collections()
        if collection_name is not None:
            self.collections.action_collections.append(ActionCollection(collection_name, collection_id))

    # Add an Action to an existing named collection; if it does not exist, add it to the top-level <Actions> element
    def add_action(self, action, action_collection_name=None):
        if action_collection_name is not None:
            # The collection has already been defined
            if self.collections.action_collections.has_collection(action_collection_name):
                action_collection = self.collections.action_collections.get_named_collection(action_collection_name)
                action_collection.add_action(action)
        elif action_collection_name == None:
            self.actions.append(action)

    # Add a new Named Object Collection
    def add_named_object_collection(self, collection_name, collection_id=None):
        if not self.collections:
            self.collections = Collections()
        if collection_name is not None:
            self.collections.object_collections.append(ObjectCollection(collection_name, collection_id))

    # return a list of all abjects from self.actions and all action collections
    def get_all_actions(self, bin=False):
        all_actions = []

        for action in self.actions:
            all_actions.append(action)

        if self.collections and self.collections.action_collections:
            for collection in self.collections.action_collections:
                for action in collection.action_list:
                    all_actions.append(action)

        if bin:
            binned_actions = {}
            for action in all_actions:
                if action.name and action.name.value not in binned_actions:
                    binned_actions[action.name.value] = [action]
                elif action.name and action.name.value in binned_actions:
                    binned_actions[action.name.value].append(action)
            return binned_actions
        else:
            return all_actions

    def get_all_actions_on_object(self, object):
        """Return a list of all of the Actions that operate on a particular Object"""
        object_actions = []
        if object.id_:
            for action in self.get_all_actions():
                associated_objects = action.associated_objects
                if associated_objects:
                    for associated_object in associated_objects:
                        if associated_object.idref and associated_object.idref == object.id_:
                            object_actions.append(action)
                        elif associated_object.id_ and associated_object.id_ == object.id_:
                            object_actions.append(action)
            return object_actions

    # Add an Object to an existing named collection; if it does not exist, add it to the top-level <Objects> element
    def add_object(self, object, object_collection_name=None):
        if object_collection_name is not None:
            # The collection has already been defined
            if self.collections.object_collections.has_collection(object_collection_name):
                object_collection = self.collections.object_collections.get_named_collection(object_collection_name)
                object_collection.add_object(object)
        elif object_collection_name == None:
            self.objects.append(object)

    # return a list of all objects from self.objects and all object collections
    def get_all_objects(self, include_actions=False):
        all_objects = []
        for obj in self.objects:
            all_objects.append(obj)
            for related_obj in obj.related_objects:
                all_objects.append(related_obj)

        if self.collections:
            for collection in self.collections.object_collections:
                for obj in collection.object_list:
                    all_objects.append(obj)
                    for related_obj in obj.related_objects:
                        all_objects.append(related_obj)

        # Include Objects in Actions, if include_actions flag is specified
        if include_actions:
            for action in self.get_all_actions():
                associated_objects = action.associated_objects
                if associated_objects:
                    for associated_object in associated_objects:
                        all_objects.append(associated_object)
                        for related_obj in associated_object.related_objects:
                            all_objects.append(related_obj)

        return all_objects

    def get_all_multiple_referenced_objects(self):
        """Return a list of all Objects in the Bundle that are referenced more than once."""
        idref_list = [x.idref for x in self.get_all_objects() if x.idref]
        return [self.get_object_by_id(x) for x in idref_list if self.get_object_by_id(x)]

    def get_all_non_reference_objects(self):
        """Return a list of all Objects in the Bundle that are not references (i.e. all of the actual Objects in the Bundle)."""
        return [x for x in self.get_all_objects(True) if x.id_ and not x.idref]

    # finds actions and objects by id
    def get_object_by_id(self, id):
        for action in self.actions:
            if action.id_ == id:
                return action

            for associated_obj in action.associated_objects:
                if associated_obj.id_ == id:
                    return associated_obj

        for collection in self.collections.action_collections:
            for action in collection.action_list:
                if action.id_ == id:
                    return action

                for associated_obj in action.associated_objects:
                    if associated_obj.id_ == id:
                        return associated_obj

        for obj in self.objects:
            if obj.id_ == id:
                return obj

        for collection in self.collections.object_collections:
            for obj in collection.object_list:
                if obj.id_ == id:
                    return obj

    # Add a new Named Behavior Collection
    def add_named_behavior_collection(self, collection_name):
        if collection_name is not None:
            self.collections.behavior_collections.append(BehaviorCollection(collection_name, collection_id))

    # Add a Behavior to an existing named collection; if it does not exist, add it to the top-level <Behaviors> element
    def add_behavior(self, behavior, behavior_collection_name=None):
        if behavior_collection_name is not None:
            # The collection has already been defined
            if self.collections.behavior_collections.has_collection(behavior_collection_name):
                behavior_collection = self.collections.behavior_collections.get_named_collection(
                    behavior_collection_name
                )
                behavior_collection.add_Behavior(behavior)
        elif behavior_collection_name == None:
            self.behaviors.append(behavior)

    # Add a new Named Behavior Collection
    def add_named_candidate_indicator_collection(self, collection_name, collection_id):
        if collection_name is not None and collection_id is not None:
            self.collections.candidate_indicator_collections.append(
                CandidateIndicatorCollection(collection_name, collection_id)
            )

    # Add a Candidate Indicator to an existing named collection; if it does not exist, add it to the top-level <Candidate_Indicators> element
    def add_candidate_indicator(self, candidate_indicator, candidate_indicator_collection_name=None):
        if candidate_indicator_collection_name is not None:
            # The collection has already been defined
            if self.collections.candidate_indicator_collections.has_collection(candidate_indicator_collection_name):
                candidate_indicator_collection = self.collections.candidate_indicator_collections.get_named_collection(
                    candidate_indicator_collection_name
                )
                candidate_indicator_collection.add_candidate_indicator(candidate_indicator)
        elif candidate_indicator_collection_name == None:
            self.candidate_indicators.append(candidate_indicator)

    def to_obj(self):
        bundle_obj = bundle_binding.BundleType(id=self.id)
        # Set the bundle schema version
        bundle_obj.set_schema_version(self.schema_version)
        # Set whether this Bundle has a defined_subject
        bundle_obj.set_defined_subject(self.defined_subject)
        # Set the bundle timestamp
        if self.timestamp is not None:
            bundle_obj.set_timestamp(self.timestamp.isoformat())
        # Set the content_type if it is not none
        if self.content_type is not None:
            bundle_obj.set_content_type(self.content_type)
        # Set the Malware Instance Object Attributes (a CybOX object) if they are not none
        if self.malware_instance_object_attributes is not None:
            bundle_obj.set_Malware_Instance_Object_Attributes(self.malware_instance_object_attributes.to_obj())
        # Add the AV Classifications
        if self.av_classifications:
            bundle_obj.set_AV_Classifications(self.av_classifications.to_obj())
        # Add the Behaviors
        if self.behaviors:
            bundle_obj.set_Behaviors(self.behaviors.to_obj())
        # Add the Capabilities
        if self.capabilities and (self.capabilities.capability or self.capabilities.capability_reference):
            bundle_obj.set_Capabilities(self.capabilities.to_obj())
        # Add the Actions
        if self.actions:
            bundle_obj.set_Actions(self.actions.to_obj())
        # Add the Objects
        if self.objects:
            bundle_obj.set_Objects(self.objects.to_obj())
        # Add the Process Tree
        if self.process_tree is not None:
            bundle_obj.set_Process_Tree(self.process_tree.to_obj())
        # Add the Candidate Indicators
        if self.candidate_indicators:
            bundle_obj.set_Candidate_Indicators(self.candidate_indicators.to_obj())
        # Add the collections
        if self.collections is not None and self.collections.has_content():
            bundle_obj.set_Collections(self.collections.to_obj())
        return bundle_obj

    def to_dict(self):
        bundle_dict = {}
        if self.id is not None:
            bundle_dict["id"] = self.id
        if self.schema_version is not None:
            bundle_dict["schema_version"] = self.schema_version
        if self.defined_subject is not None:
            bundle_dict["defined_subject"] = self.defined_subject
        if self.content_type is not None:
            bundle_dict["content_type"] = self.content_type
        if self.timestamp is not None:
            bundle_dict["timestamp"] = self.timestamp.isoformat()
        if self.malware_instance_object_attributes is not None:
            bundle_dict["malware_instance_object_attributes"] = self.malware_instance_object_attributes.to_dict()
        if self.av_classifications:
            bundle_dict["av_classifications"] = self.av_classifications.to_list()
        if self.process_tree is not None:
            bundle_dict["process_tree"] = self.process_tree.to_dict()
        if self.behaviors:
            bundle_dict["behaviors"] = self.behaviors.to_list()
        if self.capabilities:
            bundle_dict["capabilities"] = self.capabilities.to_dict()
        if self.actions:
            bundle_dict["actions"] = self.actions.to_list()
        if self.objects:
            bundle_dict["objects"] = self.objects.to_list()
        if self.candidate_indicators:
            bundle_dict["candidate_indicators"] = self.candidate_indicators.to_list()
        if self.collections is not None and self.collections.has_content():
            bundle_dict["collections"] = self.collections.to_dict()
        return bundle_dict

    @staticmethod
    def from_obj(bundle_obj):
        if not bundle_obj:
            return None
        bundle_ = Bundle(None, None)
        bundle_.id = bundle_obj.get_id()
        bundle_.schema_version = bundle_obj.get_schema_version()
        bundle_.defined_subject = bundle_obj.get_defined_subject()
        bundle_.content_type = bundle_obj.get_content_type()
        bundle_.timestamp = bundle_obj.get_timestamp()
        bundle_.malware_instance_object_attributes = Object.from_obj(
            bundle_obj.get_Malware_Instance_Object_Attributes()
        )
        if bundle_obj.get_AV_Classifications() is not None:
            bundle_.av_classifications = AVClassifications.from_obj(bundle_obj.get_AV_Classifications())
        bundle_.process_tree = ProcessTree.from_obj(bundle_obj.get_Process_Tree())
        if bundle_obj.get_Behaviors() is not None:
            bundle_.behaviors = BehaviorList.from_obj(bundle_obj.get_Behaviors())
        if bundle_obj.get_Capabilities() is not None:
            bundle_.capabilities = CapabilityList.from_obj(bundle_obj.get_Capabilities())
        if bundle_obj.get_Actions() is not None:
            bundle_.actions = ActionList.from_obj(bundle_obj.get_Actions())
        if bundle_obj.get_Objects() is not None:
            bundle_.objects = ObjectList.from_obj(bundle_obj.get_Objects())
        if bundle_obj.get_Candidate_Indicators() is not None:
            bundle_.candidate_indicators = CandidateIndicatorList.from_obj(bundle_obj.get_Candidate_Indicators())
        bundle_.collections = Collections.from_obj(bundle_obj.get_Collections())
        return bundle_

    @staticmethod
    def from_dict(bundle_dict):
        if not bundle_dict:
            return None
        bundle_ = Bundle(None, None)
        bundle_.id = bundle_dict.get("id")
        bundle_.schema_version = bundle_dict.get("schema_version")
        bundle_.defined_subject = bundle_dict.get("defined_subject")
        bundle_.content_type = bundle_dict.get("content_type")
        bundle_.timestamp = datetime.datetime.strptime(bundle_dict.get("timestamp"), "%Y-%m-%dT%H:%M:%S.%f")
        bundle_.malware_instance_object_attributes = Object.from_dict(
            bundle_dict.get("malware_instance_object_attributes")
        )
        bundle_.av_classifications = AVClassifications.from_list(bundle_dict.get("av_classifications"))
        bundle_.process_tree = ProcessTree.from_dict(bundle_dict.get("process_tree"))
        bundle_.behaviors = BehaviorList.from_list(bundle_dict.get("behaviors", []))
        bundle_.capabilities = CapabilityList.from_dict(bundle_dict.get("capabilities"))
        bundle_.actions = ActionList.from_list(bundle_dict.get("actions", []))
        bundle_.objects = ObjectList.from_list(bundle_dict.get("objects", []))
        bundle_.candidate_indicators = CandidateIndicatorList.from_list(bundle_dict.get("candidate_indicators", []))
        bundle_.collections = Collections.from_dict(bundle_dict.get("collections"))
        return bundle_

    @classmethod
    def compare(cls, bundle_list, match_on=None, case_sensitive=True):
        return BundleComparator.compare(bundle_list, match_on, case_sensitive)

    def deduplicate(self):
        BundleDeduplicator.deduplicate(self)

    def get_action_objects(self, action_name_list):
        """Get all Objects corresponding to one or more types of Actions, specified via a list of Action names"""
        action_objects = {}
        all_actions = self.get_all_actions(bin=True)
        for action_name in action_name_list:
            if action_name in all_actions:
                associated_objects = []
                associated_object_lists = [
                    [y for y in x.associated_objects if x.associated_objects] for x in all_actions[action_name]
                ]
                for associated_object_list in associated_object_lists:
                    associated_objects += associated_object_list
                action_objects[action_name] = associated_objects
        return action_objects

    def get_object_history(self):
        """Build and return the Object history for the Bundle"""
        return ObjectHistory.build(self)
Exemple #7
0
 def add_av_classification(self, av_classification):
     """Add an AV Classification to the top-level AV_Classifications entity in the Bundle."""
     if not self.av_classifications:
         self.av_classifications = AVClassifications()
     self.av_classifications.append(av_classification)
Exemple #8
0
class Bundle(maec.Entity):
    _binding = bundle_binding
    _namespace = maec.bundle._namespace
    _binding_class = bundle_binding.BundleType

    id_ = maec.TypedField("id")
    schema_version = maec.TypedField("schema_version")
    defined_subject = maec.TypedField("defined_subject")
    content_type = maec.TypedField("content_type")
    timestamp = maec.TypedField("timestamp")
    malware_instance_object_attributes = maec.TypedField("Malware_Instance_Object_Attributes", Object)
    av_classifications = maec.TypedField("AV_Classifications", AVClassifications)
    actions = maec.TypedField("Actions", ActionList)
    process_tree = maec.TypedField("Process_Tree", ProcessTree)
    behaviors = maec.TypedField("Behaviors", BehaviorList)
    capabilities = maec.TypedField("Capabilities", CapabilityList)
    objects = maec.TypedField("Objects", ObjectList)
    candidate_indicators = maec.TypedField("Candidate_Indicators", CandidateIndicatorList)
    collections = maec.TypedField("Collections", Collections)

    def __init__(self, id = None, defined_subject = False, schema_version = "4.1", content_type = None, malware_instance_object = None):
        super(Bundle, self).__init__()
        if id:
            self.id_ = id
        else:
            self.id_ = maec.utils.idgen.create_id(prefix="bundle")
        self.schema_version = schema_version
        self.defined_subject = defined_subject
        self.content_type = content_type
        self.timestamp = None
        self.malware_instance_object_attributes = malware_instance_object
        self.__input_namespaces__ = {}
        self.__input_schemalocations__ = {}

    def set_malware_instance_object_attributes(self, malware_instance_object):
        """Set the top-level Malware Instance Object Attributes entity in the Bundle."""
        self.malware_instance_object_attributes = malware_instance_object

    def add_av_classification(self, av_classification):
        """Add an AV Classification to the top-level AV_Classifications entity in the Bundle."""
        if not self.av_classifications:
            self.av_classifications = AVClassifications()
        self.av_classifications.append(av_classification)

    def add_capability(self, capability):
        """Add a Capability to the top-level Capabilities entity in the Bundle."""
        if not self.capabilities:
            self.capabilities = CapabilityList()
        self.capabilities.capability.append(capability)

    def set_process_tree(self, process_tree):
        """Set the Process Tree, in the top-level <Process_Tree> element."""
        self.process_tree = process_tree

    def add_named_action_collection(self, collection_name, collection_id = None):
        """Add a new named Action Collection to the top-level Collections entity in the Bundle."""
        if not self.collections:
            self.collections = Collections()
        if collection_name is not None:
            self.collections.add_named_action_collection(collection_name, collection_id)
        
    def add_action(self, action, action_collection_name = None):
        """Add an Action to an existing named Action Collection in the Collections entity. 
           If it does not exist, add it to the top-level Actions entity."""
        if action_collection_name is not None and self.collections:
            #The collection has already been defined
            if self.collections.action_collections.has_collection(action_collection_name):
                action_collection = self.collections.action_collections.get_named_collection(action_collection_name)
                action_collection.add_action(action)
        elif action_collection_name == None:
            if not self.actions:
                self.actions = ActionList()
            self.actions.append(action)

    def add_named_object_collection(self, collection_name, collection_id = None):
        """Add a new named Object Collection to the Collections entity in the Bundle."""
        if not self.collections:
            self.collections = Collections()
        if collection_name is not None:
            self.collections.add_named_object_collection(collection_name, collection_id)
              
    def get_all_actions(self, bin = False):
        """Return a list of all Actions in the Bundle."""
        all_actions = []

        if self.actions:
            for action in self.actions:
                all_actions.append(action)
            
        if self.collections and self.collections.action_collections:
            for collection in self.collections.action_collections:
                for action in collection.action_list:
                    all_actions.append(action)

        if bin:
            binned_actions = {}
            for action in all_actions:
                if action.name and action.name.value not in binned_actions:
                    binned_actions[action.name.value] = [action]
                elif action.name and action.name.value in binned_actions:
                    binned_actions[action.name.value].append(action)
            return binned_actions
        else:
            return all_actions

    def get_all_actions_on_object(self, object):
        """Return a list of all of the Actions in the Bundle that operate on a particular input Object."""
        object_actions = []
        if object.id_:
            for action in self.get_all_actions():
                associated_objects = action.associated_objects
                if associated_objects:
                    for associated_object in associated_objects:
                        if associated_object.idref and associated_object.idref == object.id_:
                            object_actions.append(action)
                        elif associated_object.id_ and associated_object.id_ == object.id_:
                            object_actions.append(action)
            return object_actions

    def add_object(self, object, object_collection_name = None):
        """Add an Object to an existing named Object Collection in the Collections entity. 
           If it does not exist, add it to the top-level Object entity."""
        if object_collection_name is not None and self.collections:
            #The collection has already been defined
            if self.collections.object_collections.has_collection(object_collection_name):
                object_collection = self.collections.object_collections.get_named_collection(object_collection_name)
                object_collection.add_object(object)
        elif object_collection_name == None:
            if not self.objects:
                self.objects = ObjectList()
            self.objects.append(object)

    def get_all_objects(self, include_actions = False):
        """Return a list of all Objects in the Bundle."""
        all_objects = []

        if self.objects:
            for obj in self.objects:
                all_objects.append(obj)
                if obj.related_objects:
                    for related_obj in obj.related_objects:
                        all_objects.append(related_obj)
            
        if self.collections and self.collections.object_collections:
            for collection in self.collections.object_collections:
                for obj in collection.object_list:
                    all_objects.append(obj)
                    if obj.related_objects:
                        for related_obj in obj.related_objects:
                            all_objects.append(related_obj)

        # Include Objects in Actions, if include_actions flag is specified
        if include_actions:
            for action in self.get_all_actions():
                associated_objects = action.associated_objects
                if associated_objects:
                    for associated_object in associated_objects:
                        all_objects.append(associated_object)
                        if associated_object.related_objects:
                            for related_obj in associated_object.related_objects:
                                all_objects.append(related_obj)

        # Add the Object corresponding to the Malware Instance Object Attributes, if specified
        if self.malware_instance_object_attributes:
            all_objects.append(self.malware_instance_object_attributes)

        return all_objects

    def get_all_multiple_referenced_objects(self):
        """Return a list of all Objects in the Bundle that are referenced more than once."""
        idref_list = [x.idref for x in self.get_all_objects() if x.idref]
        return [self.get_object_by_id(x) for x in idref_list if self.get_object_by_id(x)]

    def get_all_non_reference_objects(self):
        """Return a list of all Objects in the Bundle that are not references (i.e. all of the actual Objects in the Bundle)."""
        return [x for x in self.get_all_objects(True) if x.id_ and not x.idref]

    def get_object_by_id(self, id, extra_objects = [], ignore_actions = False):
        """Find and return the Entity (Action, Object, etc.) with the specified ID."""
        if not ignore_actions:
            if self.actions:
                for action in self.actions:
                    if action.id_ == id:
                        return action
            
                    if action.associated_objects:
                        for associated_obj in action.associated_objects:
                            if associated_obj.id_ == id:
                                return associated_obj
            if self.collections and self.collections.action_collections:
                for collection in self.collections.action_collections:
                    for action in collection.action_list:
                        if action.id_ == id:
                            return action
                
                        if action.associated_objects:
                            for associated_obj in action.associated_objects:
                                if associated_obj.id_ == id:
                                    return associated_obj
        if self.objects:
            for obj in self.objects:
                if obj.id_ == id:
                    return obj

        if self.collections and self.collections.object_collections:   
            for collection in self.collections.object_collections:
                for obj in collection.object_list:
                    if obj.id_ == id:
                        return obj

        # Test the extra_objects Array
        for obj in extra_objects:
            if obj.id_ == id:
                return obj

    def add_named_behavior_collection(self, collection_name, collection_id = None):
        """Add a new named Behavior Collection to the Collections entity in the Bundle."""
        if not self.collections:
            self.collections = Collections()
        if collection_name is not None:
            self.collections.add_named_behavior_collection(collection_name, collection_id)

    def add_behavior(self, behavior, behavior_collection_name = None):
        """Add a Behavior to an existing named Behavior Collection in the Collections entity. 
           If it does not exist, add it to the top-level Behaviors entity."""
        if behavior_collection_name is not None and self.collections:
            #The collection has already been defined
            if self.collections.behavior_collections.has_collection(behavior_collection_name):
                behavior_collection = self.collections.behavior_collections.get_named_collection(behavior_collection_name)
                behavior_collection.add_Behavior(behavior)
        elif behavior_collection_name == None:
            if not self.behaviors:
                self.behaviors = BehaviorList()
            self.behaviors.append(behavior)

    def add_named_candidate_indicator_collection(self, collection_name, collection_id = None):
        """Add a new named Candidate Indicator Collection to the Collections entity in the Bundle."""
        if not self.collections():
            self.collections = Collections()
        if collection_name is not None and collection_id is not None:
            self.collections.add_named_candidate_indicator_collection(collection_name, collection_id)

    def add_candidate_indicator(self, candidate_indicator, candidate_indicator_collection_name = None):
        """Add a Candidate Indicator to an existing named Candidate Indicator Collection in the Collections entity. 
           If it does not exist, add it to the top-level Candidate Indicators entity."""
        if candidate_indicator_collection_name is not None and self.collections:
            #The collection has already been defined
            if self.collections.candidate_indicator_collections.has_collection(candidate_indicator_collection_name):
                candidate_indicator_collection = self.collections.candidate_indicator_collections.get_named_collection(candidate_indicator_collection_name)
                candidate_indicator_collection.add_candidate_indicator(candidate_indicator)
        elif candidate_indicator_collection_name == None:
            if not self.candidate_indicators:
                self.candidate_indicators = CandidateIndicatorList()
            self.candidate_indicators.append(candidate_indicator)
    
    def deduplicate(self):
        """Deduplicate all Objects in the Bundle. 
           Add duplicate Objects to new "Deduplicated Objects" Object Collection,
           and replace duplicate entries with references to corresponding Object."""
        BundleDeduplicator.deduplicate(self)

    def get_action_objects(self, action_name_list):
        """Get all Objects corresponding to one or more types of Actions, specified via a list of Action names."""
        action_objects = {}
        all_actions = self.get_all_actions(bin=True)
        for action_name in action_name_list:
            if action_name in all_actions:
                associated_objects = []
                associated_object_lists = [[y for y in x.associated_objects if x.associated_objects] for x in all_actions[action_name]]
                for associated_object_list in associated_object_lists:
                    associated_objects += associated_object_list
                action_objects[action_name] = associated_objects
        return action_objects

    def get_object_history(self):
        """Build and return the Object history for the Bundle."""
        return ObjectHistory.build(self)

    def normalize_objects(self):
        """Normalize all Objects in the Bundle, using the CybOX normalize module."""
        all_objects = self.get_all_objects(include_actions = True)
        for object in all_objects:
            if object.properties:
                normalize_object_properties(object.properties)

    def dereference_objects(self, extra_objects = []):
        """Dereference any Objects in the Bundle by replacing them with the entities they reference."""
        all_objects = self.get_all_objects(include_actions=True)
        # Add any extra objects that were passed, e.g. from a Malware Subject
        all_objects = all_objects + extra_objects
        for object in all_objects:
            if object.idref and not object.id_:
                real_object = self.get_object_by_id(object.idref, extra_objects, ignore_actions = True)
                if real_object:
                    object.idref = None
                    object.id_ = real_object.id_
                    object.properties = real_object.properties

    @classmethod
    def compare(cls, bundle_list, match_on = None, case_sensitive = True):
        """Compare the Bundle to a list of other Bundles, returning a BundleComparator object."""
        return BundleComparator.compare(bundle_list, match_on, case_sensitive)
Exemple #9
0
class Bundle(maec.Entity):
    def __init__(self, id, defined_subject, schema_version = 4.0, content_type = None, malware_instance_object = None):
        self.id = id
        self.schema_version = schema_version
        self.defined_subject = defined_subject
        self.content_type = content_type
        self.timestamp = None
        self.malware_instance_object_attributes = malware_instance_object
        #Add all of the top-level containers
        self.av_classifications = AVClassifications()
        self.actions = ActionList()
        self.process_tree = None
        self.behaviors = BehaviorList()
        self.objects = ObjectList()
        self.candidate_indicators = CandidateIndicatorList()
        self.collections = Collections()

    #Set the Malware Instance Object Attributes
    def set_malware_instance_object_atttributes(self, malware_instance_object):
        self.malware_instance_object_attributes = malware_instance_object

    #Add an AV classification
    def add_av_classification(self, av_classification):
        self.av_classifications.append(av_classification)

    #Set the Process Tree, in the top-level <Process_Tree> element
    def set_process_tree(self, process_tree):
        self.process_tree = process_tree

    #Add a new Named Action Collection
    def add_named_action_collection(self, collection_name, collection_id):
        if collection_name is not None and collection_id is not None:
            self.collections.action_collections.append(ActionCollection(collection_name, collection_id))
        
    #Add an Action to an existing named collection; if it does not exist, add it to the top-level <Actions> element
    def add_action(self, action, action_collection_name = None):
        if action_collection_name is not None:
            #The collection has already been defined
            if self.collections.action_collections.has_collection(action_collection_name):
                action_collection = self.collections.action_collections.get_named_collection(action_collection_name)
                action_collection.add_action(action)
        elif action_collection_name == None:
            self.actions.append(action)

    #Add a new Named Object Collection
    def add_named_object_collection(self, collection_name, collection_id):
        if collection_name is not None and collection_id is not None:
            self.collections.object_collections.append(ObjectCollection(collection_name, collection_id))
              
    #Add an Object to an existing named collection; if it does not exist, add it to the top-level <Objects> element
    def add_object(self, object, object_collection_name = None):
        if object_collection_name is not None:
            #The collection has already been defined
            if self.collections.object_collections.has_collection(object_collection_name):
                object_collection = self.collections.object_collections.get_named_collection(object_collection_name)
                object_collection.add_object(object)
        elif object_collection_name == None:
            self.objects.append(object)

    #Add a new Named Behavior Collection
    def add_named_behavior_collection(self, collection_name, collection_id):
        if collection_name is not None and collection_id is not None:
            self.collections.behavior_collections.append(BehaviorCollection(collection_name, collection_id))

    #Add a Behavior to an existing named collection; if it does not exist, add it to the top-level <Behaviors> element
    def add_behavior(self, behavior, behavior_collection_name = None):
        if behavior_collection_name is not None:
            #The collection has already been defined
            if self.collections.behavior_collections.has_collection(behavior_collection_name):
                behavior_collection = self.collections.behavior_collections.get_named_collection(behavior_collection_name)
                behavior_collection.add_Behavior(behavior)
        elif behavior_collection_name == None:
            self.behaviors.append(behavior)

    #Add a new Named Behavior Collection
    def add_named_candidate_indicator_collection(self, collection_name, collection_id):
        if collection_name is not None and collection_id is not None:
            self.collections.candidate_indicator_collections.append(CandidateIndicatorCollection(collection_name, collection_id))

    #Add a Candidate Indicator to an existing named collection; if it does not exist, add it to the top-level <Candidate_Indicators> element
    def add_candidate_indicator(self, candidate_indicator, candidate_indicator_collection_name = None):
        if candidate_indicator_collection_name is not None:
            #The collection has already been defined
            if self.collections.candidate_indicator_collections.has_collection(candidate_indicator_collection_name):
                candidate_indicator_collection = self.collections.candidate_indicator_collections.get_named_collection(candidate_indicator_collection_name)
                candidate_indicator_collection.add_candidate_indicator(candidate_indicator)
        elif candidate_indicator_collection_name == None:
            self.candidate_indicators.append(candidate_indicator)
    
    def to_obj(self):
        bundle_obj = bundle_binding.BundleType(id=self.id)
        #Set the bundle schema version
        bundle_obj.set_schema_version(self.schema_version)
        #Set whether this Bundle has a defined_subject
        bundle_obj.set_defined_subject(self.defined_subject)
        #Set the bundle timestamp
        if self.timestamp is not None : bundle_obj.set_timestamp(self.timestamp.isoformat())
        #Set the content_type if it is not none
        if self.content_type is not None: bundle_obj.set_content_type(self.content_type)
        #Set the Malware Instance Object Attributes (a CybOX object) if they are not none
        if self.malware_instance_object_attributes is not None: bundle_obj.set_Malware_Instance_Attributes(self.malware_instance_object_attributes.to_obj())
        #Add the AV Classifications
        if len(self.av_classifications) > 0: bundle_obj.set_AV_Classifications(self.av_classifications.to_obj())
        #Add the Behaviors
        if len(self.behaviors) > 0: bundle_obj.set_Behaviors(self.behaviors.to_obj())
        #Add the Actions
        if len(self.actions) > 0: bundle_obj.set_Actions(self.actions.to_obj())
        #Add the Objects
        if len(self.objects) > 0: bundle_obj.set_Objects(self.objects.to_obj())
        #Add the Process Tree
        if self.process_tree is not None: bundle_obj.set_Process_Tree(self.process_tree.to_obj())
        #Add the Candidate Indicators
        if len(self.candidate_indicators) > 0: bundle_obj.set_Candidate_Indicators(self.candidate_indicators.to_obj())
        #Add the collections
        if self.collections is not None and self.collections.has_content(): bundle_obj.set_Collections(self.collections.to_obj())
        return bundle_obj

    def to_dict(self):
        bundle_dict = {}
        if self.id is not None : bundle_dict['id'] = self.id
        if self.schema_version is not None : bundle_dict['schema_version'] = self.schema_version
        if self.defined_subject is not None : bundle_dict['defined_subject'] = self.defined_subject
        if self.content_type is not None : bundle_dict['content_type'] = self.content_type
        if self.timestamp is not None : bundle_dict['timestamp'] = self.timestamp.isoformat()
        if self.malware_instance_object_attributes is not None : bundle_dict['malware_instance_object_attributes'] = self.malware_instance_object_attributes.to_dict()
        if len(self.av_classifications) > 0 : bundle_dict['av_classifications'] = self.av_classifications.to_list()
        if self.process_tree is not None : bundle_dict['process_tree'] = self.process_tree.to_dict()
        if len(self.behaviors) > 0 : bundle_dict['behaviors'] = self.behaviors.to_list()
        if len(self.actions) > 0 : bundle_dict['actions'] = self.actions.to_list()
        if len(self.objects) > 0 : bundle_dict['objects'] = self.objects.to_list()
        if len(self.candidate_indicators) > 0 : bundle_dict['candidate_indicators'] = self.candidate_indicators.to_list()
        if self.collections is not None and self.collections.has_content(): bundle_dict['collections'] = self.collections.to_dict()
        return bundle_dict

    @staticmethod
    def from_obj(bundle_obj):
        if not bundle_obj:
            return None
        bundle_ = Bundle(None, None)
        bundle_.id = bundle_obj.get_id()
        bundle_.schema_version = bundle_obj.get_schema_version()
        bundle_.defined_subject = bundle_obj.get_defined_subject()
        bundle_.content_type = bundle_obj.get_content_type()
        bundle_.timestamp = bundle_obj.get_timestamp()
        bundle_.malware_instance_object_attributes = Object.from_obj(bundle_obj.get_Malware_Instance_Object_Attributes())
        if bundle_obj.get_AV_Classifications() is not None: bundle_.av_classifications = AVClassifications.from_obj(bundle_obj.get_AV_Classifications())
        bundle_.process_tree = ProcessTree.from_obj(bundle_obj.get_Process_Tree())
        if bundle_obj.get_Behaviors() is not None : bundle_.behaviors = BehaviorList.from_obj(bundle_obj.get_Behaviors())
        if bundle_obj.get_Actions() is not None : bundle_.actions = ActionList.from_obj(bundle_obj.get_Actions())
        if bundle_obj.get_Candidate_Indicators() is not None : bundle_.candidate_indicators = CandidateIndicatorList.from_obj(bundle_obj.get_Candidate_Indicators())
        bundle_.collections = Collections.from_obj(bundle_obj.get_Collections())
        return bundle_

    @staticmethod
    def from_dict(bundle_dict):
        if not bundle_dict:
            return None
        bundle_ = Bundle(None, None)
        bundle_.id = bundle_dict.get('id')
        bundle_.schema_version = bundle_dict.get('schema_version')
        bundle_.defined_subject = bundle_dict.get('defined_subject')
        bundle_.content_type = bundle_dict.get('content_type')
        bundle_.timestamp = datetime.datetime.strptime(bundle_dict.get('timestamp'), "%Y-%m-%dT%H:%M:%S.%f")
        bundle_.malware_instance_object_attributes = Object.from_dict(bundle_dict.get('malware_instance_object_attributes'))
        bundle_.av_classifications = AVClassifications.from_list(bundle_dict.get('av_classifications'))
        bundle_.process_tree = ProcessTree.from_dict(bundle_dict.get('process_tree'))
        bundle_.behaviors = BehaviorList.from_list(bundle_dict.get('behaviors'))
        bundle_.actions = ActionList.from_list(bundle_dict.get('actions'))
        bundle_.candidate_indicators = CandidateIndicatorList.from_list(bundle_dict.get('candidate_indicators'))
        bundle_.collections = Collections.from_dict(bundle_dict.get('collections'))
        return bundle_