Repository: swimlane/pyattck (language: python)

Issue:
Technique objects missing Malwares property
**Describe the bug**
Malwares cannot be accessed from a technique. The malwares property is not created in techniques.

**To reproduce**
Access malware from a technique (this example is taken from the actual [AttckTechnique](https://github.com/swimlane/pyattck/blob/master/pyattck/enterprise/technique.py)   class description):
```
for technique in attack.enterprise.techniques:
    print(technique.name)
    for malware in technique.malwares:
        print(malware.name)
```



**Expected behavior**
You should get the name of the technique followed by the name of all its malwares. However, you get an error saying the property does not exist.
Deprecated attribute accessible in all objects
I want to see if the AttckObject is deprecated, at the moment this is only possible with techniques. I would like to do the same with the other objects.

Just like it's done with techniques, you would access the "deprecated" attribute. I beleive this can be done with the x_mitre_deprecated attribute in the JSON files.

I think this attribute is relevant for any type of AttckObject, but if not, it can be created only in certain types.


Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a4208971..02c2730b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
+## 5.4.0 - 2022-04-04
+
+    - Added access to malwares from techniques (thanks aacienfuegos)
+    - Access deprecated attribute from all MITRE ATT&CK objects (thanks aacienfuegos)
+    - Updated documentation
+    - Improved support of ICS framework (thanks cohmoti)
+    - Bumped minor version
+
 ## 5.0.0 - 2021-10-22
 
     - Added new V10 data sources support
diff --git a/README.md b/README.md
index 1ab59dcb..e9a81b44 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@
 ```
 	A Python package to interact with MITRE ATT&CK Frameworks
 
-> Current Version is 5.0.0
+> Current Version is 5.4.0
 
 **pyattck** is a light-weight framework for MITRE ATT&CK Frameworks. This package extracts details from the MITRE Enterprise, PRE-ATT&CK, Mobile, and ICS Frameworks.
 
diff --git a/docs/enterprise/technique.md b/docs/enterprise/technique.md
index 1b639f51..f69e5ae5 100644
--- a/docs/enterprise/technique.md
+++ b/docs/enterprise/technique.md
@@ -7,6 +7,12 @@ This class provides information about the techniques found under each tactic (co
 * Tactics a technique is found in
 * Mitigation suggestions for a given technique
 * Actor or Group(s) identified as using this technique
+* Tools used with a given technique
+* Malware used with a given technique
+* Subtechniques of a technique if `nested_subtechniques` is set to `True`
+* NIST 800-53 Controls related to a technique
+* Data Components of a technique
+* Data Sources of a technique
 
 Each technique enables you to access the following properties on the object:
 
diff --git a/docs/ics/technique.md b/docs/ics/technique.md
index 1636d6a7..31799132 100644
--- a/docs/ics/technique.md
+++ b/docs/ics/technique.md
@@ -6,6 +6,10 @@ This class provides information about the techniques found under each tactic (co
 
 * Tactics a technique is found in
 * Mitigation suggestions for a given technique
+* Malware used with a given technique
+* NIST 800-53 Controls related to a technique
+* Data Components of a technique
+* Data Sources of a technique
 
 Each technique enables you to access the following properties on the object:
 
diff --git a/docs/index.md b/docs/index.md
index 8744aa7a..b5529c68 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -17,7 +17,7 @@
 ```
 	A Python package to interact with MITRE ATT&CK Frameworks
 
-> Current Version is 5.0.0
+> Current Version is 5.4.0
 
 **pyattck** is a light-weight framework for MITRE ATT&CK Frameworks. This package extracts details from the MITRE Enterprise, PRE-ATT&CK, Mobile, and ICS Frameworks.
 
diff --git a/docs/mobile/technique.md b/docs/mobile/technique.md
index ba0ac779..d166eb62 100644
--- a/docs/mobile/technique.md
+++ b/docs/mobile/technique.md
@@ -7,6 +7,10 @@ This class provides information about the techniques found under each tactic (co
 * Tactics a technique is found in
 * Mitigation suggestions for a given technique
 * Actor or Group(s) identified as using this technique
+* Tools used with a given technique
+* Malware used with a given technique
+* Data Components of a technique
+* Data Sources of a technique
 
 Each technique enables you to access the following properties on the object:
 
diff --git a/pyattck/enterprise/attckobject.py b/pyattck/enterprise/attckobject.py
index a69d5e28..50730e19 100644
--- a/pyattck/enterprise/attckobject.py
+++ b/pyattck/enterprise/attckobject.py
@@ -35,6 +35,7 @@ def __init__(self, **kwargs):
         self.modified = self._set_attribute(kwargs, 'modified')
         self.stix = self._set_attribute(kwargs, 'id')
         self.type = self._set_attribute(kwargs, 'type')
+        self.deprecated = self._set_attribute(kwargs, 'x_mitre_deprecated')
 
     def __str__(self):
         """
diff --git a/pyattck/enterprise/technique.py b/pyattck/enterprise/technique.py
index b72a9ba1..9fbe158e 100644
--- a/pyattck/enterprise/technique.py
+++ b/pyattck/enterprise/technique.py
@@ -28,6 +28,11 @@ class AttckTechnique(AttckObject):
                 1. tactics
                 2. mitigations
                 3. actors
+                4. tools
+                5. malwares
+                6. controls
+                7. data_components
+                8. data_sources
 
             1. To iterate over an `techniques` list, do the following:
 
@@ -114,7 +119,6 @@ def __init__(self, attck_obj = None, **kwargs):
         self.wiki = self._set_wiki(kwargs)
         self.contributors = self._set_list_items(kwargs, 'x_mitre_contributors')
         self.revoked = self._set_attribute(kwargs, 'revoked')
-        self.deprecated = self._set_attribute(kwargs, 'x_mitre_deprecated')
         self.subtechnique = False if self._set_attribute(kwargs, 'x_mitre_is_subtechnique') is None else True
         self.__subtechniques = []
         self.command_list = self.__get_filtered_dataset('command_list')
@@ -305,3 +309,25 @@ def tools(self):
                 if item in item_dict:
                     return_list.append(AttckTools(attck_obj=self.__attck_obj, **item_dict[item]))
         return return_list
+
+    @property
+    def malwares(self):
+        """
+        Returns all malware objects that are used in a technique
+
+        Returns:
+            [list] -- A list of malware objects defined within the
+                      Enterprise MITRE ATT&CK Framework
+        """
+        from .malware import AttckMalware
+        return_list = []
+        item_dict = {}
+        for item in self.__attck_obj['objects']:
+            if 'type' in item:
+                if item['type'] == 'malware':
+                    item_dict[item['id']] = item
+        if self._RELATIONSHIPS.get(self.stix):
+            for item in self._RELATIONSHIPS.get(self.stix):
+                if item in item_dict:
+                    return_list.append(AttckMalware(attck_obj=self.__attck_obj, **item_dict[item]))
+        return return_list
diff --git a/pyattck/ics/attckobject.py b/pyattck/ics/attckobject.py
index c9d66a43..4c359bec 100644
--- a/pyattck/ics/attckobject.py
+++ b/pyattck/ics/attckobject.py
@@ -35,6 +35,7 @@ def __init__(self, **kwargs):
         self.modified = self._set_attribute(kwargs, 'modified')
         self.stix = self._set_attribute(kwargs, 'id')
         self.type = self._set_attribute(kwargs, 'type')
+        self.deprecated = self._set_attribute(kwargs, 'x_mitre_deprecated')
 
     def __str__(self):
         """
diff --git a/pyattck/ics/control.py b/pyattck/ics/control.py
index 77e74bdc..df2d4375 100644
--- a/pyattck/ics/control.py
+++ b/pyattck/ics/control.py
@@ -41,7 +41,7 @@ class AttckControl(AttckObject):
         kwargs (dict) -- Takes the raw control Json object
     """
 
-    def __init__(self, attck_obj = None, **kwargs):
+    def __init__(self, attck_obj = None, _enterprise_attck_obj=None, **kwargs):
         """
         This class represents a compliance Control as defined from
         external data sources.
@@ -51,6 +51,7 @@ def __init__(self, attck_obj = None, **kwargs):
         """
         super(AttckControl, self).__init__(**kwargs)
         self.__attck_obj = attck_obj
+        self.__enterprise_attck_obj = _enterprise_attck_obj
         for key,val in kwargs.items():
             prop_name = key.replace('x_mitre_','')
             if not hasattr(self, prop_name):
@@ -72,5 +73,5 @@ def techniques(self):
             if self.stix in val:
                 for item in self.__attck_obj['objects']:
                     if 'type' in item and item['type'] == 'attack-pattern' and key == item['id']:
-                        technique_list.append(AttckTechnique(attck_obj=self.__attck_obj, **item))
+                        technique_list.append(AttckTechnique(attck_obj=self.__attck_obj, _enterprise_attck_obj=self.__enterprise_attck_obj, **item))
         return technique_list
diff --git a/pyattck/ics/datasource.py b/pyattck/ics/datasource.py
index a806c0eb..912fb680 100644
--- a/pyattck/ics/datasource.py
+++ b/pyattck/ics/datasource.py
@@ -103,5 +103,5 @@ def techniques(self):
                     if data_sources.get(self.name):
                         for component in self.data_components:
                             if component.name in data_sources[self.name]:
-                                return_list.append(AttckTechnique(attck_obj=self.__ics_attck_obj, **item))
+                                return_list.append(AttckTechnique(attck_obj=self.__ics_attck_obj, _enterprise_attck_obj=self.__attck_obj, **item))
         return return_list
diff --git a/pyattck/ics/icsattck.py b/pyattck/ics/icsattck.py
index ba15490a..3f8170e7 100644
--- a/pyattck/ics/icsattck.py
+++ b/pyattck/ics/icsattck.py
@@ -187,7 +187,7 @@ def controls(self):
             if self.__nist_controls_json.get('objects'):
                 for control in self.__nist_controls_json['objects']:
                     if control.get('type') == 'course-of-action':
-                        self.__controls.append(AttckControl(attck_obj=self.__attck, **control))
+                        self.__controls.append(AttckControl(attck_obj=self.__attck, _enterprise_attck_obj=self.__enterprise_attck, **control))
         return self.__controls
 
     @property
@@ -215,7 +215,7 @@ def tactics(self):
         if not self.__tactics:
             for tactic in self.__attck['objects']:
                 if tactic['type'] == 'x-mitre-tactic':
-                    self.__tactics.append(AttckTactic(attck_obj=self.__attck, **tactic))
+                    self.__tactics.append(AttckTactic(attck_obj=self.__attck, _enterprise_attck_obj=self.__enterprise_attck, **tactic))
         return self.__tactics
 
     @property
@@ -229,7 +229,7 @@ def mitigations(self):
         if not self.__mitigations:
             for mitigation in self.__attck['objects']:
                 if mitigation['type'] == 'course-of-action':
-                    self.__mitigations.append(AttckMitigation(attck_obj=self.__attck, **mitigation))
+                    self.__mitigations.append(AttckMitigation(attck_obj=self.__attck, _enterprise_attck_obj=self.__enterprise_attck, **mitigation))
         return self.__mitigations
 
     @property
@@ -243,7 +243,7 @@ def malwares(self):
         if not self.__malwares:
             for malware in self.__attck['objects']:
                 if malware['type'] == 'malware':
-                    self.__malwares.append(AttckMalware(attck_obj=self.__attck, **malware))
+                    self.__malwares.append(AttckMalware(attck_obj=self.__attck, _enterprise_attck_obj=self.__enterprise_attck, **malware))
         return self.__malwares
 
     @property
diff --git a/pyattck/ics/malware.py b/pyattck/ics/malware.py
index 66f748ba..d5b266e1 100644
--- a/pyattck/ics/malware.py
+++ b/pyattck/ics/malware.py
@@ -54,7 +54,7 @@ class AttckMalware(AttckObject):
         AttckObject (dict) -- Takes the MITRE ATT&CK Json object as a kwargs values
     """
 
-    def __init__(self, attck_obj = None, **kwargs):
+    def __init__(self, attck_obj = None, _enterprise_attck_obj=None, **kwargs):
         """
         This class represents malware as defined by the ICS
         MITRE ATT&CK framework.
@@ -65,6 +65,7 @@ def __init__(self, attck_obj = None, **kwargs):
         """
         super(AttckMalware, self).__init__(**kwargs)
         self.__attck_obj = attck_obj
+        self.__enterprise_attck_obj = _enterprise_attck_obj
         self.id = self._set_id(kwargs)
         self.created_by_ref = self._set_attribute(kwargs, 'created_by_ref')
         self.name = self._set_attribute(kwargs, 'name')
@@ -99,5 +100,5 @@ def techniques(self):
         if self._RELATIONSHIPS.get(self.stix):
             for item in self._RELATIONSHIPS[self.stix]:
                 if item in item_dict:
-                    return_list.append(AttckTechnique(attck_obj=self.__attck_obj, **item_dict[item]))
+                    return_list.append(AttckTechnique(attck_obj=self.__attck_obj, _enterprise_attck_obj=self.__enterprise_attck_obj, **item_dict[item]))
         return return_list
diff --git a/pyattck/ics/mitigation.py b/pyattck/ics/mitigation.py
index 82f49523..19a42dbe 100644
--- a/pyattck/ics/mitigation.py
+++ b/pyattck/ics/mitigation.py
@@ -54,7 +54,7 @@ class AttckMitigation(AttckObject):
         AttckObject (dict) -- Takes the Mitre ATT&CK Json object as a kwargs values
     """
 
-    def __init__(self, attck_obj = None, **kwargs):
+    def __init__(self, attck_obj = None, _enterprise_attck_obj=None, **kwargs):
         """
         This class represents mitigation guidance as defined by the
         ICS MITRE ATT&CK framework.
@@ -64,6 +64,7 @@ def __init__(self, attck_obj = None, **kwargs):
         """
         super(AttckMitigation, self).__init__(**kwargs)
         self.__attck_obj = attck_obj
+        self.__enterprise_attck_obj = _enterprise_attck_obj
         self.created_by_ref = self._set_attribute(kwargs, 'created_by_ref')
         self.id = self._set_id(kwargs)
         self.name = self._set_attribute(kwargs, 'name')
@@ -97,5 +98,5 @@ def techniques(self):
         if self._RELATIONSHIPS.get(self.stix):
             for item in self._RELATIONSHIPS[self.stix]:
                 if item in item_dict:
-                    return_list.append(AttckTechnique(attck_obj=self.__attck_obj, **item_dict[item]))
+                    return_list.append(AttckTechnique(attck_obj=self.__attck_obj, _enterprise_attck_obj=self.__enterprise_attck_obj, **item_dict[item]))
         return return_list
diff --git a/pyattck/ics/tactic.py b/pyattck/ics/tactic.py
index 2aeb42df..f7022ad4 100644
--- a/pyattck/ics/tactic.py
+++ b/pyattck/ics/tactic.py
@@ -2,7 +2,6 @@
 
 
 class AttckTactic(AttckObject):
-
     """ICS MITRE ATT&CK Tactic object.
 
     A child class of AttckObject
@@ -57,7 +56,7 @@ class AttckTactic(AttckObject):
         AttckObject (dict) -- Takes the Mitre ATT&CK Json object as a kwargs values
     """
 
-    def __init__(self, attck_obj = None, **kwargs):
+    def __init__(self, attck_obj=None, _enterprise_attck_obj=None, **kwargs):
         """
         This class represents a Tactic as defined by the
         ICS MITRE ATT&CK framework.
@@ -68,6 +67,7 @@ def __init__(self, attck_obj = None, **kwargs):
         """
         super(AttckTactic, self).__init__(**kwargs)
         self.__attck_obj = attck_obj
+        self.__enterprise_attck_obj = _enterprise_attck_obj
         self.id = self._set_id(kwargs)
         self.created_by_ref = self._set_attribute(kwargs, 'created_by_ref')
         self.type = self._set_attribute(kwargs, 'type')
@@ -98,5 +98,6 @@ def techniques(self):
             if 'kill_chain_phases' in item:
                 for prop in item['kill_chain_phases']:
                     if str(prop['phase_name']).lower() == str(self.short_name).lower():
-                        technique_list.append(AttckTechnique(attck_obj=self.__attck_obj, **item))
+                        technique_list.append(AttckTechnique(attck_obj=self.__attck_obj,
+                                                             _enterprise_attck_obj=self.__enterprise_attck_obj, **item))
         return technique_list
diff --git a/pyattck/ics/technique.py b/pyattck/ics/technique.py
index aa59f547..f3d93561 100644
--- a/pyattck/ics/technique.py
+++ b/pyattck/ics/technique.py
@@ -2,7 +2,6 @@
 
 
 class AttckTechnique(AttckObject):
-
     """ICS MITRE ATT&CK Technique object.
 
     A child class of AttckObject
@@ -82,7 +81,7 @@ class AttckTechnique(AttckObject):
         AttckObject (dict) -- Takes the MITRE ATT&CK Json object as a kwargs values
     """
 
-    def __init__(self, attck_obj = None, _enterprise_attck_obj=None, **kwargs):
+    def __init__(self, attck_obj=None, _enterprise_attck_obj=None, **kwargs):
         """
         This class represents a Technique as defined by the
         ICS MITRE ATT&CK framework.
@@ -117,7 +116,6 @@ def __init__(self, attck_obj = None, _enterprise_attck_obj=None, **kwargs):
         self.wiki = self._set_wiki(kwargs)
         self.contributors = self._set_list_items(kwargs, 'x_mitre_contributors')
         self.revoked = self._set_attribute(kwargs, 'revoked')
-        self.deprecated = self._set_attribute(kwargs, 'x_mitre_deprecated')
         self.subtechnique = False if self._set_attribute(kwargs, 'x_mitre_is_subtechnique') is None else True
         self.command_list = self.__get_filtered_dataset('command_list')
         self.commands = self.__get_filtered_dataset('commands')
@@ -170,17 +168,19 @@ def data_sources(self):
             if 'x-mitre-data-source' in item['type']:
                 if temp_data_source_dict.get(item['name']):
                     data_source_list.append(AttckDataSource(
-                        attck_obj=self.__enterprise_attck_obj, 
+                        attck_obj=self.__enterprise_attck_obj,
                         _data_component_filter=temp_data_source_dict[item['name']],
+                        _ics_attck_obj=self.__attck_obj,
                         **item)
                     )
                     del temp_data_source_dict[item['name']]
         if temp_data_source_dict:
-            for key,val in temp_data_source_dict.items():
+            for key, val in temp_data_source_dict.items():
                 data_source_list.append(
                     AttckDataSource(
                         attck_obj=self.__enterprise_attck_obj,
                         _data_component_filter=val,
+                        _ics_attck_obj=self.__attck_obj,
                         **{
                             'name': key,
                             'data_components': val
@@ -204,7 +204,9 @@ def tactics(self):
             if 'x-mitre-tactic' in item['type']:
                 for tact in self._tactic:
                     if str(tact).lower() == str(item['x_mitre_shortname']).lower():
-                        tactic_list.append(AttckTactic(attck_obj=self.__attck_obj, **item))
+                        tactic_list.append(
+                            AttckTactic(attck_obj=self.__attck_obj, _enterprise_attck_obj=self.__enterprise_attck_obj,
+                                        **item))
         return tactic_list
 
     @tactics.setter
@@ -226,7 +228,7 @@ def tactics(self, obj):
             self._tactic = temp_list
         except:
             self._tactic = ['no phase_name']
-        
+
     @property
     def mitigations(self):
         """
@@ -246,5 +248,7 @@ def mitigations(self):
         if self._RELATIONSHIPS.get(self.stix):
             for item in self._RELATIONSHIPS[self.stix]:
                 if item in item_dict:
-                    return_list.append(AttckMitigation(attck_obj=self.__attck_obj, **item_dict[item]))
-        return return_list 
+                    return_list.append(
+                        AttckMitigation(attck_obj=self.__attck_obj, _enterprise_attck_obj=self.__enterprise_attck_obj,
+                                        **item_dict[item]))
+        return return_list
diff --git a/pyattck/mobile/mobileattckobject.py b/pyattck/mobile/mobileattckobject.py
index b1677b6a..5d1f4de1 100644
--- a/pyattck/mobile/mobileattckobject.py
+++ b/pyattck/mobile/mobileattckobject.py
@@ -35,6 +35,7 @@ def __init__(self, **kwargs):
         self.modified = self._set_attribute(kwargs, 'modified')
         self.stix = self._set_attribute(kwargs, 'id')
         self.type = self._set_attribute(kwargs, 'type')
+        self.deprecated = self._set_attribute(kwargs, 'x_mitre_deprecated')
 
     def __str__(self):
         return_dict = {}
diff --git a/pyattck/mobile/technique.py b/pyattck/mobile/technique.py
index 8fb7e10b..67abff77 100644
--- a/pyattck/mobile/technique.py
+++ b/pyattck/mobile/technique.py
@@ -79,14 +79,12 @@ def __init__(self, mobile_attck_obj = None, **kwargs):
         self.old_attack_id = self._set_attribute(kwargs, 'x_mitre_old_attack_id')
         self.platforms = self._set_list_items(kwargs, 'x_mitre_platforms')
         self.version = self._set_attribute(kwargs, 'x_mitre_version')
-        self.depricated = self._set_attribute(kwargs, 'x_mitre_deprecated')
         self.created_by_ref = self._set_attribute(kwargs, 'created_by_ref')
         self.contributor = self._set_list_items(kwargs, 'x_mitre_contributors')
         self.tactic_type = self._set_list_items(kwargs, 'x_mitre_tactic_type')
         self.external_reference = self._set_reference(kwargs)
         self.possible_detections = self._set_attribute(kwargs, 'x_mitre_detection')
         self.revoked = self._set_attribute(kwargs, 'revoked')
-        self.deprecated = self._set_attribute(kwargs, 'x_mitre_deprecated')
         self.wiki = self._set_wiki(kwargs)
         self.stix = self._set_attribute(kwargs, 'id')
         self.command_list = self.__get_filtered_dataset('command_list')
@@ -213,3 +211,27 @@ def tools(self):
                 if item in item_dict:
                     return_list.append(MobileAttckTools(attck_obj=self.__attck_obj, **item_dict[item]))
         return return_list
+
+    @property
+    def malwares(self):
+        """
+        Returns all malware objects that are used in a technique
+
+        Returns:
+            [list] -- A list of malware objects defined within the
+                      Mobile MITRE ATT&CK Framework
+        """
+        from .malware import MobileAttckMalware
+        return_list = []
+        item_dict = {}
+        for item in self.__mobile_attck_obj['objects']:
+            if 'type' in item:
+                if item['type'] == 'malware':
+                    item_dict[item['id']] = item
+        try:
+            for item in self._RELATIONSHIPS[self.stix]:
+                if item in item_dict:
+                    return_list.append(MobileAttckMalware(mobile_attck_obj=self.__mobile_attck_obj, **item_dict[item]))
+        except:
+            pass
+        return return_list
diff --git a/pyattck/utils/version.py b/pyattck/utils/version.py
index dd5233c0..fa3f56d5 100644
--- a/pyattck/utils/version.py
+++ b/pyattck/utils/version.py
@@ -1,2 +1,2 @@
-__version_info__ = (5, 3, 0)
+__version_info__ = (5, 4, 0)
 __version__ = ".".join(map(str, __version_info__))
\ No newline at end of file


Test patch:
diff --git a/tests/enterprise/test_techniques.py b/tests/enterprise/test_techniques.py
index 925548ac..f6de9e62 100644
--- a/tests/enterprise/test_techniques.py
+++ b/tests/enterprise/test_techniques.py
@@ -99,3 +99,18 @@ def test_some_techniques_have_compliance_controls(attck_fixture):
                     count += 1
     if count >= 600:
         assert True
+
+def test_techniques_have_malwares(attck_fixture):
+    """
+    Some MITRE Enterprise ATT&CK Techniques should have malwares
+
+    Args:
+        attck_fixture ([type]): our default MITRE Enterprise ATT&CK JSON fixture
+    """
+    count = 0
+    for technique in attck_fixture.enterprise.techniques:
+        if not hasattr(technique, 'malwares'):
+            if technique.malwares:
+                count += 1
+    if count >= 1:
+        assert True
diff --git a/tests/ics/test_ics_malware.py b/tests/ics/test_ics_malware.py
index 60523a20..082eab2d 100644
--- a/tests/ics/test_ics_malware.py
+++ b/tests/ics/test_ics_malware.py
@@ -9,3 +9,11 @@ def test_malware_have_techniques(attck_fixture):
     for malware in attck_fixture.ics.malwares:
         if malware.techniques:
             assert getattr(malware,'techniques')
+
+
+def test_malware_techniques_data_sources(attck_fixture):
+    for malware in attck_fixture.ics.malwares:
+        for technique in malware.techniques:
+            dss = technique.data_sources
+            if dss is None:
+                raise Exception("Data sources should not be None")
diff --git a/tests/mobile/test_mobile_attck_techniques.py b/tests/mobile/test_mobile_attck_techniques.py
index 8115f74e..9b96bcaa 100644
--- a/tests/mobile/test_mobile_attck_techniques.py
+++ b/tests/mobile/test_mobile_attck_techniques.py
@@ -26,3 +26,18 @@ def test_mobile_attck_techniques_have_actors(attck_fixture):
                 count += 1
     if count >= 1:
         assert True
+
+def test_mobile_attck_techniques_have_malwares(attck_fixture):
+    """
+    All MITRE Mobile ATT&CK Techniques should have malwares
+
+    Args:
+        attck_fixture ([type]): our default MITRE Mobile ATT&CK JSON fixture
+    """
+    count = 0
+    for technique in attck_fixture.mobile.techniques:
+        if not hasattr(technique, 'malwares'):
+            if technique.malwares:
+                count += 1
+    if count >= 1:
+        assert True