|
26 | 26 | from stix2.utils import get_type_from_id |
27 | 27 |
|
28 | 28 | from mitreattack.stix20.custom_attack_objects import ( |
| 29 | + Analytic, |
29 | 30 | Asset, |
30 | 31 | CustomStixObject, |
31 | 32 | DataComponent, |
32 | 33 | DataSource, |
| 34 | + DetectionStrategy, |
33 | 35 | Matrix, |
34 | 36 | StixObjectFactory, |
35 | 37 | Tactic, |
@@ -106,6 +108,8 @@ class MitreAttackData: |
106 | 108 | "x-mitre-data-source", |
107 | 109 | "x-mitre-data-component", |
108 | 110 | "x-mitre-asset", |
| 111 | + "x-mitre-analytic", |
| 112 | + "x-mitre-detection-strategy", |
109 | 113 | ] |
110 | 114 |
|
111 | 115 | # --- Software/Group Relationships --- |
@@ -148,6 +152,10 @@ class MitreAttackData: |
148 | 152 | all_techniques_targeting_all_assets: Optional[RelationshipMapT[Technique]] = None |
149 | 153 | all_assets_targeted_by_all_techniques: Optional[RelationshipMapT[Asset]] = None |
150 | 154 |
|
| 155 | + # --- Detection Strategy/Technique Relationships --- |
| 156 | + all_detection_strategies_detecting_all_techniques: Optional[RelationshipMapT[DetectionStrategy]] = None |
| 157 | + all_techniques_detected_by_all_detection_strategies: Optional[RelationshipMapT[Technique]] = None |
| 158 | + |
151 | 159 | def __init__(self, stix_filepath: str | None = None, src: stix2.MemoryStore | None = None): |
152 | 160 | """Initialize a MitreAttackData object. |
153 | 161 |
|
@@ -431,6 +439,36 @@ def get_datacomponents(self, remove_revoked_deprecated: bool = False) -> list[Da |
431 | 439 | """ |
432 | 440 | return self.get_objects_by_type("x-mitre-data-component", remove_revoked_deprecated) |
433 | 441 |
|
| 442 | + def get_analytics(self, remove_revoked_deprecated: bool = False) -> list[Analytic]: |
| 443 | + """Retrieve all analytic objects. |
| 444 | +
|
| 445 | + Parameters |
| 446 | + ---------- |
| 447 | + remove_revoked_deprecated : bool, optional |
| 448 | + Remove revoked or deprecated objects from the query, by default False. |
| 449 | +
|
| 450 | + Returns |
| 451 | + ------- |
| 452 | + list[Analytic] |
| 453 | + A list of Analytic objects. |
| 454 | + """ |
| 455 | + return self.get_objects_by_type("x-mitre-analytic", remove_revoked_deprecated) |
| 456 | + |
| 457 | + def get_detectionstrategies(self, remove_revoked_deprecated: bool = False) -> list[DetectionStrategy]: |
| 458 | + """Retrieve all detection strategy objects. |
| 459 | +
|
| 460 | + Parameters |
| 461 | + ---------- |
| 462 | + remove_revoked_deprecated : bool, optional |
| 463 | + Remove revoked or deprecated objects from the query, by default False. |
| 464 | +
|
| 465 | + Returns |
| 466 | + ------- |
| 467 | + list[DetectionStrategy] |
| 468 | + A list of DetectionStrategy objects. |
| 469 | + """ |
| 470 | + return self.get_objects_by_type("x-mitre-detection-strategy", remove_revoked_deprecated) |
| 471 | + |
434 | 472 | ################################### |
435 | 473 | # Get STIX Objects by Value |
436 | 474 | ################################### |
@@ -733,6 +771,37 @@ def get_techniques_used_by_group_software(self, group_stix_id: str) -> list[Tech |
733 | 771 | technique_ids = [r.target_ref for r in software_uses] |
734 | 772 | return self.src.query([Filter("type", "=", "attack-pattern"), Filter("id", "in", technique_ids)]) |
735 | 773 |
|
| 774 | + def get_analytics_by_detection_strategy( |
| 775 | + self, detection_strategy_stix_id: str, remove_revoked_deprecated: bool = False |
| 776 | + ) -> list[Analytic]: |
| 777 | + """Retrieve analytics for a detection strategy. |
| 778 | +
|
| 779 | + Parameters |
| 780 | + ---------- |
| 781 | + detection_strategy_stix_id: str |
| 782 | + Detection Strategy to search. |
| 783 | + remove_revoked_deprecated : bool, optional |
| 784 | + Remove revoked or deprecated objects from the query, by default False. |
| 785 | +
|
| 786 | + Returns |
| 787 | + ------- |
| 788 | + list[Analytic] |
| 789 | + A list of Analytic objects referenced by the given detection strategy. |
| 790 | +
|
| 791 | + Raises |
| 792 | + ------ |
| 793 | + ValueError |
| 794 | + If no detection strategy with the given STIX ID is found. |
| 795 | + """ |
| 796 | + detection_strategy = self.get_object_by_stix_id(detection_strategy_stix_id) |
| 797 | + analytic_refs = self.get_field(detection_strategy, "x_mitre_analytic_refs", []) |
| 798 | + |
| 799 | + filters = [Filter("type", "=", "x-mitre-analytic"), Filter("id", "in", analytic_refs)] |
| 800 | + analytics = self.src.query(filters) |
| 801 | + if remove_revoked_deprecated: |
| 802 | + analytics = self.remove_revoked_deprecated(analytics) |
| 803 | + return analytics |
| 804 | + |
736 | 805 | ################################### |
737 | 806 | # Get STIX Object by Value |
738 | 807 | ################################### |
@@ -1960,3 +2029,87 @@ def get_assets_targeted_by_technique(self, technique_stix_id: str) -> list[Relat |
1960 | 2029 | if technique_stix_id in assets_targeted_by_techniques |
1961 | 2030 | else [] |
1962 | 2031 | ) |
| 2032 | + |
| 2033 | + ############################################ |
| 2034 | + # Detection Strategy/Technique Relationships |
| 2035 | + ############################################ |
| 2036 | + |
| 2037 | + def get_all_detection_strategies_detecting_all_techniques(self) -> RelationshipMapT[DetectionStrategy]: |
| 2038 | + """Get all detection strategies detecting all techniques. |
| 2039 | +
|
| 2040 | + Returns |
| 2041 | + ------- |
| 2042 | + RelationshipMapT[DetectionStrategy] |
| 2043 | + Mapping of asset_stix_id to RelationshipEntry[DetectionStrategy] for each detection strategy detecting the technique. |
| 2044 | + """ |
| 2045 | + # return data if it has already been fetched |
| 2046 | + if self.all_detection_strategies_detecting_all_techniques: |
| 2047 | + return self.all_detection_strategies_detecting_all_techniques |
| 2048 | + |
| 2049 | + self.all_detection_strategies_detecting_all_techniques = self.get_related( |
| 2050 | + "x-mitre-detection-strategy", "detects", "attack-pattern", reverse=True |
| 2051 | + ) |
| 2052 | + |
| 2053 | + return self.all_detection_strategies_detecting_all_techniques |
| 2054 | + |
| 2055 | + def get_detection_strategies_detecting_technique( |
| 2056 | + self, technique_stix_id: str |
| 2057 | + ) -> list[RelationshipEntry[DetectionStrategy]]: |
| 2058 | + """Get all detection strategies detecting a technique. |
| 2059 | +
|
| 2060 | + Parameters |
| 2061 | + ---------- |
| 2062 | + technique_stix_id : str |
| 2063 | + The STIX ID of the technique. |
| 2064 | +
|
| 2065 | + Returns |
| 2066 | + ------- |
| 2067 | + list[RelationshipEntry[DetectionStrategy]] |
| 2068 | + List of RelationshipEntry[DetectionStrategy] for each detection strategy detecting the technique. |
| 2069 | + """ |
| 2070 | + detection_strategies_detecting_techniques = self.get_all_detection_strategies_detecting_all_techniques() |
| 2071 | + return ( |
| 2072 | + detection_strategies_detecting_techniques[technique_stix_id] |
| 2073 | + if technique_stix_id in detection_strategies_detecting_techniques |
| 2074 | + else [] |
| 2075 | + ) |
| 2076 | + |
| 2077 | + def get_all_techniques_detected_by_all_detection_strategies(self) -> RelationshipMapT[Technique]: |
| 2078 | + """Get all techniques detected by all detection strategies. |
| 2079 | +
|
| 2080 | + Returns |
| 2081 | + ------- |
| 2082 | + RelationshipMapT[Technique] |
| 2083 | + Mapping of detection_strategy_stix_id to RelationshipEntry[Technique] for each technique detected by the detection strategy. |
| 2084 | + """ |
| 2085 | + # return data if it has already been fetched |
| 2086 | + if self.all_techniques_detected_by_all_detection_strategies: |
| 2087 | + return self.all_techniques_detected_by_all_detection_strategies |
| 2088 | + |
| 2089 | + self.all_techniques_detected_by_all_detection_strategies = self.get_related( |
| 2090 | + "x-mitre-detection-strategy", "detects", "attack-pattern" |
| 2091 | + ) |
| 2092 | + |
| 2093 | + return self.all_techniques_detected_by_all_detection_strategies |
| 2094 | + |
| 2095 | + def get_techniques_detected_by_detection_strategy( |
| 2096 | + self, detection_strategy_stix_id: str |
| 2097 | + ) -> list[RelationshipEntry[Technique]]: |
| 2098 | + """Get all techniques detected by a detection strategy. |
| 2099 | +
|
| 2100 | + Parameters |
| 2101 | + ---------- |
| 2102 | + detection_strategy_stix_id : str |
| 2103 | + The STIX ID of the detection strategy. |
| 2104 | +
|
| 2105 | + Returns |
| 2106 | + ------- |
| 2107 | + list[RelationshipEntry[Technique]] |
| 2108 | + List of RelationshipEntry[Technique] for each technique detected by the detection strategy. |
| 2109 | + """ |
| 2110 | + techniques_detected_by_detection_strategies = self.get_all_techniques_detected_by_all_detection_strategies() |
| 2111 | + return ( |
| 2112 | + techniques_detected_by_detection_strategies[detection_strategy_stix_id] |
| 2113 | + if detection_strategy_stix_id in techniques_detected_by_detection_strategies |
| 2114 | + else [] |
| 2115 | + ) |
0 commit comments