From 95fecfa2021ac7f99b5c7e793307642ccfc9cb10 Mon Sep 17 00:00:00 2001 From: Chase Dillard Date: Mon, 10 Jul 2023 14:14:38 -0400 Subject: [PATCH 1/2] Add get_release_notes method stub --- mitreattack/stix20/MitreAttackData.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mitreattack/stix20/MitreAttackData.py b/mitreattack/stix20/MitreAttackData.py index feb3a267..d9bb3a99 100644 --- a/mitreattack/stix20/MitreAttackData.py +++ b/mitreattack/stix20/MitreAttackData.py @@ -1623,3 +1623,6 @@ def get_revoking_object(self, revoked_stix_id: str = "") -> object: return None return revoked_by[0] + + def get_release_notes(self, enterprise_stix, mobile_stix, ics_stix): + return \ No newline at end of file From fd177573335ca0f489f1afd536033d859509b279 Mon Sep 17 00:00:00 2001 From: Chase Dillard Date: Tue, 18 Jul 2023 15:58:58 -0400 Subject: [PATCH 2/2] Add functionality to get_release_notes method stub --- examples/get_release_notes.py | 11 +++++++ mitreattack/stix20/MitreAttackData.py | 44 +++++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 examples/get_release_notes.py diff --git a/examples/get_release_notes.py b/examples/get_release_notes.py new file mode 100644 index 00000000..949284e8 --- /dev/null +++ b/examples/get_release_notes.py @@ -0,0 +1,11 @@ +from mitreattack.stix20 import get_release_notes +from mitreattack.stix20 import MitreAttackData + + +def main(): + MitreAttackData.print_release_notes("enterprise-attack.json", "mobile-attack.json", "ics-attack.json") + return + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/mitreattack/stix20/MitreAttackData.py b/mitreattack/stix20/MitreAttackData.py index d9bb3a99..ac4c50f2 100644 --- a/mitreattack/stix20/MitreAttackData.py +++ b/mitreattack/stix20/MitreAttackData.py @@ -1624,5 +1624,45 @@ def get_revoking_object(self, revoked_stix_id: str = "") -> object: return revoked_by[0] - def get_release_notes(self, enterprise_stix, mobile_stix, ics_stix): - return \ No newline at end of file + def get_release_notes(self): + groups = self.remove_revoked_deprecated(self.get_groups()) + software = self.remove_revoked_deprecated(self.get_software()) + subtechniques = self.remove_revoked_deprecated(self.get_subtechniques()) + tactics = self.remove_revoked_deprecated(self.get_tactics()) + techniques = self.remove_revoked_deprecated(self.get_techniques()) + campaigns = self.remove_revoked_deprecated(self.get_campaigns()) + + ret = {} + ret["software"] = len(software) + ret["groups"] = len(groups) + ret["campaigns"] = len(campaigns) + ret["tactics"] = len(tactics) + ret["subtechniques"] = len(subtechniques) + ret["techniques"] = len(techniques) - ret["subtechniques"] + + return ret + + @staticmethod + def print_release_notes(enterprise_stix, mobile_stix, ics_stix): + enterprise = MitreAttackData(enterprise_stix).get_release_notes() + mobile = MitreAttackData(mobile_stix).get_release_notes() + ics = MitreAttackData(ics_stix).get_release_notes() + + software = enterprise["software"] + mobile["software"] + ics["software"] + campaigns = enterprise["campaigns"] + mobile["campaigns"] + ics["campaigns"] + groups = enterprise["groups"] + mobile["groups"] + ics["groups"] + + dictionary = {} + dictionary["Enterprise"] = enterprise + dictionary["Mobile"] = mobile + dictionary["ICS"] = ics + + print(f"This version of ATT&CK contains {software} Pieces of Software, {groups} Groups, and {campaigns} Campaigns") + print("Broken out by domain:\n") + for key, stix in dictionary.items(): + print((f"-ATT&CK for {key} contains {stix['tactics']} " + f"Tactics, {stix['techniques']} Techniques, " + f"{stix['subtechniques']} Sub-Techniques, " + f"{stix['groups']} Groups, {stix['campaigns']} " + f"Campaigns, and {stix['software']} Pieces of Software.")) + \ No newline at end of file