diff --git a/stix2/test/v21/constants.py b/stix2/test/v21/constants.py index b0ba1ef..66cb956 100644 --- a/stix2/test/v21/constants.py +++ b/stix2/test/v21/constants.py @@ -78,6 +78,7 @@ IDENTITY_KWARGS = dict( INDICATOR_KWARGS = dict( indicator_types=['malicious-activity'], pattern="[file:hashes.MD5 = 'd41d8cd98f00b204e9800998ecf8427e']", + valid_from="2017-01-01T12:34:56Z", ) INTRUSION_SET_KWARGS = dict( @@ -87,6 +88,7 @@ INTRUSION_SET_KWARGS = dict( MALWARE_KWARGS = dict( malware_types=['ransomware'], name="Cryptolocker", + is_family=False, ) MALWARE_MORE_KWARGS = dict( @@ -97,6 +99,7 @@ MALWARE_MORE_KWARGS = dict( malware_types=['ransomware'], name="Cryptolocker", description="A ransomware related to ...", + is_family=False, ) OBSERVED_DATA_KWARGS = dict( diff --git a/stix2/test/v21/test_bundle.py b/stix2/test/v21/test_bundle.py index 47d0a7a..9b78215 100644 --- a/stix2/test/v21/test_bundle.py +++ b/stix2/test/v21/test_bundle.py @@ -31,7 +31,8 @@ EXPECTED_BUNDLE = """{ "name": "Cryptolocker", "malware_types": [ "ransomware" - ] + ], + "is_family": False }, { "type": "relationship", @@ -72,6 +73,7 @@ EXPECTED_BUNDLE_DICT = { "malware_types": [ "ransomware", ], + "is_family": False, }, { "type": "relationship", @@ -244,6 +246,7 @@ def test_bundle_obj_id_found(): "malware_types": [ "ransomware", ], + "is_family": False, }, { "type": "malware", @@ -255,6 +258,7 @@ def test_bundle_obj_id_found(): "malware_types": [ "ransomware", ], + "is_family": False, }, { "type": "relationship", diff --git a/stix2/test/v21/test_core.py b/stix2/test/v21/test_core.py index bf45f32..06a829c 100644 --- a/stix2/test/v21/test_core.py +++ b/stix2/test/v21/test_core.py @@ -31,6 +31,7 @@ BUNDLE = { "malware_types": [ "ransomware", ], + "is_family": False, }, { "type": "relationship", diff --git a/stix2/test/v21/test_datastore_filters.py b/stix2/test/v21/test_datastore_filters.py index 4b9878a..cbe3fe4 100644 --- a/stix2/test/v21/test_datastore_filters.py +++ b/stix2/test/v21/test_datastore_filters.py @@ -16,6 +16,7 @@ stix_objs = [ "remote-access-trojan", ], "modified": "2017-01-27T13:49:53.997Z", + "is_family": False, "name": "Poison Ivy", "type": "malware", }, diff --git a/stix2/test/v21/test_environment.py b/stix2/test/v21/test_environment.py index e08971e..53ab744 100644 --- a/stix2/test/v21/test_environment.py +++ b/stix2/test/v21/test_environment.py @@ -219,7 +219,8 @@ def test_parse_malware(): "name": "Cryptolocker", "malware_types": [ "ransomware" - ] + ], + "is_family": False }""" mal = env.parse(data, version="2.1") @@ -230,6 +231,7 @@ def test_parse_malware(): assert mal.modified == FAKE_TIME assert mal.malware_types == ['ransomware'] assert mal.name == "Cryptolocker" + assert not mal.is_family def test_creator_of(): @@ -351,6 +353,7 @@ def test_related_to_no_id(ds): mal = { "type": "malware", "name": "some variant", + "is_family": False, } with pytest.raises(ValueError) as excinfo: env.related_to(mal) diff --git a/stix2/test/v21/test_indicator.py b/stix2/test/v21/test_indicator.py index 49bc6e0..d061104 100644 --- a/stix2/test/v21/test_indicator.py +++ b/stix2/test/v21/test_indicator.py @@ -98,7 +98,7 @@ def test_indicator_required_properties(): stix2.v21.Indicator() assert excinfo.value.cls == stix2.v21.Indicator - assert excinfo.value.properties == ["indicator_types", "pattern"] + assert excinfo.value.properties == ["indicator_types", "pattern", "valid_from"] assert str(excinfo.value) == "No values for required properties for Indicator: (indicator_types, pattern)." @@ -107,7 +107,7 @@ def test_indicator_required_property_pattern(): stix2.v21.Indicator(indicator_types=['malicious-activity']) assert excinfo.value.cls == stix2.v21.Indicator - assert excinfo.value.properties == ["pattern"] + assert excinfo.value.properties == ["pattern", "valid_from"] def test_indicator_created_ref_invalid_format(): @@ -184,6 +184,7 @@ def test_invalid_indicator_pattern(): stix2.v21.Indicator( indicator_types=['malicious-activity'], pattern="file:hashes.MD5 = 'd41d8cd98f00b204e9800998ecf8427e'", + valid_from="2017-01-01T12:34:56Z", ) assert excinfo.value.cls == stix2.v21.Indicator assert excinfo.value.prop_name == 'pattern' diff --git a/stix2/test/v21/test_malware.py b/stix2/test/v21/test_malware.py index c55bfa9..e6dfc2e 100644 --- a/stix2/test/v21/test_malware.py +++ b/stix2/test/v21/test_malware.py @@ -17,7 +17,8 @@ EXPECTED_MALWARE = """{ "name": "Cryptolocker", "malware_types": [ "ransomware" - ] + ], + "is_family": False }""" @@ -31,6 +32,7 @@ def test_malware_with_all_required_properties(): modified=now, malware_types=["ransomware"], name="Cryptolocker", + is_family=False, ) assert str(mal) == EXPECTED_MALWARE @@ -77,7 +79,7 @@ def test_malware_required_properties(): stix2.v21.Malware() assert excinfo.value.cls == stix2.v21.Malware - assert excinfo.value.properties == ["malware_types", "name"] + assert excinfo.value.properties == ["is_family", "malware_types", "name"] def test_malware_required_property_name(): @@ -85,7 +87,7 @@ def test_malware_required_property_name(): stix2.v21.Malware(malware_types=['ransomware']) assert excinfo.value.cls == stix2.v21.Malware - assert excinfo.value.properties == ["name"] + assert excinfo.value.properties == ["is_family", "name"] def test_cannot_assign_to_malware_attributes(malware): @@ -115,6 +117,7 @@ def test_invalid_kwarg_to_malware(): "modified": "2016-05-12T08:17:27.000Z", "malware_types": ["ransomware"], "name": "Cryptolocker", + "is_family": False, }, ], ) @@ -128,6 +131,7 @@ def test_parse_malware(data): assert mal.modified == dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc) assert mal.malware_types == ['ransomware'] assert mal.name == 'Cryptolocker' + assert not mal.is_family def test_parse_malware_invalid_labels(): diff --git a/stix2/test/v21/test_versioning.py b/stix2/test/v21/test_versioning.py index a7f4a2f..c46183c 100644 --- a/stix2/test/v21/test_versioning.py +++ b/stix2/test/v21/test_versioning.py @@ -230,6 +230,7 @@ def test_remove_custom_stix_property(): malware_types=["rootkit"], x_custom="armada", allow_custom=True, + is_family=False, ) mal_nc = stix2.utils.remove_custom_stix(mal) diff --git a/stix2/test/v21/test_workbench.py b/stix2/test/v21/test_workbench.py index 0a976d7..0d84422 100644 --- a/stix2/test/v21/test_workbench.py +++ b/stix2/test/v21/test_workbench.py @@ -199,7 +199,7 @@ def test_workbench_related(): def test_workbench_related_with_filters(): malware = Malware( malware_types=["ransomware"], name="CryptorBit", - created_by_ref=IDENTITY_ID, + created_by_ref=IDENTITY_ID, is_family=False, ) rel = Relationship(malware.id, 'variant-of', MALWARE_ID) save([malware, rel]) diff --git a/stix2/v21/sdo.py b/stix2/v21/sdo.py index 0ae0c80..8ec4131 100644 --- a/stix2/v21/sdo.py +++ b/stix2/v21/sdo.py @@ -198,7 +198,7 @@ class Indicator(STIXDomainObject): ('description', StringProperty()), ('indicator_types', ListProperty(StringProperty, required=True)), ('pattern', PatternProperty(required=True)), - ('valid_from', TimestampProperty(default=lambda: NOW)), + ('valid_from', TimestampProperty(default=lambda: NOW, required=True)), ('valid_until', TimestampProperty()), ('kill_chain_phases', ListProperty(KillChainPhase)), ('revoked', BooleanProperty(default=lambda: False)), @@ -683,6 +683,7 @@ class Tool(STIXDomainObject): ('name', StringProperty(required=True)), ('description', StringProperty()), ('tool_types', ListProperty(StringProperty, required=True)), + ('aliases', ListProperty(StringProperty)), ('kill_chain_phases', ListProperty(KillChainPhase)), ('tool_version', StringProperty()), ('revoked', BooleanProperty(default=lambda: False)),