1# MAEC Malware Subject Class
2
3# Copyright (c) 2018, The MITRE Corporation
4# All rights reserved
5
6from mixbox import fields
7from mixbox import idgen
8
9from cybox.common import vocabs, VocabString, PlatformSpecification, ToolInformation
10from cybox.objects.file_object import File
11from cybox.objects.uri_object import URI
12from cybox.core import Object
13
14import maec
15from . import _namespace
16import maec.bindings.maec_package as package_binding
17from maec.bundle import Bundle
18from maec.package import (ActionEquivalenceList, Analysis,
19                          MalwareSubjectReference, ObjectEquivalenceList)
20from maec.vocabs.vocabs import MalwareLabel
21from maec.vocabs.vocabs import MalwareConfigurationParameter as MalwareConfigParameterVocab
22from maec.vocabs.vocabs import MalwareSubjectRelationship as MalwareSubjectRelationshipVocab
23
24class MinorVariants(maec.EntityList):
25    _binding_class = package_binding.MinorVariantListType
26    _namespace = _namespace
27    minor_variant = fields.TypedField("Minor_Variant", Object, multiple=True)
28
29class Analyses(maec.EntityList):
30    _binding_class = package_binding.AnalysisListType
31    _namespace = _namespace
32    analysis = fields.TypedField("Analysis", Analysis, multiple=True)
33
34class MalwareSubjectRelationship(maec.Entity):
35    _binding = package_binding
36    _binding_class = package_binding.MalwareSubjectRelationshipType
37    _namespace = _namespace
38
39    malware_subject_reference = fields.TypedField("Malware_Subject_Reference", MalwareSubjectReference, multiple = True)
40    type_ = vocabs.VocabField("Type", MalwareSubjectRelationshipVocab)
41
42    def __init__(self):
43        super(MalwareSubjectRelationship, self).__init__()
44
45
46class MalwareSubjectRelationshipList(maec.EntityList):
47    _binding_class = package_binding.MalwareSubjectRelationshipListType
48    _namespace = _namespace
49    relationship = fields.TypedField("Relationship", MalwareSubjectRelationship, multiple=True)
50
51class MetaAnalysis(maec.Entity):
52    _binding = package_binding
53    _binding_class = package_binding.MetaAnalysisType
54    _namespace = _namespace
55
56    action_equivalences = fields.TypedField("Action_Equivalences", ActionEquivalenceList)
57    object_equivalences = fields.TypedField("Object_Equivalences", ObjectEquivalenceList)
58
59    def __init__(self):
60        super(MetaAnalysis, self).__init__()
61
62class FindingsBundleList(maec.Entity):
63    _binding = package_binding
64    _binding_class = package_binding.FindingsBundleListType
65    _namespace = _namespace
66
67    meta_analysis = fields.TypedField("Meta_Analysis", MetaAnalysis)
68    bundle = fields.TypedField("Bundle", Bundle, multiple = True)
69    bundle_external_reference = fields.TypedField("Bundle_External_Reference", multiple = True)
70
71    def __init__(self):
72        super(FindingsBundleList, self).__init__()
73
74    def add_bundle(self, bundle):
75        if not self.bundle:
76            self.bundle = []
77        self.bundle.append(bundle)
78
79    def add_bundle_external_reference(self, bundle_external_reference):
80        if not self.bundle_external_reference:
81            self.bundle_external_reference = []
82        self.bundle_external_reference.append(bundle_external_reference)
83
84class MalwareDevelopmentEnvironment(maec.Entity):
85    _binding = package_binding
86    _binding_class = package_binding.MalwareDevelopmentEnvironmentType
87    _namespace = _namespace
88
89    tools = fields.TypedField("Tools", ToolInformation)
90    debugging_file = fields.TypedField("Debugging_File", File, multiple = True)
91
92    def __init__(self):
93        super(MalwareDevelopmentEnvironment, self).__init__()
94
95
96class MalwareConfigurationParameter(maec.Entity):
97    _binding = package_binding
98    _binding_class = package_binding.MalwareConfigurationParameterType
99    _namespace = _namespace
100
101    name = vocabs.VocabField("Name", MalwareConfigParameterVocab)
102    value = fields.TypedField("Value")
103
104    def __init__(self):
105        super(MalwareConfigurationParameter, self).__init__()
106
107
108class MalwareBinaryConfigurationStorageDetails(maec.Entity):
109    _binding = package_binding
110    _binding_class = package_binding.MalwareBinaryConfigurationStorageDetailsType
111    _namespace = _namespace
112
113    file_offset = fields.TypedField("File_Offset")
114    section_name = fields.TypedField("Section_Name")
115    section_offset = fields.TypedField("Section_Offset")
116
117    def __init__(self):
118        super(MalwareBinaryConfigurationStorageDetails, self).__init__()
119
120class MalwareConfigurationStorageDetails(maec.Entity):
121    _binding = package_binding
122    _binding_class = package_binding.MalwareConfigurationStorageDetailsType
123    _namespace = _namespace
124
125    malware_binary = fields.TypedField("Malware_Binary", MalwareBinaryConfigurationStorageDetails)
126    file = fields.TypedField("File", File)
127    url = fields.TypedField("URL", URI, multiple = True)
128
129    def __init__(self):
130        super(MalwareConfigurationStorageDetails, self).__init__()
131
132class MalwareConfigurationObfuscationAlgorithm(maec.Entity):
133    _binding = package_binding
134    _binding_class = package_binding.MalwareConfigurationObfuscationAlgorithmType
135    _namespace = _namespace
136
137    ordinal_position = fields.TypedField("ordinal_position")
138    key = fields.TypedField("Key")
139    algorithm_name = fields.TypedField("Algorithm_Name", VocabString)
140
141    def __init__(self):
142        super(MalwareConfigurationObfuscationAlgorithm, self).__init__()
143
144
145class MalwareConfigurationObfuscationDetails(maec.Entity):
146    _binding = package_binding
147    _binding_class = package_binding.MalwareConfigurationObfuscationDetailsType
148    _namespace = _namespace
149
150    is_encoded = fields.TypedField("is_encoded")
151    is_encrypted = fields.TypedField("is_encrypted")
152    algorithm_details = fields.TypedField("Algorithm_Details", MalwareConfigurationObfuscationAlgorithm, multiple = True)
153
154    def __init__(self):
155        super(MalwareConfigurationObfuscationDetails, self).__init__()
156        self.algorithm_details = []
157
158
159class MalwareConfigurationDetails(maec.Entity):
160    _binding = package_binding
161    _binding_class = package_binding.MalwareConfigurationDetailsType
162    _namespace = _namespace
163
164    storage = fields.TypedField("Storage", MalwareConfigurationStorageDetails)
165    obfuscation = fields.TypedField("Obfuscation", MalwareConfigurationObfuscationDetails)
166    configuration_parameter = fields.TypedField("Configuration_Parameter", MalwareConfigurationParameter, multiple = True)
167
168    def __init__(self):
169        super(MalwareConfigurationDetails, self).__init__()
170
171class MalwareSubject(maec.Entity):
172    _binding = package_binding
173    _binding_class = package_binding.MalwareSubjectType
174    _namespace = _namespace
175
176    id_ = fields.TypedField("id")
177    malware_instance_object_attributes = fields.TypedField("Malware_Instance_Object_Attributes", Object)
178    label = vocabs.VocabField("Label", MalwareLabel, multiple=True)
179    configuration_details = fields.TypedField("Configuration_Details", MalwareConfigurationDetails)
180    minor_variants = fields.TypedField("Minor_Variants", MinorVariants)
181    development_environment = fields.TypedField("Development_Environment", MalwareDevelopmentEnvironment)
182    #field_data = fields.TypedField("field_data") # TODO: support metadata:fieldDataEntry
183    analyses = fields.TypedField("Analyses", Analyses)
184    findings_bundles = fields.TypedField("Findings_Bundles", FindingsBundleList)
185    relationships = fields.TypedField("Relationships", MalwareSubjectRelationshipList)
186    compatible_platform = fields.TypedField("Compatible_Platform", PlatformSpecification, multiple=True)
187
188    def __init__(self, id = None, malware_instance_object_attributes = None):
189        super(MalwareSubject, self).__init__()
190        if id:
191            self.id_ = id
192        else:
193            self.id_ = idgen.create_id(prefix="malware_subject")
194        #Set the Malware Instance Object Attributes (a CybOX object) if they are not none
195        self.malware_instance_object_attributes = malware_instance_object_attributes
196
197    #Public methods
198    #Set the Malware_Instance_Object_Attributes with a CybOX object
199    def set_malware_instance_object_attributes(self, malware_instance_object_attributes):
200        self.malware_instance_object_attributes = malware_instance_object_attributes
201
202    #Add an Analysis to the Analyses
203    def add_analysis(self, analysis):
204        if not self.analyses:
205            self.analyses = Analyses()
206        self.analyses.append(analysis)
207
208    def get_analyses(self):
209        return self.analyses
210
211    #Get all Bundles in the Subject
212    def get_all_bundles(self):
213        return self.findings_bundles.bundle
214
215    #Add a MAEC Bundle to the Findings Bundles
216    def add_findings_bundle(self, bundle):
217        if not self.findings_bundles:
218            self.findings_bundles = FindingsBundleList()
219        self.findings_bundles.add_bundle(bundle)
220
221    def deduplicate_bundles(self):
222        """DeDuplicate all Findings Bundles in the Malware Subject. For now, only handles Objects"""
223        all_bundles = self.get_all_bundles()
224        for bundle in all_bundles:
225            bundle.deduplicate()
226
227    def dereference_bundles(self):
228        """Dereference all Findings Bundles in the Malware Subject. For now, only handles Objects"""
229        all_bundles = self.get_all_bundles()
230        for bundle in all_bundles:
231            bundle.dereference_objects([self.malware_instance_object_attributes])
232
233    def normalize_bundles(self):
234        """Normalize all Findings Bundles in the Malware Subject. For now, only handles Objects"""
235        all_bundles = self.get_all_bundles()
236        for bundle in all_bundles:
237            bundle.normalize_objects()
238
239class MalwareSubjectList(maec.EntityList):
240    _binding_class = package_binding.MalwareSubjectListType
241    #_binding_var = "Malware_Subject"
242    _namespace = _namespace
243
244    malware_subject = fields.TypedField("Malware_Subject", MalwareSubject, multiple=True)
245