From 34002c4f7cc13d46b2e11a6af117e0c238fbdb27 Mon Sep 17 00:00:00 2001 From: Chris Lenk Date: Fri, 21 Dec 2018 14:33:59 -0500 Subject: [PATCH 01/62] Fix error when printing WindowsRegistryKey Caused by WindowsRegistryKey having a 'values' property. Fixes #236. --- stix2/test/v20/test_observed_data.py | 2 ++ stix2/test/v21/test_observed_data.py | 2 ++ stix2/v20/observables.py | 15 ++++++++++++++- stix2/v21/observables.py | 15 ++++++++++++++- 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/stix2/test/v20/test_observed_data.py b/stix2/test/v20/test_observed_data.py index 41a80d6..190a1f0 100644 --- a/stix2/test/v20/test_observed_data.py +++ b/stix2/test/v20/test_observed_data.py @@ -1290,6 +1290,8 @@ def test_windows_registry_key_example(): assert w.values[0].name == "Foo" assert w.values[0].data == "qwerty" assert w.values[0].data_type == "REG_SZ" + # ensure no errors in serialization because of 'values' + assert "Foo" in str(w) def test_x509_certificate_example(): diff --git a/stix2/test/v21/test_observed_data.py b/stix2/test/v21/test_observed_data.py index 5a5881a..6d4eda8 100644 --- a/stix2/test/v21/test_observed_data.py +++ b/stix2/test/v21/test_observed_data.py @@ -1264,6 +1264,8 @@ def test_windows_registry_key_example(): assert w.values[0].name == "Foo" assert w.values[0].data == "qwerty" assert w.values[0].data_type == "REG_SZ" + # ensure no errors in serialization because of 'values' + assert "Foo" in str(w) def test_x509_certificate_example(): diff --git a/stix2/v20/observables.py b/stix2/v20/observables.py index 0e7c4a0..a462661 100644 --- a/stix2/v20/observables.py +++ b/stix2/v20/observables.py @@ -706,6 +706,19 @@ class WindowsRegistryValueType(_STIXBase): ]) +class CallableValues(list): + """Wrapper to allow `values()` method on WindowsRegistryKey objects. + Needed because `values` is also a property. + """ + + def __init__(self, parent_instance, *args, **kwargs): + self.parent_instance = parent_instance + super(CallableValues, self).__init__(*args, **kwargs) + + def __call__(self): + return _Observable.values(self.parent_instance) + + class WindowsRegistryKey(_Observable): """For more detailed information on this object's properties, see `the STIX 2.0 specification `__. @@ -726,7 +739,7 @@ class WindowsRegistryKey(_Observable): @property def values(self): # Needed because 'values' is a property on collections.Mapping objects - return self._inner['values'] + return CallableValues(self, self._inner['values']) class X509V3ExtenstionsType(_STIXBase): diff --git a/stix2/v21/observables.py b/stix2/v21/observables.py index 1b2251d..92fe36a 100644 --- a/stix2/v21/observables.py +++ b/stix2/v21/observables.py @@ -758,6 +758,19 @@ class WindowsRegistryValueType(_STIXBase): ]) +class CallableValues(list): + """Wrapper to allow `values()` method on WindowsRegistryKey objects. + Needed because `values` is also a property. + """ + + def __init__(self, parent_instance, *args, **kwargs): + self.parent_instance = parent_instance + super(CallableValues, self).__init__(*args, **kwargs) + + def __call__(self): + return _Observable.values(self.parent_instance) + + class WindowsRegistryKey(_Observable): # TODO: Add link """For more detailed information on this object's properties, see @@ -779,7 +792,7 @@ class WindowsRegistryKey(_Observable): @property def values(self): # Needed because 'values' is a property on collections.Mapping objects - return self._inner['values'] + return CallableValues(self, self._inner['values']) class X509V3ExtenstionsType(_STIXBase): From 2966efa4f0418ea605a5cdce6409032a45534d18 Mon Sep 17 00:00:00 2001 From: Chris Lenk Date: Mon, 7 Jan 2019 11:15:47 -0500 Subject: [PATCH 02/62] Remove dictionary/extension property non-empty req Only bundle.objects and observed-data.objects have a requirement to include at least one item. --- stix2/properties.py | 4 ---- stix2/test/v20/test_observed_data.py | 9 --------- stix2/test/v20/test_properties.py | 1 - stix2/test/v21/test_observed_data.py | 9 --------- stix2/test/v21/test_properties.py | 1 - 5 files changed, 24 deletions(-) diff --git a/stix2/properties.py b/stix2/properties.py index 24549aa..7202f9a 100644 --- a/stix2/properties.py +++ b/stix2/properties.py @@ -291,8 +291,6 @@ class DictionaryProperty(Property): dictified = _get_dict(value) except ValueError: raise ValueError("The dictionary property must contain a dictionary") - if dictified == {}: - raise ValueError("The dictionary property must contain a non-empty dictionary") for k in dictified.keys(): if self.spec_version == '2.0': if len(k) < 3: @@ -498,8 +496,6 @@ class ExtensionsProperty(DictionaryProperty): dictified = copy.deepcopy(dictified) except ValueError: raise ValueError("The extensions property must contain a dictionary") - if dictified == {}: - raise ValueError("The extensions property must contain a non-empty dictionary") v = 'v' + self.spec_version.replace('.', '') diff --git a/stix2/test/v20/test_observed_data.py b/stix2/test/v20/test_observed_data.py index 41a80d6..b922c81 100644 --- a/stix2/test/v20/test_observed_data.py +++ b/stix2/test/v20/test_observed_data.py @@ -1140,15 +1140,6 @@ def test_process_example_windows_process_ext_empty(): assert excinfo.value.properties == sorted(properties_of_extension) -def test_process_example_extensions_empty(): - with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: - stix2.v20.Process(extensions={}) - - assert excinfo.value.cls == stix2.v20.Process - assert excinfo.value.prop_name == 'extensions' - assert 'non-empty dictionary' in excinfo.value.reason - - def test_process_example_with_WindowsProcessExt_Object(): p = stix2.v20.Process(extensions={ "windows-process-ext": stix2.v20.WindowsProcessExt( diff --git a/stix2/test/v20/test_properties.py b/stix2/test/v20/test_properties.py index 24c1c99..e9a513e 100644 --- a/stix2/test/v20/test_properties.py +++ b/stix2/test/v20/test_properties.py @@ -360,7 +360,6 @@ def test_dictionary_property_invalid_key(d): @pytest.mark.parametrize( "d", [ - ({}, "The dictionary property must contain a non-empty dictionary"), # TODO: This error message could be made more helpful. The error is caused # because `json.loads()` doesn't like the *single* quotes around the key # name, even though they are valid in a Python dictionary. While technically diff --git a/stix2/test/v21/test_observed_data.py b/stix2/test/v21/test_observed_data.py index 5a5881a..c859aed 100644 --- a/stix2/test/v21/test_observed_data.py +++ b/stix2/test/v21/test_observed_data.py @@ -1114,15 +1114,6 @@ def test_process_example_windows_process_ext_empty(): assert excinfo.value.properties == sorted(properties_of_extension) -def test_process_example_extensions_empty(): - with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: - stix2.v21.Process(extensions={}) - - assert excinfo.value.cls == stix2.v21.Process - assert excinfo.value.prop_name == 'extensions' - assert 'non-empty dictionary' in excinfo.value.reason - - def test_process_example_with_WindowsProcessExt_Object(): p = stix2.v21.Process(extensions={ "windows-process-ext": stix2.v21.WindowsProcessExt( diff --git a/stix2/test/v21/test_properties.py b/stix2/test/v21/test_properties.py index 611ec5e..298a8df 100644 --- a/stix2/test/v21/test_properties.py +++ b/stix2/test/v21/test_properties.py @@ -369,7 +369,6 @@ def test_dictionary_property_invalid_key(d): @pytest.mark.parametrize( "d", [ - ({}, "The dictionary property must contain a non-empty dictionary"), # TODO: This error message could be made more helpful. The error is caused # because `json.loads()` doesn't like the *single* quotes around the key # name, even though they are valid in a Python dictionary. While technically From ab687d8d0e8e8acef86de1c0014bc7b28ae7bf10 Mon Sep 17 00:00:00 2001 From: Chris Lenk Date: Mon, 7 Jan 2019 15:22:08 -0500 Subject: [PATCH 03/62] Test empty extension property serialization --- stix2/test/v20/test_observed_data.py | 10 ++++++++++ stix2/test/v21/test_observed_data.py | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/stix2/test/v20/test_observed_data.py b/stix2/test/v20/test_observed_data.py index b922c81..17d732e 100644 --- a/stix2/test/v20/test_observed_data.py +++ b/stix2/test/v20/test_observed_data.py @@ -1140,6 +1140,16 @@ def test_process_example_windows_process_ext_empty(): assert excinfo.value.properties == sorted(properties_of_extension) +def test_process_example_extensions_empty(): + proc = stix2.v20.Process( + pid=314, + name="foobar.exe", + extensions={}, + ) + + assert '{}' in str(proc) + + def test_process_example_with_WindowsProcessExt_Object(): p = stix2.v20.Process(extensions={ "windows-process-ext": stix2.v20.WindowsProcessExt( diff --git a/stix2/test/v21/test_observed_data.py b/stix2/test/v21/test_observed_data.py index c859aed..d3ecde8 100644 --- a/stix2/test/v21/test_observed_data.py +++ b/stix2/test/v21/test_observed_data.py @@ -1114,6 +1114,16 @@ def test_process_example_windows_process_ext_empty(): assert excinfo.value.properties == sorted(properties_of_extension) +def test_process_example_extensions_empty(): + proc = stix2.v20.Process( + pid=314, + name="foobar.exe", + extensions={}, + ) + + assert '{}' in str(proc) + + def test_process_example_with_WindowsProcessExt_Object(): p = stix2.v21.Process(extensions={ "windows-process-ext": stix2.v21.WindowsProcessExt( From 67d3970a507a578aacfdac166028189d5fc9178f Mon Sep 17 00:00:00 2001 From: Emmanuelle Vargas-Gonzalez Date: Tue, 8 Jan 2019 09:35:01 -0500 Subject: [PATCH 04/62] Update test_observed_data.py Change to correct version --- stix2/test/v21/test_observed_data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stix2/test/v21/test_observed_data.py b/stix2/test/v21/test_observed_data.py index d3ecde8..69b170a 100644 --- a/stix2/test/v21/test_observed_data.py +++ b/stix2/test/v21/test_observed_data.py @@ -1115,7 +1115,7 @@ def test_process_example_windows_process_ext_empty(): def test_process_example_extensions_empty(): - proc = stix2.v20.Process( + proc = stix2.v21.Process( pid=314, name="foobar.exe", extensions={}, From 26a658b7899aa857cdc10e9b3b3ee67c1ed819bd Mon Sep 17 00:00:00 2001 From: Emmanuelle Vargas-Gonzalez Date: Tue, 8 Jan 2019 09:41:53 -0500 Subject: [PATCH 05/62] Update test to v21 --- stix2/test/v21/test_observed_data.py | 1 - 1 file changed, 1 deletion(-) diff --git a/stix2/test/v21/test_observed_data.py b/stix2/test/v21/test_observed_data.py index 69b170a..d2aaf52 100644 --- a/stix2/test/v21/test_observed_data.py +++ b/stix2/test/v21/test_observed_data.py @@ -1117,7 +1117,6 @@ def test_process_example_windows_process_ext_empty(): def test_process_example_extensions_empty(): proc = stix2.v21.Process( pid=314, - name="foobar.exe", extensions={}, ) From 7883614d2f5a7adbd4f589ddeecc37ba703cd9cb Mon Sep 17 00:00:00 2001 From: "Desai, Kartikey H" Date: Wed, 9 Jan 2019 08:36:10 -0500 Subject: [PATCH 06/62] Fixes #232 --- stix2/datastore/filesystem.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stix2/datastore/filesystem.py b/stix2/datastore/filesystem.py index b4f3d15..27dc45d 100644 --- a/stix2/datastore/filesystem.py +++ b/stix2/datastore/filesystem.py @@ -15,7 +15,7 @@ import six from stix2 import v20, v21 from stix2.base import _STIXBase from stix2.core import parse -from stix2.datastore import DataSink, DataSource, DataStoreMixin +from stix2.datastore import DataSink, DataSource, DataStoreMixin, DataSourceError from stix2.datastore.filters import Filter, FilterSet, apply_common_filters from stix2.utils import format_datetime, get_type_from_id, is_marking @@ -546,7 +546,7 @@ class FileSystemSink(DataSink): # TODO: Better handling of the overwriting case. if os.path.isfile(file_path): - print("Attempted to overwrite file!", file_path, file=sys.stderr) + raise DataSourceError("Attempted to overwrite file (!) at: {}".format(file_path)) else: with io.open(file_path, 'w', encoding=encoding) as f: stix_obj = stix_obj.serialize(pretty=True, encoding=encoding, ensure_ascii=False) From 77b2e0e3e3db594b21dfa61ac52b63883bc096b5 Mon Sep 17 00:00:00 2001 From: "Desai, Kartikey H" Date: Wed, 9 Jan 2019 10:22:33 -0500 Subject: [PATCH 07/62] Remove a few comments and Fixes #232 --- stix2/datastore/filesystem.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/stix2/datastore/filesystem.py b/stix2/datastore/filesystem.py index 27dc45d..e0f5d68 100644 --- a/stix2/datastore/filesystem.py +++ b/stix2/datastore/filesystem.py @@ -1,7 +1,4 @@ """Python STIX2 FileSystem Source/Sink""" -# Temporary while we address TODO statement -from __future__ import print_function - import errno import io import json @@ -544,7 +541,6 @@ class FileSystemSink(DataSink): else: stix_obj = v20.Bundle(stix_obj, allow_custom=self.allow_custom) - # TODO: Better handling of the overwriting case. if os.path.isfile(file_path): raise DataSourceError("Attempted to overwrite file (!) at: {}".format(file_path)) else: From 1ad64dfc0c134bdf90f714e068513f1b45712d91 Mon Sep 17 00:00:00 2001 From: Chris Lenk Date: Wed, 9 Jan 2019 10:46:48 -0500 Subject: [PATCH 08/62] Move CallableValues to prevent duplicate code --- stix2/properties.py | 15 ++++++++++++++- stix2/v20/observables.py | 15 +-------------- stix2/v21/observables.py | 15 +-------------- 3 files changed, 16 insertions(+), 29 deletions(-) diff --git a/stix2/properties.py b/stix2/properties.py index 24549aa..5e1b07f 100644 --- a/stix2/properties.py +++ b/stix2/properties.py @@ -11,7 +11,7 @@ import uuid from six import string_types, text_type from stix2patterns.validator import run_validator -from .base import _STIXBase +from .base import _Observable, _STIXBase from .core import STIX2_OBJ_MAPS, parse, parse_observable from .exceptions import CustomContentError, DictionaryKeyError from .utils import _get_dict, get_class_hierarchy_names, parse_into_datetime @@ -167,6 +167,19 @@ class ListProperty(Property): return result +class CallableValues(list): + """Wrapper to allow `values()` method on WindowsRegistryKey objects. + Needed because `values` is also a property. + """ + + def __init__(self, parent_instance, *args, **kwargs): + self.parent_instance = parent_instance + super(CallableValues, self).__init__(*args, **kwargs) + + def __call__(self): + return _Observable.values(self.parent_instance) + + class StringProperty(Property): def __init__(self, **kwargs): diff --git a/stix2/v20/observables.py b/stix2/v20/observables.py index a462661..55872cd 100644 --- a/stix2/v20/observables.py +++ b/stix2/v20/observables.py @@ -12,7 +12,7 @@ from ..base import _Extension, _Observable, _STIXBase from ..custom import _custom_extension_builder, _custom_observable_builder from ..exceptions import AtLeastOnePropertyError, DependentPropertiesError from ..properties import ( - BinaryProperty, BooleanProperty, DictionaryProperty, + BinaryProperty, BooleanProperty, CallableValues, DictionaryProperty, EmbeddedObjectProperty, EnumProperty, ExtensionsProperty, FloatProperty, HashesProperty, HexProperty, IntegerProperty, ListProperty, ObjectReferenceProperty, StringProperty, TimestampProperty, TypeProperty, @@ -706,19 +706,6 @@ class WindowsRegistryValueType(_STIXBase): ]) -class CallableValues(list): - """Wrapper to allow `values()` method on WindowsRegistryKey objects. - Needed because `values` is also a property. - """ - - def __init__(self, parent_instance, *args, **kwargs): - self.parent_instance = parent_instance - super(CallableValues, self).__init__(*args, **kwargs) - - def __call__(self): - return _Observable.values(self.parent_instance) - - class WindowsRegistryKey(_Observable): """For more detailed information on this object's properties, see `the STIX 2.0 specification `__. diff --git a/stix2/v21/observables.py b/stix2/v21/observables.py index 92fe36a..f383899 100644 --- a/stix2/v21/observables.py +++ b/stix2/v21/observables.py @@ -12,7 +12,7 @@ from ..base import _Extension, _Observable, _STIXBase from ..custom import _custom_extension_builder, _custom_observable_builder from ..exceptions import AtLeastOnePropertyError, DependentPropertiesError from ..properties import ( - BinaryProperty, BooleanProperty, DictionaryProperty, + BinaryProperty, BooleanProperty, CallableValues, DictionaryProperty, EmbeddedObjectProperty, EnumProperty, ExtensionsProperty, FloatProperty, HashesProperty, HexProperty, IntegerProperty, ListProperty, ObjectReferenceProperty, StringProperty, TimestampProperty, TypeProperty, @@ -758,19 +758,6 @@ class WindowsRegistryValueType(_STIXBase): ]) -class CallableValues(list): - """Wrapper to allow `values()` method on WindowsRegistryKey objects. - Needed because `values` is also a property. - """ - - def __init__(self, parent_instance, *args, **kwargs): - self.parent_instance = parent_instance - super(CallableValues, self).__init__(*args, **kwargs) - - def __call__(self): - return _Observable.values(self.parent_instance) - - class WindowsRegistryKey(_Observable): # TODO: Add link """For more detailed information on this object's properties, see From 767a758b28b5a3569ade11e37b76605a31971da3 Mon Sep 17 00:00:00 2001 From: "Desai, Kartikey H" Date: Wed, 9 Jan 2019 11:32:51 -0500 Subject: [PATCH 09/62] Fix styling issue around imports for issue 232 --- stix2/datastore/filesystem.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/stix2/datastore/filesystem.py b/stix2/datastore/filesystem.py index e0f5d68..0e8bed2 100644 --- a/stix2/datastore/filesystem.py +++ b/stix2/datastore/filesystem.py @@ -5,14 +5,15 @@ import json import os import re import stat -import sys import six from stix2 import v20, v21 from stix2.base import _STIXBase from stix2.core import parse -from stix2.datastore import DataSink, DataSource, DataStoreMixin, DataSourceError +from stix2.datastore import ( + DataSink, DataSource, DataSourceError, DataStoreMixin, +) from stix2.datastore.filters import Filter, FilterSet, apply_common_filters from stix2.utils import format_datetime, get_type_from_id, is_marking From 6e28cc8fe68a84c685f36bb674d76ed1da3a00a3 Mon Sep 17 00:00:00 2001 From: "Desai, Kartikey H" Date: Fri, 11 Jan 2019 09:26:55 -0500 Subject: [PATCH 10/62] Add test to fix for issue 232 --- stix2/test/v20/test_datastore_filesystem.py | 36 +++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/stix2/test/v20/test_datastore_filesystem.py b/stix2/test/v20/test_datastore_filesystem.py index 84a3034..c8607e2 100644 --- a/stix2/test/v20/test_datastore_filesystem.py +++ b/stix2/test/v20/test_datastore_filesystem.py @@ -9,6 +9,7 @@ import pytest import pytz import stix2 +from stix2.datastore import DataSourceError from stix2.datastore.filesystem import ( AuthSet, _find_search_optimizations, _get_matching_dir_entries, _timestamp2filename, @@ -420,6 +421,41 @@ def test_filesystem_sink_add_objects_list(fs_sink, fs_source): os.remove(camp7filepath) +def test_filesystem_sink_attempt_stix_file_overwrite(fs_sink, fs_source): + # add python stix object + camp8 = stix2.v20.Campaign( + name="George Washington", + objective="Create an awesome country", + aliases=["Georgey"], + ) + + fs_sink.add(camp8) + + filepath = os.path.join( + FS_PATH, "campaign", camp8.id, + _timestamp2filename(camp8.modified) + ".json", + ) + assert os.path.exists(filepath) + + camp8_r = fs_source.get(camp8.id) + assert camp8_r.id == camp8.id + assert camp8_r.name == "George Washington" + assert "Georgey" in camp8_r.aliases + + # now attempt to overwrite the same file + camp9 = stix2.v20.Campaign( + name="George Washington", + objective="Create an awesome country", + aliases=["Georgey"], + ) + + with pytest.raises(DataSourceError) as excinfo: + fs_sink.add(camp9) + assert "Attempted to overwrite file" in str(excinfo) + + os.remove(filepath) + + def test_filesystem_sink_marking(fs_sink): marking = stix2.v20.MarkingDefinition( definition_type="tlp", From 5dea09547e1d689777d391e3ed6ed0ddcea46968 Mon Sep 17 00:00:00 2001 From: "Desai, Kartikey H" Date: Fri, 11 Jan 2019 09:40:57 -0500 Subject: [PATCH 11/62] Fix test for fix to issue 232 --- stix2/test/v20/test_datastore_filesystem.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/stix2/test/v20/test_datastore_filesystem.py b/stix2/test/v20/test_datastore_filesystem.py index c8607e2..e447c73 100644 --- a/stix2/test/v20/test_datastore_filesystem.py +++ b/stix2/test/v20/test_datastore_filesystem.py @@ -443,14 +443,14 @@ def test_filesystem_sink_attempt_stix_file_overwrite(fs_sink, fs_source): assert "Georgey" in camp8_r.aliases # now attempt to overwrite the same file - camp9 = stix2.v20.Campaign( - name="George Washington", - objective="Create an awesome country", - aliases=["Georgey"], - ) + # camp9 = stix2.v20.Campaign( + # name="George Washington", + # objective="Create an awesome country", + # aliases=["Georgey"], + # ) with pytest.raises(DataSourceError) as excinfo: - fs_sink.add(camp9) + fs_sink.add(camp8) assert "Attempted to overwrite file" in str(excinfo) os.remove(filepath) From 72d7757c7b292450c604dae44a7b1c723d78b991 Mon Sep 17 00:00:00 2001 From: "Desai, Kartikey H" Date: Fri, 11 Jan 2019 10:46:16 -0500 Subject: [PATCH 12/62] Change test to use store instead of source & sink --- stix2/test/v20/test_datastore_filesystem.py | 28 ++++++++------------- 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/stix2/test/v20/test_datastore_filesystem.py b/stix2/test/v20/test_datastore_filesystem.py index e447c73..86846c4 100644 --- a/stix2/test/v20/test_datastore_filesystem.py +++ b/stix2/test/v20/test_datastore_filesystem.py @@ -421,7 +421,7 @@ def test_filesystem_sink_add_objects_list(fs_sink, fs_source): os.remove(camp7filepath) -def test_filesystem_sink_attempt_stix_file_overwrite(fs_sink, fs_source): +def test_filesystem_attempt_stix_file_overwrite(fs_store): # add python stix object camp8 = stix2.v20.Campaign( name="George Washington", @@ -429,28 +429,20 @@ def test_filesystem_sink_attempt_stix_file_overwrite(fs_sink, fs_source): aliases=["Georgey"], ) - fs_sink.add(camp8) + fs_store.add(camp8) + + camp8_r = fs_store.get(camp8.id) + assert camp8_r.id == camp8_r.id + assert camp8_r.name == camp8.name filepath = os.path.join( - FS_PATH, "campaign", camp8.id, - _timestamp2filename(camp8.modified) + ".json", + FS_PATH, "campaign", camp8_r.id, + _timestamp2filename(camp8_r.modified) + ".json", ) - assert os.path.exists(filepath) - - camp8_r = fs_source.get(camp8.id) - assert camp8_r.id == camp8.id - assert camp8_r.name == "George Washington" - assert "Georgey" in camp8_r.aliases - - # now attempt to overwrite the same file - # camp9 = stix2.v20.Campaign( - # name="George Washington", - # objective="Create an awesome country", - # aliases=["Georgey"], - # ) + # Now attempt to overwrite the existing file with pytest.raises(DataSourceError) as excinfo: - fs_sink.add(camp8) + fs_store.add(camp8) assert "Attempted to overwrite file" in str(excinfo) os.remove(filepath) From db5f8f2ebfcc6cfeff518bb145833b74d199ff2d Mon Sep 17 00:00:00 2001 From: Emmanuelle Vargas-Gonzalez Date: Fri, 11 Jan 2019 13:55:05 -0500 Subject: [PATCH 13/62] Update docstrings to relocate links\documentation --- docs/api/stix2.v20.bundle.rst | 5 ----- docs/api/stix2.v20.common.rst | 5 ----- docs/api/stix2.v20.observables.rst | 5 ----- docs/api/stix2.v20.sdo.rst | 5 ----- docs/api/stix2.v20.sro.rst | 5 ----- docs/api/stix2.v21.bundle.rst | 5 ----- docs/api/stix2.v21.common.rst | 5 ----- docs/api/stix2.v21.observables.rst | 5 ----- docs/api/stix2.v21.sdo.rst | 5 ----- docs/api/stix2.v21.sro.rst | 5 ----- stix2/__init__.py | 12 ++---------- stix2/v20/__init__.py | 14 +++++++++++++- stix2/v21/__init__.py | 14 +++++++++++++- 13 files changed, 28 insertions(+), 62 deletions(-) delete mode 100644 docs/api/stix2.v20.bundle.rst delete mode 100644 docs/api/stix2.v20.common.rst delete mode 100644 docs/api/stix2.v20.observables.rst delete mode 100644 docs/api/stix2.v20.sdo.rst delete mode 100644 docs/api/stix2.v20.sro.rst delete mode 100644 docs/api/stix2.v21.bundle.rst delete mode 100644 docs/api/stix2.v21.common.rst delete mode 100644 docs/api/stix2.v21.observables.rst delete mode 100644 docs/api/stix2.v21.sdo.rst delete mode 100644 docs/api/stix2.v21.sro.rst diff --git a/docs/api/stix2.v20.bundle.rst b/docs/api/stix2.v20.bundle.rst deleted file mode 100644 index bd2abd4..0000000 --- a/docs/api/stix2.v20.bundle.rst +++ /dev/null @@ -1,5 +0,0 @@ -bundle -================ - -.. automodule:: stix2.v20.bundle - :members: \ No newline at end of file diff --git a/docs/api/stix2.v20.common.rst b/docs/api/stix2.v20.common.rst deleted file mode 100644 index 8cec059..0000000 --- a/docs/api/stix2.v20.common.rst +++ /dev/null @@ -1,5 +0,0 @@ -common -================ - -.. automodule:: stix2.v20.common - :members: diff --git a/docs/api/stix2.v20.observables.rst b/docs/api/stix2.v20.observables.rst deleted file mode 100644 index 4d9803a..0000000 --- a/docs/api/stix2.v20.observables.rst +++ /dev/null @@ -1,5 +0,0 @@ -observables -===================== - -.. automodule:: stix2.v20.observables - :members: diff --git a/docs/api/stix2.v20.sdo.rst b/docs/api/stix2.v20.sdo.rst deleted file mode 100644 index a115d5b..0000000 --- a/docs/api/stix2.v20.sdo.rst +++ /dev/null @@ -1,5 +0,0 @@ -sdo -============= - -.. automodule:: stix2.v20.sdo - :members: diff --git a/docs/api/stix2.v20.sro.rst b/docs/api/stix2.v20.sro.rst deleted file mode 100644 index 397cf29..0000000 --- a/docs/api/stix2.v20.sro.rst +++ /dev/null @@ -1,5 +0,0 @@ -sro -============= - -.. automodule:: stix2.v20.sro - :members: diff --git a/docs/api/stix2.v21.bundle.rst b/docs/api/stix2.v21.bundle.rst deleted file mode 100644 index da67082..0000000 --- a/docs/api/stix2.v21.bundle.rst +++ /dev/null @@ -1,5 +0,0 @@ -bundle -================ - -.. automodule:: stix2.v21.bundle - :members: \ No newline at end of file diff --git a/docs/api/stix2.v21.common.rst b/docs/api/stix2.v21.common.rst deleted file mode 100644 index b480481..0000000 --- a/docs/api/stix2.v21.common.rst +++ /dev/null @@ -1,5 +0,0 @@ -common -================ - -.. automodule:: stix2.v21.common - :members: \ No newline at end of file diff --git a/docs/api/stix2.v21.observables.rst b/docs/api/stix2.v21.observables.rst deleted file mode 100644 index 56f409a..0000000 --- a/docs/api/stix2.v21.observables.rst +++ /dev/null @@ -1,5 +0,0 @@ -observables -===================== - -.. automodule:: stix2.v21.observables - :members: \ No newline at end of file diff --git a/docs/api/stix2.v21.sdo.rst b/docs/api/stix2.v21.sdo.rst deleted file mode 100644 index b1a568d..0000000 --- a/docs/api/stix2.v21.sdo.rst +++ /dev/null @@ -1,5 +0,0 @@ -sdo -============= - -.. automodule:: stix2.v21.sdo - :members: \ No newline at end of file diff --git a/docs/api/stix2.v21.sro.rst b/docs/api/stix2.v21.sro.rst deleted file mode 100644 index 3532a37..0000000 --- a/docs/api/stix2.v21.sro.rst +++ /dev/null @@ -1,5 +0,0 @@ -sro -============= - -.. automodule:: stix2.v21.sro - :members: \ No newline at end of file diff --git a/stix2/__init__.py b/stix2/__init__.py index 3bedec8..246ecaf 100644 --- a/stix2/__init__.py +++ b/stix2/__init__.py @@ -12,16 +12,8 @@ patterns properties utils - v20.bundle - v20.common - v20.observables - v20.sdo - v20.sro - v21.bundle - v21.common - v21.observables - v21.sdo - v21.sro + v20 + v21 workbench """ diff --git a/stix2/v20/__init__.py b/stix2/v20/__init__.py index bef7d66..4d0a98f 100644 --- a/stix2/v20/__init__.py +++ b/stix2/v20/__init__.py @@ -1,4 +1,16 @@ -"""STIX 2.0 API Objects.""" +"""STIX 2.0 API Objects. + +.. autosummary:: + :toctree: v20 + + bundle + common + observables + sdo + sro + +| +""" # flake8: noqa diff --git a/stix2/v21/__init__.py b/stix2/v21/__init__.py index 4a8fe29..c1caae4 100644 --- a/stix2/v21/__init__.py +++ b/stix2/v21/__init__.py @@ -1,4 +1,16 @@ -"""STIX 2.1 API Objects.""" +"""STIX 2.1 API Objects. + +.. autosummary:: + :toctree: v21 + + bundle + common + observables + sdo + sro + +| +""" # flake8: noqa From f80728d3f5ea26509ab00113208ac796a8779d4f Mon Sep 17 00:00:00 2001 From: Emmanuelle Vargas-Gonzalez Date: Fri, 11 Jan 2019 13:59:08 -0500 Subject: [PATCH 14/62] New files and directories for RST files. closes #234 --- docs/api/stix2.v20.rst | 5 +++++ docs/api/stix2.v21.rst | 5 +++++ docs/api/v20/stix2.v20.bundle.rst | 5 +++++ docs/api/v20/stix2.v20.common.rst | 5 +++++ docs/api/v20/stix2.v20.observables.rst | 5 +++++ docs/api/v20/stix2.v20.sdo.rst | 5 +++++ docs/api/v20/stix2.v20.sro.rst | 5 +++++ docs/api/v21/stix2.v21.bundle.rst | 5 +++++ docs/api/v21/stix2.v21.common.rst | 5 +++++ docs/api/v21/stix2.v21.observables.rst | 5 +++++ docs/api/v21/stix2.v21.sdo.rst | 5 +++++ docs/api/v21/stix2.v21.sro.rst | 5 +++++ 12 files changed, 60 insertions(+) create mode 100644 docs/api/stix2.v20.rst create mode 100644 docs/api/stix2.v21.rst create mode 100644 docs/api/v20/stix2.v20.bundle.rst create mode 100644 docs/api/v20/stix2.v20.common.rst create mode 100644 docs/api/v20/stix2.v20.observables.rst create mode 100644 docs/api/v20/stix2.v20.sdo.rst create mode 100644 docs/api/v20/stix2.v20.sro.rst create mode 100644 docs/api/v21/stix2.v21.bundle.rst create mode 100644 docs/api/v21/stix2.v21.common.rst create mode 100644 docs/api/v21/stix2.v21.observables.rst create mode 100644 docs/api/v21/stix2.v21.sdo.rst create mode 100644 docs/api/v21/stix2.v21.sro.rst diff --git a/docs/api/stix2.v20.rst b/docs/api/stix2.v20.rst new file mode 100644 index 0000000..2cbb2e3 --- /dev/null +++ b/docs/api/stix2.v20.rst @@ -0,0 +1,5 @@ +v20 +========= + +.. automodule:: stix2.v20 + :members: \ No newline at end of file diff --git a/docs/api/stix2.v21.rst b/docs/api/stix2.v21.rst new file mode 100644 index 0000000..fc02330 --- /dev/null +++ b/docs/api/stix2.v21.rst @@ -0,0 +1,5 @@ +v21 +========= + +.. automodule:: stix2.v21 + :members: \ No newline at end of file diff --git a/docs/api/v20/stix2.v20.bundle.rst b/docs/api/v20/stix2.v20.bundle.rst new file mode 100644 index 0000000..bd2abd4 --- /dev/null +++ b/docs/api/v20/stix2.v20.bundle.rst @@ -0,0 +1,5 @@ +bundle +================ + +.. automodule:: stix2.v20.bundle + :members: \ No newline at end of file diff --git a/docs/api/v20/stix2.v20.common.rst b/docs/api/v20/stix2.v20.common.rst new file mode 100644 index 0000000..0c7a296 --- /dev/null +++ b/docs/api/v20/stix2.v20.common.rst @@ -0,0 +1,5 @@ +common +================ + +.. automodule:: stix2.v20.common + :members: \ No newline at end of file diff --git a/docs/api/v20/stix2.v20.observables.rst b/docs/api/v20/stix2.v20.observables.rst new file mode 100644 index 0000000..d31f75f --- /dev/null +++ b/docs/api/v20/stix2.v20.observables.rst @@ -0,0 +1,5 @@ +observables +===================== + +.. automodule:: stix2.v20.observables + :members: \ No newline at end of file diff --git a/docs/api/v20/stix2.v20.sdo.rst b/docs/api/v20/stix2.v20.sdo.rst new file mode 100644 index 0000000..c4c97f8 --- /dev/null +++ b/docs/api/v20/stix2.v20.sdo.rst @@ -0,0 +1,5 @@ +sdo +============= + +.. automodule:: stix2.v20.sdo + :members: \ No newline at end of file diff --git a/docs/api/v20/stix2.v20.sro.rst b/docs/api/v20/stix2.v20.sro.rst new file mode 100644 index 0000000..379ed18 --- /dev/null +++ b/docs/api/v20/stix2.v20.sro.rst @@ -0,0 +1,5 @@ +sro +============= + +.. automodule:: stix2.v20.sro + :members: \ No newline at end of file diff --git a/docs/api/v21/stix2.v21.bundle.rst b/docs/api/v21/stix2.v21.bundle.rst new file mode 100644 index 0000000..da67082 --- /dev/null +++ b/docs/api/v21/stix2.v21.bundle.rst @@ -0,0 +1,5 @@ +bundle +================ + +.. automodule:: stix2.v21.bundle + :members: \ No newline at end of file diff --git a/docs/api/v21/stix2.v21.common.rst b/docs/api/v21/stix2.v21.common.rst new file mode 100644 index 0000000..b480481 --- /dev/null +++ b/docs/api/v21/stix2.v21.common.rst @@ -0,0 +1,5 @@ +common +================ + +.. automodule:: stix2.v21.common + :members: \ No newline at end of file diff --git a/docs/api/v21/stix2.v21.observables.rst b/docs/api/v21/stix2.v21.observables.rst new file mode 100644 index 0000000..56f409a --- /dev/null +++ b/docs/api/v21/stix2.v21.observables.rst @@ -0,0 +1,5 @@ +observables +===================== + +.. automodule:: stix2.v21.observables + :members: \ No newline at end of file diff --git a/docs/api/v21/stix2.v21.sdo.rst b/docs/api/v21/stix2.v21.sdo.rst new file mode 100644 index 0000000..b1a568d --- /dev/null +++ b/docs/api/v21/stix2.v21.sdo.rst @@ -0,0 +1,5 @@ +sdo +============= + +.. automodule:: stix2.v21.sdo + :members: \ No newline at end of file diff --git a/docs/api/v21/stix2.v21.sro.rst b/docs/api/v21/stix2.v21.sro.rst new file mode 100644 index 0000000..3532a37 --- /dev/null +++ b/docs/api/v21/stix2.v21.sro.rst @@ -0,0 +1,5 @@ +sro +============= + +.. automodule:: stix2.v21.sro + :members: \ No newline at end of file From ce1bb3bfa793d6b023f9cdf95d4772cd4dd913b3 Mon Sep 17 00:00:00 2001 From: Emmanuelle Vargas-Gonzalez Date: Fri, 11 Jan 2019 14:21:05 -0500 Subject: [PATCH 15/62] Update CHANGELOG for v1.1.1 --- CHANGELOG | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 6dcfef9..5e47891 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,13 @@ CHANGELOG ========= +1.1.1 - 2019-01-11 + +* #234 Update documentation structure to better navigate between v20/v21 objects +* #232 FileSystemStore now raises an exception if you attempt to overwrite an existing file +* #236 Fix a serialization problem with the WindowsRegistryKey observable object +* #238 Fix a problem with the LanguageContent object not allowing its creation with an empty dictionary + 1.1.0 - 2018-12-11 - Most (if not all) STIX 2.1 SDOs/SROs and core objects have been implemented according to the latest CSD/WD document From 7e64c70d8b7e9f083ad4b99ece484aaca255bc08 Mon Sep 17 00:00:00 2001 From: Emmanuelle Vargas-Gonzalez Date: Fri, 11 Jan 2019 14:27:35 -0500 Subject: [PATCH 16/62] =?UTF-8?q?Bump=20version:=201.1.0=20=E2=86=92=201.1?= =?UTF-8?q?.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- setup.cfg | 2 +- stix2/version.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.cfg b/setup.cfg index a1aaca9..e5e52e4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 1.1.0 +current_version = 1.1.1 commit = True tag = True diff --git a/stix2/version.py b/stix2/version.py index 6849410..a82b376 100644 --- a/stix2/version.py +++ b/stix2/version.py @@ -1 +1 @@ -__version__ = "1.1.0" +__version__ = "1.1.1" From 5658cebf57e38c2ba614303354b5d2b7f68df33a Mon Sep 17 00:00:00 2001 From: "Desai, Kartikey H" Date: Fri, 18 Jan 2019 13:28:37 -0500 Subject: [PATCH 17/62] Update JSON files so timestamps are only precise to the millisecond (3 decimal points), per the specs --- .../20170531213019735010.json | 4 ++-- .../20170531213026496201.json | 4 ++-- .../20170531213029458940.json | 4 ++-- .../20170531213045139269.json | 4 ++-- .../20170531213041022897.json | 4 ++-- .../20170531213032662702.json | 4 ++-- .../20170531213026495974.json | 4 ++-- .../20170531213041022744.json | 4 ++-- .../20170531213149412497.json | 4 ++-- .../20170531213153197755.json | 4 ++-- .../20170531213258226477.json | 4 ++-- .../20170531213326565056.json | 4 ++-- .../20170531213248482655.json | 4 ++-- .../20170531213215263882.json | 4 ++-- .../20170531213327182784.json | 4 ++-- .../20170531213327082801.json | 4 ++-- .../20170531213327018782.json | 4 ++-- .../20170531213327100701.json | 4 ++-- .../20170531213327143973.json | 4 ++-- .../20170531213327021562.json | 4 ++-- .../20170531213327044387.json | 4 ++-- .../20170531213327051532.json | 4 ++-- .../20170531213231601148.json | 4 ++-- .../20170531213212684914.json | 4 ++-- 24 files changed, 48 insertions(+), 48 deletions(-) diff --git a/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--0a3ead4e-6d47-4ccb-854c-a6a4f9d96b22/20170531213019735010.json b/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--0a3ead4e-6d47-4ccb-854c-a6a4f9d96b22/20170531213019735010.json index ccbe2cc..f9fdf75 100644 --- a/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--0a3ead4e-6d47-4ccb-854c-a6a4f9d96b22/20170531213019735010.json +++ b/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--0a3ead4e-6d47-4ccb-854c-a6a4f9d96b22/20170531213019735010.json @@ -2,7 +2,7 @@ "id": "bundle--f68640b4-0cdc-42ae-b176-def1754a1ea0", "objects": [ { - "created": "2017-05-31T21:30:19.73501Z", + "created": "2017-05-31T21:30:19.735Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "Credential dumping is the process of obtaining account login and password information from the operating system and software. Credentials can be used to perform Windows Credential Editor, Mimikatz, and gsecdump. These tools are in use by both professional security testers and adversaries.\n\nPlaintext passwords can be obtained using tools such as Mimikatz to extract passwords stored by the Local Security Authority (LSA). If smart cards are used to authenticate to a domain using a personal identification number (PIN), then that PIN is also cached as a result and may be dumped.Mimikatz access the LSA Subsystem Service (LSASS) process by opening the process, locating the LSA secrets key, and decrypting the sections in memory where credential details are stored. Credential dumpers may also use methods for reflective DLL Injection to reduce potential indicators of malicious activity.\n\nNTLM hash dumpers open the Security Accounts Manager (SAM) on the local file system (%SystemRoot%/system32/config/SAM) or create a dump of the Registry SAM key to access stored account password hashes. Some hash dumpers will open the local file system as a device and parse to the SAM table to avoid file access defenses. Others will make an in-memory copy of the SAM table before reading hashes. Detection of compromised Legitimate Credentials in-use by adversaries may help as well. \n\nOn Windows 8.1 and Windows Server 2012 R2, monitor Windows Logs for LSASS.exe creation to verify that LSASS started as a protected process.\n\nMonitor processes and command-line arguments for program execution that may be indicative of credential dumping. Remote access tools may contain built-in features or incorporate existing tools like Mimikatz. PowerShell scripts also exist that contain credential dumping functionality, such as PowerSploit's Invoke-Mimikatz module,[[Citation: Powersploit]] which may require additional logging features to be configured in the operating system to collect necessary information for analysis.\n\nPlatforms: Windows Server 2003, Windows Server 2008, Windows Server 2012, Windows XP, Windows 7, Windows 8, Windows Server 2003 R2, Windows Server 2008 R2, Windows Server 2012 R2, Windows Vista, Windows 8.1\n\nData Sources: API monitoring, Process command-line parameters, Process monitoring, PowerShell logs", "external_references": [ @@ -29,7 +29,7 @@ "phase_name": "credential-access" } ], - "modified": "2017-05-31T21:30:19.73501Z", + "modified": "2017-05-31T21:30:19.735Z", "name": "Credential Dumping", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" diff --git a/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--0f20e3cb-245b-4a61-8a91-2d93f7cb0e9b/20170531213026496201.json b/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--0f20e3cb-245b-4a61-8a91-2d93f7cb0e9b/20170531213026496201.json index c36831e..abc6725 100644 --- a/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--0f20e3cb-245b-4a61-8a91-2d93f7cb0e9b/20170531213026496201.json +++ b/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--0f20e3cb-245b-4a61-8a91-2d93f7cb0e9b/20170531213026496201.json @@ -2,7 +2,7 @@ "id": "bundle--b07d6fd6-7cc5-492d-a1eb-9ba956b329d5", "objects": [ { - "created": "2017-05-31T21:30:26.496201Z", + "created": "2017-05-31T21:30:26.496Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "Rootkits are programs that hide the existence of malware by intercepting and modifying operating system API calls that supply system information. Rootkits or rootkit enabling functionality may reside at the user or kernel level in the operating system or lower, to include a Hypervisor, Master Boot Record, or the Basic Input/Output System.[[Citation: Wikipedia Rootkit]]\n\nAdversaries may use rootkits to hide the presence of programs, files, network connections, services, drivers, and other system components.\n\nDetection: Some rootkit protections may be built into anti-virus or operating system software. There are dedicated rootkit detection tools that look for specific types of rootkit behavior. Monitor for the existence of unrecognized DLLs, devices, services, and changes to the MBR.[[Citation: Wikipedia Rootkit]]\n\nPlatforms: Windows Server 2003, Windows Server 2008, Windows Server 2012, Windows XP, Windows 7, Windows 8, Windows Server 2003 R2, Windows Server 2008 R2, Windows Server 2012 R2, Windows Vista, Windows 8.1\n\nData Sources: BIOS, MBR, System calls", "external_references": [ @@ -24,7 +24,7 @@ "phase_name": "defense-evasion" } ], - "modified": "2017-05-31T21:30:26.496201Z", + "modified": "2017-05-31T21:30:26.496Z", "name": "Rootkit", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" diff --git a/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--774a3188-6ba9-4dc4-879d-d54ee48a5ce9/20170531213029458940.json b/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--774a3188-6ba9-4dc4-879d-d54ee48a5ce9/20170531213029458940.json index 0504875..4bde369 100644 --- a/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--774a3188-6ba9-4dc4-879d-d54ee48a5ce9/20170531213029458940.json +++ b/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--774a3188-6ba9-4dc4-879d-d54ee48a5ce9/20170531213029458940.json @@ -2,7 +2,7 @@ "id": "bundle--1a854c96-639e-4771-befb-e7b960a65974", "objects": [ { - "created": "2017-05-31T21:30:29.45894Z", + "created": "2017-05-31T21:30:29.458Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "Data, such as sensitive documents, may be exfiltrated through the use of automated processing or Scripting after being gathered during Exfiltration Over Command and Control Channel and Exfiltration Over Alternative Protocol.\n\nDetection: Monitor process file access patterns and network behavior. Unrecognized processes or scripts that appear to be traversing file systems and sending network traffic may be suspicious.\n\nPlatforms: Windows Server 2003, Windows Server 2008, Windows Server 2012, Windows XP, Windows 7, Windows 8, Windows Server 2003 R2, Windows Server 2008 R2, Windows Server 2012 R2, Windows Vista, Windows 8.1\n\nData Sources: File monitoring, Process monitoring, Process use of network", "external_references": [ @@ -19,7 +19,7 @@ "phase_name": "exfiltration" } ], - "modified": "2017-05-31T21:30:29.45894Z", + "modified": "2017-05-31T21:30:29.458Z", "name": "Automated Exfiltration", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" diff --git a/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--7e150503-88e7-4861-866b-ff1ac82c4475/20170531213045139269.json b/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--7e150503-88e7-4861-866b-ff1ac82c4475/20170531213045139269.json index 2e3b622..582a935 100644 --- a/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--7e150503-88e7-4861-866b-ff1ac82c4475/20170531213045139269.json +++ b/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--7e150503-88e7-4861-866b-ff1ac82c4475/20170531213045139269.json @@ -2,7 +2,7 @@ "id": "bundle--33e3e33a-38b8-4a37-9455-5b8c82d3b10a", "objects": [ { - "created": "2017-05-31T21:30:45.139269Z", + "created": "2017-05-31T21:30:45.139Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "Adversaries may attempt to get a listing of network connections to or from the compromised system.\nUtilities and commands that acquire this information include netstat, \"net use,\" and \"net session\" with Net.\n\nDetection: System and network discovery techniques normally occur throughout an operation as an adversary learns the environment. Data and events should not be viewed in isolation, but as part of a chain of behavior that could lead to other activities, such as Windows Management Instrumentation and PowerShell.\n\nPlatforms: Windows Server 2003, Windows Server 2008, Windows Server 2012, Windows XP, Windows 7, Windows 8, Windows Server 2003 R2, Windows Server 2008 R2, Windows Server 2012 R2, Windows Vista, Windows 8.1\n\nData Sources: Process command-line parameters, Process monitoring", "external_references": [ @@ -19,7 +19,7 @@ "phase_name": "discovery" } ], - "modified": "2017-05-31T21:30:45.139269Z", + "modified": "2017-05-31T21:30:45.139Z", "name": "Local Network Connections Discovery", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" diff --git a/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--ae676644-d2d2-41b7-af7e-9bed1b55898c/20170531213041022897.json b/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--ae676644-d2d2-41b7-af7e-9bed1b55898c/20170531213041022897.json index 8819fcb..8827c4b 100644 --- a/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--ae676644-d2d2-41b7-af7e-9bed1b55898c/20170531213041022897.json +++ b/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--ae676644-d2d2-41b7-af7e-9bed1b55898c/20170531213041022897.json @@ -2,7 +2,7 @@ "id": "bundle--a87938c5-cc1e-4e06-a8a3-b10243ae397d", "objects": [ { - "created": "2017-05-31T21:30:41.022897Z", + "created": "2017-05-31T21:30:41.022Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "Sensitive data can be collected from remote systems via shared network drives (host shared directory, network file server, etc.) that are accessible from the current system prior to cmd may be used to gather information.\n\nDetection: Monitor processes and command-line arguments for actions that could be taken to collect files from a network share. Remote access tools with built-in features may interact directly with the Windows API to gather data. Data may also be acquired through Windows system management tools such as Windows Management Instrumentation and PowerShell.\n\nPlatforms: Windows Server 2003, Windows Server 2008, Windows Server 2012, Windows XP, Windows 7, Windows 8, Windows Server 2003 R2, Windows Server 2008 R2, Windows Server 2012 R2, Windows Vista, Windows 8.1\n\nData Sources: File monitoring, Process monitoring, Process command-line parameters", "external_references": [ @@ -19,7 +19,7 @@ "phase_name": "collection" } ], - "modified": "2017-05-31T21:30:41.022897Z", + "modified": "2017-05-31T21:30:41.022Z", "name": "Data from Network Shared Drive", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" diff --git a/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--b3d682b6-98f2-4fb0-aa3b-b4df007ca70a/20170531213032662702.json b/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--b3d682b6-98f2-4fb0-aa3b-b4df007ca70a/20170531213032662702.json index 7d2b58e..219ce46 100644 --- a/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--b3d682b6-98f2-4fb0-aa3b-b4df007ca70a/20170531213032662702.json +++ b/stix2/test/v21/stix2_data/attack-pattern/attack-pattern--b3d682b6-98f2-4fb0-aa3b-b4df007ca70a/20170531213032662702.json @@ -2,7 +2,7 @@ "id": "bundle--5ddaeff9-eca7-4094-9e65-4f53da21a444", "objects": [ { - "created": "2017-05-31T21:30:32.662702Z", + "created": "2017-05-31T21:30:32.662Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "Adversaries may attempt to make an executable or file difficult to discover or analyze by encrypting, encoding, or otherwise obfuscating its contents on the system.\n\nDetection: Detection of file obfuscation is difficult unless artifacts are left behind by the obfuscation process that are uniquely detectable with a signature. If detection of the obfuscation itself is not possible, it may be possible to detect the malicious activity that caused the obfuscated file (for example, the method that was used to write, read, or modify the file on the file system).\n\nPlatforms: Windows Server 2003, Windows Server 2008, Windows Server 2012, Windows XP, Windows 7, Windows 8, Windows Server 2003 R2, Windows Server 2008 R2, Windows Server 2012 R2, Windows Vista, Windows 8.1\n\nData Sources: Network protocol analysis, Process use of network, Binary file metadata, File monitoring, Malware reverse engineering", "external_references": [ @@ -19,7 +19,7 @@ "phase_name": "defense-evasion" } ], - "modified": "2017-05-31T21:30:32.662702Z", + "modified": "2017-05-31T21:30:32.662Z", "name": "Obfuscated Files or Information", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" diff --git a/stix2/test/v21/stix2_data/course-of-action/course-of-action--95ddb356-7ba0-4bd9-a889-247262b8946f/20170531213026495974.json b/stix2/test/v21/stix2_data/course-of-action/course-of-action--95ddb356-7ba0-4bd9-a889-247262b8946f/20170531213026495974.json index 3117103..b59ae52 100644 --- a/stix2/test/v21/stix2_data/course-of-action/course-of-action--95ddb356-7ba0-4bd9-a889-247262b8946f/20170531213026495974.json +++ b/stix2/test/v21/stix2_data/course-of-action/course-of-action--95ddb356-7ba0-4bd9-a889-247262b8946f/20170531213026495974.json @@ -2,11 +2,11 @@ "id": "bundle--a42d26fe-c938-4074-a1b3-50d852e6f0bd", "objects": [ { - "created": "2017-05-31T21:30:26.495974Z", + "created": "2017-05-31T21:30:26.495Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "Identify potentially malicious software that may contain rootkit functionality, and audit and/or block it by using whitelisting[[CiteRef::Beechey 2010]] tools, like AppLocker,[[CiteRef::Windows Commands JPCERT]][[CiteRef::NSA MS AppLocker]] or Software Restriction Policies[[CiteRef::Corio 2008]] where appropriate.[[CiteRef::TechNet Applocker vs SRP]]", "id": "course-of-action--95ddb356-7ba0-4bd9-a889-247262b8946f", - "modified": "2017-05-31T21:30:26.495974Z", + "modified": "2017-05-31T21:30:26.495Z", "name": "Rootkit Mitigation", "spec_version": "2.1", "type": "course-of-action" diff --git a/stix2/test/v21/stix2_data/course-of-action/course-of-action--d9727aee-48b8-4fdb-89e2-4c49746ba4dd/20170531213041022744.json b/stix2/test/v21/stix2_data/course-of-action/course-of-action--d9727aee-48b8-4fdb-89e2-4c49746ba4dd/20170531213041022744.json index dcc5b0d..1c05407 100644 --- a/stix2/test/v21/stix2_data/course-of-action/course-of-action--d9727aee-48b8-4fdb-89e2-4c49746ba4dd/20170531213041022744.json +++ b/stix2/test/v21/stix2_data/course-of-action/course-of-action--d9727aee-48b8-4fdb-89e2-4c49746ba4dd/20170531213041022744.json @@ -1,9 +1,9 @@ { - "created": "2017-05-31T21:30:41.022744Z", + "created": "2017-05-31T21:30:41.022Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "Identify unnecessary system utilities or potentially malicious software that may be used to collect data from a network share, and audit and/or block them by using whitelisting[[CiteRef::Beechey 2010]] tools, like AppLocker,[[CiteRef::Windows Commands JPCERT]][[CiteRef::NSA MS AppLocker]] or Software Restriction Policies[[CiteRef::Corio 2008]] where appropriate.[[CiteRef::TechNet Applocker vs SRP]]", "id": "course-of-action--d9727aee-48b8-4fdb-89e2-4c49746ba4dd", - "modified": "2017-05-31T21:30:41.022744Z", + "modified": "2017-05-31T21:30:41.022Z", "name": "Data from Network Shared Drive Mitigation", "spec_version": "2.1", "type": "course-of-action" diff --git a/stix2/test/v21/stix2_data/intrusion-set/intrusion-set--a653431d-6a5e-4600-8ad3-609b5af57064/20170531213149412497.json b/stix2/test/v21/stix2_data/intrusion-set/intrusion-set--a653431d-6a5e-4600-8ad3-609b5af57064/20170531213149412497.json index b8372aa..c7947e8 100644 --- a/stix2/test/v21/stix2_data/intrusion-set/intrusion-set--a653431d-6a5e-4600-8ad3-609b5af57064/20170531213149412497.json +++ b/stix2/test/v21/stix2_data/intrusion-set/intrusion-set--a653431d-6a5e-4600-8ad3-609b5af57064/20170531213149412497.json @@ -10,7 +10,7 @@ "PinkPanther", "Black Vine" ], - "created": "2017-05-31T21:31:49.412497Z", + "created": "2017-05-31T21:31:49.412Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "Deep Panda is a suspected Chinese threat group known to target many industries, including government, defense, financial, and telecommunications.Deep Panda.Deep Panda also appears to be known as Black Vine based on the attribution of both group names to the Anthem intrusion.[[Citation: Symantec Black Vine]]", "external_references": [ @@ -41,7 +41,7 @@ } ], "id": "intrusion-set--a653431d-6a5e-4600-8ad3-609b5af57064", - "modified": "2017-05-31T21:31:49.412497Z", + "modified": "2017-05-31T21:31:49.412Z", "name": "Deep Panda", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" diff --git a/stix2/test/v21/stix2_data/intrusion-set/intrusion-set--f3bdec95-3d62-42d9-a840-29630f6cdc1a/20170531213153197755.json b/stix2/test/v21/stix2_data/intrusion-set/intrusion-set--f3bdec95-3d62-42d9-a840-29630f6cdc1a/20170531213153197755.json index 2fe46f1..b48a477 100644 --- a/stix2/test/v21/stix2_data/intrusion-set/intrusion-set--f3bdec95-3d62-42d9-a840-29630f6cdc1a/20170531213153197755.json +++ b/stix2/test/v21/stix2_data/intrusion-set/intrusion-set--f3bdec95-3d62-42d9-a840-29630f6cdc1a/20170531213153197755.json @@ -5,7 +5,7 @@ "aliases": [ "DragonOK" ], - "created": "2017-05-31T21:31:53.197755Z", + "created": "2017-05-31T21:31:53.197Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "DragonOK is a threat group that has targeted Japanese organizations with phishing emails. Due to overlapping TTPs, including similar custom tools, DragonOK is thought to have a direct or indirect relationship with the threat group Moafee. [[Citation: Operation Quantum Entanglement]][[Citation: Symbiotic APT Groups]] It is known to use a variety of malware, including Sysget/HelloBridge, PlugX, PoisonIvy, FormerFirstRat, NFlog, and NewCT. [[Citation: New DragonOK]]", "external_references": [ @@ -31,7 +31,7 @@ } ], "id": "intrusion-set--f3bdec95-3d62-42d9-a840-29630f6cdc1a", - "modified": "2017-05-31T21:31:53.197755Z", + "modified": "2017-05-31T21:31:53.197Z", "name": "DragonOK", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" diff --git a/stix2/test/v21/stix2_data/malware/malware--6b616fc1-1505-48e3-8b2c-0d19337bff38/20170531213258226477.json b/stix2/test/v21/stix2_data/malware/malware--6b616fc1-1505-48e3-8b2c-0d19337bff38/20170531213258226477.json index 8ea538e..1bedc5b 100644 --- a/stix2/test/v21/stix2_data/malware/malware--6b616fc1-1505-48e3-8b2c-0d19337bff38/20170531213258226477.json +++ b/stix2/test/v21/stix2_data/malware/malware--6b616fc1-1505-48e3-8b2c-0d19337bff38/20170531213258226477.json @@ -2,7 +2,7 @@ "id": "bundle--f64de948-7067-4534-8018-85f03d470625", "objects": [ { - "created": "2017-05-31T21:32:58.226477Z", + "created": "2017-05-31T21:32:58.226Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "Rover is malware suspected of being used for espionage purposes. It was used in 2015 in a targeted email sent to an Indian Ambassador to Afghanistan.[[Citation: Palo Alto Rover]]", "external_references": [ @@ -21,7 +21,7 @@ "malware_types": [ "malware" ], - "modified": "2017-05-31T21:32:58.226477Z", + "modified": "2017-05-31T21:32:58.226Z", "name": "Rover", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" diff --git a/stix2/test/v21/stix2_data/malware/malware--92ec0cbd-2c30-44a2-b270-73f4ec949841/20170531213326565056.json b/stix2/test/v21/stix2_data/malware/malware--92ec0cbd-2c30-44a2-b270-73f4ec949841/20170531213326565056.json index 9f51a11..0b7c01e 100644 --- a/stix2/test/v21/stix2_data/malware/malware--92ec0cbd-2c30-44a2-b270-73f4ec949841/20170531213326565056.json +++ b/stix2/test/v21/stix2_data/malware/malware--92ec0cbd-2c30-44a2-b270-73f4ec949841/20170531213326565056.json @@ -2,7 +2,7 @@ "id": "bundle--c633942b-545c-4c87-91b7-9fe5740365e0", "objects": [ { - "created": "2017-05-31T21:33:26.565056Z", + "created": "2017-05-31T21:33:26.565Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "RTM is custom malware written in Delphi. It is used by the group of the same name (RTM).[[Citation: ESET RTM Feb 2017]]", "external_references": [ @@ -21,7 +21,7 @@ "malware_types": [ "malware" ], - "modified": "2017-05-31T21:33:26.565056Z", + "modified": "2017-05-31T21:33:26.565Z", "name": "RTM", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" diff --git a/stix2/test/v21/stix2_data/malware/malware--96b08451-b27a-4ff6-893f-790e26393a8e/20170531213248482655.json b/stix2/test/v21/stix2_data/malware/malware--96b08451-b27a-4ff6-893f-790e26393a8e/20170531213248482655.json index 2808866..195c973 100644 --- a/stix2/test/v21/stix2_data/malware/malware--96b08451-b27a-4ff6-893f-790e26393a8e/20170531213248482655.json +++ b/stix2/test/v21/stix2_data/malware/malware--96b08451-b27a-4ff6-893f-790e26393a8e/20170531213248482655.json @@ -2,7 +2,7 @@ "id": "bundle--09ce4338-8741-4fcf-9738-d216c8e40974", "objects": [ { - "created": "2017-05-31T21:32:48.482655Z", + "created": "2017-05-31T21:32:48.482Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "Sakula is a remote access tool (RAT) that first surfaced in 2012 and was used in intrusions throughout 2015.[[Citation: Dell Sakula]]\n\nAliases: Sakula, Sakurel, VIPER", "external_references": [ @@ -21,7 +21,7 @@ "malware_types": [ "malware" ], - "modified": "2017-05-31T21:32:48.482655Z", + "modified": "2017-05-31T21:32:48.482Z", "name": "Sakula", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" diff --git a/stix2/test/v21/stix2_data/malware/malware--b42378e0-f147-496f-992a-26a49705395b/20170531213215263882.json b/stix2/test/v21/stix2_data/malware/malware--b42378e0-f147-496f-992a-26a49705395b/20170531213215263882.json index 3e1c870..4d57db5 100644 --- a/stix2/test/v21/stix2_data/malware/malware--b42378e0-f147-496f-992a-26a49705395b/20170531213215263882.json +++ b/stix2/test/v21/stix2_data/malware/malware--b42378e0-f147-496f-992a-26a49705395b/20170531213215263882.json @@ -2,7 +2,7 @@ "id": "bundle--611947ce-ae3b-4fdb-b297-aed8eab22e4f", "objects": [ { - "created": "2017-05-31T21:32:15.263882Z", + "created": "2017-05-31T21:32:15.263Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "PoisonIvy is a popular remote access tool (RAT) that has been used by many groups.[[Citation: FireEye Poison Ivy]]\n\nAliases: PoisonIvy, Poison Ivy", "external_references": [ @@ -21,7 +21,7 @@ "labels": [ "malware" ], - "modified": "2017-05-31T21:32:15.263882Z", + "modified": "2017-05-31T21:32:15.263Z", "name": "PoisonIvy", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" diff --git a/stix2/test/v21/stix2_data/relationship/relationship--0d4a7788-7f3b-4df8-a498-31a38003c883/20170531213327182784.json b/stix2/test/v21/stix2_data/relationship/relationship--0d4a7788-7f3b-4df8-a498-31a38003c883/20170531213327182784.json index 915b126..b428b3b 100644 --- a/stix2/test/v21/stix2_data/relationship/relationship--0d4a7788-7f3b-4df8-a498-31a38003c883/20170531213327182784.json +++ b/stix2/test/v21/stix2_data/relationship/relationship--0d4a7788-7f3b-4df8-a498-31a38003c883/20170531213327182784.json @@ -2,10 +2,10 @@ "id": "bundle--7e715462-dd9d-40b9-968a-10ef0ecf126d", "objects": [ { - "created": "2017-05-31T21:33:27.182784Z", + "created": "2017-05-31T21:33:27.182Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "id": "relationship--0d4a7788-7f3b-4df8-a498-31a38003c883", - "modified": "2017-05-31T21:33:27.182784Z", + "modified": "2017-05-31T21:33:27.182Z", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], diff --git a/stix2/test/v21/stix2_data/relationship/relationship--0e55ee98-0c6d-43d4-b424-b18a0036b227/20170531213327082801.json b/stix2/test/v21/stix2_data/relationship/relationship--0e55ee98-0c6d-43d4-b424-b18a0036b227/20170531213327082801.json index 478ca3a..ca0d1f0 100644 --- a/stix2/test/v21/stix2_data/relationship/relationship--0e55ee98-0c6d-43d4-b424-b18a0036b227/20170531213327082801.json +++ b/stix2/test/v21/stix2_data/relationship/relationship--0e55ee98-0c6d-43d4-b424-b18a0036b227/20170531213327082801.json @@ -2,10 +2,10 @@ "id": "bundle--a53eef35-abfc-4bcd-b84e-a048f7b4a9bf", "objects": [ { - "created": "2017-05-31T21:33:27.082801Z", + "created": "2017-05-31T21:33:27.082Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "id": "relationship--0e55ee98-0c6d-43d4-b424-b18a0036b227", - "modified": "2017-05-31T21:33:27.082801Z", + "modified": "2017-05-31T21:33:27.082Z", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], diff --git a/stix2/test/v21/stix2_data/relationship/relationship--1e91cd45-a725-4965-abe3-700694374432/20170531213327018782.json b/stix2/test/v21/stix2_data/relationship/relationship--1e91cd45-a725-4965-abe3-700694374432/20170531213327018782.json index 2ea9d22..5087f28 100644 --- a/stix2/test/v21/stix2_data/relationship/relationship--1e91cd45-a725-4965-abe3-700694374432/20170531213327018782.json +++ b/stix2/test/v21/stix2_data/relationship/relationship--1e91cd45-a725-4965-abe3-700694374432/20170531213327018782.json @@ -2,10 +2,10 @@ "id": "bundle--0b9f6412-314f-44e3-8779-9738c9578ef5", "objects": [ { - "created": "2017-05-31T21:33:27.018782Z", + "created": "2017-05-31T21:33:27.018Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "id": "relationship--1e91cd45-a725-4965-abe3-700694374432", - "modified": "2017-05-31T21:33:27.018782Z", + "modified": "2017-05-31T21:33:27.018Z", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], diff --git a/stix2/test/v21/stix2_data/relationship/relationship--3a3084f9-0302-4fd5-9b8a-e0db10f5345e/20170531213327100701.json b/stix2/test/v21/stix2_data/relationship/relationship--3a3084f9-0302-4fd5-9b8a-e0db10f5345e/20170531213327100701.json index d0a2a50..6d73f52 100644 --- a/stix2/test/v21/stix2_data/relationship/relationship--3a3084f9-0302-4fd5-9b8a-e0db10f5345e/20170531213327100701.json +++ b/stix2/test/v21/stix2_data/relationship/relationship--3a3084f9-0302-4fd5-9b8a-e0db10f5345e/20170531213327100701.json @@ -2,10 +2,10 @@ "id": "bundle--6d5b04a8-efb2-4179-990e-74f1dcc76e0c", "objects": [ { - "created": "2017-05-31T21:33:27.100701Z", + "created": "2017-05-31T21:33:27.100Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "id": "relationship--3a3084f9-0302-4fd5-9b8a-e0db10f5345e", - "modified": "2017-05-31T21:33:27.100701Z", + "modified": "2017-05-31T21:33:27.100Z", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], diff --git a/stix2/test/v21/stix2_data/relationship/relationship--3a3ed0b2-0c38-441f-ac40-53b873e545d1/20170531213327143973.json b/stix2/test/v21/stix2_data/relationship/relationship--3a3ed0b2-0c38-441f-ac40-53b873e545d1/20170531213327143973.json index 0ff1d5a..5d4594c 100644 --- a/stix2/test/v21/stix2_data/relationship/relationship--3a3ed0b2-0c38-441f-ac40-53b873e545d1/20170531213327143973.json +++ b/stix2/test/v21/stix2_data/relationship/relationship--3a3ed0b2-0c38-441f-ac40-53b873e545d1/20170531213327143973.json @@ -2,10 +2,10 @@ "id": "bundle--a7efc025-040d-49c7-bf97-e5a1120ecacc", "objects": [ { - "created": "2017-05-31T21:33:27.143973Z", + "created": "2017-05-31T21:33:27.143Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "id": "relationship--3a3ed0b2-0c38-441f-ac40-53b873e545d1", - "modified": "2017-05-31T21:33:27.143973Z", + "modified": "2017-05-31T21:33:27.143Z", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], diff --git a/stix2/test/v21/stix2_data/relationship/relationship--592d0c31-e61f-495e-a60e-70d7be59a719/20170531213327021562.json b/stix2/test/v21/stix2_data/relationship/relationship--592d0c31-e61f-495e-a60e-70d7be59a719/20170531213327021562.json index 640be0c..c18ade2 100644 --- a/stix2/test/v21/stix2_data/relationship/relationship--592d0c31-e61f-495e-a60e-70d7be59a719/20170531213327021562.json +++ b/stix2/test/v21/stix2_data/relationship/relationship--592d0c31-e61f-495e-a60e-70d7be59a719/20170531213327021562.json @@ -2,10 +2,10 @@ "id": "bundle--9f013d47-7704-41c2-9749-23d0d94af94d", "objects": [ { - "created": "2017-05-31T21:33:27.021562Z", + "created": "2017-05-31T21:33:27.021Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "id": "relationship--592d0c31-e61f-495e-a60e-70d7be59a719", - "modified": "2017-05-31T21:33:27.021562Z", + "modified": "2017-05-31T21:33:27.021Z", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], diff --git a/stix2/test/v21/stix2_data/relationship/relationship--70dc6b5c-c524-429e-a6ab-0dd40f0482c1/20170531213327044387.json b/stix2/test/v21/stix2_data/relationship/relationship--70dc6b5c-c524-429e-a6ab-0dd40f0482c1/20170531213327044387.json index 41be9df..d7a1fc2 100644 --- a/stix2/test/v21/stix2_data/relationship/relationship--70dc6b5c-c524-429e-a6ab-0dd40f0482c1/20170531213327044387.json +++ b/stix2/test/v21/stix2_data/relationship/relationship--70dc6b5c-c524-429e-a6ab-0dd40f0482c1/20170531213327044387.json @@ -2,10 +2,10 @@ "id": "bundle--15167b24-4cee-4c96-a140-32a6c37df4b4", "objects": [ { - "created": "2017-05-31T21:33:27.044387Z", + "created": "2017-05-31T21:33:27.044Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "id": "relationship--70dc6b5c-c524-429e-a6ab-0dd40f0482c1", - "modified": "2017-05-31T21:33:27.044387Z", + "modified": "2017-05-31T21:33:27.044Z", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], diff --git a/stix2/test/v21/stix2_data/relationship/relationship--8797579b-e3be-4209-a71b-255a4d08243d/20170531213327051532.json b/stix2/test/v21/stix2_data/relationship/relationship--8797579b-e3be-4209-a71b-255a4d08243d/20170531213327051532.json index ce33f67..f406224 100644 --- a/stix2/test/v21/stix2_data/relationship/relationship--8797579b-e3be-4209-a71b-255a4d08243d/20170531213327051532.json +++ b/stix2/test/v21/stix2_data/relationship/relationship--8797579b-e3be-4209-a71b-255a4d08243d/20170531213327051532.json @@ -2,10 +2,10 @@ "id": "bundle--ff845dca-7036-416f-aae0-95030994c49f", "objects": [ { - "created": "2017-05-31T21:33:27.051532Z", + "created": "2017-05-31T21:33:27.051Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "id": "relationship--8797579b-e3be-4209-a71b-255a4d08243d", - "modified": "2017-05-31T21:33:27.051532Z", + "modified": "2017-05-31T21:33:27.051Z", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], diff --git a/stix2/test/v21/stix2_data/tool/tool--03342581-f790-4f03-ba41-e82e67392e23/20170531213231601148.json b/stix2/test/v21/stix2_data/tool/tool--03342581-f790-4f03-ba41-e82e67392e23/20170531213231601148.json index 103e8ec..a8a9455 100644 --- a/stix2/test/v21/stix2_data/tool/tool--03342581-f790-4f03-ba41-e82e67392e23/20170531213231601148.json +++ b/stix2/test/v21/stix2_data/tool/tool--03342581-f790-4f03-ba41-e82e67392e23/20170531213231601148.json @@ -2,7 +2,7 @@ "id": "bundle--d8826afc-1561-4362-a4e3-05a4c2c3ac3c", "objects": [ { - "created": "2017-05-31T21:32:31.601148Z", + "created": "2017-05-31T21:32:31.601Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "The Net utility is a component of the Windows operating system. It is used in command-line operations for control of users, groups, services, and network connections.Net has a great deal of functionality,[[Citation: Savill 1999]] much of which is useful for an adversary, such as gathering system and network information for [[Discovery]], moving laterally through [[Windows admin shares]] using net use commands, and interacting with services.\n\nAliases: Net, net.exe", "external_references": [ @@ -26,7 +26,7 @@ "tool_types": [ "tool" ], - "modified": "2017-05-31T21:32:31.601148Z", + "modified": "2017-05-31T21:32:31.601Z", "name": "Net", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" diff --git a/stix2/test/v21/stix2_data/tool/tool--242f3da3-4425-4d11-8f5c-b842886da966/20170531213212684914.json b/stix2/test/v21/stix2_data/tool/tool--242f3da3-4425-4d11-8f5c-b842886da966/20170531213212684914.json index 32ea7ba..b3c9451 100644 --- a/stix2/test/v21/stix2_data/tool/tool--242f3da3-4425-4d11-8f5c-b842886da966/20170531213212684914.json +++ b/stix2/test/v21/stix2_data/tool/tool--242f3da3-4425-4d11-8f5c-b842886da966/20170531213212684914.json @@ -2,7 +2,7 @@ "id": "bundle--7dbde18f-6f14-4bf0-8389-505c89d6d5a6", "objects": [ { - "created": "2017-05-31T21:32:12.684914Z", + "created": "2017-05-31T21:32:12.684Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "Windows Credential Editor is a password dumping tool.[[Citation: Amplia WCE]]\n\nAliases: Windows Credential Editor, WCE", "external_references": [ @@ -21,7 +21,7 @@ "tool_types": [ "tool" ], - "modified": "2017-05-31T21:32:12.684914Z", + "modified": "2017-05-31T21:32:12.684Z", "name": "Windows Credential Editor", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" From dda8a7f724e172fdff63fdecfe935c0ee639544a Mon Sep 17 00:00:00 2001 From: "Desai, Kartikey H" Date: Tue, 22 Jan 2019 10:05:22 -0500 Subject: [PATCH 18/62] Add two tests to ensure millisecond precision is used in timestamps irrespective of user-provided precision --- stix2/test/v21/test_attack_pattern.py | 37 ++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/stix2/test/v21/test_attack_pattern.py b/stix2/test/v21/test_attack_pattern.py index 9c13a12..1d6649b 100644 --- a/stix2/test/v21/test_attack_pattern.py +++ b/stix2/test/v21/test_attack_pattern.py @@ -5,8 +5,6 @@ import pytz import stix2 -from .constants import ATTACK_PATTERN_ID - EXPECTED = """{ "type": "attack-pattern", "spec_version": "2.1", @@ -65,7 +63,7 @@ def test_parse_attack_pattern(data): assert ap.type == 'attack-pattern' assert ap.spec_version == '2.1' - assert ap.id == ATTACK_PATTERN_ID + assert ap.id == "attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061" assert ap.created == dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc) assert ap.modified == dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc) assert ap.description == "..." @@ -84,4 +82,37 @@ def test_attack_pattern_invalid_labels(): labels=1, ) + +def test_overly_precise_timestamps(): + ap = stix2.v21.AttackPattern( + id="attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", + created="2016-05-12T08:17:27.0000342Z", + modified="2016-05-12T08:17:27.000287Z", + name="Spear Phishing", + external_references=[{ + "source_name": "capec", + "external_id": "CAPEC-163", + }], + description="...", + ) + + assert str(ap) == EXPECTED + + +def test_less_precise_timestamps(): + ap = stix2.v21.AttackPattern( + id="attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", + created="2016-05-12T08:17:27.00Z", + modified="2016-05-12T08:17:27.0Z", + name="Spear Phishing", + external_references=[{ + "source_name": "capec", + "external_id": "CAPEC-163", + }], + description="...", + ) + + assert str(ap) == EXPECTED + + # TODO: Add other examples From f59db77352acdb3829c9a3b1849d85dde6b9644b Mon Sep 17 00:00:00 2001 From: "Desai, Kartikey H" Date: Tue, 22 Jan 2019 12:42:47 -0500 Subject: [PATCH 19/62] Update v21 tests and add them to v20 test suite --- stix2/test/v20/test_attack_pattern.py | 38 ++++++++++++++++++++++++--- stix2/test/v21/test_attack_pattern.py | 14 +++++----- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/stix2/test/v20/test_attack_pattern.py b/stix2/test/v20/test_attack_pattern.py index f071d3a..caeb46e 100644 --- a/stix2/test/v20/test_attack_pattern.py +++ b/stix2/test/v20/test_attack_pattern.py @@ -25,7 +25,7 @@ EXPECTED = """{ def test_attack_pattern_example(): ap = stix2.v20.AttackPattern( - id="attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", + id=ATTACK_PATTERN_ID, created="2016-05-12T08:17:27.000Z", modified="2016-05-12T08:17:27.000Z", name="Spear Phishing", @@ -44,7 +44,7 @@ def test_attack_pattern_example(): EXPECTED, { "type": "attack-pattern", - "id": "attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", + "id": ATTACK_PATTERN_ID, "created": "2016-05-12T08:17:27.000Z", "modified": "2016-05-12T08:17:27.000Z", "description": "...", @@ -74,11 +74,43 @@ def test_parse_attack_pattern(data): def test_attack_pattern_invalid_labels(): with pytest.raises(stix2.exceptions.InvalidValueError): stix2.v20.AttackPattern( - id="attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", + id=ATTACK_PATTERN_ID, created="2016-05-12T08:17:27Z", modified="2016-05-12T08:17:27Z", name="Spear Phishing", labels=1, ) + +def test_overly_precise_timestamps(): + ap = stix2.v21.AttackPattern( + id=ATTACK_PATTERN_ID, + created="2016-05-12T08:17:27.0000342Z", + modified="2016-05-12T08:17:27.000287Z", + name="Spear Phishing", + external_references=[{ + "source_name": "capec", + "external_id": "CAPEC-163", + }], + description="...", + ) + + assert str(ap) == EXPECTED + + +def test_less_precise_timestamps(): + ap = stix2.v21.AttackPattern( + id=ATTACK_PATTERN_ID, + created="2016-05-12T08:17:27.00Z", + modified="2016-05-12T08:17:27.0Z", + name="Spear Phishing", + external_references=[{ + "source_name": "capec", + "external_id": "CAPEC-163", + }], + description="...", + ) + + assert str(ap) == EXPECTED + # TODO: Add other examples diff --git a/stix2/test/v21/test_attack_pattern.py b/stix2/test/v21/test_attack_pattern.py index 1d6649b..165581c 100644 --- a/stix2/test/v21/test_attack_pattern.py +++ b/stix2/test/v21/test_attack_pattern.py @@ -5,6 +5,8 @@ import pytz import stix2 +from .constants import ATTACK_PATTERN_ID + EXPECTED = """{ "type": "attack-pattern", "spec_version": "2.1", @@ -24,7 +26,7 @@ EXPECTED = """{ def test_attack_pattern_example(): ap = stix2.v21.AttackPattern( - id="attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", + id=ATTACK_PATTERN_ID, created="2016-05-12T08:17:27.000Z", modified="2016-05-12T08:17:27.000Z", name="Spear Phishing", @@ -44,7 +46,7 @@ def test_attack_pattern_example(): { "type": "attack-pattern", "spec_version": "2.1", - "id": "attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", + "id": ATTACK_PATTERN_ID, "created": "2016-05-12T08:17:27.000Z", "modified": "2016-05-12T08:17:27.000Z", "description": "...", @@ -63,7 +65,7 @@ def test_parse_attack_pattern(data): assert ap.type == 'attack-pattern' assert ap.spec_version == '2.1' - assert ap.id == "attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061" + assert ap.id == ATTACK_PATTERN_ID assert ap.created == dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc) assert ap.modified == dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc) assert ap.description == "..." @@ -75,7 +77,7 @@ def test_parse_attack_pattern(data): def test_attack_pattern_invalid_labels(): with pytest.raises(stix2.exceptions.InvalidValueError): stix2.v21.AttackPattern( - id="attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", + id=ATTACK_PATTERN_ID, created="2016-05-12T08:17:27Z", modified="2016-05-12T08:17:27Z", name="Spear Phishing", @@ -85,7 +87,7 @@ def test_attack_pattern_invalid_labels(): def test_overly_precise_timestamps(): ap = stix2.v21.AttackPattern( - id="attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", + id=ATTACK_PATTERN_ID, created="2016-05-12T08:17:27.0000342Z", modified="2016-05-12T08:17:27.000287Z", name="Spear Phishing", @@ -101,7 +103,7 @@ def test_overly_precise_timestamps(): def test_less_precise_timestamps(): ap = stix2.v21.AttackPattern( - id="attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", + id=ATTACK_PATTERN_ID, created="2016-05-12T08:17:27.00Z", modified="2016-05-12T08:17:27.0Z", name="Spear Phishing", From 59ec498fa08ee027814873629c4eec2433f40171 Mon Sep 17 00:00:00 2001 From: "Desai, Kartikey H" Date: Tue, 22 Jan 2019 12:55:19 -0500 Subject: [PATCH 20/62] Fix test cases in v20 --- stix2/test/v20/test_attack_pattern.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stix2/test/v20/test_attack_pattern.py b/stix2/test/v20/test_attack_pattern.py index caeb46e..8d35e52 100644 --- a/stix2/test/v20/test_attack_pattern.py +++ b/stix2/test/v20/test_attack_pattern.py @@ -83,7 +83,7 @@ def test_attack_pattern_invalid_labels(): def test_overly_precise_timestamps(): - ap = stix2.v21.AttackPattern( + ap = stix2.v20.AttackPattern( id=ATTACK_PATTERN_ID, created="2016-05-12T08:17:27.0000342Z", modified="2016-05-12T08:17:27.000287Z", @@ -99,7 +99,7 @@ def test_overly_precise_timestamps(): def test_less_precise_timestamps(): - ap = stix2.v21.AttackPattern( + ap = stix2.v20.AttackPattern( id=ATTACK_PATTERN_ID, created="2016-05-12T08:17:27.00Z", modified="2016-05-12T08:17:27.0Z", From 5fb69e1d44a38c5f5b4281708326eebf67aefe35 Mon Sep 17 00:00:00 2001 From: "Desai, Kartikey H" Date: Tue, 22 Jan 2019 21:25:09 -0500 Subject: [PATCH 21/62] Start updating test suites to fix issue 245 --- stix2/test/v20/test_attack_pattern.py | 6 +++--- stix2/test/v20/test_campaign.py | 13 +++---------- stix2/test/v20/test_course_of_action.py | 2 +- stix2/test/v20/test_identity.py | 4 ++-- stix2/test/v21/test_attack_pattern.py | 6 +++--- 5 files changed, 12 insertions(+), 19 deletions(-) diff --git a/stix2/test/v20/test_attack_pattern.py b/stix2/test/v20/test_attack_pattern.py index f071d3a..be291c5 100644 --- a/stix2/test/v20/test_attack_pattern.py +++ b/stix2/test/v20/test_attack_pattern.py @@ -25,7 +25,7 @@ EXPECTED = """{ def test_attack_pattern_example(): ap = stix2.v20.AttackPattern( - id="attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", + id=ATTACK_PATTERN_ID, created="2016-05-12T08:17:27.000Z", modified="2016-05-12T08:17:27.000Z", name="Spear Phishing", @@ -44,7 +44,7 @@ def test_attack_pattern_example(): EXPECTED, { "type": "attack-pattern", - "id": "attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", + "id": ATTACK_PATTERN_ID, "created": "2016-05-12T08:17:27.000Z", "modified": "2016-05-12T08:17:27.000Z", "description": "...", @@ -74,7 +74,7 @@ def test_parse_attack_pattern(data): def test_attack_pattern_invalid_labels(): with pytest.raises(stix2.exceptions.InvalidValueError): stix2.v20.AttackPattern( - id="attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", + id=ATTACK_PATTERN_ID, created="2016-05-12T08:17:27Z", modified="2016-05-12T08:17:27Z", name="Spear Phishing", diff --git a/stix2/test/v20/test_campaign.py b/stix2/test/v20/test_campaign.py index 57dbfd2..746d560 100644 --- a/stix2/test/v20/test_campaign.py +++ b/stix2/test/v20/test_campaign.py @@ -5,7 +5,7 @@ import pytz import stix2 -from .constants import CAMPAIGN_ID +from .constants import CAMPAIGN_ID, CAMPAIGN_MORE_KWARGS EXPECTED = """{ "type": "campaign", @@ -19,14 +19,7 @@ EXPECTED = """{ def test_campaign_example(): - campaign = stix2.v20.Campaign( - id="campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", - created="2016-04-06T20:03:00Z", - modified="2016-04-06T20:03:00Z", - name="Green Group Attacks Against Finance", - description="Campaign by Green Group against a series of targets in the financial services sector.", - ) + campaign = stix2.v20.Campaign(**CAMPAIGN_MORE_KWARGS) assert str(campaign) == EXPECTED @@ -36,7 +29,7 @@ def test_campaign_example(): EXPECTED, { "type": "campaign", - "id": "campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", + "id": CAMPAIGN_ID, "created": "2016-04-06T20:03:00Z", "modified": "2016-04-06T20:03:00Z", "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", diff --git a/stix2/test/v20/test_course_of_action.py b/stix2/test/v20/test_course_of_action.py index d1c0fb7..3064e26 100644 --- a/stix2/test/v20/test_course_of_action.py +++ b/stix2/test/v20/test_course_of_action.py @@ -20,7 +20,7 @@ EXPECTED = """{ def test_course_of_action_example(): coa = stix2.v20.CourseOfAction( - id="course-of-action--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", + id=COURSE_OF_ACTION_ID, created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T20:03:48.000Z", modified="2016-04-06T20:03:48.000Z", diff --git a/stix2/test/v20/test_identity.py b/stix2/test/v20/test_identity.py index 4a88a8a..750c6f2 100644 --- a/stix2/test/v20/test_identity.py +++ b/stix2/test/v20/test_identity.py @@ -19,7 +19,7 @@ EXPECTED = """{ def test_identity_example(): identity = stix2.v20.Identity( - id="identity--311b2d2d-f010-4473-83ec-1edf84858f4c", + id=IDENTITY_ID, created="2015-12-21T19:59:11.000Z", modified="2015-12-21T19:59:11.000Z", name="John Smith", @@ -34,7 +34,7 @@ def test_identity_example(): EXPECTED, { "created": "2015-12-21T19:59:11.000Z", - "id": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c", + "id": IDENTITY_ID, "identity_class": "individual", "modified": "2015-12-21T19:59:11.000Z", "name": "John Smith", diff --git a/stix2/test/v21/test_attack_pattern.py b/stix2/test/v21/test_attack_pattern.py index 9c13a12..f0e88ee 100644 --- a/stix2/test/v21/test_attack_pattern.py +++ b/stix2/test/v21/test_attack_pattern.py @@ -26,7 +26,7 @@ EXPECTED = """{ def test_attack_pattern_example(): ap = stix2.v21.AttackPattern( - id="attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", + id=ATTACK_PATTERN_ID, created="2016-05-12T08:17:27.000Z", modified="2016-05-12T08:17:27.000Z", name="Spear Phishing", @@ -46,7 +46,7 @@ def test_attack_pattern_example(): { "type": "attack-pattern", "spec_version": "2.1", - "id": "attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", + "id": ATTACK_PATTERN_ID, "created": "2016-05-12T08:17:27.000Z", "modified": "2016-05-12T08:17:27.000Z", "description": "...", @@ -77,7 +77,7 @@ def test_parse_attack_pattern(data): def test_attack_pattern_invalid_labels(): with pytest.raises(stix2.exceptions.InvalidValueError): stix2.v21.AttackPattern( - id="attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", + id=ATTACK_PATTERN_ID, created="2016-05-12T08:17:27Z", modified="2016-05-12T08:17:27Z", name="Spear Phishing", From 9941014f3a7f6448081bdf32d309eebe0e784133 Mon Sep 17 00:00:00 2001 From: "Desai, Kartikey H" Date: Tue, 22 Jan 2019 23:07:20 -0500 Subject: [PATCH 22/62] Update v20 test suite to fix issue 245 --- stix2/test/v20/constants.py | 1 + stix2/test/v20/test_bundle.py | 4 ++- stix2/test/v20/test_campaign.py | 4 +-- stix2/test/v20/test_core.py | 6 +++-- stix2/test/v20/test_course_of_action.py | 10 ++++---- stix2/test/v20/test_datastore_filters.py | 6 +++-- stix2/test/v20/test_indicator.py | 2 +- stix2/test/v20/test_intrusion_set.py | 10 ++++---- stix2/test/v20/test_malware.py | 2 +- stix2/test/v20/test_markings.py | 32 +++++++++++++----------- stix2/test/v20/test_observed_data.py | 32 ++++++++++++------------ stix2/test/v20/test_relationship.py | 12 ++++----- stix2/test/v20/test_report.py | 8 +++--- stix2/test/v20/test_sighting.py | 4 +-- stix2/test/v20/test_threat_actor.py | 18 ++++++------- stix2/test/v20/test_tool.py | 24 ++++++++---------- stix2/test/v20/test_utils.py | 4 ++- stix2/test/v20/test_vulnerability.py | 4 +-- 18 files changed, 95 insertions(+), 88 deletions(-) diff --git a/stix2/test/v20/constants.py b/stix2/test/v20/constants.py index 8d439f1..1baeb25 100644 --- a/stix2/test/v20/constants.py +++ b/stix2/test/v20/constants.py @@ -8,6 +8,7 @@ ATTACK_PATTERN_ID = "attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061" CAMPAIGN_ID = "campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f" COURSE_OF_ACTION_ID = "course-of-action--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f" IDENTITY_ID = "identity--311b2d2d-f010-4473-83ec-1edf84858f4c" +IDENTITY_ALT_ID = "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff" INDICATOR_ID = "indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7" INTRUSION_SET_ID = "intrusion-set--4e78f46f-a023-4e5f-bc24-71b3ca22ec29" MALWARE_ID = "malware--9c4638ec-f1de-4ddb-abf4-1b760417654e" diff --git a/stix2/test/v20/test_bundle.py b/stix2/test/v20/test_bundle.py index 907f632..1a135ac 100644 --- a/stix2/test/v20/test_bundle.py +++ b/stix2/test/v20/test_bundle.py @@ -4,6 +4,8 @@ import pytest import stix2 +from .constants import IDENTITY_ALT_ID + EXPECTED_BUNDLE = """{ "type": "bundle", "id": "bundle--00000000-0000-4000-8000-000000000007", @@ -185,7 +187,7 @@ def test_parse_unknown_type(): "id": "other--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", "created": "2016-04-06T20:03:00Z", "modified": "2016-04-06T20:03:00Z", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": IDENTITY_ALT_ID, "description": "Campaign by Green Group against a series of targets in the financial services sector.", "name": "Green Group Attacks Against Finance", } diff --git a/stix2/test/v20/test_campaign.py b/stix2/test/v20/test_campaign.py index 746d560..0ccfd37 100644 --- a/stix2/test/v20/test_campaign.py +++ b/stix2/test/v20/test_campaign.py @@ -5,7 +5,7 @@ import pytz import stix2 -from .constants import CAMPAIGN_ID, CAMPAIGN_MORE_KWARGS +from .constants import CAMPAIGN_ID, CAMPAIGN_MORE_KWARGS, IDENTITY_ALT_ID EXPECTED = """{ "type": "campaign", @@ -45,7 +45,7 @@ def test_parse_campaign(data): assert cmpn.id == CAMPAIGN_ID assert cmpn.created == dt.datetime(2016, 4, 6, 20, 3, 0, tzinfo=pytz.utc) assert cmpn.modified == dt.datetime(2016, 4, 6, 20, 3, 0, tzinfo=pytz.utc) - assert cmpn.created_by_ref == "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff" + assert cmpn.created_by_ref == IDENTITY_ALT_ID assert cmpn.description == "Campaign by Green Group against a series of targets in the financial services sector." assert cmpn.name == "Green Group Attacks Against Finance" diff --git a/stix2/test/v20/test_core.py b/stix2/test/v20/test_core.py index 017344f..e9ec399 100644 --- a/stix2/test/v20/test_core.py +++ b/stix2/test/v20/test_core.py @@ -3,6 +3,8 @@ import pytest import stix2 from stix2 import core, exceptions +from .constants import IDENTITY_ALT_ID + BUNDLE = { "type": "bundle", "spec_version": "2.0", @@ -96,7 +98,7 @@ def test_register_marking_with_no_version(): def test_register_observable_with_version(): observed_data = stix2.v20.ObservedData( id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ALT_ID, created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", @@ -134,7 +136,7 @@ def test_register_observable_with_version(): def test_register_observable_extension_with_version(): observed_data = stix2.v20.ObservedData( id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ALT_ID, created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", diff --git a/stix2/test/v20/test_course_of_action.py b/stix2/test/v20/test_course_of_action.py index 3064e26..b247fe2 100644 --- a/stix2/test/v20/test_course_of_action.py +++ b/stix2/test/v20/test_course_of_action.py @@ -5,7 +5,7 @@ import pytz import stix2 -from .constants import COURSE_OF_ACTION_ID +from .constants import COURSE_OF_ACTION_ID, IDENTITY_ALT_ID EXPECTED = """{ "type": "course-of-action", @@ -21,7 +21,7 @@ EXPECTED = """{ def test_course_of_action_example(): coa = stix2.v20.CourseOfAction( id=COURSE_OF_ACTION_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ALT_ID, created="2016-04-06T20:03:48.000Z", modified="2016-04-06T20:03:48.000Z", name="Add TCP port 80 Filter Rule to the existing Block UDP 1434 Filter", @@ -36,9 +36,9 @@ def test_course_of_action_example(): EXPECTED, { "created": "2016-04-06T20:03:48.000Z", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": IDENTITY_ALT_ID, "description": "This is how to add a filter rule to block inbound access to TCP port 80 to the existing UDP 1434 filter ...", - "id": "course-of-action--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", + "id": COURSE_OF_ACTION_ID, "modified": "2016-04-06T20:03:48.000Z", "name": "Add TCP port 80 Filter Rule to the existing Block UDP 1434 Filter", "type": "course-of-action", @@ -52,7 +52,7 @@ def test_parse_course_of_action(data): assert coa.id == COURSE_OF_ACTION_ID assert coa.created == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) assert coa.modified == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) - assert coa.created_by_ref == "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff" + assert coa.created_by_ref == IDENTITY_ALT_ID assert coa.description == "This is how to add a filter rule to block inbound access to TCP port 80 to the existing UDP 1434 filter ..." assert coa.name == "Add TCP port 80 Filter Rule to the existing Block UDP 1434 Filter" diff --git a/stix2/test/v20/test_datastore_filters.py b/stix2/test/v20/test_datastore_filters.py index c5d26c1..415109a 100644 --- a/stix2/test/v20/test_datastore_filters.py +++ b/stix2/test/v20/test_datastore_filters.py @@ -4,6 +4,8 @@ from stix2 import parse from stix2.datastore.filters import Filter, apply_common_filters from stix2.utils import STIXdatetime, parse_into_datetime +from .constants import IDENTITY_ALT_ID + stix_objs = [ { "created": "2017-01-27T13:49:53.997Z", @@ -68,7 +70,7 @@ stix_objs = [ { "type": "observed-data", "id": "observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": IDENTITY_ALT_ID, "created": "2016-04-06T19:58:16.000Z", "modified": "2016-04-06T19:58:16.000Z", "first_observed": "2015-12-21T19:00:00Z", @@ -439,7 +441,7 @@ def test_filters7(stix_objs2, real_stix_objs2): obsvd_data_obj = { "type": "observed-data", "id": "observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": IDENTITY_ALT_ID, "created": "2016-04-06T19:58:16.000Z", "modified": "2016-04-06T19:58:16.000Z", "first_observed": "2015-12-21T19:00:00Z", diff --git a/stix2/test/v20/test_indicator.py b/stix2/test/v20/test_indicator.py index f8c3a91..0d062bd 100644 --- a/stix2/test/v20/test_indicator.py +++ b/stix2/test/v20/test_indicator.py @@ -153,7 +153,7 @@ def test_created_modified_time_are_identical_by_default(): EXPECTED_INDICATOR, { "type": "indicator", - "id": "indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7", + "id": INDICATOR_ID, "created": "2017-01-01T00:00:01Z", "modified": "2017-01-01T00:00:01Z", "labels": [ diff --git a/stix2/test/v20/test_intrusion_set.py b/stix2/test/v20/test_intrusion_set.py index bf4a7d5..8dbff0d 100644 --- a/stix2/test/v20/test_intrusion_set.py +++ b/stix2/test/v20/test_intrusion_set.py @@ -5,7 +5,7 @@ import pytz import stix2 -from .constants import INTRUSION_SET_ID +from .constants import IDENTITY_ALT_ID, INTRUSION_SET_ID EXPECTED = """{ "type": "intrusion-set", @@ -28,8 +28,8 @@ EXPECTED = """{ def test_intrusion_set_example(): intrusion_set = stix2.v20.IntrusionSet( - id="intrusion-set--4e78f46f-a023-4e5f-bc24-71b3ca22ec29", - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + id=INTRUSION_SET_ID, + created_by_ref=IDENTITY_ALT_ID, created="2016-04-06T20:03:48.000Z", modified="2016-04-06T20:03:48.000Z", name="Bobcat Breakin", @@ -49,14 +49,14 @@ def test_intrusion_set_example(): "Zookeeper", ], "created": "2016-04-06T20:03:48.000Z", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": IDENTITY_ALT_ID, "description": "Incidents usually feature a shared TTP of a bobcat being released...", "goals": [ "acquisition-theft", "harassment", "damage", ], - "id": "intrusion-set--4e78f46f-a023-4e5f-bc24-71b3ca22ec29", + "id": INTRUSION_SET_ID, "modified": "2016-04-06T20:03:48.000Z", "name": "Bobcat Breakin", "type": "intrusion-set", diff --git a/stix2/test/v20/test_malware.py b/stix2/test/v20/test_malware.py index 844c7d9..d0c6d7e 100644 --- a/stix2/test/v20/test_malware.py +++ b/stix2/test/v20/test_malware.py @@ -108,7 +108,7 @@ def test_invalid_kwarg_to_malware(): EXPECTED_MALWARE, { "type": "malware", - "id": "malware--9c4638ec-f1de-4ddb-abf4-1b760417654e", + "id": MALWARE_ID, "created": "2016-05-12T08:17:27.000Z", "modified": "2016-05-12T08:17:27.000Z", "labels": ["ransomware"], diff --git a/stix2/test/v20/test_markings.py b/stix2/test/v20/test_markings.py index cbf1f5b..d011959 100644 --- a/stix2/test/v20/test_markings.py +++ b/stix2/test/v20/test_markings.py @@ -6,7 +6,7 @@ import pytz import stix2 from stix2.v20 import TLP_WHITE -from .constants import MARKING_DEFINITION_ID +from .constants import CAMPAIGN_ID, MARKING_DEFINITION_ID EXPECTED_TLP_MARKING_DEFINITION = """{ "type": "marking-definition", @@ -76,7 +76,7 @@ def test_marking_def_example_with_tlp(): def test_marking_def_example_with_statement_positional_argument(): marking_definition = stix2.v20.MarkingDefinition( - id="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", + id=MARKING_DEFINITION_ID, created="2017-01-20T00:00:00.000Z", definition_type="statement", definition=stix2.v20.StatementMarking(statement="Copyright 2016, Example Corp"), @@ -88,7 +88,7 @@ def test_marking_def_example_with_statement_positional_argument(): def test_marking_def_example_with_kwargs_statement(): kwargs = dict(statement="Copyright 2016, Example Corp") marking_definition = stix2.v20.MarkingDefinition( - id="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", + id=MARKING_DEFINITION_ID, created="2017-01-20T00:00:00.000Z", definition_type="statement", definition=stix2.v20.StatementMarking(**kwargs), @@ -100,7 +100,7 @@ def test_marking_def_example_with_kwargs_statement(): def test_marking_def_invalid_type(): with pytest.raises(ValueError): stix2.v20.MarkingDefinition( - id="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", + id=MARKING_DEFINITION_ID, created="2017-01-20T00:00:00.000Z", definition_type="my-definition-type", definition=stix2.v20.StatementMarking("Copyright 2016, Example Corp"), @@ -109,10 +109,11 @@ def test_marking_def_invalid_type(): def test_campaign_with_markings_example(): campaign = stix2.v20.Campaign( - id="campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", + type='campaign', + id=CAMPAIGN_ID, created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", - created="2016-04-06T20:03:00Z", - modified="2016-04-06T20:03:00Z", + created="2016-04-06T20:03:00.000Z", + modified="2016-04-06T20:03:00.000Z", name="Green Group Attacks Against Finance", description="Campaign by Green Group against a series of targets in the financial services sector.", object_marking_refs=TLP_WHITE, @@ -122,7 +123,7 @@ def test_campaign_with_markings_example(): def test_granular_example(): granular_marking = stix2.v20.GranularMarking( - marking_ref="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", + marking_ref=MARKING_DEFINITION_ID, selectors=["abc", "abc.[23]", "abc.def", "abc.[2].efg"], ) @@ -132,7 +133,7 @@ def test_granular_example(): def test_granular_example_with_bad_selector(): with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: stix2.v20.GranularMarking( - marking_ref="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", + marking_ref=MARKING_DEFINITION_ID, selectors=["abc[0]"], # missing "." ) @@ -144,15 +145,16 @@ def test_granular_example_with_bad_selector(): def test_campaign_with_granular_markings_example(): campaign = stix2.v20.Campaign( - id="campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", + type='campaign', + id=CAMPAIGN_ID, created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", - created="2016-04-06T20:03:00Z", - modified="2016-04-06T20:03:00Z", + created="2016-04-06T20:03:00.000Z", + modified="2016-04-06T20:03:00.000Z", name="Green Group Attacks Against Finance", description="Campaign by Green Group against a series of targets in the financial services sector.", granular_markings=[ stix2.v20.GranularMarking( - marking_ref="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", + marking_ref=MARKING_DEFINITION_ID, selectors=["description"], ), ], @@ -164,7 +166,7 @@ def test_campaign_with_granular_markings_example(): "data", [ EXPECTED_TLP_MARKING_DEFINITION, { - "id": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", + "id": MARKING_DEFINITION_ID, "type": "marking-definition", "created": "2017-01-20T00:00:00Z", "definition": { @@ -258,7 +260,7 @@ def test_marking_wrong_type_construction(): def test_campaign_add_markings(): campaign = stix2.v20.Campaign( - id="campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", + id=CAMPAIGN_ID, created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T20:03:00Z", modified="2016-04-06T20:03:00Z", diff --git a/stix2/test/v20/test_observed_data.py b/stix2/test/v20/test_observed_data.py index c186361..d30a407 100644 --- a/stix2/test/v20/test_observed_data.py +++ b/stix2/test/v20/test_observed_data.py @@ -6,7 +6,7 @@ import pytz import stix2 -from .constants import OBSERVED_DATA_ID +from .constants import IDENTITY_ALT_ID, OBSERVED_DATA_ID OBJECTS_REGEX = re.compile('\"objects\": {(?:.*?)(?:(?:[^{]*?)|(?:{[^{]*?}))*}', re.DOTALL) @@ -31,8 +31,8 @@ EXPECTED = """{ def test_observed_data_example(): observed_data = stix2.v20.ObservedData( - id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + id=OBSERVED_DATA_ID, + created_by_ref=IDENTITY_ALT_ID, created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", @@ -76,8 +76,8 @@ EXPECTED_WITH_REF = """{ def test_observed_data_example_with_refs(): observed_data = stix2.v20.ObservedData( - id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + id=OBSERVED_DATA_ID, + created_by_ref=IDENTITY_ALT_ID, created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", @@ -102,8 +102,8 @@ def test_observed_data_example_with_refs(): def test_observed_data_example_with_bad_refs(): with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: stix2.v20.ObservedData( - id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + id=OBSERVED_DATA_ID, + created_by_ref=IDENTITY_ALT_ID, created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", @@ -130,8 +130,8 @@ def test_observed_data_example_with_bad_refs(): def test_observed_data_example_with_non_dictionary(): with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: stix2.v20.ObservedData( - id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + id=OBSERVED_DATA_ID, + created_by_ref=IDENTITY_ALT_ID, created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", @@ -148,8 +148,8 @@ def test_observed_data_example_with_non_dictionary(): def test_observed_data_example_with_empty_dictionary(): with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: stix2.v20.ObservedData( - id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + id=OBSERVED_DATA_ID, + created_by_ref=IDENTITY_ALT_ID, created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", @@ -168,9 +168,9 @@ def test_observed_data_example_with_empty_dictionary(): EXPECTED, { "type": "observed-data", - "id": "observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", + "id": OBSERVED_DATA_ID, "created": "2016-04-06T19:58:16.000Z", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": IDENTITY_ALT_ID, "first_observed": "2015-12-21T19:00:00Z", "last_observed": "2015-12-21T19:00:00Z", "modified": "2016-04-06T19:58:16.000Z", @@ -193,7 +193,7 @@ def test_parse_observed_data(data): assert odata.modified == dt.datetime(2016, 4, 6, 19, 58, 16, tzinfo=pytz.utc) assert odata.first_observed == dt.datetime(2015, 12, 21, 19, 0, 0, tzinfo=pytz.utc) assert odata.last_observed == dt.datetime(2015, 12, 21, 19, 0, 0, tzinfo=pytz.utc) - assert odata.created_by_ref == "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff" + assert odata.created_by_ref == IDENTITY_ALT_ID assert odata.objects["0"].type == "file" @@ -563,8 +563,8 @@ EXPECTED_PROCESS_OD = """{ def test_observed_data_with_process_example(): observed_data = stix2.v20.ObservedData( - id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + id=OBSERVED_DATA_ID, + created_by_ref=IDENTITY_ALT_ID, created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", diff --git a/stix2/test/v20/test_relationship.py b/stix2/test/v20/test_relationship.py index 4dc1de8..a0fccf4 100644 --- a/stix2/test/v20/test_relationship.py +++ b/stix2/test/v20/test_relationship.py @@ -142,12 +142,12 @@ def test_create_relationship_with_positional_args(indicator, malware): EXPECTED_RELATIONSHIP, { "created": "2016-04-06T20:06:37Z", - "id": "relationship--df7c87eb-75d2-4948-af81-9d49d246f301", + "id": RELATIONSHIP_ID, "modified": "2016-04-06T20:06:37Z", - "relationship_type": "indicates", - "source_ref": "indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7", - "target_ref": "malware--9c4638ec-f1de-4ddb-abf4-1b760417654e", "type": "relationship", + "relationship_type": "indicates", + "source_ref": INDICATOR_ID, + "target_ref": MALWARE_ID, }, ], ) @@ -159,5 +159,5 @@ def test_parse_relationship(data): assert rel.created == dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc) assert rel.modified == dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc) assert rel.relationship_type == "indicates" - assert rel.source_ref == "indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7" - assert rel.target_ref == "malware--9c4638ec-f1de-4ddb-abf4-1b760417654e" + assert rel.source_ref == INDICATOR_ID + assert rel.target_ref == MALWARE_ID diff --git a/stix2/test/v20/test_report.py b/stix2/test/v20/test_report.py index 072fc95..49fc5ac 100644 --- a/stix2/test/v20/test_report.py +++ b/stix2/test/v20/test_report.py @@ -29,7 +29,7 @@ EXPECTED = """{ def test_report_example(): report = stix2.v20.Report( - id="report--84e4d88f-44ea-4bcd-bbf3-b2c1c320bcb3", + id=REPORT_ID, created_by_ref="identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283", created="2015-12-21T19:59:11.000Z", modified="2015-12-21T19:59:11.000Z", @@ -49,7 +49,7 @@ def test_report_example(): def test_report_example_objects_in_object_refs(): report = stix2.v20.Report( - id="report--84e4d88f-44ea-4bcd-bbf3-b2c1c320bcb3", + id=REPORT_ID, created_by_ref="identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283", created="2015-12-21T19:59:11.000Z", modified="2015-12-21T19:59:11.000Z", @@ -70,7 +70,7 @@ def test_report_example_objects_in_object_refs(): def test_report_example_objects_in_object_refs_with_bad_id(): with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: stix2.v20.Report( - id="report--84e4d88f-44ea-4bcd-bbf3-b2c1c320bcb3", + id=REPORT_ID, created_by_ref="identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283", created="2015-12-21T19:59:11.000Z", modified="2015-12-21T19:59:11.000Z", @@ -98,7 +98,7 @@ def test_report_example_objects_in_object_refs_with_bad_id(): "created": "2015-12-21T19:59:11.000Z", "created_by_ref": "identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283", "description": "A simple report with an indicator and campaign", - "id": "report--84e4d88f-44ea-4bcd-bbf3-b2c1c320bcb3", + "id": REPORT_ID, "labels": [ "campaign", ], diff --git a/stix2/test/v20/test_sighting.py b/stix2/test/v20/test_sighting.py index e93ca7e..e0c9b3b 100644 --- a/stix2/test/v20/test_sighting.py +++ b/stix2/test/v20/test_sighting.py @@ -94,7 +94,7 @@ def test_create_sighting_from_objects_rather_than_ids(malware): # noqa: F811 EXPECTED_SIGHTING, { "created": "2016-04-06T20:06:37Z", - "id": "sighting--bfbc19db-ec35-4e45-beed-f8bde2a772fb", + "id": SIGHTING_ID, "modified": "2016-04-06T20:06:37Z", "sighting_of_ref": "indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7", "type": "sighting", @@ -111,5 +111,5 @@ def test_parse_sighting(data): assert sighting.id == SIGHTING_ID assert sighting.created == dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc) assert sighting.modified == dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc) - assert sighting.sighting_of_ref == "indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7" + assert sighting.sighting_of_ref == INDICATOR_ID assert sighting.where_sighted_refs == ["identity--8cc7afd6-5455-4d2b-a736-e614ee631d99"] diff --git a/stix2/test/v20/test_threat_actor.py b/stix2/test/v20/test_threat_actor.py index f7ef843..d8b73fc 100644 --- a/stix2/test/v20/test_threat_actor.py +++ b/stix2/test/v20/test_threat_actor.py @@ -5,7 +5,7 @@ import pytz import stix2 -from .constants import THREAT_ACTOR_ID +from .constants import IDENTITY_ALT_ID, THREAT_ACTOR_ID EXPECTED = """{ "type": "threat-actor", @@ -23,13 +23,13 @@ EXPECTED = """{ def test_threat_actor_example(): threat_actor = stix2.v20.ThreatActor( - id="threat-actor--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + id=THREAT_ACTOR_ID, + created_by_ref=IDENTITY_ALT_ID, created="2016-04-06T20:03:48.000Z", modified="2016-04-06T20:03:48.000Z", - name="Evil Org", description="The Evil Org threat actor group", labels=["crime-syndicate"], + name="Evil Org", ) assert str(threat_actor) == EXPECTED @@ -40,13 +40,11 @@ def test_threat_actor_example(): EXPECTED, { "created": "2016-04-06T20:03:48.000Z", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": IDENTITY_ALT_ID, "description": "The Evil Org threat actor group", - "id": "threat-actor--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", - "labels": [ - "crime-syndicate", - ], + "id": THREAT_ACTOR_ID, "modified": "2016-04-06T20:03:48.000Z", + "labels": ["crime-syndicate"], "name": "Evil Org", "type": "threat-actor", }, @@ -59,7 +57,7 @@ def test_parse_threat_actor(data): assert actor.id == THREAT_ACTOR_ID assert actor.created == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) assert actor.modified == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) - assert actor.created_by_ref == "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff" + assert actor.created_by_ref == IDENTITY_ALT_ID assert actor.description == "The Evil Org threat actor group" assert actor.name == "Evil Org" assert actor.labels == ["crime-syndicate"] diff --git a/stix2/test/v20/test_tool.py b/stix2/test/v20/test_tool.py index e0c7082..be44a32 100644 --- a/stix2/test/v20/test_tool.py +++ b/stix2/test/v20/test_tool.py @@ -5,7 +5,7 @@ import pytz import stix2 -from .constants import TOOL_ID +from .constants import IDENTITY_ALT_ID, TOOL_ID EXPECTED = """{ "type": "tool", @@ -35,12 +35,12 @@ EXPECTED_WITH_REVOKED = """{ def test_tool_example(): tool = stix2.v20.Tool( - id="tool--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + id=TOOL_ID, + created_by_ref=IDENTITY_ALT_ID, created="2016-04-06T20:03:48.000Z", modified="2016-04-06T20:03:48.000Z", - name="VNC", labels=["remote-access"], + name="VNC", ) assert str(tool) == EXPECTED @@ -51,12 +51,10 @@ def test_tool_example(): EXPECTED, { "created": "2016-04-06T20:03:48Z", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", - "id": "tool--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", - "labels": [ - "remote-access", - ], + "created_by_ref": IDENTITY_ALT_ID, + "id": TOOL_ID, "modified": "2016-04-06T20:03:48Z", + "labels": ["remote-access"], "name": "VNC", "type": "tool", }, @@ -69,7 +67,7 @@ def test_parse_tool(data): assert tool.id == TOOL_ID assert tool.created == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) assert tool.modified == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) - assert tool.created_by_ref == "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff" + assert tool.created_by_ref == IDENTITY_ALT_ID assert tool.labels == ["remote-access"] assert tool.name == "VNC" @@ -82,12 +80,12 @@ def test_tool_no_workbench_wrappers(): def test_tool_serialize_with_defaults(): tool = stix2.v20.Tool( - id="tool--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + id=TOOL_ID, + created_by_ref=IDENTITY_ALT_ID, created="2016-04-06T20:03:48.000Z", modified="2016-04-06T20:03:48.000Z", - name="VNC", labels=["remote-access"], + name="VNC", ) assert tool.serialize(pretty=True, include_optional_defaults=True) == EXPECTED_WITH_REVOKED diff --git a/stix2/test/v20/test_utils.py b/stix2/test/v20/test_utils.py index 1aa85b1..30872d5 100644 --- a/stix2/test/v20/test_utils.py +++ b/stix2/test/v20/test_utils.py @@ -8,6 +8,8 @@ import pytz import stix2.utils +from .constants import IDENTITY_ALT_ID + amsterdam = pytz.timezone('Europe/Amsterdam') eastern = pytz.timezone('US/Eastern') @@ -123,7 +125,7 @@ def test_deduplicate(stix_objs1): ( stix2.v20.ObservedData( id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ALT_ID, created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", diff --git a/stix2/test/v20/test_vulnerability.py b/stix2/test/v20/test_vulnerability.py index 7ce05ef..5a69d82 100644 --- a/stix2/test/v20/test_vulnerability.py +++ b/stix2/test/v20/test_vulnerability.py @@ -24,7 +24,7 @@ EXPECTED = """{ def test_vulnerability_example(): vulnerability = stix2.v20.Vulnerability( - id="vulnerability--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", + id=VULNERABILITY_ID, created="2016-05-12T08:17:27.000Z", modified="2016-05-12T08:17:27.000Z", name="CVE-2016-1234", @@ -50,7 +50,7 @@ def test_vulnerability_example(): "source_name": "cve", }, ], - "id": "vulnerability--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", + "id": VULNERABILITY_ID, "modified": "2016-05-12T08:17:27Z", "name": "CVE-2016-1234", "type": "vulnerability", From cdac66c04dbec3c67709e9de8630d50bcc1c8bd9 Mon Sep 17 00:00:00 2001 From: "Desai, Kartikey H" Date: Wed, 23 Jan 2019 10:56:20 -0500 Subject: [PATCH 23/62] Update v21 test suite. Fixes #245 --- stix2/test/v20/constants.py | 1 - stix2/test/v20/test_bundle.py | 4 +--- stix2/test/v20/test_campaign.py | 4 ++-- stix2/test/v20/test_core.py | 6 ++---- stix2/test/v20/test_course_of_action.py | 8 ++++---- stix2/test/v20/test_datastore_filters.py | 6 ++---- stix2/test/v20/test_intrusion_set.py | 6 +++--- stix2/test/v20/test_observed_data.py | 18 +++++++++--------- stix2/test/v20/test_threat_actor.py | 8 ++++---- stix2/test/v20/test_tool.py | 10 +++++----- stix2/test/v20/test_utils.py | 4 +--- stix2/test/v21/test_campaign.py | 11 +++-------- stix2/test/v21/test_core.py | 6 ++++-- stix2/test/v21/test_course_of_action.py | 4 ++-- stix2/test/v21/test_custom.py | 16 ++++++++-------- stix2/test/v21/test_datastore_filters.py | 6 ++++-- stix2/test/v21/test_identity.py | 4 ++-- stix2/test/v21/test_indicator.py | 2 +- stix2/test/v21/test_intrusion_set.py | 4 ++-- stix2/test/v21/test_location.py | 24 ++++++++++++------------ stix2/test/v21/test_malware.py | 2 +- stix2/test/v21/test_markings.py | 14 +++++++------- stix2/test/v21/test_note.py | 4 ++-- stix2/test/v21/test_observed_data.py | 14 +++++++------- stix2/test/v21/test_opinion.py | 2 +- stix2/test/v21/test_relationship.py | 16 ++++++++-------- stix2/test/v21/test_report.py | 8 ++++---- stix2/test/v21/test_sighting.py | 4 ++-- stix2/test/v21/test_threat_actor.py | 4 ++-- stix2/test/v21/test_tool.py | 6 +++--- stix2/test/v21/test_vulnerability.py | 4 ++-- 31 files changed, 110 insertions(+), 120 deletions(-) diff --git a/stix2/test/v20/constants.py b/stix2/test/v20/constants.py index 1baeb25..8d439f1 100644 --- a/stix2/test/v20/constants.py +++ b/stix2/test/v20/constants.py @@ -8,7 +8,6 @@ ATTACK_PATTERN_ID = "attack-pattern--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061" CAMPAIGN_ID = "campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f" COURSE_OF_ACTION_ID = "course-of-action--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f" IDENTITY_ID = "identity--311b2d2d-f010-4473-83ec-1edf84858f4c" -IDENTITY_ALT_ID = "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff" INDICATOR_ID = "indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7" INTRUSION_SET_ID = "intrusion-set--4e78f46f-a023-4e5f-bc24-71b3ca22ec29" MALWARE_ID = "malware--9c4638ec-f1de-4ddb-abf4-1b760417654e" diff --git a/stix2/test/v20/test_bundle.py b/stix2/test/v20/test_bundle.py index 1a135ac..907f632 100644 --- a/stix2/test/v20/test_bundle.py +++ b/stix2/test/v20/test_bundle.py @@ -4,8 +4,6 @@ import pytest import stix2 -from .constants import IDENTITY_ALT_ID - EXPECTED_BUNDLE = """{ "type": "bundle", "id": "bundle--00000000-0000-4000-8000-000000000007", @@ -187,7 +185,7 @@ def test_parse_unknown_type(): "id": "other--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", "created": "2016-04-06T20:03:00Z", "modified": "2016-04-06T20:03:00Z", - "created_by_ref": IDENTITY_ALT_ID, + "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", "description": "Campaign by Green Group against a series of targets in the financial services sector.", "name": "Green Group Attacks Against Finance", } diff --git a/stix2/test/v20/test_campaign.py b/stix2/test/v20/test_campaign.py index 0ccfd37..746d560 100644 --- a/stix2/test/v20/test_campaign.py +++ b/stix2/test/v20/test_campaign.py @@ -5,7 +5,7 @@ import pytz import stix2 -from .constants import CAMPAIGN_ID, CAMPAIGN_MORE_KWARGS, IDENTITY_ALT_ID +from .constants import CAMPAIGN_ID, CAMPAIGN_MORE_KWARGS EXPECTED = """{ "type": "campaign", @@ -45,7 +45,7 @@ def test_parse_campaign(data): assert cmpn.id == CAMPAIGN_ID assert cmpn.created == dt.datetime(2016, 4, 6, 20, 3, 0, tzinfo=pytz.utc) assert cmpn.modified == dt.datetime(2016, 4, 6, 20, 3, 0, tzinfo=pytz.utc) - assert cmpn.created_by_ref == IDENTITY_ALT_ID + assert cmpn.created_by_ref == "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff" assert cmpn.description == "Campaign by Green Group against a series of targets in the financial services sector." assert cmpn.name == "Green Group Attacks Against Finance" diff --git a/stix2/test/v20/test_core.py b/stix2/test/v20/test_core.py index e9ec399..017344f 100644 --- a/stix2/test/v20/test_core.py +++ b/stix2/test/v20/test_core.py @@ -3,8 +3,6 @@ import pytest import stix2 from stix2 import core, exceptions -from .constants import IDENTITY_ALT_ID - BUNDLE = { "type": "bundle", "spec_version": "2.0", @@ -98,7 +96,7 @@ def test_register_marking_with_no_version(): def test_register_observable_with_version(): observed_data = stix2.v20.ObservedData( id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", - created_by_ref=IDENTITY_ALT_ID, + created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", @@ -136,7 +134,7 @@ def test_register_observable_with_version(): def test_register_observable_extension_with_version(): observed_data = stix2.v20.ObservedData( id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", - created_by_ref=IDENTITY_ALT_ID, + created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", diff --git a/stix2/test/v20/test_course_of_action.py b/stix2/test/v20/test_course_of_action.py index b247fe2..ee722fe 100644 --- a/stix2/test/v20/test_course_of_action.py +++ b/stix2/test/v20/test_course_of_action.py @@ -5,7 +5,7 @@ import pytz import stix2 -from .constants import COURSE_OF_ACTION_ID, IDENTITY_ALT_ID +from .constants import COURSE_OF_ACTION_ID EXPECTED = """{ "type": "course-of-action", @@ -21,7 +21,7 @@ EXPECTED = """{ def test_course_of_action_example(): coa = stix2.v20.CourseOfAction( id=COURSE_OF_ACTION_ID, - created_by_ref=IDENTITY_ALT_ID, + created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T20:03:48.000Z", modified="2016-04-06T20:03:48.000Z", name="Add TCP port 80 Filter Rule to the existing Block UDP 1434 Filter", @@ -36,7 +36,7 @@ def test_course_of_action_example(): EXPECTED, { "created": "2016-04-06T20:03:48.000Z", - "created_by_ref": IDENTITY_ALT_ID, + "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", "description": "This is how to add a filter rule to block inbound access to TCP port 80 to the existing UDP 1434 filter ...", "id": COURSE_OF_ACTION_ID, "modified": "2016-04-06T20:03:48.000Z", @@ -52,7 +52,7 @@ def test_parse_course_of_action(data): assert coa.id == COURSE_OF_ACTION_ID assert coa.created == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) assert coa.modified == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) - assert coa.created_by_ref == IDENTITY_ALT_ID + assert coa.created_by_ref == "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff" assert coa.description == "This is how to add a filter rule to block inbound access to TCP port 80 to the existing UDP 1434 filter ..." assert coa.name == "Add TCP port 80 Filter Rule to the existing Block UDP 1434 Filter" diff --git a/stix2/test/v20/test_datastore_filters.py b/stix2/test/v20/test_datastore_filters.py index 415109a..c5d26c1 100644 --- a/stix2/test/v20/test_datastore_filters.py +++ b/stix2/test/v20/test_datastore_filters.py @@ -4,8 +4,6 @@ from stix2 import parse from stix2.datastore.filters import Filter, apply_common_filters from stix2.utils import STIXdatetime, parse_into_datetime -from .constants import IDENTITY_ALT_ID - stix_objs = [ { "created": "2017-01-27T13:49:53.997Z", @@ -70,7 +68,7 @@ stix_objs = [ { "type": "observed-data", "id": "observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", - "created_by_ref": IDENTITY_ALT_ID, + "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", "created": "2016-04-06T19:58:16.000Z", "modified": "2016-04-06T19:58:16.000Z", "first_observed": "2015-12-21T19:00:00Z", @@ -441,7 +439,7 @@ def test_filters7(stix_objs2, real_stix_objs2): obsvd_data_obj = { "type": "observed-data", "id": "observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", - "created_by_ref": IDENTITY_ALT_ID, + "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", "created": "2016-04-06T19:58:16.000Z", "modified": "2016-04-06T19:58:16.000Z", "first_observed": "2015-12-21T19:00:00Z", diff --git a/stix2/test/v20/test_intrusion_set.py b/stix2/test/v20/test_intrusion_set.py index 8dbff0d..f02fbcb 100644 --- a/stix2/test/v20/test_intrusion_set.py +++ b/stix2/test/v20/test_intrusion_set.py @@ -5,7 +5,7 @@ import pytz import stix2 -from .constants import IDENTITY_ALT_ID, INTRUSION_SET_ID +from .constants import INTRUSION_SET_ID EXPECTED = """{ "type": "intrusion-set", @@ -29,7 +29,7 @@ EXPECTED = """{ def test_intrusion_set_example(): intrusion_set = stix2.v20.IntrusionSet( id=INTRUSION_SET_ID, - created_by_ref=IDENTITY_ALT_ID, + created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T20:03:48.000Z", modified="2016-04-06T20:03:48.000Z", name="Bobcat Breakin", @@ -49,7 +49,7 @@ def test_intrusion_set_example(): "Zookeeper", ], "created": "2016-04-06T20:03:48.000Z", - "created_by_ref": IDENTITY_ALT_ID, + "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", "description": "Incidents usually feature a shared TTP of a bobcat being released...", "goals": [ "acquisition-theft", diff --git a/stix2/test/v20/test_observed_data.py b/stix2/test/v20/test_observed_data.py index d30a407..223184f 100644 --- a/stix2/test/v20/test_observed_data.py +++ b/stix2/test/v20/test_observed_data.py @@ -6,7 +6,7 @@ import pytz import stix2 -from .constants import IDENTITY_ALT_ID, OBSERVED_DATA_ID +from .constants import OBSERVED_DATA_ID OBJECTS_REGEX = re.compile('\"objects\": {(?:.*?)(?:(?:[^{]*?)|(?:{[^{]*?}))*}', re.DOTALL) @@ -32,7 +32,7 @@ EXPECTED = """{ def test_observed_data_example(): observed_data = stix2.v20.ObservedData( id=OBSERVED_DATA_ID, - created_by_ref=IDENTITY_ALT_ID, + created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", @@ -77,7 +77,7 @@ EXPECTED_WITH_REF = """{ def test_observed_data_example_with_refs(): observed_data = stix2.v20.ObservedData( id=OBSERVED_DATA_ID, - created_by_ref=IDENTITY_ALT_ID, + created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", @@ -103,7 +103,7 @@ def test_observed_data_example_with_bad_refs(): with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: stix2.v20.ObservedData( id=OBSERVED_DATA_ID, - created_by_ref=IDENTITY_ALT_ID, + created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", @@ -131,7 +131,7 @@ def test_observed_data_example_with_non_dictionary(): with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: stix2.v20.ObservedData( id=OBSERVED_DATA_ID, - created_by_ref=IDENTITY_ALT_ID, + created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", @@ -149,7 +149,7 @@ def test_observed_data_example_with_empty_dictionary(): with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: stix2.v20.ObservedData( id=OBSERVED_DATA_ID, - created_by_ref=IDENTITY_ALT_ID, + created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", @@ -170,7 +170,7 @@ def test_observed_data_example_with_empty_dictionary(): "type": "observed-data", "id": OBSERVED_DATA_ID, "created": "2016-04-06T19:58:16.000Z", - "created_by_ref": IDENTITY_ALT_ID, + "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", "first_observed": "2015-12-21T19:00:00Z", "last_observed": "2015-12-21T19:00:00Z", "modified": "2016-04-06T19:58:16.000Z", @@ -193,7 +193,7 @@ def test_parse_observed_data(data): assert odata.modified == dt.datetime(2016, 4, 6, 19, 58, 16, tzinfo=pytz.utc) assert odata.first_observed == dt.datetime(2015, 12, 21, 19, 0, 0, tzinfo=pytz.utc) assert odata.last_observed == dt.datetime(2015, 12, 21, 19, 0, 0, tzinfo=pytz.utc) - assert odata.created_by_ref == IDENTITY_ALT_ID + assert odata.created_by_ref == "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff" assert odata.objects["0"].type == "file" @@ -564,7 +564,7 @@ EXPECTED_PROCESS_OD = """{ def test_observed_data_with_process_example(): observed_data = stix2.v20.ObservedData( id=OBSERVED_DATA_ID, - created_by_ref=IDENTITY_ALT_ID, + created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", diff --git a/stix2/test/v20/test_threat_actor.py b/stix2/test/v20/test_threat_actor.py index d8b73fc..20cb26e 100644 --- a/stix2/test/v20/test_threat_actor.py +++ b/stix2/test/v20/test_threat_actor.py @@ -5,7 +5,7 @@ import pytz import stix2 -from .constants import IDENTITY_ALT_ID, THREAT_ACTOR_ID +from .constants import THREAT_ACTOR_ID EXPECTED = """{ "type": "threat-actor", @@ -24,7 +24,7 @@ EXPECTED = """{ def test_threat_actor_example(): threat_actor = stix2.v20.ThreatActor( id=THREAT_ACTOR_ID, - created_by_ref=IDENTITY_ALT_ID, + created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T20:03:48.000Z", modified="2016-04-06T20:03:48.000Z", description="The Evil Org threat actor group", @@ -40,7 +40,7 @@ def test_threat_actor_example(): EXPECTED, { "created": "2016-04-06T20:03:48.000Z", - "created_by_ref": IDENTITY_ALT_ID, + "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", "description": "The Evil Org threat actor group", "id": THREAT_ACTOR_ID, "modified": "2016-04-06T20:03:48.000Z", @@ -57,7 +57,7 @@ def test_parse_threat_actor(data): assert actor.id == THREAT_ACTOR_ID assert actor.created == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) assert actor.modified == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) - assert actor.created_by_ref == IDENTITY_ALT_ID + assert actor.created_by_ref == "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff" assert actor.description == "The Evil Org threat actor group" assert actor.name == "Evil Org" assert actor.labels == ["crime-syndicate"] diff --git a/stix2/test/v20/test_tool.py b/stix2/test/v20/test_tool.py index be44a32..257b787 100644 --- a/stix2/test/v20/test_tool.py +++ b/stix2/test/v20/test_tool.py @@ -5,7 +5,7 @@ import pytz import stix2 -from .constants import IDENTITY_ALT_ID, TOOL_ID +from .constants import TOOL_ID EXPECTED = """{ "type": "tool", @@ -36,7 +36,7 @@ EXPECTED_WITH_REVOKED = """{ def test_tool_example(): tool = stix2.v20.Tool( id=TOOL_ID, - created_by_ref=IDENTITY_ALT_ID, + created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T20:03:48.000Z", modified="2016-04-06T20:03:48.000Z", labels=["remote-access"], @@ -51,7 +51,7 @@ def test_tool_example(): EXPECTED, { "created": "2016-04-06T20:03:48Z", - "created_by_ref": IDENTITY_ALT_ID, + "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", "id": TOOL_ID, "modified": "2016-04-06T20:03:48Z", "labels": ["remote-access"], @@ -67,7 +67,7 @@ def test_parse_tool(data): assert tool.id == TOOL_ID assert tool.created == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) assert tool.modified == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) - assert tool.created_by_ref == IDENTITY_ALT_ID + assert tool.created_by_ref == "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff" assert tool.labels == ["remote-access"] assert tool.name == "VNC" @@ -81,7 +81,7 @@ def test_tool_no_workbench_wrappers(): def test_tool_serialize_with_defaults(): tool = stix2.v20.Tool( id=TOOL_ID, - created_by_ref=IDENTITY_ALT_ID, + created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T20:03:48.000Z", modified="2016-04-06T20:03:48.000Z", labels=["remote-access"], diff --git a/stix2/test/v20/test_utils.py b/stix2/test/v20/test_utils.py index 30872d5..1aa85b1 100644 --- a/stix2/test/v20/test_utils.py +++ b/stix2/test/v20/test_utils.py @@ -8,8 +8,6 @@ import pytz import stix2.utils -from .constants import IDENTITY_ALT_ID - amsterdam = pytz.timezone('Europe/Amsterdam') eastern = pytz.timezone('US/Eastern') @@ -125,7 +123,7 @@ def test_deduplicate(stix_objs1): ( stix2.v20.ObservedData( id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", - created_by_ref=IDENTITY_ALT_ID, + created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", diff --git a/stix2/test/v21/test_campaign.py b/stix2/test/v21/test_campaign.py index ad7e753..e4c1707 100644 --- a/stix2/test/v21/test_campaign.py +++ b/stix2/test/v21/test_campaign.py @@ -5,7 +5,7 @@ import pytz import stix2 -from .constants import CAMPAIGN_ID +from .constants import CAMPAIGN_ID, CAMPAIGN_MORE_KWARGS EXPECTED = """{ "type": "campaign", @@ -21,12 +21,7 @@ EXPECTED = """{ def test_campaign_example(): campaign = stix2.v21.Campaign( - id="campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", - created="2016-04-06T20:03:00Z", - modified="2016-04-06T20:03:00Z", - name="Green Group Attacks Against Finance", - description="Campaign by Green Group against a series of targets in the financial services sector.", + **CAMPAIGN_MORE_KWARGS ) assert str(campaign) == EXPECTED @@ -38,7 +33,7 @@ def test_campaign_example(): { "type": "campaign", "spec_version": "2.1", - "id": "campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", + "id": CAMPAIGN_ID, "created": "2016-04-06T20:03:00Z", "modified": "2016-04-06T20:03:00Z", "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", diff --git a/stix2/test/v21/test_core.py b/stix2/test/v21/test_core.py index 19aa275..c90592b 100644 --- a/stix2/test/v21/test_core.py +++ b/stix2/test/v21/test_core.py @@ -3,6 +3,8 @@ import pytest import stix2 from stix2 import core, exceptions +from .constants import OBSERVED_DATA_ID + BUNDLE = { "type": "bundle", "id": "bundle--00000000-0000-4000-8000-000000000007", @@ -98,7 +100,7 @@ def test_register_marking_with_no_version(): def test_register_observable_with_default_version(): observed_data = stix2.v21.ObservedData( - id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", + id=OBSERVED_DATA_ID, created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", @@ -136,7 +138,7 @@ def test_register_observable_with_default_version(): def test_register_observable_extension_with_default_version(): observed_data = stix2.v21.ObservedData( - id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", + id=OBSERVED_DATA_ID, created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", diff --git a/stix2/test/v21/test_course_of_action.py b/stix2/test/v21/test_course_of_action.py index 73e8eca..c27b20d 100644 --- a/stix2/test/v21/test_course_of_action.py +++ b/stix2/test/v21/test_course_of_action.py @@ -21,7 +21,7 @@ EXPECTED = """{ def test_course_of_action_example(): coa = stix2.v21.CourseOfAction( - id="course-of-action--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", + id=COURSE_OF_ACTION_ID, created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T20:03:48.000Z", modified="2016-04-06T20:03:48.000Z", @@ -39,7 +39,7 @@ def test_course_of_action_example(): "created": "2016-04-06T20:03:48.000Z", "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", "description": "This is how to add a filter rule to block inbound access to TCP port 80 to the existing UDP 1434 filter ...", - "id": "course-of-action--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", + "id": COURSE_OF_ACTION_ID, "modified": "2016-04-06T20:03:48.000Z", "name": "Add TCP port 80 Filter Rule to the existing Block UDP 1434 Filter", "spec_version": "2.1", diff --git a/stix2/test/v21/test_custom.py b/stix2/test/v21/test_custom.py index 295520e..6e1e585 100644 --- a/stix2/test/v21/test_custom.py +++ b/stix2/test/v21/test_custom.py @@ -3,7 +3,7 @@ import pytest import stix2 import stix2.base -from .constants import FAKE_TIME, MARKING_DEFINITION_ID +from .constants import FAKE_TIME, IDENTITY_ID, MARKING_DEFINITION_ID IDENTITY_CUSTOM_PROP = stix2.v21.Identity( name="John Smith", @@ -16,7 +16,7 @@ IDENTITY_CUSTOM_PROP = stix2.v21.Identity( def test_identity_custom_property(): with pytest.raises(ValueError) as excinfo: stix2.v21.Identity( - id="identity--311b2d2d-f010-4473-83ec-1edf84858f4c", + id=IDENTITY_ID, created="2015-12-21T19:59:11Z", modified="2015-12-21T19:59:11Z", name="John Smith", @@ -27,7 +27,7 @@ def test_identity_custom_property(): with pytest.raises(stix2.exceptions.ExtraPropertiesError) as excinfo: stix2.v21.Identity( - id="identity--311b2d2d-f010-4473-83ec-1edf84858f4c", + id=IDENTITY_ID, created="2015-12-21T19:59:11Z", modified="2015-12-21T19:59:11Z", name="John Smith", @@ -40,7 +40,7 @@ def test_identity_custom_property(): assert "Unexpected properties for Identity" in str(excinfo.value) identity = stix2.v21.Identity( - id="identity--311b2d2d-f010-4473-83ec-1edf84858f4c", + id=IDENTITY_ID, created="2015-12-21T19:59:11Z", modified="2015-12-21T19:59:11Z", name="John Smith", @@ -55,7 +55,7 @@ def test_identity_custom_property(): def test_identity_custom_property_invalid(): with pytest.raises(stix2.exceptions.ExtraPropertiesError) as excinfo: stix2.v21.Identity( - id="identity--311b2d2d-f010-4473-83ec-1edf84858f4c", + id=IDENTITY_ID, created="2015-12-21T19:59:11Z", modified="2015-12-21T19:59:11Z", name="John Smith", @@ -69,7 +69,7 @@ def test_identity_custom_property_invalid(): def test_identity_custom_property_allowed(): identity = stix2.v21.Identity( - id="identity--311b2d2d-f010-4473-83ec-1edf84858f4c", + id=IDENTITY_ID, created="2015-12-21T19:59:11Z", modified="2015-12-21T19:59:11Z", name="John Smith", @@ -130,7 +130,7 @@ def test_custom_property_dict_in_bundled_object(): custom_identity = { 'type': 'identity', 'spec_version': '2.1', - 'id': 'identity--311b2d2d-f010-4473-83ec-1edf84858f4c', + 'id': IDENTITY_ID, 'created': '2015-12-21T19:59:11Z', 'name': 'John Smith', 'identity_class': 'individual', @@ -148,7 +148,7 @@ def test_custom_properties_dict_in_bundled_object(): custom_identity = { 'type': 'identity', 'spec_version': '2.1', - 'id': 'identity--311b2d2d-f010-4473-83ec-1edf84858f4c', + 'id': IDENTITY_ID, 'created': '2015-12-21T19:59:11Z', 'name': 'John Smith', 'identity_class': 'individual', diff --git a/stix2/test/v21/test_datastore_filters.py b/stix2/test/v21/test_datastore_filters.py index 466d304..4b9878a 100644 --- a/stix2/test/v21/test_datastore_filters.py +++ b/stix2/test/v21/test_datastore_filters.py @@ -4,6 +4,8 @@ from stix2 import parse from stix2.datastore.filters import Filter, apply_common_filters from stix2.utils import STIXdatetime, parse_into_datetime +from .constants import OBSERVED_DATA_ID + stix_objs = [ { "created": "2017-01-27T13:49:53.997Z", @@ -72,7 +74,7 @@ stix_objs = [ { "type": "observed-data", "spec_version": "2.1", - "id": "observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", + "id": OBSERVED_DATA_ID, "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", "created": "2016-04-06T19:58:16.000Z", "modified": "2016-04-06T19:58:16.000Z", @@ -444,7 +446,7 @@ def test_filters7(stix_objs2, real_stix_objs2): obsvd_data_obj = { "type": "observed-data", "spec_version": "2.1", - "id": "observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", + "id": OBSERVED_DATA_ID, "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", "created": "2016-04-06T19:58:16.000Z", "modified": "2016-04-06T19:58:16.000Z", diff --git a/stix2/test/v21/test_identity.py b/stix2/test/v21/test_identity.py index da99de4..9d17723 100644 --- a/stix2/test/v21/test_identity.py +++ b/stix2/test/v21/test_identity.py @@ -20,7 +20,7 @@ EXPECTED = """{ def test_identity_example(): identity = stix2.v21.Identity( - id="identity--311b2d2d-f010-4473-83ec-1edf84858f4c", + id=IDENTITY_ID, created="2015-12-21T19:59:11.000Z", modified="2015-12-21T19:59:11.000Z", name="John Smith", @@ -35,7 +35,7 @@ def test_identity_example(): EXPECTED, { "created": "2015-12-21T19:59:11.000Z", - "id": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c", + "id": IDENTITY_ID, "identity_class": "individual", "modified": "2015-12-21T19:59:11.000Z", "name": "John Smith", diff --git a/stix2/test/v21/test_indicator.py b/stix2/test/v21/test_indicator.py index 628bdff..fe8f0ce 100644 --- a/stix2/test/v21/test_indicator.py +++ b/stix2/test/v21/test_indicator.py @@ -157,7 +157,7 @@ def test_created_modified_time_are_identical_by_default(): EXPECTED_INDICATOR, { "type": "indicator", - "id": "indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7", + "id": INDICATOR_ID, "created": "2017-01-01T00:00:01Z", "modified": "2017-01-01T00:00:01Z", "indicator_types": [ diff --git a/stix2/test/v21/test_intrusion_set.py b/stix2/test/v21/test_intrusion_set.py index d87780c..f8d5dc2 100644 --- a/stix2/test/v21/test_intrusion_set.py +++ b/stix2/test/v21/test_intrusion_set.py @@ -29,7 +29,7 @@ EXPECTED = """{ def test_intrusion_set_example(): intrusion_set = stix2.v21.IntrusionSet( - id="intrusion-set--4e78f46f-a023-4e5f-bc24-71b3ca22ec29", + id=INTRUSION_SET_ID, created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T20:03:48.000Z", modified="2016-04-06T20:03:48.000Z", @@ -57,7 +57,7 @@ def test_intrusion_set_example(): "harassment", "damage", ], - "id": "intrusion-set--4e78f46f-a023-4e5f-bc24-71b3ca22ec29", + "id": INTRUSION_SET_ID, "modified": "2016-04-06T20:03:48.000Z", "name": "Bobcat Breakin", "spec_version": "2.1", diff --git a/stix2/test/v21/test_location.py b/stix2/test/v21/test_location.py index 62fd9e0..5a4e17a 100644 --- a/stix2/test/v21/test_location.py +++ b/stix2/test/v21/test_location.py @@ -69,7 +69,7 @@ def test_location_with_some_required_properties(): { "type": "location", "spec_version": "2.1", - "id": "location--a6e9345f-5a15-4c29-8bb3-7dcc5d168d64", + "id": LOCATION_ID, "created": "2016-04-06T20:03:00.000Z", "modified": "2016-04-06T20:03:00.000Z", "region": "north-america", @@ -94,7 +94,7 @@ def test_parse_location(data): { "type": "location", "spec_version": "2.1", - "id": "location--a6e9345f-5a15-4c29-8bb3-7dcc5d168d64", + "id": LOCATION_ID, "created": "2016-04-06T20:03:00.000Z", "modified": "2016-04-06T20:03:00.000Z", "latitude": 90.01, @@ -103,7 +103,7 @@ def test_parse_location(data): { "type": "location", "spec_version": "2.1", - "id": "location--a6e9345f-5a15-4c29-8bb3-7dcc5d168d64", + "id": LOCATION_ID, "created": "2016-04-06T20:03:00.000Z", "modified": "2016-04-06T20:03:00.000Z", "latitude": -90.1, @@ -123,7 +123,7 @@ def test_location_bad_latitude(data): { "type": "location", "spec_version": "2.1", - "id": "location--a6e9345f-5a15-4c29-8bb3-7dcc5d168d64", + "id": LOCATION_ID, "created": "2016-04-06T20:03:00.000Z", "modified": "2016-04-06T20:03:00.000Z", "latitude": 80, @@ -132,7 +132,7 @@ def test_location_bad_latitude(data): { "type": "location", "spec_version": "2.1", - "id": "location--a6e9345f-5a15-4c29-8bb3-7dcc5d168d64", + "id": LOCATION_ID, "created": "2016-04-06T20:03:00.000Z", "modified": "2016-04-06T20:03:00.000Z", "latitude": 80, @@ -152,7 +152,7 @@ def test_location_bad_longitude(data): { "type": "location", "spec_version": "2.1", - "id": "location--a6e9345f-5a15-4c29-8bb3-7dcc5d168d64", + "id": LOCATION_ID, "created": "2016-04-06T20:03:00.000Z", "modified": "2016-04-06T20:03:00.000Z", "longitude": 175.7, @@ -161,7 +161,7 @@ def test_location_bad_longitude(data): { "type": "location", "spec_version": "2.1", - "id": "location--a6e9345f-5a15-4c29-8bb3-7dcc5d168d64", + "id": LOCATION_ID, "created": "2016-04-06T20:03:00.000Z", "modified": "2016-04-06T20:03:00.000Z", "latitude": 80, @@ -181,7 +181,7 @@ def test_location_properties_missing_when_precision_is_present(data): { "type": "location", "spec_version": "2.1", - "id": "location--a6e9345f-5a15-4c29-8bb3-7dcc5d168d64", + "id": LOCATION_ID, "created": "2016-04-06T20:03:00.000Z", "modified": "2016-04-06T20:03:00.000Z", "latitude": 18.468842, @@ -203,7 +203,7 @@ def test_location_negative_precision(data): { "type": "location", "spec_version": "2.1", - "id": "location--a6e9345f-5a15-4c29-8bb3-7dcc5d168d64", + "id": LOCATION_ID, "created": "2016-04-06T20:03:00.000Z", "modified": "2016-04-06T20:03:00.000Z", "latitude": 18.468842, @@ -215,7 +215,7 @@ def test_location_negative_precision(data): { "type": "location", "spec_version": "2.1", - "id": "location--a6e9345f-5a15-4c29-8bb3-7dcc5d168d64", + "id": LOCATION_ID, "created": "2016-04-06T20:03:00.000Z", "modified": "2016-04-06T20:03:00.000Z", "longitude": 160.7, @@ -238,7 +238,7 @@ def test_location_latitude_dependency_missing(data, msg): { "type": "location", "spec_version": "2.1", - "id": "location--a6e9345f-5a15-4c29-8bb3-7dcc5d168d64", + "id": LOCATION_ID, "created": "2016-04-06T20:03:00.000Z", "modified": "2016-04-06T20:03:00.000Z", "latitude": 18.468842, @@ -249,7 +249,7 @@ def test_location_latitude_dependency_missing(data, msg): { "type": "location", "spec_version": "2.1", - "id": "location--a6e9345f-5a15-4c29-8bb3-7dcc5d168d64", + "id": LOCATION_ID, "created": "2016-04-06T20:03:00.000Z", "modified": "2016-04-06T20:03:00.000Z", "longitude": 160.7, diff --git a/stix2/test/v21/test_malware.py b/stix2/test/v21/test_malware.py index 3ae96d9..c55bfa9 100644 --- a/stix2/test/v21/test_malware.py +++ b/stix2/test/v21/test_malware.py @@ -110,7 +110,7 @@ def test_invalid_kwarg_to_malware(): { "type": "malware", "spec_version": "2.1", - "id": "malware--9c4638ec-f1de-4ddb-abf4-1b760417654e", + "id": MALWARE_ID, "created": "2016-05-12T08:17:27.000Z", "modified": "2016-05-12T08:17:27.000Z", "malware_types": ["ransomware"], diff --git a/stix2/test/v21/test_markings.py b/stix2/test/v21/test_markings.py index 7782236..11b6a95 100644 --- a/stix2/test/v21/test_markings.py +++ b/stix2/test/v21/test_markings.py @@ -80,7 +80,7 @@ def test_marking_def_example_with_tlp(): def test_marking_def_example_with_statement_positional_argument(): marking_definition = stix2.v21.MarkingDefinition( - id="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", + id=MARKING_DEFINITION_ID, created="2017-01-20T00:00:00.000Z", definition_type="statement", definition=stix2.StatementMarking(statement="Copyright 2016, Example Corp"), @@ -92,7 +92,7 @@ def test_marking_def_example_with_statement_positional_argument(): def test_marking_def_example_with_kwargs_statement(): kwargs = dict(statement="Copyright 2016, Example Corp") marking_definition = stix2.v21.MarkingDefinition( - id="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", + id=MARKING_DEFINITION_ID, created="2017-01-20T00:00:00.000Z", definition_type="statement", definition=stix2.StatementMarking(**kwargs), @@ -104,7 +104,7 @@ def test_marking_def_example_with_kwargs_statement(): def test_marking_def_invalid_type(): with pytest.raises(ValueError): stix2.v21.MarkingDefinition( - id="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", + id=MARKING_DEFINITION_ID, created="2017-01-20T00:00:00.000Z", definition_type="my-definition-type", definition=stix2.StatementMarking("Copyright 2016, Example Corp"), @@ -126,7 +126,7 @@ def test_campaign_with_markings_example(): def test_granular_example(): granular_marking = stix2.v21.GranularMarking( - marking_ref="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", + marking_ref=MARKING_DEFINITION_ID, selectors=["abc", "abc.[23]", "abc.def", "abc.[2].efg"], ) @@ -136,7 +136,7 @@ def test_granular_example(): def test_granular_example_with_bad_selector(): with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: stix2.v21.GranularMarking( - marking_ref="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", + marking_ref=MARKING_DEFINITION_ID, selectors=["abc[0]"], # missing "." ) @@ -156,7 +156,7 @@ def test_campaign_with_granular_markings_example(): description="Campaign by Green Group against a series of targets in the financial services sector.", granular_markings=[ stix2.v21.GranularMarking( - marking_ref="marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", + marking_ref=MARKING_DEFINITION_ID, selectors=["description"], ), ], @@ -168,7 +168,7 @@ def test_campaign_with_granular_markings_example(): "data", [ EXPECTED_TLP_MARKING_DEFINITION, { - "id": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", + "id": MARKING_DEFINITION_ID, "spec_version": "2.1", "type": "marking-definition", "created": "2017-01-20T00:00:00Z", diff --git a/stix2/test/v21/test_note.py b/stix2/test/v21/test_note.py index a9807e8..47a191e 100644 --- a/stix2/test/v21/test_note.py +++ b/stix2/test/v21/test_note.py @@ -84,7 +84,7 @@ def test_note_with_required_properties(): { "type": "note", "spec_version": "2.1", - "id": "note--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", + "id": NOTE_ID, "created": "2016-05-12T08:17:27.000Z", "modified": "2016-05-12T08:17:27.000Z", "abstract": "Tracking Team Note#1", @@ -93,7 +93,7 @@ def test_note_with_required_properties(): "John Doe", ], "object_refs": [ - "campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", + CAMPAIGN_ID, ], "external_references": [ { diff --git a/stix2/test/v21/test_observed_data.py b/stix2/test/v21/test_observed_data.py index eb811b2..3dde027 100644 --- a/stix2/test/v21/test_observed_data.py +++ b/stix2/test/v21/test_observed_data.py @@ -32,7 +32,7 @@ EXPECTED = """{ def test_observed_data_example(): observed_data = stix2.v21.ObservedData( - id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", + id=OBSERVED_DATA_ID, created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", @@ -78,7 +78,7 @@ EXPECTED_WITH_REF = """{ def test_observed_data_example_with_refs(): observed_data = stix2.v21.ObservedData( - id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", + id=OBSERVED_DATA_ID, created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", @@ -104,7 +104,7 @@ def test_observed_data_example_with_refs(): def test_observed_data_example_with_bad_refs(): with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: stix2.v21.ObservedData( - id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", + id=OBSERVED_DATA_ID, created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", @@ -132,7 +132,7 @@ def test_observed_data_example_with_bad_refs(): def test_observed_data_example_with_non_dictionary(): with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: stix2.v21.ObservedData( - id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", + id=OBSERVED_DATA_ID, created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", @@ -150,7 +150,7 @@ def test_observed_data_example_with_non_dictionary(): def test_observed_data_example_with_empty_dictionary(): with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: stix2.v21.ObservedData( - id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", + id=OBSERVED_DATA_ID, created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", @@ -171,7 +171,7 @@ def test_observed_data_example_with_empty_dictionary(): { "type": "observed-data", "spec_version": "2.1", - "id": "observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", + "id": OBSERVED_DATA_ID, "created": "2016-04-06T19:58:16.000Z", "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", "first_observed": "2015-12-21T19:00:00Z", @@ -565,7 +565,7 @@ EXPECTED_PROCESS_OD = """{ def test_observed_data_with_process_example(): observed_data = stix2.v21.ObservedData( - id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", + id=OBSERVED_DATA_ID, created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", diff --git a/stix2/test/v21/test_opinion.py b/stix2/test/v21/test_opinion.py index 79e97ca..b2f6dc0 100644 --- a/stix2/test/v21/test_opinion.py +++ b/stix2/test/v21/test_opinion.py @@ -66,7 +66,7 @@ def test_opinion_with_required_properties(): { "type": "opinion", "spec_version": "2.1", - "id": "opinion--b01efc25-77b4-4003-b18b-f6e24b5cd9f7", + "id": OPINION_ID, "created": "2016-05-12T08:17:27.000Z", "modified": "2016-05-12T08:17:27.000Z", "explanation": EXPLANATION, diff --git a/stix2/test/v21/test_relationship.py b/stix2/test/v21/test_relationship.py index 0ec3e08..386e24b 100644 --- a/stix2/test/v21/test_relationship.py +++ b/stix2/test/v21/test_relationship.py @@ -162,11 +162,11 @@ def test_create_relationship_with_positional_args(indicator, malware): EXPECTED_RELATIONSHIP, { "created": "2016-04-06T20:06:37Z", - "id": "relationship--df7c87eb-75d2-4948-af81-9d49d246f301", + "id": RELATIONSHIP_ID, "modified": "2016-04-06T20:06:37Z", "relationship_type": "indicates", - "source_ref": "indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7", - "target_ref": "malware--9c4638ec-f1de-4ddb-abf4-1b760417654e", + "source_ref": INDICATOR_ID, + "target_ref": MALWARE_ID, "spec_version": "2.1", "type": "relationship", }, @@ -181,19 +181,19 @@ def test_parse_relationship(data): assert rel.created == dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc) assert rel.modified == dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc) assert rel.relationship_type == "indicates" - assert rel.source_ref == "indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7" - assert rel.target_ref == "malware--9c4638ec-f1de-4ddb-abf4-1b760417654e" + assert rel.source_ref == INDICATOR_ID + assert rel.target_ref == MALWARE_ID @pytest.mark.parametrize( "data", [ { "created": "2016-04-06T20:06:37Z", - "id": "relationship--df7c87eb-75d2-4948-af81-9d49d246f301", + "id": RELATIONSHIP_ID, "modified": "2016-04-06T20:06:37Z", "relationship_type": "indicates", - "source_ref": "indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7", - "target_ref": "malware--9c4638ec-f1de-4ddb-abf4-1b760417654e", + "source_ref": INDICATOR_ID, + "target_ref": MALWARE_ID, "start_time": "2018-04-06T20:06:37Z", "stop_time": "2016-04-06T20:06:37Z", "spec_version": "2.1", diff --git a/stix2/test/v21/test_report.py b/stix2/test/v21/test_report.py index c9d790e..22b5fb8 100644 --- a/stix2/test/v21/test_report.py +++ b/stix2/test/v21/test_report.py @@ -30,7 +30,7 @@ EXPECTED = """{ def test_report_example(): report = stix2.v21.Report( - id="report--84e4d88f-44ea-4bcd-bbf3-b2c1c320bcb3", + id=REPORT_ID, created_by_ref="identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283", created="2015-12-21T19:59:11.000Z", modified="2015-12-21T19:59:11.000Z", @@ -50,7 +50,7 @@ def test_report_example(): def test_report_example_objects_in_object_refs(): report = stix2.v21.Report( - id="report--84e4d88f-44ea-4bcd-bbf3-b2c1c320bcb3", + id=REPORT_ID, created_by_ref="identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283", created="2015-12-21T19:59:11.000Z", modified="2015-12-21T19:59:11.000Z", @@ -71,7 +71,7 @@ def test_report_example_objects_in_object_refs(): def test_report_example_objects_in_object_refs_with_bad_id(): with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: stix2.v21.Report( - id="report--84e4d88f-44ea-4bcd-bbf3-b2c1c320bcb3", + id=REPORT_ID, created_by_ref="identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283", created="2015-12-21T19:59:11.000Z", modified="2015-12-21T19:59:11.000Z", @@ -99,7 +99,7 @@ def test_report_example_objects_in_object_refs_with_bad_id(): "created": "2015-12-21T19:59:11.000Z", "created_by_ref": "identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283", "description": "A simple report with an indicator and campaign", - "id": "report--84e4d88f-44ea-4bcd-bbf3-b2c1c320bcb3", + "id": REPORT_ID, "report_types": [ "campaign", ], diff --git a/stix2/test/v21/test_sighting.py b/stix2/test/v21/test_sighting.py index 8fcbb6d..c0fa7c3 100644 --- a/stix2/test/v21/test_sighting.py +++ b/stix2/test/v21/test_sighting.py @@ -96,7 +96,7 @@ def test_create_sighting_from_objects_rather_than_ids(malware): # noqa: F811 EXPECTED_SIGHTING, { "created": "2016-04-06T20:06:37Z", - "id": "sighting--bfbc19db-ec35-4e45-beed-f8bde2a772fb", + "id": SIGHTING_ID, "modified": "2016-04-06T20:06:37Z", "sighting_of_ref": "indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7", "spec_version": "2.1", @@ -115,5 +115,5 @@ def test_parse_sighting(data): assert sighting.id == SIGHTING_ID assert sighting.created == dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc) assert sighting.modified == dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc) - assert sighting.sighting_of_ref == "indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7" + assert sighting.sighting_of_ref == INDICATOR_ID assert sighting.where_sighted_refs == ["identity--8cc7afd6-5455-4d2b-a736-e614ee631d99"] diff --git a/stix2/test/v21/test_threat_actor.py b/stix2/test/v21/test_threat_actor.py index a7a29f8..fd4dcf7 100644 --- a/stix2/test/v21/test_threat_actor.py +++ b/stix2/test/v21/test_threat_actor.py @@ -24,7 +24,7 @@ EXPECTED = """{ def test_threat_actor_example(): threat_actor = stix2.v21.ThreatActor( - id="threat-actor--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", + id=THREAT_ACTOR_ID, created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T20:03:48.000Z", modified="2016-04-06T20:03:48.000Z", @@ -43,7 +43,7 @@ def test_threat_actor_example(): "created": "2016-04-06T20:03:48.000Z", "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", "description": "The Evil Org threat actor group", - "id": "threat-actor--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", + "id": THREAT_ACTOR_ID, "threat_actor_types": [ "crime-syndicate", ], diff --git a/stix2/test/v21/test_tool.py b/stix2/test/v21/test_tool.py index 9258a23..e0ec6b0 100644 --- a/stix2/test/v21/test_tool.py +++ b/stix2/test/v21/test_tool.py @@ -37,7 +37,7 @@ EXPECTED_WITH_REVOKED = """{ def test_tool_example(): tool = stix2.v21.Tool( - id="tool--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", + id=TOOL_ID, created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T20:03:48.000Z", modified="2016-04-06T20:03:48.000Z", @@ -54,7 +54,7 @@ def test_tool_example(): { "created": "2016-04-06T20:03:48Z", "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", - "id": "tool--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", + "id": TOOL_ID, "tool_types": [ "remote-access", ], @@ -86,7 +86,7 @@ def test_tool_no_workbench_wrappers(): def test_tool_serialize_with_defaults(): tool = stix2.v21.Tool( - id="tool--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", + id=TOOL_ID, created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", created="2016-04-06T20:03:48.000Z", modified="2016-04-06T20:03:48.000Z", diff --git a/stix2/test/v21/test_vulnerability.py b/stix2/test/v21/test_vulnerability.py index 9c618e5..ee63a0e 100644 --- a/stix2/test/v21/test_vulnerability.py +++ b/stix2/test/v21/test_vulnerability.py @@ -25,7 +25,7 @@ EXPECTED = """{ def test_vulnerability_example(): vulnerability = stix2.v21.Vulnerability( - id="vulnerability--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", + id=VULNERABILITY_ID, created="2016-05-12T08:17:27.000Z", modified="2016-05-12T08:17:27.000Z", name="CVE-2016-1234", @@ -51,7 +51,7 @@ def test_vulnerability_example(): "source_name": "cve", }, ], - "id": "vulnerability--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061", + "id": VULNERABILITY_ID, "modified": "2016-05-12T08:17:27Z", "name": "CVE-2016-1234", "spec_version": "2.1", From b4d4a582cefd32719e13de1b76de9e32d8b656b7 Mon Sep 17 00:00:00 2001 From: "Desai, Kartikey H" Date: Wed, 23 Jan 2019 13:42:25 -0500 Subject: [PATCH 24/62] Update timestamps in v20 testsuite JSON files --- .../20170531213019735010.json | 4 ++-- .../20170531213026496201.json | 4 ++-- .../20170531213029458940.json | 4 ++-- .../20170531213045139269.json | 4 ++-- .../20170531213041022897.json | 4 ++-- .../20170531213032662702.json | 4 ++-- .../20170531213026495974.json | 4 ++-- .../20170531213041022744.json | 4 ++-- .../20170601000000000000.json | 4 ++-- .../20170531213149412497.json | 4 ++-- .../20170531213153197755.json | 4 ++-- .../20170531213258226477.json | 4 ++-- .../20170531213326565056.json | 4 ++-- .../20170531213248482655.json | 4 ++-- .../20170531213215263882.json | 4 ++-- .../20170531213327182784.json | 4 ++-- .../20170531213327082801.json | 4 ++-- .../20170531213327018782.json | 4 ++-- .../20170531213327100701.json | 4 ++-- .../20170531213327143973.json | 4 ++-- .../20170531213327021562.json | 4 ++-- .../20170531213327044387.json | 4 ++-- .../20170531213327051532.json | 4 ++-- .../20170531213231601148.json | 4 ++-- .../20170531213212684914.json | 4 ++-- .../20170601000000000000.json | 4 ++-- 26 files changed, 52 insertions(+), 52 deletions(-) diff --git a/stix2/test/v20/stix2_data/attack-pattern/attack-pattern--0a3ead4e-6d47-4ccb-854c-a6a4f9d96b22/20170531213019735010.json b/stix2/test/v20/stix2_data/attack-pattern/attack-pattern--0a3ead4e-6d47-4ccb-854c-a6a4f9d96b22/20170531213019735010.json index 47dd5f8..98521dc 100644 --- a/stix2/test/v20/stix2_data/attack-pattern/attack-pattern--0a3ead4e-6d47-4ccb-854c-a6a4f9d96b22/20170531213019735010.json +++ b/stix2/test/v20/stix2_data/attack-pattern/attack-pattern--0a3ead4e-6d47-4ccb-854c-a6a4f9d96b22/20170531213019735010.json @@ -2,7 +2,7 @@ "id": "bundle--f68640b4-0cdc-42ae-b176-def1754a1ea0", "objects": [ { - "created": "2017-05-31T21:30:19.73501Z", + "created": "2017-05-31T21:30:19.735Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "Credential dumping is the process of obtaining account login and password information from the operating system and software. Credentials can be used to perform Windows Credential Editor, Mimikatz, and gsecdump. These tools are in use by both professional security testers and adversaries.\n\nPlaintext passwords can be obtained using tools such as Mimikatz to extract passwords stored by the Local Security Authority (LSA). If smart cards are used to authenticate to a domain using a personal identification number (PIN), then that PIN is also cached as a result and may be dumped.Mimikatz access the LSA Subsystem Service (LSASS) process by opening the process, locating the LSA secrets key, and decrypting the sections in memory where credential details are stored. Credential dumpers may also use methods for reflective DLL Injection to reduce potential indicators of malicious activity.\n\nNTLM hash dumpers open the Security Accounts Manager (SAM) on the local file system (%SystemRoot%/system32/config/SAM) or create a dump of the Registry SAM key to access stored account password hashes. Some hash dumpers will open the local file system as a device and parse to the SAM table to avoid file access defenses. Others will make an in-memory copy of the SAM table before reading hashes. Detection of compromised Legitimate Credentials in-use by adversaries may help as well. \n\nOn Windows 8.1 and Windows Server 2012 R2, monitor Windows Logs for LSASS.exe creation to verify that LSASS started as a protected process.\n\nMonitor processes and command-line arguments for program execution that may be indicative of credential dumping. Remote access tools may contain built-in features or incorporate existing tools like Mimikatz. PowerShell scripts also exist that contain credential dumping functionality, such as PowerSploit's Invoke-Mimikatz module,[[Citation: Powersploit]] which may require additional logging features to be configured in the operating system to collect necessary information for analysis.\n\nPlatforms: Windows Server 2003, Windows Server 2008, Windows Server 2012, Windows XP, Windows 7, Windows 8, Windows Server 2003 R2, Windows Server 2008 R2, Windows Server 2012 R2, Windows Vista, Windows 8.1\n\nData Sources: API monitoring, Process command-line parameters, Process monitoring, PowerShell logs", "external_references": [ @@ -29,7 +29,7 @@ "phase_name": "credential-access" } ], - "modified": "2017-05-31T21:30:19.73501Z", + "modified": "2017-05-31T21:30:19.735Z", "name": "Credential Dumping", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" diff --git a/stix2/test/v20/stix2_data/attack-pattern/attack-pattern--0f20e3cb-245b-4a61-8a91-2d93f7cb0e9b/20170531213026496201.json b/stix2/test/v20/stix2_data/attack-pattern/attack-pattern--0f20e3cb-245b-4a61-8a91-2d93f7cb0e9b/20170531213026496201.json index 13f900f..da4e238 100644 --- a/stix2/test/v20/stix2_data/attack-pattern/attack-pattern--0f20e3cb-245b-4a61-8a91-2d93f7cb0e9b/20170531213026496201.json +++ b/stix2/test/v20/stix2_data/attack-pattern/attack-pattern--0f20e3cb-245b-4a61-8a91-2d93f7cb0e9b/20170531213026496201.json @@ -2,7 +2,7 @@ "id": "bundle--b07d6fd6-7cc5-492d-a1eb-9ba956b329d5", "objects": [ { - "created": "2017-05-31T21:30:26.496201Z", + "created": "2017-05-31T21:30:26.496Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "Rootkits are programs that hide the existence of malware by intercepting and modifying operating system API calls that supply system information. Rootkits or rootkit enabling functionality may reside at the user or kernel level in the operating system or lower, to include a Hypervisor, Master Boot Record, or the Basic Input/Output System.[[Citation: Wikipedia Rootkit]]\n\nAdversaries may use rootkits to hide the presence of programs, files, network connections, services, drivers, and other system components.\n\nDetection: Some rootkit protections may be built into anti-virus or operating system software. There are dedicated rootkit detection tools that look for specific types of rootkit behavior. Monitor for the existence of unrecognized DLLs, devices, services, and changes to the MBR.[[Citation: Wikipedia Rootkit]]\n\nPlatforms: Windows Server 2003, Windows Server 2008, Windows Server 2012, Windows XP, Windows 7, Windows 8, Windows Server 2003 R2, Windows Server 2008 R2, Windows Server 2012 R2, Windows Vista, Windows 8.1\n\nData Sources: BIOS, MBR, System calls", "external_references": [ @@ -24,7 +24,7 @@ "phase_name": "defense-evasion" } ], - "modified": "2017-05-31T21:30:26.496201Z", + "modified": "2017-05-31T21:30:26.496Z", "name": "Rootkit", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" diff --git a/stix2/test/v20/stix2_data/attack-pattern/attack-pattern--774a3188-6ba9-4dc4-879d-d54ee48a5ce9/20170531213029458940.json b/stix2/test/v20/stix2_data/attack-pattern/attack-pattern--774a3188-6ba9-4dc4-879d-d54ee48a5ce9/20170531213029458940.json index db57e2c..1c8e76c 100644 --- a/stix2/test/v20/stix2_data/attack-pattern/attack-pattern--774a3188-6ba9-4dc4-879d-d54ee48a5ce9/20170531213029458940.json +++ b/stix2/test/v20/stix2_data/attack-pattern/attack-pattern--774a3188-6ba9-4dc4-879d-d54ee48a5ce9/20170531213029458940.json @@ -2,7 +2,7 @@ "id": "bundle--1a854c96-639e-4771-befb-e7b960a65974", "objects": [ { - "created": "2017-05-31T21:30:29.45894Z", + "created": "2017-05-31T21:30:29.458Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "Data, such as sensitive documents, may be exfiltrated through the use of automated processing or Scripting after being gathered during Exfiltration Over Command and Control Channel and Exfiltration Over Alternative Protocol.\n\nDetection: Monitor process file access patterns and network behavior. Unrecognized processes or scripts that appear to be traversing file systems and sending network traffic may be suspicious.\n\nPlatforms: Windows Server 2003, Windows Server 2008, Windows Server 2012, Windows XP, Windows 7, Windows 8, Windows Server 2003 R2, Windows Server 2008 R2, Windows Server 2012 R2, Windows Vista, Windows 8.1\n\nData Sources: File monitoring, Process monitoring, Process use of network", "external_references": [ @@ -19,7 +19,7 @@ "phase_name": "exfiltration" } ], - "modified": "2017-05-31T21:30:29.45894Z", + "modified": "2017-05-31T21:30:29.458Z", "name": "Automated Exfiltration", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" diff --git a/stix2/test/v20/stix2_data/attack-pattern/attack-pattern--7e150503-88e7-4861-866b-ff1ac82c4475/20170531213045139269.json b/stix2/test/v20/stix2_data/attack-pattern/attack-pattern--7e150503-88e7-4861-866b-ff1ac82c4475/20170531213045139269.json index d48092d..c4f2436 100644 --- a/stix2/test/v20/stix2_data/attack-pattern/attack-pattern--7e150503-88e7-4861-866b-ff1ac82c4475/20170531213045139269.json +++ b/stix2/test/v20/stix2_data/attack-pattern/attack-pattern--7e150503-88e7-4861-866b-ff1ac82c4475/20170531213045139269.json @@ -2,7 +2,7 @@ "id": "bundle--33e3e33a-38b8-4a37-9455-5b8c82d3b10a", "objects": [ { - "created": "2017-05-31T21:30:45.139269Z", + "created": "2017-05-31T21:30:45.139Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "Adversaries may attempt to get a listing of network connections to or from the compromised system.\nUtilities and commands that acquire this information include netstat, \"net use,\" and \"net session\" with Net.\n\nDetection: System and network discovery techniques normally occur throughout an operation as an adversary learns the environment. Data and events should not be viewed in isolation, but as part of a chain of behavior that could lead to other activities, such as Windows Management Instrumentation and PowerShell.\n\nPlatforms: Windows Server 2003, Windows Server 2008, Windows Server 2012, Windows XP, Windows 7, Windows 8, Windows Server 2003 R2, Windows Server 2008 R2, Windows Server 2012 R2, Windows Vista, Windows 8.1\n\nData Sources: Process command-line parameters, Process monitoring", "external_references": [ @@ -19,7 +19,7 @@ "phase_name": "discovery" } ], - "modified": "2017-05-31T21:30:45.139269Z", + "modified": "2017-05-31T21:30:45.139Z", "name": "Local Network Connections Discovery", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" diff --git a/stix2/test/v20/stix2_data/attack-pattern/attack-pattern--ae676644-d2d2-41b7-af7e-9bed1b55898c/20170531213041022897.json b/stix2/test/v20/stix2_data/attack-pattern/attack-pattern--ae676644-d2d2-41b7-af7e-9bed1b55898c/20170531213041022897.json index 031419e..1a64591 100644 --- a/stix2/test/v20/stix2_data/attack-pattern/attack-pattern--ae676644-d2d2-41b7-af7e-9bed1b55898c/20170531213041022897.json +++ b/stix2/test/v20/stix2_data/attack-pattern/attack-pattern--ae676644-d2d2-41b7-af7e-9bed1b55898c/20170531213041022897.json @@ -2,7 +2,7 @@ "id": "bundle--a87938c5-cc1e-4e06-a8a3-b10243ae397d", "objects": [ { - "created": "2017-05-31T21:30:41.022897Z", + "created": "2017-05-31T21:30:41.022Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "Sensitive data can be collected from remote systems via shared network drives (host shared directory, network file server, etc.) that are accessible from the current system prior to cmd may be used to gather information.\n\nDetection: Monitor processes and command-line arguments for actions that could be taken to collect files from a network share. Remote access tools with built-in features may interact directly with the Windows API to gather data. Data may also be acquired through Windows system management tools such as Windows Management Instrumentation and PowerShell.\n\nPlatforms: Windows Server 2003, Windows Server 2008, Windows Server 2012, Windows XP, Windows 7, Windows 8, Windows Server 2003 R2, Windows Server 2008 R2, Windows Server 2012 R2, Windows Vista, Windows 8.1\n\nData Sources: File monitoring, Process monitoring, Process command-line parameters", "external_references": [ @@ -19,7 +19,7 @@ "phase_name": "collection" } ], - "modified": "2017-05-31T21:30:41.022897Z", + "modified": "2017-05-31T21:30:41.022Z", "name": "Data from Network Shared Drive", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" diff --git a/stix2/test/v20/stix2_data/attack-pattern/attack-pattern--b3d682b6-98f2-4fb0-aa3b-b4df007ca70a/20170531213032662702.json b/stix2/test/v20/stix2_data/attack-pattern/attack-pattern--b3d682b6-98f2-4fb0-aa3b-b4df007ca70a/20170531213032662702.json index 67c380c..e968c1f 100644 --- a/stix2/test/v20/stix2_data/attack-pattern/attack-pattern--b3d682b6-98f2-4fb0-aa3b-b4df007ca70a/20170531213032662702.json +++ b/stix2/test/v20/stix2_data/attack-pattern/attack-pattern--b3d682b6-98f2-4fb0-aa3b-b4df007ca70a/20170531213032662702.json @@ -2,7 +2,7 @@ "id": "bundle--5ddaeff9-eca7-4094-9e65-4f53da21a444", "objects": [ { - "created": "2017-05-31T21:30:32.662702Z", + "created": "2017-05-31T21:30:32.662Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "Adversaries may attempt to make an executable or file difficult to discover or analyze by encrypting, encoding, or otherwise obfuscating its contents on the system.\n\nDetection: Detection of file obfuscation is difficult unless artifacts are left behind by the obfuscation process that are uniquely detectable with a signature. If detection of the obfuscation itself is not possible, it may be possible to detect the malicious activity that caused the obfuscated file (for example, the method that was used to write, read, or modify the file on the file system).\n\nPlatforms: Windows Server 2003, Windows Server 2008, Windows Server 2012, Windows XP, Windows 7, Windows 8, Windows Server 2003 R2, Windows Server 2008 R2, Windows Server 2012 R2, Windows Vista, Windows 8.1\n\nData Sources: Network protocol analysis, Process use of network, Binary file metadata, File monitoring, Malware reverse engineering", "external_references": [ @@ -19,7 +19,7 @@ "phase_name": "defense-evasion" } ], - "modified": "2017-05-31T21:30:32.662702Z", + "modified": "2017-05-31T21:30:32.662Z", "name": "Obfuscated Files or Information", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" diff --git a/stix2/test/v20/stix2_data/course-of-action/course-of-action--95ddb356-7ba0-4bd9-a889-247262b8946f/20170531213026495974.json b/stix2/test/v20/stix2_data/course-of-action/course-of-action--95ddb356-7ba0-4bd9-a889-247262b8946f/20170531213026495974.json index 541ede1..9a7e4f5 100644 --- a/stix2/test/v20/stix2_data/course-of-action/course-of-action--95ddb356-7ba0-4bd9-a889-247262b8946f/20170531213026495974.json +++ b/stix2/test/v20/stix2_data/course-of-action/course-of-action--95ddb356-7ba0-4bd9-a889-247262b8946f/20170531213026495974.json @@ -2,11 +2,11 @@ "id": "bundle--a42d26fe-c938-4074-a1b3-50d852e6f0bd", "objects": [ { - "created": "2017-05-31T21:30:26.495974Z", + "created": "2017-05-31T21:30:26.495Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "Identify potentially malicious software that may contain rootkit functionality, and audit and/or block it by using whitelisting[[CiteRef::Beechey 2010]] tools, like AppLocker,[[CiteRef::Windows Commands JPCERT]][[CiteRef::NSA MS AppLocker]] or Software Restriction Policies[[CiteRef::Corio 2008]] where appropriate.[[CiteRef::TechNet Applocker vs SRP]]", "id": "course-of-action--95ddb356-7ba0-4bd9-a889-247262b8946f", - "modified": "2017-05-31T21:30:26.495974Z", + "modified": "2017-05-31T21:30:26.495Z", "name": "Rootkit Mitigation", "type": "course-of-action" } diff --git a/stix2/test/v20/stix2_data/course-of-action/course-of-action--d9727aee-48b8-4fdb-89e2-4c49746ba4dd/20170531213041022744.json b/stix2/test/v20/stix2_data/course-of-action/course-of-action--d9727aee-48b8-4fdb-89e2-4c49746ba4dd/20170531213041022744.json index 669aae5..902cf1b 100644 --- a/stix2/test/v20/stix2_data/course-of-action/course-of-action--d9727aee-48b8-4fdb-89e2-4c49746ba4dd/20170531213041022744.json +++ b/stix2/test/v20/stix2_data/course-of-action/course-of-action--d9727aee-48b8-4fdb-89e2-4c49746ba4dd/20170531213041022744.json @@ -1,9 +1,9 @@ { - "created": "2017-05-31T21:30:41.022744Z", + "created": "2017-05-31T21:30:41.022Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "Identify unnecessary system utilities or potentially malicious software that may be used to collect data from a network share, and audit and/or block them by using whitelisting[[CiteRef::Beechey 2010]] tools, like AppLocker,[[CiteRef::Windows Commands JPCERT]][[CiteRef::NSA MS AppLocker]] or Software Restriction Policies[[CiteRef::Corio 2008]] where appropriate.[[CiteRef::TechNet Applocker vs SRP]]", "id": "course-of-action--d9727aee-48b8-4fdb-89e2-4c49746ba4dd", - "modified": "2017-05-31T21:30:41.022744Z", + "modified": "2017-05-31T21:30:41.022Z", "name": "Data from Network Shared Drive Mitigation", "type": "course-of-action" } diff --git a/stix2/test/v20/stix2_data/identity/identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5/20170601000000000000.json b/stix2/test/v20/stix2_data/identity/identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5/20170601000000000000.json index d110a09..9b86896 100644 --- a/stix2/test/v20/stix2_data/identity/identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5/20170601000000000000.json +++ b/stix2/test/v20/stix2_data/identity/identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5/20170601000000000000.json @@ -2,10 +2,10 @@ "id": "bundle--81884287-2548-47fc-a997-39489ddd5462", "objects": [ { - "created": "2017-06-01T00:00:00Z", + "created": "2017-06-01T00:00:00.000Z", "id": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "identity_class": "organization", - "modified": "2017-06-01T00:00:00Z", + "modified": "2017-06-01T00:00:00.000Z", "name": "The MITRE Corporation", "type": "identity" } diff --git a/stix2/test/v20/stix2_data/intrusion-set/intrusion-set--a653431d-6a5e-4600-8ad3-609b5af57064/20170531213149412497.json b/stix2/test/v20/stix2_data/intrusion-set/intrusion-set--a653431d-6a5e-4600-8ad3-609b5af57064/20170531213149412497.json index 648ed94..b1adad5 100644 --- a/stix2/test/v20/stix2_data/intrusion-set/intrusion-set--a653431d-6a5e-4600-8ad3-609b5af57064/20170531213149412497.json +++ b/stix2/test/v20/stix2_data/intrusion-set/intrusion-set--a653431d-6a5e-4600-8ad3-609b5af57064/20170531213149412497.json @@ -10,7 +10,7 @@ "PinkPanther", "Black Vine" ], - "created": "2017-05-31T21:31:49.412497Z", + "created": "2017-05-31T21:31:49.412Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "Deep Panda is a suspected Chinese threat group known to target many industries, including government, defense, financial, and telecommunications.Deep Panda.Deep Panda also appears to be known as Black Vine based on the attribution of both group names to the Anthem intrusion.[[Citation: Symantec Black Vine]]", "external_references": [ @@ -41,7 +41,7 @@ } ], "id": "intrusion-set--a653431d-6a5e-4600-8ad3-609b5af57064", - "modified": "2017-05-31T21:31:49.412497Z", + "modified": "2017-05-31T21:31:49.412Z", "name": "Deep Panda", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" diff --git a/stix2/test/v20/stix2_data/intrusion-set/intrusion-set--f3bdec95-3d62-42d9-a840-29630f6cdc1a/20170531213153197755.json b/stix2/test/v20/stix2_data/intrusion-set/intrusion-set--f3bdec95-3d62-42d9-a840-29630f6cdc1a/20170531213153197755.json index bf3daa6..db2e43e 100644 --- a/stix2/test/v20/stix2_data/intrusion-set/intrusion-set--f3bdec95-3d62-42d9-a840-29630f6cdc1a/20170531213153197755.json +++ b/stix2/test/v20/stix2_data/intrusion-set/intrusion-set--f3bdec95-3d62-42d9-a840-29630f6cdc1a/20170531213153197755.json @@ -5,7 +5,7 @@ "aliases": [ "DragonOK" ], - "created": "2017-05-31T21:31:53.197755Z", + "created": "2017-05-31T21:31:53.197Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "DragonOK is a threat group that has targeted Japanese organizations with phishing emails. Due to overlapping TTPs, including similar custom tools, DragonOK is thought to have a direct or indirect relationship with the threat group Moafee. [[Citation: Operation Quantum Entanglement]][[Citation: Symbiotic APT Groups]] It is known to use a variety of malware, including Sysget/HelloBridge, PlugX, PoisonIvy, FormerFirstRat, NFlog, and NewCT. [[Citation: New DragonOK]]", "external_references": [ @@ -31,7 +31,7 @@ } ], "id": "intrusion-set--f3bdec95-3d62-42d9-a840-29630f6cdc1a", - "modified": "2017-05-31T21:31:53.197755Z", + "modified": "2017-05-31T21:31:53.197Z", "name": "DragonOK", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" diff --git a/stix2/test/v20/stix2_data/malware/malware--6b616fc1-1505-48e3-8b2c-0d19337bff38/20170531213258226477.json b/stix2/test/v20/stix2_data/malware/malware--6b616fc1-1505-48e3-8b2c-0d19337bff38/20170531213258226477.json index c60200b..63f6f55 100644 --- a/stix2/test/v20/stix2_data/malware/malware--6b616fc1-1505-48e3-8b2c-0d19337bff38/20170531213258226477.json +++ b/stix2/test/v20/stix2_data/malware/malware--6b616fc1-1505-48e3-8b2c-0d19337bff38/20170531213258226477.json @@ -2,7 +2,7 @@ "id": "bundle--f64de948-7067-4534-8018-85f03d470625", "objects": [ { - "created": "2017-05-31T21:32:58.226477Z", + "created": "2017-05-31T21:32:58.226Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "Rover is malware suspected of being used for espionage purposes. It was used in 2015 in a targeted email sent to an Indian Ambassador to Afghanistan.[[Citation: Palo Alto Rover]]", "external_references": [ @@ -21,7 +21,7 @@ "labels": [ "malware" ], - "modified": "2017-05-31T21:32:58.226477Z", + "modified": "2017-05-31T21:32:58.226Z", "name": "Rover", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" diff --git a/stix2/test/v20/stix2_data/malware/malware--92ec0cbd-2c30-44a2-b270-73f4ec949841/20170531213326565056.json b/stix2/test/v20/stix2_data/malware/malware--92ec0cbd-2c30-44a2-b270-73f4ec949841/20170531213326565056.json index 50c8a5d..f354e6c 100644 --- a/stix2/test/v20/stix2_data/malware/malware--92ec0cbd-2c30-44a2-b270-73f4ec949841/20170531213326565056.json +++ b/stix2/test/v20/stix2_data/malware/malware--92ec0cbd-2c30-44a2-b270-73f4ec949841/20170531213326565056.json @@ -2,7 +2,7 @@ "id": "bundle--c633942b-545c-4c87-91b7-9fe5740365e0", "objects": [ { - "created": "2017-05-31T21:33:26.565056Z", + "created": "2017-05-31T21:33:26.565Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "RTM is custom malware written in Delphi. It is used by the group of the same name (RTM).[[Citation: ESET RTM Feb 2017]]", "external_references": [ @@ -21,7 +21,7 @@ "labels": [ "malware" ], - "modified": "2017-05-31T21:33:26.565056Z", + "modified": "2017-05-31T21:33:26.565Z", "name": "RTM", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" diff --git a/stix2/test/v20/stix2_data/malware/malware--96b08451-b27a-4ff6-893f-790e26393a8e/20170531213248482655.json b/stix2/test/v20/stix2_data/malware/malware--96b08451-b27a-4ff6-893f-790e26393a8e/20170531213248482655.json index 224f6a9..efbd6ca 100644 --- a/stix2/test/v20/stix2_data/malware/malware--96b08451-b27a-4ff6-893f-790e26393a8e/20170531213248482655.json +++ b/stix2/test/v20/stix2_data/malware/malware--96b08451-b27a-4ff6-893f-790e26393a8e/20170531213248482655.json @@ -2,7 +2,7 @@ "id": "bundle--09ce4338-8741-4fcf-9738-d216c8e40974", "objects": [ { - "created": "2017-05-31T21:32:48.482655Z", + "created": "2017-05-31T21:32:48.482Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "Sakula is a remote access tool (RAT) that first surfaced in 2012 and was used in intrusions throughout 2015.[[Citation: Dell Sakula]]\n\nAliases: Sakula, Sakurel, VIPER", "external_references": [ @@ -21,7 +21,7 @@ "labels": [ "malware" ], - "modified": "2017-05-31T21:32:48.482655Z", + "modified": "2017-05-31T21:32:48.482Z", "name": "Sakula", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" diff --git a/stix2/test/v20/stix2_data/malware/malware--b42378e0-f147-496f-992a-26a49705395b/20170531213215263882.json b/stix2/test/v20/stix2_data/malware/malware--b42378e0-f147-496f-992a-26a49705395b/20170531213215263882.json index 3e1c870..4d57db5 100644 --- a/stix2/test/v20/stix2_data/malware/malware--b42378e0-f147-496f-992a-26a49705395b/20170531213215263882.json +++ b/stix2/test/v20/stix2_data/malware/malware--b42378e0-f147-496f-992a-26a49705395b/20170531213215263882.json @@ -2,7 +2,7 @@ "id": "bundle--611947ce-ae3b-4fdb-b297-aed8eab22e4f", "objects": [ { - "created": "2017-05-31T21:32:15.263882Z", + "created": "2017-05-31T21:32:15.263Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "PoisonIvy is a popular remote access tool (RAT) that has been used by many groups.[[Citation: FireEye Poison Ivy]]\n\nAliases: PoisonIvy, Poison Ivy", "external_references": [ @@ -21,7 +21,7 @@ "labels": [ "malware" ], - "modified": "2017-05-31T21:32:15.263882Z", + "modified": "2017-05-31T21:32:15.263Z", "name": "PoisonIvy", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" diff --git a/stix2/test/v20/stix2_data/relationship/relationship--0d4a7788-7f3b-4df8-a498-31a38003c883/20170531213327182784.json b/stix2/test/v20/stix2_data/relationship/relationship--0d4a7788-7f3b-4df8-a498-31a38003c883/20170531213327182784.json index 0f4a32a..22d3fc9 100644 --- a/stix2/test/v20/stix2_data/relationship/relationship--0d4a7788-7f3b-4df8-a498-31a38003c883/20170531213327182784.json +++ b/stix2/test/v20/stix2_data/relationship/relationship--0d4a7788-7f3b-4df8-a498-31a38003c883/20170531213327182784.json @@ -2,10 +2,10 @@ "id": "bundle--7e715462-dd9d-40b9-968a-10ef0ecf126d", "objects": [ { - "created": "2017-05-31T21:33:27.182784Z", + "created": "2017-05-31T21:33:27.182Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "id": "relationship--0d4a7788-7f3b-4df8-a498-31a38003c883", - "modified": "2017-05-31T21:33:27.182784Z", + "modified": "2017-05-31T21:33:27.182Z", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], diff --git a/stix2/test/v20/stix2_data/relationship/relationship--0e55ee98-0c6d-43d4-b424-b18a0036b227/20170531213327082801.json b/stix2/test/v20/stix2_data/relationship/relationship--0e55ee98-0c6d-43d4-b424-b18a0036b227/20170531213327082801.json index e5e1e87..68a8c8f 100644 --- a/stix2/test/v20/stix2_data/relationship/relationship--0e55ee98-0c6d-43d4-b424-b18a0036b227/20170531213327082801.json +++ b/stix2/test/v20/stix2_data/relationship/relationship--0e55ee98-0c6d-43d4-b424-b18a0036b227/20170531213327082801.json @@ -2,10 +2,10 @@ "id": "bundle--a53eef35-abfc-4bcd-b84e-a048f7b4a9bf", "objects": [ { - "created": "2017-05-31T21:33:27.082801Z", + "created": "2017-05-31T21:33:27.082Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "id": "relationship--0e55ee98-0c6d-43d4-b424-b18a0036b227", - "modified": "2017-05-31T21:33:27.082801Z", + "modified": "2017-05-31T21:33:27.082Z", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], diff --git a/stix2/test/v20/stix2_data/relationship/relationship--1e91cd45-a725-4965-abe3-700694374432/20170531213327018782.json b/stix2/test/v20/stix2_data/relationship/relationship--1e91cd45-a725-4965-abe3-700694374432/20170531213327018782.json index 9651425..1d5112d 100644 --- a/stix2/test/v20/stix2_data/relationship/relationship--1e91cd45-a725-4965-abe3-700694374432/20170531213327018782.json +++ b/stix2/test/v20/stix2_data/relationship/relationship--1e91cd45-a725-4965-abe3-700694374432/20170531213327018782.json @@ -2,10 +2,10 @@ "id": "bundle--0b9f6412-314f-44e3-8779-9738c9578ef5", "objects": [ { - "created": "2017-05-31T21:33:27.018782Z", + "created": "2017-05-31T21:33:27.018Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "id": "relationship--1e91cd45-a725-4965-abe3-700694374432", - "modified": "2017-05-31T21:33:27.018782Z", + "modified": "2017-05-31T21:33:27.018Z", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], diff --git a/stix2/test/v20/stix2_data/relationship/relationship--3a3084f9-0302-4fd5-9b8a-e0db10f5345e/20170531213327100701.json b/stix2/test/v20/stix2_data/relationship/relationship--3a3084f9-0302-4fd5-9b8a-e0db10f5345e/20170531213327100701.json index 7e355fc..671f905 100644 --- a/stix2/test/v20/stix2_data/relationship/relationship--3a3084f9-0302-4fd5-9b8a-e0db10f5345e/20170531213327100701.json +++ b/stix2/test/v20/stix2_data/relationship/relationship--3a3084f9-0302-4fd5-9b8a-e0db10f5345e/20170531213327100701.json @@ -2,10 +2,10 @@ "id": "bundle--6d5b04a8-efb2-4179-990e-74f1dcc76e0c", "objects": [ { - "created": "2017-05-31T21:33:27.100701Z", + "created": "2017-05-31T21:33:27.100Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "id": "relationship--3a3084f9-0302-4fd5-9b8a-e0db10f5345e", - "modified": "2017-05-31T21:33:27.100701Z", + "modified": "2017-05-31T21:33:27.100Z", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], diff --git a/stix2/test/v20/stix2_data/relationship/relationship--3a3ed0b2-0c38-441f-ac40-53b873e545d1/20170531213327143973.json b/stix2/test/v20/stix2_data/relationship/relationship--3a3ed0b2-0c38-441f-ac40-53b873e545d1/20170531213327143973.json index f537309..5392ff8 100644 --- a/stix2/test/v20/stix2_data/relationship/relationship--3a3ed0b2-0c38-441f-ac40-53b873e545d1/20170531213327143973.json +++ b/stix2/test/v20/stix2_data/relationship/relationship--3a3ed0b2-0c38-441f-ac40-53b873e545d1/20170531213327143973.json @@ -2,10 +2,10 @@ "id": "bundle--a7efc025-040d-49c7-bf97-e5a1120ecacc", "objects": [ { - "created": "2017-05-31T21:33:27.143973Z", + "created": "2017-05-31T21:33:27.143Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "id": "relationship--3a3ed0b2-0c38-441f-ac40-53b873e545d1", - "modified": "2017-05-31T21:33:27.143973Z", + "modified": "2017-05-31T21:33:27.143Z", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], diff --git a/stix2/test/v20/stix2_data/relationship/relationship--592d0c31-e61f-495e-a60e-70d7be59a719/20170531213327021562.json b/stix2/test/v20/stix2_data/relationship/relationship--592d0c31-e61f-495e-a60e-70d7be59a719/20170531213327021562.json index 47008f0..d91e48c 100644 --- a/stix2/test/v20/stix2_data/relationship/relationship--592d0c31-e61f-495e-a60e-70d7be59a719/20170531213327021562.json +++ b/stix2/test/v20/stix2_data/relationship/relationship--592d0c31-e61f-495e-a60e-70d7be59a719/20170531213327021562.json @@ -2,10 +2,10 @@ "id": "bundle--9f013d47-7704-41c2-9749-23d0d94af94d", "objects": [ { - "created": "2017-05-31T21:33:27.021562Z", + "created": "2017-05-31T21:33:27.021Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "id": "relationship--592d0c31-e61f-495e-a60e-70d7be59a719", - "modified": "2017-05-31T21:33:27.021562Z", + "modified": "2017-05-31T21:33:27.021Z", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], diff --git a/stix2/test/v20/stix2_data/relationship/relationship--70dc6b5c-c524-429e-a6ab-0dd40f0482c1/20170531213327044387.json b/stix2/test/v20/stix2_data/relationship/relationship--70dc6b5c-c524-429e-a6ab-0dd40f0482c1/20170531213327044387.json index d697277..21cd833 100644 --- a/stix2/test/v20/stix2_data/relationship/relationship--70dc6b5c-c524-429e-a6ab-0dd40f0482c1/20170531213327044387.json +++ b/stix2/test/v20/stix2_data/relationship/relationship--70dc6b5c-c524-429e-a6ab-0dd40f0482c1/20170531213327044387.json @@ -2,10 +2,10 @@ "id": "bundle--15167b24-4cee-4c96-a140-32a6c37df4b4", "objects": [ { - "created": "2017-05-31T21:33:27.044387Z", + "created": "2017-05-31T21:33:27.044Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "id": "relationship--70dc6b5c-c524-429e-a6ab-0dd40f0482c1", - "modified": "2017-05-31T21:33:27.044387Z", + "modified": "2017-05-31T21:33:27.044Z", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], diff --git a/stix2/test/v20/stix2_data/relationship/relationship--8797579b-e3be-4209-a71b-255a4d08243d/20170531213327051532.json b/stix2/test/v20/stix2_data/relationship/relationship--8797579b-e3be-4209-a71b-255a4d08243d/20170531213327051532.json index d7f2ff7..ef0ad24 100644 --- a/stix2/test/v20/stix2_data/relationship/relationship--8797579b-e3be-4209-a71b-255a4d08243d/20170531213327051532.json +++ b/stix2/test/v20/stix2_data/relationship/relationship--8797579b-e3be-4209-a71b-255a4d08243d/20170531213327051532.json @@ -2,10 +2,10 @@ "id": "bundle--ff845dca-7036-416f-aae0-95030994c49f", "objects": [ { - "created": "2017-05-31T21:33:27.051532Z", + "created": "2017-05-31T21:33:27.051Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "id": "relationship--8797579b-e3be-4209-a71b-255a4d08243d", - "modified": "2017-05-31T21:33:27.051532Z", + "modified": "2017-05-31T21:33:27.051Z", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" ], diff --git a/stix2/test/v20/stix2_data/tool/tool--03342581-f790-4f03-ba41-e82e67392e23/20170531213231601148.json b/stix2/test/v20/stix2_data/tool/tool--03342581-f790-4f03-ba41-e82e67392e23/20170531213231601148.json index 9d47880..02df113 100644 --- a/stix2/test/v20/stix2_data/tool/tool--03342581-f790-4f03-ba41-e82e67392e23/20170531213231601148.json +++ b/stix2/test/v20/stix2_data/tool/tool--03342581-f790-4f03-ba41-e82e67392e23/20170531213231601148.json @@ -2,7 +2,7 @@ "id": "bundle--d8826afc-1561-4362-a4e3-05a4c2c3ac3c", "objects": [ { - "created": "2017-05-31T21:32:31.601148Z", + "created": "2017-05-31T21:32:31.601Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "The Net utility is a component of the Windows operating system. It is used in command-line operations for control of users, groups, services, and network connections.Net has a great deal of functionality,[[Citation: Savill 1999]] much of which is useful for an adversary, such as gathering system and network information for [[Discovery]], moving laterally through [[Windows admin shares]] using net use commands, and interacting with services.\n\nAliases: Net, net.exe", "external_references": [ @@ -26,7 +26,7 @@ "labels": [ "tool" ], - "modified": "2017-05-31T21:32:31.601148Z", + "modified": "2017-05-31T21:32:31.601Z", "name": "Net", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" diff --git a/stix2/test/v20/stix2_data/tool/tool--242f3da3-4425-4d11-8f5c-b842886da966/20170531213212684914.json b/stix2/test/v20/stix2_data/tool/tool--242f3da3-4425-4d11-8f5c-b842886da966/20170531213212684914.json index 281888e..2480a80 100644 --- a/stix2/test/v20/stix2_data/tool/tool--242f3da3-4425-4d11-8f5c-b842886da966/20170531213212684914.json +++ b/stix2/test/v20/stix2_data/tool/tool--242f3da3-4425-4d11-8f5c-b842886da966/20170531213212684914.json @@ -2,7 +2,7 @@ "id": "bundle--7dbde18f-6f14-4bf0-8389-505c89d6d5a6", "objects": [ { - "created": "2017-05-31T21:32:12.684914Z", + "created": "2017-05-31T21:32:12.684Z", "created_by_ref": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "description": "Windows Credential Editor is a password dumping tool.[[Citation: Amplia WCE]]\n\nAliases: Windows Credential Editor, WCE", "external_references": [ @@ -21,7 +21,7 @@ "labels": [ "tool" ], - "modified": "2017-05-31T21:32:12.684914Z", + "modified": "2017-05-31T21:32:12.684Z", "name": "Windows Credential Editor", "object_marking_refs": [ "marking-definition--fa42a846-8d90-4e51-bc29-71d5b4802168" diff --git a/stix2/test/v21/stix2_data/identity/identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5/20170601000000000000.json b/stix2/test/v21/stix2_data/identity/identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5/20170601000000000000.json index 368273d..e235745 100644 --- a/stix2/test/v21/stix2_data/identity/identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5/20170601000000000000.json +++ b/stix2/test/v21/stix2_data/identity/identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5/20170601000000000000.json @@ -2,10 +2,10 @@ "id": "bundle--81884287-2548-47fc-a997-39489ddd5462", "objects": [ { - "created": "2017-06-01T00:00:00Z", + "created": "2017-06-01T00:00:00.000Z", "id": "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5", "identity_class": "organization", - "modified": "2017-06-01T00:00:00Z", + "modified": "2017-06-01T00:00:00.000Z", "name": "The MITRE Corporation", "spec_version": "2.1", "type": "identity" From a788dbb64ce9f70ef16062a5242015baf11d0bd9 Mon Sep 17 00:00:00 2001 From: "Desai, Kartikey H" Date: Tue, 29 Jan 2019 10:52:59 -0500 Subject: [PATCH 25/62] Replace most SDO/SRO values in tests with IDs from constants.py --- stix2/test/v20/constants.py | 2 +- stix2/test/v20/test_bundle.py | 4 +- stix2/test/v20/test_campaign.py | 8 ++-- stix2/test/v20/test_core.py | 6 ++- stix2/test/v20/test_course_of_action.py | 10 ++--- stix2/test/v20/test_custom.py | 16 ++++---- stix2/test/v20/test_datastore_memory.py | 4 +- stix2/test/v20/test_intrusion_set.py | 8 ++-- stix2/test/v20/test_markings.py | 12 +++--- stix2/test/v20/test_observed_data.py | 24 ++++++------ stix2/test/v20/test_pickle.py | 4 +- stix2/test/v20/test_report.py | 51 +++++++++++++------------ stix2/test/v20/test_sighting.py | 10 ++--- stix2/test/v20/test_threat_actor.py | 10 ++--- stix2/test/v20/test_tool.py | 14 +++---- stix2/test/v20/test_utils.py | 4 +- stix2/test/v21/constants.py | 2 +- stix2/test/v21/test_bundle.py | 4 +- stix2/test/v21/test_campaign.py | 8 ++-- stix2/test/v21/test_core.py | 6 +-- stix2/test/v21/test_course_of_action.py | 10 ++--- stix2/test/v21/test_datastore_memory.py | 4 +- stix2/test/v21/test_intrusion_set.py | 8 ++-- stix2/test/v21/test_markings.py | 12 +++--- stix2/test/v21/test_observed_data.py | 24 ++++++------ stix2/test/v21/test_pickle.py | 4 +- stix2/test/v21/test_report.py | 51 +++++++++++++------------ stix2/test/v21/test_sighting.py | 10 ++--- stix2/test/v21/test_threat_actor.py | 10 ++--- stix2/test/v21/test_tool.py | 14 +++---- stix2/test/v21/test_utils.py | 4 +- 31 files changed, 189 insertions(+), 169 deletions(-) diff --git a/stix2/test/v20/constants.py b/stix2/test/v20/constants.py index 8d439f1..37b9da2 100644 --- a/stix2/test/v20/constants.py +++ b/stix2/test/v20/constants.py @@ -50,7 +50,7 @@ CAMPAIGN_KWARGS = dict( CAMPAIGN_MORE_KWARGS = dict( type='campaign', id=CAMPAIGN_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T20:03:00.000Z", modified="2016-04-06T20:03:00.000Z", name="Green Group Attacks Against Finance", diff --git a/stix2/test/v20/test_bundle.py b/stix2/test/v20/test_bundle.py index 907f632..72523bb 100644 --- a/stix2/test/v20/test_bundle.py +++ b/stix2/test/v20/test_bundle.py @@ -4,6 +4,8 @@ import pytest import stix2 +from .constants import IDENTITY_ID + EXPECTED_BUNDLE = """{ "type": "bundle", "id": "bundle--00000000-0000-4000-8000-000000000007", @@ -185,7 +187,7 @@ def test_parse_unknown_type(): "id": "other--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", "created": "2016-04-06T20:03:00Z", "modified": "2016-04-06T20:03:00Z", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": IDENTITY_ID, "description": "Campaign by Green Group against a series of targets in the financial services sector.", "name": "Green Group Attacks Against Finance", } diff --git a/stix2/test/v20/test_campaign.py b/stix2/test/v20/test_campaign.py index 746d560..0d4a202 100644 --- a/stix2/test/v20/test_campaign.py +++ b/stix2/test/v20/test_campaign.py @@ -5,12 +5,12 @@ import pytz import stix2 -from .constants import CAMPAIGN_ID, CAMPAIGN_MORE_KWARGS +from .constants import CAMPAIGN_ID, CAMPAIGN_MORE_KWARGS, IDENTITY_ID EXPECTED = """{ "type": "campaign", "id": "campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c", "created": "2016-04-06T20:03:00.000Z", "modified": "2016-04-06T20:03:00.000Z", "name": "Green Group Attacks Against Finance", @@ -32,7 +32,7 @@ def test_campaign_example(): "id": CAMPAIGN_ID, "created": "2016-04-06T20:03:00Z", "modified": "2016-04-06T20:03:00Z", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": IDENTITY_ID, "description": "Campaign by Green Group against a series of targets in the financial services sector.", "name": "Green Group Attacks Against Finance", }, @@ -45,7 +45,7 @@ def test_parse_campaign(data): assert cmpn.id == CAMPAIGN_ID assert cmpn.created == dt.datetime(2016, 4, 6, 20, 3, 0, tzinfo=pytz.utc) assert cmpn.modified == dt.datetime(2016, 4, 6, 20, 3, 0, tzinfo=pytz.utc) - assert cmpn.created_by_ref == "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff" + assert cmpn.created_by_ref == IDENTITY_ID assert cmpn.description == "Campaign by Green Group against a series of targets in the financial services sector." assert cmpn.name == "Green Group Attacks Against Finance" diff --git a/stix2/test/v20/test_core.py b/stix2/test/v20/test_core.py index 017344f..c2056b8 100644 --- a/stix2/test/v20/test_core.py +++ b/stix2/test/v20/test_core.py @@ -3,6 +3,8 @@ import pytest import stix2 from stix2 import core, exceptions +from .constants import IDENTITY_ID + BUNDLE = { "type": "bundle", "spec_version": "2.0", @@ -96,7 +98,7 @@ def test_register_marking_with_no_version(): def test_register_observable_with_version(): observed_data = stix2.v20.ObservedData( id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", @@ -134,7 +136,7 @@ def test_register_observable_with_version(): def test_register_observable_extension_with_version(): observed_data = stix2.v20.ObservedData( id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", diff --git a/stix2/test/v20/test_course_of_action.py b/stix2/test/v20/test_course_of_action.py index ee722fe..f648907 100644 --- a/stix2/test/v20/test_course_of_action.py +++ b/stix2/test/v20/test_course_of_action.py @@ -5,12 +5,12 @@ import pytz import stix2 -from .constants import COURSE_OF_ACTION_ID +from .constants import COURSE_OF_ACTION_ID, IDENTITY_ID EXPECTED = """{ "type": "course-of-action", "id": "course-of-action--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c", "created": "2016-04-06T20:03:48.000Z", "modified": "2016-04-06T20:03:48.000Z", "name": "Add TCP port 80 Filter Rule to the existing Block UDP 1434 Filter", @@ -21,7 +21,7 @@ EXPECTED = """{ def test_course_of_action_example(): coa = stix2.v20.CourseOfAction( id=COURSE_OF_ACTION_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T20:03:48.000Z", modified="2016-04-06T20:03:48.000Z", name="Add TCP port 80 Filter Rule to the existing Block UDP 1434 Filter", @@ -36,7 +36,7 @@ def test_course_of_action_example(): EXPECTED, { "created": "2016-04-06T20:03:48.000Z", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": IDENTITY_ID, "description": "This is how to add a filter rule to block inbound access to TCP port 80 to the existing UDP 1434 filter ...", "id": COURSE_OF_ACTION_ID, "modified": "2016-04-06T20:03:48.000Z", @@ -52,7 +52,7 @@ def test_parse_course_of_action(data): assert coa.id == COURSE_OF_ACTION_ID assert coa.created == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) assert coa.modified == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) - assert coa.created_by_ref == "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff" + assert coa.created_by_ref == IDENTITY_ID assert coa.description == "This is how to add a filter rule to block inbound access to TCP port 80 to the existing UDP 1434 filter ..." assert coa.name == "Add TCP port 80 Filter Rule to the existing Block UDP 1434 Filter" diff --git a/stix2/test/v20/test_custom.py b/stix2/test/v20/test_custom.py index 40ffa88..32632b9 100644 --- a/stix2/test/v20/test_custom.py +++ b/stix2/test/v20/test_custom.py @@ -2,7 +2,7 @@ import pytest import stix2 -from .constants import FAKE_TIME, MARKING_DEFINITION_ID +from .constants import FAKE_TIME, IDENTITY_ID, MARKING_DEFINITION_ID IDENTITY_CUSTOM_PROP = stix2.v20.Identity( name="John Smith", @@ -15,7 +15,7 @@ IDENTITY_CUSTOM_PROP = stix2.v20.Identity( def test_identity_custom_property(): with pytest.raises(ValueError) as excinfo: stix2.v20.Identity( - id="identity--311b2d2d-f010-4473-83ec-1edf84858f4c", + id=IDENTITY_ID, created="2015-12-21T19:59:11Z", modified="2015-12-21T19:59:11Z", name="John Smith", @@ -26,7 +26,7 @@ def test_identity_custom_property(): with pytest.raises(stix2.exceptions.ExtraPropertiesError) as excinfo: stix2.v20.Identity( - id="identity--311b2d2d-f010-4473-83ec-1edf84858f4c", + id=IDENTITY_ID, created="2015-12-21T19:59:11Z", modified="2015-12-21T19:59:11Z", name="John Smith", @@ -39,7 +39,7 @@ def test_identity_custom_property(): assert "Unexpected properties for Identity" in str(excinfo.value) identity = stix2.v20.Identity( - id="identity--311b2d2d-f010-4473-83ec-1edf84858f4c", + id=IDENTITY_ID, created="2015-12-21T19:59:11Z", modified="2015-12-21T19:59:11Z", name="John Smith", @@ -54,7 +54,7 @@ def test_identity_custom_property(): def test_identity_custom_property_invalid(): with pytest.raises(stix2.exceptions.ExtraPropertiesError) as excinfo: stix2.v20.Identity( - id="identity--311b2d2d-f010-4473-83ec-1edf84858f4c", + id=IDENTITY_ID, created="2015-12-21T19:59:11Z", modified="2015-12-21T19:59:11Z", name="John Smith", @@ -68,7 +68,7 @@ def test_identity_custom_property_invalid(): def test_identity_custom_property_allowed(): identity = stix2.v20.Identity( - id="identity--311b2d2d-f010-4473-83ec-1edf84858f4c", + id=IDENTITY_ID, created="2015-12-21T19:59:11Z", modified="2015-12-21T19:59:11Z", name="John Smith", @@ -127,7 +127,7 @@ def test_custom_properties_object_in_bundled_object(): def test_custom_property_dict_in_bundled_object(): custom_identity = { 'type': 'identity', - 'id': 'identity--311b2d2d-f010-4473-83ec-1edf84858f4c', + 'id': IDENTITY_ID, 'created': '2015-12-21T19:59:11Z', 'name': 'John Smith', 'identity_class': 'individual', @@ -144,7 +144,7 @@ def test_custom_property_dict_in_bundled_object(): def test_custom_properties_dict_in_bundled_object(): custom_identity = { 'type': 'identity', - 'id': 'identity--311b2d2d-f010-4473-83ec-1edf84858f4c', + 'id': IDENTITY_ID, 'created': '2015-12-21T19:59:11Z', 'name': 'John Smith', 'identity_class': 'individual', diff --git a/stix2/test/v20/test_datastore_memory.py b/stix2/test/v20/test_datastore_memory.py index 495652b..fba96dd 100644 --- a/stix2/test/v20/test_datastore_memory.py +++ b/stix2/test/v20/test_datastore_memory.py @@ -275,13 +275,13 @@ def test_memory_store_object_creator_of_present(mem_store): camp = Campaign( name="Scipio Africanus", objective="Defeat the Carthaginians", - created_by_ref="identity--e4196283-7420-4277-a7a3-d57f61ef1389", + created_by_ref=IDENTITY_ID, x_empire="Roman", allow_custom=True, ) iden = Identity( - id="identity--e4196283-7420-4277-a7a3-d57f61ef1389", + id=IDENTITY_ID, name="Foo Corp.", identity_class="corporation", ) diff --git a/stix2/test/v20/test_intrusion_set.py b/stix2/test/v20/test_intrusion_set.py index f02fbcb..69b336e 100644 --- a/stix2/test/v20/test_intrusion_set.py +++ b/stix2/test/v20/test_intrusion_set.py @@ -5,12 +5,12 @@ import pytz import stix2 -from .constants import INTRUSION_SET_ID +from .constants import IDENTITY_ID, INTRUSION_SET_ID EXPECTED = """{ "type": "intrusion-set", "id": "intrusion-set--4e78f46f-a023-4e5f-bc24-71b3ca22ec29", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c", "created": "2016-04-06T20:03:48.000Z", "modified": "2016-04-06T20:03:48.000Z", "name": "Bobcat Breakin", @@ -29,7 +29,7 @@ EXPECTED = """{ def test_intrusion_set_example(): intrusion_set = stix2.v20.IntrusionSet( id=INTRUSION_SET_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T20:03:48.000Z", modified="2016-04-06T20:03:48.000Z", name="Bobcat Breakin", @@ -49,7 +49,7 @@ def test_intrusion_set_example(): "Zookeeper", ], "created": "2016-04-06T20:03:48.000Z", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": IDENTITY_ID, "description": "Incidents usually feature a shared TTP of a bobcat being released...", "goals": [ "acquisition-theft", diff --git a/stix2/test/v20/test_markings.py b/stix2/test/v20/test_markings.py index d011959..b34ef43 100644 --- a/stix2/test/v20/test_markings.py +++ b/stix2/test/v20/test_markings.py @@ -6,7 +6,7 @@ import pytz import stix2 from stix2.v20 import TLP_WHITE -from .constants import CAMPAIGN_ID, MARKING_DEFINITION_ID +from .constants import CAMPAIGN_ID, IDENTITY_ID, MARKING_DEFINITION_ID EXPECTED_TLP_MARKING_DEFINITION = """{ "type": "marking-definition", @@ -31,7 +31,7 @@ EXPECTED_STATEMENT_MARKING_DEFINITION = """{ EXPECTED_CAMPAIGN_WITH_OBJECT_MARKING = """{ "type": "campaign", "id": "campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c", "created": "2016-04-06T20:03:00.000Z", "modified": "2016-04-06T20:03:00.000Z", "name": "Green Group Attacks Against Finance", @@ -54,7 +54,7 @@ EXPECTED_GRANULAR_MARKING = """{ EXPECTED_CAMPAIGN_WITH_GRANULAR_MARKINGS = """{ "type": "campaign", "id": "campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c", "created": "2016-04-06T20:03:00.000Z", "modified": "2016-04-06T20:03:00.000Z", "name": "Green Group Attacks Against Finance", @@ -111,7 +111,7 @@ def test_campaign_with_markings_example(): campaign = stix2.v20.Campaign( type='campaign', id=CAMPAIGN_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T20:03:00.000Z", modified="2016-04-06T20:03:00.000Z", name="Green Group Attacks Against Finance", @@ -147,7 +147,7 @@ def test_campaign_with_granular_markings_example(): campaign = stix2.v20.Campaign( type='campaign', id=CAMPAIGN_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T20:03:00.000Z", modified="2016-04-06T20:03:00.000Z", name="Green Group Attacks Against Finance", @@ -261,7 +261,7 @@ def test_marking_wrong_type_construction(): def test_campaign_add_markings(): campaign = stix2.v20.Campaign( id=CAMPAIGN_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T20:03:00Z", modified="2016-04-06T20:03:00Z", name="Green Group Attacks Against Finance", diff --git a/stix2/test/v20/test_observed_data.py b/stix2/test/v20/test_observed_data.py index 223184f..1c3cad4 100644 --- a/stix2/test/v20/test_observed_data.py +++ b/stix2/test/v20/test_observed_data.py @@ -6,7 +6,7 @@ import pytz import stix2 -from .constants import OBSERVED_DATA_ID +from .constants import IDENTITY_ID, OBSERVED_DATA_ID OBJECTS_REGEX = re.compile('\"objects\": {(?:.*?)(?:(?:[^{]*?)|(?:{[^{]*?}))*}', re.DOTALL) @@ -14,7 +14,7 @@ OBJECTS_REGEX = re.compile('\"objects\": {(?:.*?)(?:(?:[^{]*?)|(?:{[^{]*?}))*}', EXPECTED = """{ "type": "observed-data", "id": "observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c", "created": "2016-04-06T19:58:16.000Z", "modified": "2016-04-06T19:58:16.000Z", "first_observed": "2015-12-21T19:00:00Z", @@ -32,7 +32,7 @@ EXPECTED = """{ def test_observed_data_example(): observed_data = stix2.v20.ObservedData( id=OBSERVED_DATA_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", @@ -52,7 +52,7 @@ def test_observed_data_example(): EXPECTED_WITH_REF = """{ "type": "observed-data", "id": "observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c", "created": "2016-04-06T19:58:16.000Z", "modified": "2016-04-06T19:58:16.000Z", "first_observed": "2015-12-21T19:00:00Z", @@ -77,7 +77,7 @@ EXPECTED_WITH_REF = """{ def test_observed_data_example_with_refs(): observed_data = stix2.v20.ObservedData( id=OBSERVED_DATA_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", @@ -103,7 +103,7 @@ def test_observed_data_example_with_bad_refs(): with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: stix2.v20.ObservedData( id=OBSERVED_DATA_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", @@ -131,7 +131,7 @@ def test_observed_data_example_with_non_dictionary(): with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: stix2.v20.ObservedData( id=OBSERVED_DATA_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", @@ -149,7 +149,7 @@ def test_observed_data_example_with_empty_dictionary(): with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: stix2.v20.ObservedData( id=OBSERVED_DATA_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", @@ -170,7 +170,7 @@ def test_observed_data_example_with_empty_dictionary(): "type": "observed-data", "id": OBSERVED_DATA_ID, "created": "2016-04-06T19:58:16.000Z", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": IDENTITY_ID, "first_observed": "2015-12-21T19:00:00Z", "last_observed": "2015-12-21T19:00:00Z", "modified": "2016-04-06T19:58:16.000Z", @@ -193,7 +193,7 @@ def test_parse_observed_data(data): assert odata.modified == dt.datetime(2016, 4, 6, 19, 58, 16, tzinfo=pytz.utc) assert odata.first_observed == dt.datetime(2015, 12, 21, 19, 0, 0, tzinfo=pytz.utc) assert odata.last_observed == dt.datetime(2015, 12, 21, 19, 0, 0, tzinfo=pytz.utc) - assert odata.created_by_ref == "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff" + assert odata.created_by_ref == IDENTITY_ID assert odata.objects["0"].type == "file" @@ -533,7 +533,7 @@ def test_parse_basic_tcp_traffic_with_error(data): EXPECTED_PROCESS_OD = """{ "created": "2016-04-06T19:58:16.000Z", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c", "first_observed": "2015-12-21T19:00:00Z", "id": "observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", "last_observed": "2015-12-21T19:00:00Z", @@ -564,7 +564,7 @@ EXPECTED_PROCESS_OD = """{ def test_observed_data_with_process_example(): observed_data = stix2.v20.ObservedData( id=OBSERVED_DATA_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", diff --git a/stix2/test/v20/test_pickle.py b/stix2/test/v20/test_pickle.py index 6c65d8f..416341c 100644 --- a/stix2/test/v20/test_pickle.py +++ b/stix2/test/v20/test_pickle.py @@ -2,13 +2,15 @@ import pickle import stix2 +from .constants import IDENTITY_ID + def test_pickling(): """ Ensure a pickle/unpickle cycle works okay. """ identity = stix2.v20.Identity( - id="identity--d66cb89d-5228-4983-958c-fa84ef75c88c", + id=IDENTITY_ID, name="alice", description="this is a pickle test", identity_class="some_class", diff --git a/stix2/test/v20/test_report.py b/stix2/test/v20/test_report.py index 49fc5ac..7f93511 100644 --- a/stix2/test/v20/test_report.py +++ b/stix2/test/v20/test_report.py @@ -5,21 +5,24 @@ import pytz import stix2 -from .constants import INDICATOR_KWARGS, REPORT_ID +from .constants import ( + CAMPAIGN_ID, IDENTITY_ID, INDICATOR_ID, INDICATOR_KWARGS, RELATIONSHIP_ID, + REPORT_ID, +) EXPECTED = """{ "type": "report", "id": "report--84e4d88f-44ea-4bcd-bbf3-b2c1c320bcb3", - "created_by_ref": "identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283", + "created_by_ref": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c", "created": "2015-12-21T19:59:11.000Z", "modified": "2015-12-21T19:59:11.000Z", "name": "The Black Vine Cyberespionage Group", "description": "A simple report with an indicator and campaign", "published": "2016-01-20T17:00:00Z", "object_refs": [ - "indicator--26ffb872-1dd9-446e-b6f5-d58527e5b5d2", - "campaign--83422c77-904c-4dc1-aff5-5c38f3a2c55c", - "relationship--f82356ae-fe6c-437c-9c24-6b64314ae68a" + "indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7", + "campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", + "relationship--df7c87eb-75d2-4948-af81-9d49d246f301" ], "labels": [ "campaign" @@ -30,7 +33,7 @@ EXPECTED = """{ def test_report_example(): report = stix2.v20.Report( id=REPORT_ID, - created_by_ref="identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283", + created_by_ref=IDENTITY_ID, created="2015-12-21T19:59:11.000Z", modified="2015-12-21T19:59:11.000Z", name="The Black Vine Cyberespionage Group", @@ -38,9 +41,9 @@ def test_report_example(): published="2016-01-20T17:00:00Z", labels=["campaign"], object_refs=[ - "indicator--26ffb872-1dd9-446e-b6f5-d58527e5b5d2", - "campaign--83422c77-904c-4dc1-aff5-5c38f3a2c55c", - "relationship--f82356ae-fe6c-437c-9c24-6b64314ae68a", + INDICATOR_ID, + CAMPAIGN_ID, + RELATIONSHIP_ID, ], ) @@ -50,7 +53,7 @@ def test_report_example(): def test_report_example_objects_in_object_refs(): report = stix2.v20.Report( id=REPORT_ID, - created_by_ref="identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283", + created_by_ref=IDENTITY_ID, created="2015-12-21T19:59:11.000Z", modified="2015-12-21T19:59:11.000Z", name="The Black Vine Cyberespionage Group", @@ -58,9 +61,9 @@ def test_report_example_objects_in_object_refs(): published="2016-01-20T17:00:00Z", labels=["campaign"], object_refs=[ - stix2.v20.Indicator(id="indicator--26ffb872-1dd9-446e-b6f5-d58527e5b5d2", **INDICATOR_KWARGS), - "campaign--83422c77-904c-4dc1-aff5-5c38f3a2c55c", - "relationship--f82356ae-fe6c-437c-9c24-6b64314ae68a", + stix2.v20.Indicator(id=INDICATOR_ID, **INDICATOR_KWARGS), + CAMPAIGN_ID, + RELATIONSHIP_ID, ], ) @@ -71,7 +74,7 @@ def test_report_example_objects_in_object_refs_with_bad_id(): with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: stix2.v20.Report( id=REPORT_ID, - created_by_ref="identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283", + created_by_ref=IDENTITY_ID, created="2015-12-21T19:59:11.000Z", modified="2015-12-21T19:59:11.000Z", name="The Black Vine Cyberespionage Group", @@ -79,9 +82,9 @@ def test_report_example_objects_in_object_refs_with_bad_id(): published="2016-01-20T17:00:00Z", labels=["campaign"], object_refs=[ - stix2.v20.Indicator(id="indicator--26ffb872-1dd9-446e-b6f5-d58527e5b5d2", **INDICATOR_KWARGS), + stix2.v20.Indicator(id=INDICATOR_ID, **INDICATOR_KWARGS), "campaign-83422c77-904c-4dc1-aff5-5c38f3a2c55c", # the "bad" id, missing a "-" - "relationship--f82356ae-fe6c-437c-9c24-6b64314ae68a", + RELATIONSHIP_ID, ], ) @@ -96,7 +99,7 @@ def test_report_example_objects_in_object_refs_with_bad_id(): EXPECTED, { "created": "2015-12-21T19:59:11.000Z", - "created_by_ref": "identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283", + "created_by_ref": IDENTITY_ID, "description": "A simple report with an indicator and campaign", "id": REPORT_ID, "labels": [ @@ -105,9 +108,9 @@ def test_report_example_objects_in_object_refs_with_bad_id(): "modified": "2015-12-21T19:59:11.000Z", "name": "The Black Vine Cyberespionage Group", "object_refs": [ - "indicator--26ffb872-1dd9-446e-b6f5-d58527e5b5d2", - "campaign--83422c77-904c-4dc1-aff5-5c38f3a2c55c", - "relationship--f82356ae-fe6c-437c-9c24-6b64314ae68a", + INDICATOR_ID, + CAMPAIGN_ID, + RELATIONSHIP_ID, ], "published": "2016-01-20T17:00:00Z", "type": "report", @@ -121,11 +124,11 @@ def test_parse_report(data): assert rept.id == REPORT_ID assert rept.created == dt.datetime(2015, 12, 21, 19, 59, 11, tzinfo=pytz.utc) assert rept.modified == dt.datetime(2015, 12, 21, 19, 59, 11, tzinfo=pytz.utc) - assert rept.created_by_ref == "identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283" + assert rept.created_by_ref == IDENTITY_ID assert rept.object_refs == [ - "indicator--26ffb872-1dd9-446e-b6f5-d58527e5b5d2", - "campaign--83422c77-904c-4dc1-aff5-5c38f3a2c55c", - "relationship--f82356ae-fe6c-437c-9c24-6b64314ae68a", + INDICATOR_ID, + CAMPAIGN_ID, + RELATIONSHIP_ID, ] assert rept.description == "A simple report with an indicator and campaign" assert rept.labels == ["campaign"] diff --git a/stix2/test/v20/test_sighting.py b/stix2/test/v20/test_sighting.py index e0c9b3b..994335c 100644 --- a/stix2/test/v20/test_sighting.py +++ b/stix2/test/v20/test_sighting.py @@ -5,7 +5,7 @@ import pytz import stix2 -from .constants import INDICATOR_ID, SIGHTING_ID, SIGHTING_KWARGS +from .constants import IDENTITY_ID, INDICATOR_ID, SIGHTING_ID, SIGHTING_KWARGS EXPECTED_SIGHTING = """{ "type": "sighting", @@ -14,7 +14,7 @@ EXPECTED_SIGHTING = """{ "modified": "2016-04-06T20:06:37.000Z", "sighting_of_ref": "indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7", "where_sighted_refs": [ - "identity--8cc7afd6-5455-4d2b-a736-e614ee631d99" + "identity--311b2d2d-f010-4473-83ec-1edf84858f4c" ] }""" @@ -39,7 +39,7 @@ def test_sighting_all_required_properties(): created=now, modified=now, sighting_of_ref=INDICATOR_ID, - where_sighted_refs=["identity--8cc7afd6-5455-4d2b-a736-e614ee631d99"], + where_sighted_refs=[IDENTITY_ID], ) assert str(s) == EXPECTED_SIGHTING @@ -99,7 +99,7 @@ def test_create_sighting_from_objects_rather_than_ids(malware): # noqa: F811 "sighting_of_ref": "indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7", "type": "sighting", "where_sighted_refs": [ - "identity--8cc7afd6-5455-4d2b-a736-e614ee631d99", + IDENTITY_ID, ], }, ], @@ -112,4 +112,4 @@ def test_parse_sighting(data): assert sighting.created == dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc) assert sighting.modified == dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc) assert sighting.sighting_of_ref == INDICATOR_ID - assert sighting.where_sighted_refs == ["identity--8cc7afd6-5455-4d2b-a736-e614ee631d99"] + assert sighting.where_sighted_refs == [IDENTITY_ID] diff --git a/stix2/test/v20/test_threat_actor.py b/stix2/test/v20/test_threat_actor.py index 20cb26e..854e77a 100644 --- a/stix2/test/v20/test_threat_actor.py +++ b/stix2/test/v20/test_threat_actor.py @@ -5,12 +5,12 @@ import pytz import stix2 -from .constants import THREAT_ACTOR_ID +from .constants import IDENTITY_ID, THREAT_ACTOR_ID EXPECTED = """{ "type": "threat-actor", "id": "threat-actor--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c", "created": "2016-04-06T20:03:48.000Z", "modified": "2016-04-06T20:03:48.000Z", "name": "Evil Org", @@ -24,7 +24,7 @@ EXPECTED = """{ def test_threat_actor_example(): threat_actor = stix2.v20.ThreatActor( id=THREAT_ACTOR_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T20:03:48.000Z", modified="2016-04-06T20:03:48.000Z", description="The Evil Org threat actor group", @@ -40,7 +40,7 @@ def test_threat_actor_example(): EXPECTED, { "created": "2016-04-06T20:03:48.000Z", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": IDENTITY_ID, "description": "The Evil Org threat actor group", "id": THREAT_ACTOR_ID, "modified": "2016-04-06T20:03:48.000Z", @@ -57,7 +57,7 @@ def test_parse_threat_actor(data): assert actor.id == THREAT_ACTOR_ID assert actor.created == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) assert actor.modified == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) - assert actor.created_by_ref == "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff" + assert actor.created_by_ref == IDENTITY_ID assert actor.description == "The Evil Org threat actor group" assert actor.name == "Evil Org" assert actor.labels == ["crime-syndicate"] diff --git a/stix2/test/v20/test_tool.py b/stix2/test/v20/test_tool.py index 257b787..435b85e 100644 --- a/stix2/test/v20/test_tool.py +++ b/stix2/test/v20/test_tool.py @@ -5,12 +5,12 @@ import pytz import stix2 -from .constants import TOOL_ID +from .constants import IDENTITY_ID, TOOL_ID EXPECTED = """{ "type": "tool", "id": "tool--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c", "created": "2016-04-06T20:03:48.000Z", "modified": "2016-04-06T20:03:48.000Z", "name": "VNC", @@ -22,7 +22,7 @@ EXPECTED = """{ EXPECTED_WITH_REVOKED = """{ "type": "tool", "id": "tool--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c", "created": "2016-04-06T20:03:48.000Z", "modified": "2016-04-06T20:03:48.000Z", "name": "VNC", @@ -36,7 +36,7 @@ EXPECTED_WITH_REVOKED = """{ def test_tool_example(): tool = stix2.v20.Tool( id=TOOL_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T20:03:48.000Z", modified="2016-04-06T20:03:48.000Z", labels=["remote-access"], @@ -51,7 +51,7 @@ def test_tool_example(): EXPECTED, { "created": "2016-04-06T20:03:48Z", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": IDENTITY_ID, "id": TOOL_ID, "modified": "2016-04-06T20:03:48Z", "labels": ["remote-access"], @@ -67,7 +67,7 @@ def test_parse_tool(data): assert tool.id == TOOL_ID assert tool.created == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) assert tool.modified == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) - assert tool.created_by_ref == "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff" + assert tool.created_by_ref == IDENTITY_ID assert tool.labels == ["remote-access"] assert tool.name == "VNC" @@ -81,7 +81,7 @@ def test_tool_no_workbench_wrappers(): def test_tool_serialize_with_defaults(): tool = stix2.v20.Tool( id=TOOL_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T20:03:48.000Z", modified="2016-04-06T20:03:48.000Z", labels=["remote-access"], diff --git a/stix2/test/v20/test_utils.py b/stix2/test/v20/test_utils.py index 1aa85b1..ee011c1 100644 --- a/stix2/test/v20/test_utils.py +++ b/stix2/test/v20/test_utils.py @@ -8,6 +8,8 @@ import pytz import stix2.utils +from .constants import IDENTITY_ID + amsterdam = pytz.timezone('Europe/Amsterdam') eastern = pytz.timezone('US/Eastern') @@ -123,7 +125,7 @@ def test_deduplicate(stix_objs1): ( stix2.v20.ObservedData( id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", diff --git a/stix2/test/v21/constants.py b/stix2/test/v21/constants.py index e03c610..bbce32c 100644 --- a/stix2/test/v21/constants.py +++ b/stix2/test/v21/constants.py @@ -53,7 +53,7 @@ CAMPAIGN_MORE_KWARGS = dict( type='campaign', spec_version='2.1', id=CAMPAIGN_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T20:03:00.000Z", modified="2016-04-06T20:03:00.000Z", name="Green Group Attacks Against Finance", diff --git a/stix2/test/v21/test_bundle.py b/stix2/test/v21/test_bundle.py index 86c2d00..7adea92 100644 --- a/stix2/test/v21/test_bundle.py +++ b/stix2/test/v21/test_bundle.py @@ -4,6 +4,8 @@ import pytest import stix2 +from .constants import IDENTITY_ID + EXPECTED_BUNDLE = """{ "type": "bundle", "id": "bundle--00000000-0000-4000-8000-000000000007", @@ -190,7 +192,7 @@ def test_parse_unknown_type(): "id": "other--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", "created": "2016-04-06T20:03:00Z", "modified": "2016-04-06T20:03:00Z", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": IDENTITY_ID, "description": "Campaign by Green Group against a series of targets in the financial services sector.", "name": "Green Group Attacks Against Finance", } diff --git a/stix2/test/v21/test_campaign.py b/stix2/test/v21/test_campaign.py index e4c1707..10f5d7b 100644 --- a/stix2/test/v21/test_campaign.py +++ b/stix2/test/v21/test_campaign.py @@ -5,13 +5,13 @@ import pytz import stix2 -from .constants import CAMPAIGN_ID, CAMPAIGN_MORE_KWARGS +from .constants import CAMPAIGN_ID, CAMPAIGN_MORE_KWARGS, IDENTITY_ID EXPECTED = """{ "type": "campaign", "spec_version": "2.1", "id": "campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c", "created": "2016-04-06T20:03:00.000Z", "modified": "2016-04-06T20:03:00.000Z", "name": "Green Group Attacks Against Finance", @@ -36,7 +36,7 @@ def test_campaign_example(): "id": CAMPAIGN_ID, "created": "2016-04-06T20:03:00Z", "modified": "2016-04-06T20:03:00Z", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": IDENTITY_ID, "description": "Campaign by Green Group against a series of targets in the financial services sector.", "name": "Green Group Attacks Against Finance", }, @@ -50,7 +50,7 @@ def test_parse_campaign(data): assert cmpn.id == CAMPAIGN_ID assert cmpn.created == dt.datetime(2016, 4, 6, 20, 3, 0, tzinfo=pytz.utc) assert cmpn.modified == dt.datetime(2016, 4, 6, 20, 3, 0, tzinfo=pytz.utc) - assert cmpn.created_by_ref == "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff" + assert cmpn.created_by_ref == IDENTITY_ID assert cmpn.description == "Campaign by Green Group against a series of targets in the financial services sector." assert cmpn.name == "Green Group Attacks Against Finance" diff --git a/stix2/test/v21/test_core.py b/stix2/test/v21/test_core.py index c90592b..bf45f32 100644 --- a/stix2/test/v21/test_core.py +++ b/stix2/test/v21/test_core.py @@ -3,7 +3,7 @@ import pytest import stix2 from stix2 import core, exceptions -from .constants import OBSERVED_DATA_ID +from .constants import IDENTITY_ID, OBSERVED_DATA_ID BUNDLE = { "type": "bundle", @@ -101,7 +101,7 @@ def test_register_marking_with_no_version(): def test_register_observable_with_default_version(): observed_data = stix2.v21.ObservedData( id=OBSERVED_DATA_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", @@ -139,7 +139,7 @@ def test_register_observable_with_default_version(): def test_register_observable_extension_with_default_version(): observed_data = stix2.v21.ObservedData( id=OBSERVED_DATA_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", diff --git a/stix2/test/v21/test_course_of_action.py b/stix2/test/v21/test_course_of_action.py index c27b20d..7cbaed2 100644 --- a/stix2/test/v21/test_course_of_action.py +++ b/stix2/test/v21/test_course_of_action.py @@ -5,13 +5,13 @@ import pytz import stix2 -from .constants import COURSE_OF_ACTION_ID +from .constants import COURSE_OF_ACTION_ID, IDENTITY_ID EXPECTED = """{ "type": "course-of-action", "spec_version": "2.1", "id": "course-of-action--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c", "created": "2016-04-06T20:03:48.000Z", "modified": "2016-04-06T20:03:48.000Z", "name": "Add TCP port 80 Filter Rule to the existing Block UDP 1434 Filter", @@ -22,7 +22,7 @@ EXPECTED = """{ def test_course_of_action_example(): coa = stix2.v21.CourseOfAction( id=COURSE_OF_ACTION_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T20:03:48.000Z", modified="2016-04-06T20:03:48.000Z", name="Add TCP port 80 Filter Rule to the existing Block UDP 1434 Filter", @@ -37,7 +37,7 @@ def test_course_of_action_example(): EXPECTED, { "created": "2016-04-06T20:03:48.000Z", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": IDENTITY_ID, "description": "This is how to add a filter rule to block inbound access to TCP port 80 to the existing UDP 1434 filter ...", "id": COURSE_OF_ACTION_ID, "modified": "2016-04-06T20:03:48.000Z", @@ -55,7 +55,7 @@ def test_parse_course_of_action(data): assert coa.id == COURSE_OF_ACTION_ID assert coa.created == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) assert coa.modified == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) - assert coa.created_by_ref == "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff" + assert coa.created_by_ref == IDENTITY_ID assert coa.description == "This is how to add a filter rule to block inbound access to TCP port 80 to the existing UDP 1434 filter ..." assert coa.name == "Add TCP port 80 Filter Rule to the existing Block UDP 1434 Filter" diff --git a/stix2/test/v21/test_datastore_memory.py b/stix2/test/v21/test_datastore_memory.py index eb30f07..b69d4d6 100644 --- a/stix2/test/v21/test_datastore_memory.py +++ b/stix2/test/v21/test_datastore_memory.py @@ -282,13 +282,13 @@ def test_memory_store_object_creator_of_present(mem_store): camp = Campaign( name="Scipio Africanus", objective="Defeat the Carthaginians", - created_by_ref="identity--e4196283-7420-4277-a7a3-d57f61ef1389", + created_by_ref=IDENTITY_ID, x_empire="Roman", allow_custom=True, ) iden = Identity( - id="identity--e4196283-7420-4277-a7a3-d57f61ef1389", + id=IDENTITY_ID, name="Foo Corp.", identity_class="corporation", ) diff --git a/stix2/test/v21/test_intrusion_set.py b/stix2/test/v21/test_intrusion_set.py index f8d5dc2..778eda7 100644 --- a/stix2/test/v21/test_intrusion_set.py +++ b/stix2/test/v21/test_intrusion_set.py @@ -5,13 +5,13 @@ import pytz import stix2 -from .constants import INTRUSION_SET_ID +from .constants import IDENTITY_ID, INTRUSION_SET_ID EXPECTED = """{ "type": "intrusion-set", "spec_version": "2.1", "id": "intrusion-set--4e78f46f-a023-4e5f-bc24-71b3ca22ec29", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c", "created": "2016-04-06T20:03:48.000Z", "modified": "2016-04-06T20:03:48.000Z", "name": "Bobcat Breakin", @@ -30,7 +30,7 @@ EXPECTED = """{ def test_intrusion_set_example(): intrusion_set = stix2.v21.IntrusionSet( id=INTRUSION_SET_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T20:03:48.000Z", modified="2016-04-06T20:03:48.000Z", name="Bobcat Breakin", @@ -50,7 +50,7 @@ def test_intrusion_set_example(): "Zookeeper", ], "created": "2016-04-06T20:03:48.000Z", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": IDENTITY_ID, "description": "Incidents usually feature a shared TTP of a bobcat being released...", "goals": [ "acquisition-theft", diff --git a/stix2/test/v21/test_markings.py b/stix2/test/v21/test_markings.py index 11b6a95..7793889 100644 --- a/stix2/test/v21/test_markings.py +++ b/stix2/test/v21/test_markings.py @@ -6,7 +6,7 @@ import pytz import stix2 from stix2.v21 import TLP_WHITE -from .constants import MARKING_DEFINITION_ID +from .constants import IDENTITY_ID, MARKING_DEFINITION_ID EXPECTED_TLP_MARKING_DEFINITION = """{ "type": "marking-definition", @@ -34,7 +34,7 @@ EXPECTED_CAMPAIGN_WITH_OBJECT_MARKING = """{ "type": "campaign", "spec_version": "2.1", "id": "campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c", "created": "2016-04-06T20:03:00.000Z", "modified": "2016-04-06T20:03:00.000Z", "name": "Green Group Attacks Against Finance", @@ -58,7 +58,7 @@ EXPECTED_CAMPAIGN_WITH_GRANULAR_MARKINGS = """{ "type": "campaign", "spec_version": "2.1", "id": "campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c", "created": "2016-04-06T20:03:00.000Z", "modified": "2016-04-06T20:03:00.000Z", "name": "Green Group Attacks Against Finance", @@ -114,7 +114,7 @@ def test_marking_def_invalid_type(): def test_campaign_with_markings_example(): campaign = stix2.v21.Campaign( id="campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T20:03:00Z", modified="2016-04-06T20:03:00Z", name="Green Group Attacks Against Finance", @@ -149,7 +149,7 @@ def test_granular_example_with_bad_selector(): def test_campaign_with_granular_markings_example(): campaign = stix2.v21.Campaign( id="campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T20:03:00Z", modified="2016-04-06T20:03:00Z", name="Green Group Attacks Against Finance", @@ -265,7 +265,7 @@ def test_marking_wrong_type_construction(): def test_campaign_add_markings(): campaign = stix2.v21.Campaign( id="campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T20:03:00Z", modified="2016-04-06T20:03:00Z", name="Green Group Attacks Against Finance", diff --git a/stix2/test/v21/test_observed_data.py b/stix2/test/v21/test_observed_data.py index 3dde027..f3e1ea0 100644 --- a/stix2/test/v21/test_observed_data.py +++ b/stix2/test/v21/test_observed_data.py @@ -6,7 +6,7 @@ import pytz import stix2 -from .constants import OBSERVED_DATA_ID +from .constants import IDENTITY_ID, OBSERVED_DATA_ID OBJECTS_REGEX = re.compile('\"objects\": {(?:.*?)(?:(?:[^{]*?)|(?:{[^{]*?}))*}', re.DOTALL) @@ -15,7 +15,7 @@ EXPECTED = """{ "type": "observed-data", "spec_version": "2.1", "id": "observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c", "created": "2016-04-06T19:58:16.000Z", "modified": "2016-04-06T19:58:16.000Z", "first_observed": "2015-12-21T19:00:00Z", @@ -33,7 +33,7 @@ EXPECTED = """{ def test_observed_data_example(): observed_data = stix2.v21.ObservedData( id=OBSERVED_DATA_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", @@ -54,7 +54,7 @@ EXPECTED_WITH_REF = """{ "type": "observed-data", "spec_version": "2.1", "id": "observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c", "created": "2016-04-06T19:58:16.000Z", "modified": "2016-04-06T19:58:16.000Z", "first_observed": "2015-12-21T19:00:00Z", @@ -79,7 +79,7 @@ EXPECTED_WITH_REF = """{ def test_observed_data_example_with_refs(): observed_data = stix2.v21.ObservedData( id=OBSERVED_DATA_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", @@ -105,7 +105,7 @@ def test_observed_data_example_with_bad_refs(): with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: stix2.v21.ObservedData( id=OBSERVED_DATA_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", @@ -133,7 +133,7 @@ def test_observed_data_example_with_non_dictionary(): with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: stix2.v21.ObservedData( id=OBSERVED_DATA_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", @@ -151,7 +151,7 @@ def test_observed_data_example_with_empty_dictionary(): with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: stix2.v21.ObservedData( id=OBSERVED_DATA_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", @@ -173,7 +173,7 @@ def test_observed_data_example_with_empty_dictionary(): "spec_version": "2.1", "id": OBSERVED_DATA_ID, "created": "2016-04-06T19:58:16.000Z", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": IDENTITY_ID, "first_observed": "2015-12-21T19:00:00Z", "last_observed": "2015-12-21T19:00:00Z", "modified": "2016-04-06T19:58:16.000Z", @@ -197,7 +197,7 @@ def test_parse_observed_data(data): assert odata.modified == dt.datetime(2016, 4, 6, 19, 58, 16, tzinfo=pytz.utc) assert odata.first_observed == dt.datetime(2015, 12, 21, 19, 0, 0, tzinfo=pytz.utc) assert odata.last_observed == dt.datetime(2015, 12, 21, 19, 0, 0, tzinfo=pytz.utc) - assert odata.created_by_ref == "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff" + assert odata.created_by_ref == IDENTITY_ID assert odata.objects["0"].type == "file" @@ -537,7 +537,7 @@ def test_parse_basic_tcp_traffic_with_error(data): EXPECTED_PROCESS_OD = """{ "created": "2016-04-06T19:58:16.000Z", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c", "first_observed": "2015-12-21T19:00:00Z", "id": "observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", "last_observed": "2015-12-21T19:00:00Z", @@ -566,7 +566,7 @@ EXPECTED_PROCESS_OD = """{ def test_observed_data_with_process_example(): observed_data = stix2.v21.ObservedData( id=OBSERVED_DATA_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", diff --git a/stix2/test/v21/test_pickle.py b/stix2/test/v21/test_pickle.py index 0dc1c4c..faef4c4 100644 --- a/stix2/test/v21/test_pickle.py +++ b/stix2/test/v21/test_pickle.py @@ -2,13 +2,15 @@ import pickle import stix2 +from .constants import IDENTITY_ID + def test_pickling(): """ Ensure a pickle/unpickle cycle works okay. """ identity = stix2.v21.Identity( - id="identity--d66cb89d-5228-4983-958c-fa84ef75c88c", + id=IDENTITY_ID, name="alice", description="this is a pickle test", identity_class="some_class", diff --git a/stix2/test/v21/test_report.py b/stix2/test/v21/test_report.py index 22b5fb8..d6aa288 100644 --- a/stix2/test/v21/test_report.py +++ b/stix2/test/v21/test_report.py @@ -5,13 +5,16 @@ import pytz import stix2 -from .constants import INDICATOR_KWARGS, REPORT_ID +from .constants import ( + CAMPAIGN_ID, IDENTITY_ID, INDICATOR_ID, INDICATOR_KWARGS, RELATIONSHIP_ID, + REPORT_ID, +) EXPECTED = """{ "type": "report", "spec_version": "2.1", "id": "report--84e4d88f-44ea-4bcd-bbf3-b2c1c320bcb3", - "created_by_ref": "identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283", + "created_by_ref": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c", "created": "2015-12-21T19:59:11.000Z", "modified": "2015-12-21T19:59:11.000Z", "name": "The Black Vine Cyberespionage Group", @@ -21,9 +24,9 @@ EXPECTED = """{ ], "published": "2016-01-20T17:00:00Z", "object_refs": [ - "indicator--26ffb872-1dd9-446e-b6f5-d58527e5b5d2", - "campaign--83422c77-904c-4dc1-aff5-5c38f3a2c55c", - "relationship--f82356ae-fe6c-437c-9c24-6b64314ae68a" + "indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7", + "campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", + "relationship--df7c87eb-75d2-4948-af81-9d49d246f301" ] }""" @@ -31,7 +34,7 @@ EXPECTED = """{ def test_report_example(): report = stix2.v21.Report( id=REPORT_ID, - created_by_ref="identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283", + created_by_ref=IDENTITY_ID, created="2015-12-21T19:59:11.000Z", modified="2015-12-21T19:59:11.000Z", name="The Black Vine Cyberespionage Group", @@ -39,9 +42,9 @@ def test_report_example(): published="2016-01-20T17:00:00Z", report_types=["campaign"], object_refs=[ - "indicator--26ffb872-1dd9-446e-b6f5-d58527e5b5d2", - "campaign--83422c77-904c-4dc1-aff5-5c38f3a2c55c", - "relationship--f82356ae-fe6c-437c-9c24-6b64314ae68a", + INDICATOR_ID, + CAMPAIGN_ID, + RELATIONSHIP_ID, ], ) @@ -51,7 +54,7 @@ def test_report_example(): def test_report_example_objects_in_object_refs(): report = stix2.v21.Report( id=REPORT_ID, - created_by_ref="identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283", + created_by_ref=IDENTITY_ID, created="2015-12-21T19:59:11.000Z", modified="2015-12-21T19:59:11.000Z", name="The Black Vine Cyberespionage Group", @@ -59,9 +62,9 @@ def test_report_example_objects_in_object_refs(): published="2016-01-20T17:00:00Z", report_types=["campaign"], object_refs=[ - stix2.v21.Indicator(id="indicator--26ffb872-1dd9-446e-b6f5-d58527e5b5d2", **INDICATOR_KWARGS), - "campaign--83422c77-904c-4dc1-aff5-5c38f3a2c55c", - "relationship--f82356ae-fe6c-437c-9c24-6b64314ae68a", + stix2.v21.Indicator(id=INDICATOR_ID, **INDICATOR_KWARGS), + CAMPAIGN_ID, + RELATIONSHIP_ID, ], ) @@ -72,7 +75,7 @@ def test_report_example_objects_in_object_refs_with_bad_id(): with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo: stix2.v21.Report( id=REPORT_ID, - created_by_ref="identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283", + created_by_ref=IDENTITY_ID, created="2015-12-21T19:59:11.000Z", modified="2015-12-21T19:59:11.000Z", name="The Black Vine Cyberespionage Group", @@ -80,9 +83,9 @@ def test_report_example_objects_in_object_refs_with_bad_id(): published="2016-01-20T17:00:00Z", report_types=["campaign"], object_refs=[ - stix2.v21.Indicator(id="indicator--26ffb872-1dd9-446e-b6f5-d58527e5b5d2", **INDICATOR_KWARGS), + stix2.v21.Indicator(id=INDICATOR_ID, **INDICATOR_KWARGS), "campaign-83422c77-904c-4dc1-aff5-5c38f3a2c55c", # the "bad" id, missing a "-" - "relationship--f82356ae-fe6c-437c-9c24-6b64314ae68a", + RELATIONSHIP_ID, ], ) @@ -97,7 +100,7 @@ def test_report_example_objects_in_object_refs_with_bad_id(): EXPECTED, { "created": "2015-12-21T19:59:11.000Z", - "created_by_ref": "identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283", + "created_by_ref": IDENTITY_ID, "description": "A simple report with an indicator and campaign", "id": REPORT_ID, "report_types": [ @@ -106,9 +109,9 @@ def test_report_example_objects_in_object_refs_with_bad_id(): "modified": "2015-12-21T19:59:11.000Z", "name": "The Black Vine Cyberespionage Group", "object_refs": [ - "indicator--26ffb872-1dd9-446e-b6f5-d58527e5b5d2", - "campaign--83422c77-904c-4dc1-aff5-5c38f3a2c55c", - "relationship--f82356ae-fe6c-437c-9c24-6b64314ae68a", + INDICATOR_ID, + CAMPAIGN_ID, + RELATIONSHIP_ID, ], "published": "2016-01-20T17:00:00Z", "spec_version": "2.1", @@ -124,11 +127,11 @@ def test_parse_report(data): assert rept.id == REPORT_ID assert rept.created == dt.datetime(2015, 12, 21, 19, 59, 11, tzinfo=pytz.utc) assert rept.modified == dt.datetime(2015, 12, 21, 19, 59, 11, tzinfo=pytz.utc) - assert rept.created_by_ref == "identity--a463ffb3-1bd9-4d94-b02d-74e4f1658283" + assert rept.created_by_ref == IDENTITY_ID assert rept.object_refs == [ - "indicator--26ffb872-1dd9-446e-b6f5-d58527e5b5d2", - "campaign--83422c77-904c-4dc1-aff5-5c38f3a2c55c", - "relationship--f82356ae-fe6c-437c-9c24-6b64314ae68a", + INDICATOR_ID, + CAMPAIGN_ID, + RELATIONSHIP_ID, ] assert rept.description == "A simple report with an indicator and campaign" assert rept.report_types == ["campaign"] diff --git a/stix2/test/v21/test_sighting.py b/stix2/test/v21/test_sighting.py index c0fa7c3..950aebb 100644 --- a/stix2/test/v21/test_sighting.py +++ b/stix2/test/v21/test_sighting.py @@ -5,7 +5,7 @@ import pytz import stix2 -from .constants import INDICATOR_ID, SIGHTING_ID, SIGHTING_KWARGS +from .constants import IDENTITY_ID, INDICATOR_ID, SIGHTING_ID, SIGHTING_KWARGS EXPECTED_SIGHTING = """{ "type": "sighting", @@ -15,7 +15,7 @@ EXPECTED_SIGHTING = """{ "modified": "2016-04-06T20:06:37.000Z", "sighting_of_ref": "indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7", "where_sighted_refs": [ - "identity--8cc7afd6-5455-4d2b-a736-e614ee631d99" + "identity--311b2d2d-f010-4473-83ec-1edf84858f4c" ] }""" @@ -41,7 +41,7 @@ def test_sighting_all_required_properties(): created=now, modified=now, sighting_of_ref=INDICATOR_ID, - where_sighted_refs=["identity--8cc7afd6-5455-4d2b-a736-e614ee631d99"], + where_sighted_refs=[IDENTITY_ID], ) assert str(s) == EXPECTED_SIGHTING @@ -102,7 +102,7 @@ def test_create_sighting_from_objects_rather_than_ids(malware): # noqa: F811 "spec_version": "2.1", "type": "sighting", "where_sighted_refs": [ - "identity--8cc7afd6-5455-4d2b-a736-e614ee631d99", + IDENTITY_ID, ], }, ], @@ -116,4 +116,4 @@ def test_parse_sighting(data): assert sighting.created == dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc) assert sighting.modified == dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc) assert sighting.sighting_of_ref == INDICATOR_ID - assert sighting.where_sighted_refs == ["identity--8cc7afd6-5455-4d2b-a736-e614ee631d99"] + assert sighting.where_sighted_refs == [IDENTITY_ID] diff --git a/stix2/test/v21/test_threat_actor.py b/stix2/test/v21/test_threat_actor.py index fd4dcf7..5468731 100644 --- a/stix2/test/v21/test_threat_actor.py +++ b/stix2/test/v21/test_threat_actor.py @@ -5,13 +5,13 @@ import pytz import stix2 -from .constants import THREAT_ACTOR_ID +from .constants import IDENTITY_ID, THREAT_ACTOR_ID EXPECTED = """{ "type": "threat-actor", "spec_version": "2.1", "id": "threat-actor--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c", "created": "2016-04-06T20:03:48.000Z", "modified": "2016-04-06T20:03:48.000Z", "name": "Evil Org", @@ -25,7 +25,7 @@ EXPECTED = """{ def test_threat_actor_example(): threat_actor = stix2.v21.ThreatActor( id=THREAT_ACTOR_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T20:03:48.000Z", modified="2016-04-06T20:03:48.000Z", name="Evil Org", @@ -41,7 +41,7 @@ def test_threat_actor_example(): EXPECTED, { "created": "2016-04-06T20:03:48.000Z", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": IDENTITY_ID, "description": "The Evil Org threat actor group", "id": THREAT_ACTOR_ID, "threat_actor_types": [ @@ -62,7 +62,7 @@ def test_parse_threat_actor(data): assert actor.id == THREAT_ACTOR_ID assert actor.created == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) assert actor.modified == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) - assert actor.created_by_ref == "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff" + assert actor.created_by_ref == IDENTITY_ID assert actor.description == "The Evil Org threat actor group" assert actor.name == "Evil Org" assert actor.threat_actor_types == ["crime-syndicate"] diff --git a/stix2/test/v21/test_tool.py b/stix2/test/v21/test_tool.py index e0ec6b0..6a7d89c 100644 --- a/stix2/test/v21/test_tool.py +++ b/stix2/test/v21/test_tool.py @@ -5,13 +5,13 @@ import pytz import stix2 -from .constants import TOOL_ID +from .constants import IDENTITY_ID, TOOL_ID EXPECTED = """{ "type": "tool", "spec_version": "2.1", "id": "tool--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c", "created": "2016-04-06T20:03:48.000Z", "modified": "2016-04-06T20:03:48.000Z", "name": "VNC", @@ -24,7 +24,7 @@ EXPECTED_WITH_REVOKED = """{ "type": "tool", "spec_version": "2.1", "id": "tool--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c", "created": "2016-04-06T20:03:48.000Z", "modified": "2016-04-06T20:03:48.000Z", "name": "VNC", @@ -38,7 +38,7 @@ EXPECTED_WITH_REVOKED = """{ def test_tool_example(): tool = stix2.v21.Tool( id=TOOL_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T20:03:48.000Z", modified="2016-04-06T20:03:48.000Z", name="VNC", @@ -53,7 +53,7 @@ def test_tool_example(): EXPECTED, { "created": "2016-04-06T20:03:48Z", - "created_by_ref": "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + "created_by_ref": IDENTITY_ID, "id": TOOL_ID, "tool_types": [ "remote-access", @@ -73,7 +73,7 @@ def test_parse_tool(data): assert tool.id == TOOL_ID assert tool.created == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) assert tool.modified == dt.datetime(2016, 4, 6, 20, 3, 48, tzinfo=pytz.utc) - assert tool.created_by_ref == "identity--f431f809-377b-45e0-aa1c-6a4751cae5ff" + assert tool.created_by_ref == IDENTITY_ID assert tool.tool_types == ["remote-access"] assert tool.name == "VNC" @@ -87,7 +87,7 @@ def test_tool_no_workbench_wrappers(): def test_tool_serialize_with_defaults(): tool = stix2.v21.Tool( id=TOOL_ID, - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T20:03:48.000Z", modified="2016-04-06T20:03:48.000Z", name="VNC", diff --git a/stix2/test/v21/test_utils.py b/stix2/test/v21/test_utils.py index 96a06d3..dec3294 100644 --- a/stix2/test/v21/test_utils.py +++ b/stix2/test/v21/test_utils.py @@ -8,6 +8,8 @@ import pytz import stix2.utils +from .constants import IDENTITY_ID + amsterdam = pytz.timezone('Europe/Amsterdam') eastern = pytz.timezone('US/Eastern') @@ -123,7 +125,7 @@ def test_deduplicate(stix_objs1): ( stix2.v21.ObservedData( id="observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf", - created_by_ref="identity--f431f809-377b-45e0-aa1c-6a4751cae5ff", + created_by_ref=IDENTITY_ID, created="2016-04-06T19:58:16.000Z", modified="2016-04-06T19:58:16.000Z", first_observed="2015-12-21T19:00:00Z", From 1c03b4a1f09b2b27731765dacfd4b0b59adb7f63 Mon Sep 17 00:00:00 2001 From: John-Mark Gurney Date: Mon, 4 Feb 2019 13:58:33 -0800 Subject: [PATCH 26/62] minor grammar fix --- stix2/datastore/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stix2/datastore/__init__.py b/stix2/datastore/__init__.py index 561fe9e..57cb513 100644 --- a/stix2/datastore/__init__.py +++ b/stix2/datastore/__init__.py @@ -420,7 +420,7 @@ class CompositeDataSource(DataSource): """Controller for all the attached DataSources. A user can have a single CompositeDataSource as an interface - the a set of DataSources. When an API call is made to the + to a set of DataSources. When an API call is made to the CompositeDataSource, it is delegated to each of the (real) DataSources that are attached to it. From 0ca2bc087a0a7440cf7f5e1666e07769809d3f9d Mon Sep 17 00:00:00 2001 From: Chris Lenk Date: Wed, 6 Feb 2019 14:27:33 -0500 Subject: [PATCH 27/62] Fix SDO link in docs --- docs/guide/creating.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/creating.ipynb b/docs/guide/creating.ipynb index 058aae3..83efb56 100644 --- a/docs/guide/creating.ipynb +++ b/docs/guide/creating.ipynb @@ -498,7 +498,7 @@ "source": [ "As with indicators, the ``type``, ``id``, ``created``, and ``modified`` properties will be set automatically if not provided. For Malware objects, the ``labels`` and ``name`` properties must be provided.\n", "\n", - "You can see the full list of SDO classes [here](../api/stix2.v20.sdo.rst)." + "You can see the full list of SDO classes [here](../api/v20/stix2.v20.sdo.rst)." ] }, { From 69d2529f0ecfca41ddcd1d42a1a1945cd97a5de3 Mon Sep 17 00:00:00 2001 From: Chris Lenk Date: Wed, 6 Feb 2019 15:23:00 -0500 Subject: [PATCH 28/62] Fix style issues --- stix2/markings/utils.py | 2 +- stix2/properties.py | 2 +- stix2/test/v20/test_observed_data.py | 24 ++++++++++++------------ stix2/test/v21/test_observed_data.py | 18 +++++++++--------- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/stix2/markings/utils.py b/stix2/markings/utils.py index 4b4841c..d8bbf1d 100644 --- a/stix2/markings/utils.py +++ b/stix2/markings/utils.py @@ -39,7 +39,7 @@ def _validate_selector(obj, selector): def _get_marking_id(marking): - if type(marking).__name__ is 'MarkingDefinition': # avoid circular import + if type(marking).__name__ == 'MarkingDefinition': # avoid circular import return marking.id return marking diff --git a/stix2/properties.py b/stix2/properties.py index d6cc624..5de7a1e 100644 --- a/stix2/properties.py +++ b/stix2/properties.py @@ -143,7 +143,7 @@ class ListProperty(Property): if type(self.contained) is EmbeddedObjectProperty: obj_type = self.contained.type - elif type(self.contained).__name__ is "STIXObjectProperty": + elif type(self.contained).__name__ == "STIXObjectProperty": # ^ this way of checking doesn't require a circular import # valid is already an instance of a python-stix2 class; no need # to turn it into a dictionary and then pass it to the class diff --git a/stix2/test/v20/test_observed_data.py b/stix2/test/v20/test_observed_data.py index 1c3cad4..84cdf72 100644 --- a/stix2/test/v20/test_observed_data.py +++ b/stix2/test/v20/test_observed_data.py @@ -1095,11 +1095,11 @@ def test_process_example_empty_error(): def test_process_example_empty_with_extensions(): with pytest.raises(stix2.exceptions.AtLeastOnePropertyError) as excinfo: - stix2.v20.Process( - extensions={ - "windows-process-ext": {}, - }, - ) + stix2.v20.Process( + extensions={ + "windows-process-ext": {}, + }, + ) assert excinfo.value.cls == stix2.v20.WindowsProcessExt properties_of_extension = list(stix2.v20.WindowsProcessExt._properties.keys()) @@ -1127,13 +1127,13 @@ def test_process_example_windows_process_ext(): def test_process_example_windows_process_ext_empty(): with pytest.raises(stix2.exceptions.AtLeastOnePropertyError) as excinfo: - stix2.v20.Process( - pid=1221, - name="gedit-bin", - extensions={ - "windows-process-ext": {}, - }, - ) + stix2.v20.Process( + pid=1221, + name="gedit-bin", + extensions={ + "windows-process-ext": {}, + }, + ) assert excinfo.value.cls == stix2.v20.WindowsProcessExt properties_of_extension = list(stix2.v20.WindowsProcessExt._properties.keys()) diff --git a/stix2/test/v21/test_observed_data.py b/stix2/test/v21/test_observed_data.py index f3e1ea0..5d0f9b1 100644 --- a/stix2/test/v21/test_observed_data.py +++ b/stix2/test/v21/test_observed_data.py @@ -1073,9 +1073,9 @@ def test_process_example_empty_error(): def test_process_example_empty_with_extensions(): with pytest.raises(stix2.exceptions.AtLeastOnePropertyError) as excinfo: - stix2.v21.Process(extensions={ - "windows-process-ext": {}, - }) + stix2.v21.Process(extensions={ + "windows-process-ext": {}, + }) assert excinfo.value.cls == stix2.v21.WindowsProcessExt properties_of_extension = list(stix2.v21.WindowsProcessExt._properties.keys()) @@ -1102,12 +1102,12 @@ def test_process_example_windows_process_ext(): def test_process_example_windows_process_ext_empty(): with pytest.raises(stix2.exceptions.AtLeastOnePropertyError) as excinfo: - stix2.v21.Process( - pid=1221, - extensions={ - "windows-process-ext": {}, - }, - ) + stix2.v21.Process( + pid=1221, + extensions={ + "windows-process-ext": {}, + }, + ) assert excinfo.value.cls == stix2.v21.WindowsProcessExt properties_of_extension = list(stix2.v21.WindowsProcessExt._properties.keys()) From dc91c9cbf4f343a0d8483b404dd60b2e4b142cea Mon Sep 17 00:00:00 2001 From: "Desai, Kartikey H" Date: Wed, 6 Feb 2019 16:16:50 -0500 Subject: [PATCH 29/62] Initial fix for issue 86. Fixes #86 --- stix2/v21/sdo.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/stix2/v21/sdo.py b/stix2/v21/sdo.py index 37699a6..887fd0b 100644 --- a/stix2/v21/sdo.py +++ b/stix2/v21/sdo.py @@ -3,6 +3,8 @@ from collections import OrderedDict import itertools +from six.moves.urllib.parse import quote_plus + from ..core import STIXDomainObject from ..custom import _custom_object_builder from ..properties import ( @@ -263,6 +265,30 @@ class Location(STIXDomainObject): self._check_properties_dependency(['latitude'], ['longitude']) self._check_properties_dependency(['longitude'], ['latitude']) + def to_maps_url(self, map_engine="Google Maps"): + params = [] + if self.get('latitude') is not None and self.get('longitude') is not None: + latitude = self.get('latitude') + longitude = self.get('longitude') + params.extend([str(latitude), str(longitude)]) + else: + properties = ['street_address', 'city', 'region', 'administrative_area', 'country', 'postal_code'] + params = [self.get(prop) for prop in properties if self.get(prop) is not None] + + return self._to_maps_url_creator(map_engine, params) + + def _to_maps_url_creator(self, map_engine, params): + if map_engine == "Google Maps": + url_base = "https://www.google.com/maps/search/?api=1&query=" + url_ending = params[0] + for i in range(1, len(params)): + url_ending = url_ending + "," + params[i] + + final_url = url_base + quote_plus(url_ending) + return final_url + else: + return "Other map engines are not currently supported." + class Malware(STIXDomainObject): # TODO: Add link From 8be704a5b991724c14349e6e461a6f19aa790aff Mon Sep 17 00:00:00 2001 From: "Desai, Kartikey H" Date: Thu, 7 Feb 2019 10:31:51 -0500 Subject: [PATCH 30/62] Update to_map_url and add tests. Fixes #86 --- stix2/test/v21/test_location.py | 73 +++++++++++++++++++++++++++++++++ stix2/v21/sdo.py | 11 ++--- 2 files changed, 79 insertions(+), 5 deletions(-) diff --git a/stix2/test/v21/test_location.py b/stix2/test/v21/test_location.py index 5a4e17a..9244b1d 100644 --- a/stix2/test/v21/test_location.py +++ b/stix2/test/v21/test_location.py @@ -263,3 +263,76 @@ def test_location_lat_or_lon_dependency_missing(data, msg): stix2.parse(data) assert msg in str(excinfo.value) + + +def test_map_url_long_lat_provided(): + EXPECTED_URL = "https://www.google.com/maps/search/?api=1&query=41.862401%2C-87.616001" + now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc) + + loc = stix2.v21.Location( + type="location", + id=LOCATION_ID, + created=now, + modified=now, + latitude=41.862401, + longitude=-87.616001, + ) + + loc_url = loc.to_maps_url() + assert loc_url == EXPECTED_URL + + +def test_map_url_multiple_props_no_long_lat_provided(): + EXPECTED_URL = "https://www.google.com/maps/search/?api=1&query=1410+Museum+Campus+Drive%2C+Chicago%2C+IL+60605%2CUnited+States+of+America%2CNorth+America" + now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc) + + loc = stix2.v21.Location( + type="location", + id=LOCATION_ID, + created=now, + modified=now, + region="North America", + country="United States of America", + street_address="1410 Museum Campus Drive, Chicago, IL 60605", + ) + + loc_url = loc.to_maps_url() + assert loc_url == EXPECTED_URL + + +def test_map_url_multiple_props_and_long_lat_provided(): + EXPECTED_URL = "https://www.google.com/maps/search/?api=1&query=41.862401%2C-87.616001" + now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc) + + loc = stix2.v21.Location( + type="location", + id=LOCATION_ID, + created=now, + modified=now, + region="North America", + country="United States of America", + street_address="1410 Museum Campus Drive, Chicago, IL 60605", + latitude=41.862401, + longitude=-87.616001, + ) + + loc_url = loc.to_maps_url() + assert loc_url == EXPECTED_URL + + +def test_map_url_invalid_map_engine_provided(): + now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc) + + loc = stix2.v21.Location( + type="location", + id=LOCATION_ID, + created=now, + modified=now, + latitude=41.862401, + longitude=-87.616001, + ) + + with pytest.raises(ValueError) as excinfo: + loc.to_maps_url("Fake Maps") + + assert "is not a valid or currently-supported map engine" in str(excinfo.value) diff --git a/stix2/v21/sdo.py b/stix2/v21/sdo.py index 887fd0b..6fbb6f5 100644 --- a/stix2/v21/sdo.py +++ b/stix2/v21/sdo.py @@ -267,12 +267,13 @@ class Location(STIXDomainObject): def to_maps_url(self, map_engine="Google Maps"): params = [] - if self.get('latitude') is not None and self.get('longitude') is not None: - latitude = self.get('latitude') - longitude = self.get('longitude') + + latitude = self.get('latitude', None) + longitude = self.get('longitude', None) + if latitude is not None and longitude is not None: params.extend([str(latitude), str(longitude)]) else: - properties = ['street_address', 'city', 'region', 'administrative_area', 'country', 'postal_code'] + properties = ['street_address', 'city', 'country', 'region', 'administrative_area', 'postal_code'] params = [self.get(prop) for prop in properties if self.get(prop) is not None] return self._to_maps_url_creator(map_engine, params) @@ -287,7 +288,7 @@ class Location(STIXDomainObject): final_url = url_base + quote_plus(url_ending) return final_url else: - return "Other map engines are not currently supported." + raise ValueError(map_engine + " is not a valid or currently-supported map engine") class Malware(STIXDomainObject): From edfe0ba51adbc4b5ecd581752cd35a8c7539da93 Mon Sep 17 00:00:00 2001 From: "Desai, Kartikey H" Date: Fri, 8 Feb 2019 09:37:27 -0500 Subject: [PATCH 31/62] Add support for Bing Maps and corresponding tests. Fixes #86 --- stix2/test/v21/test_location.py | 61 +++++++++++++++++++++++++++++++-- stix2/v21/sdo.py | 32 ++++++++++++----- 2 files changed, 81 insertions(+), 12 deletions(-) diff --git a/stix2/test/v21/test_location.py b/stix2/test/v21/test_location.py index 9244b1d..c8bf0fc 100644 --- a/stix2/test/v21/test_location.py +++ b/stix2/test/v21/test_location.py @@ -265,7 +265,7 @@ def test_location_lat_or_lon_dependency_missing(data, msg): assert msg in str(excinfo.value) -def test_map_url_long_lat_provided(): +def test_google_map_url_long_lat_provided(): EXPECTED_URL = "https://www.google.com/maps/search/?api=1&query=41.862401%2C-87.616001" now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc) @@ -282,7 +282,7 @@ def test_map_url_long_lat_provided(): assert loc_url == EXPECTED_URL -def test_map_url_multiple_props_no_long_lat_provided(): +def test_google_map_url_multiple_props_no_long_lat_provided(): EXPECTED_URL = "https://www.google.com/maps/search/?api=1&query=1410+Museum+Campus+Drive%2C+Chicago%2C+IL+60605%2CUnited+States+of+America%2CNorth+America" now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc) @@ -300,7 +300,7 @@ def test_map_url_multiple_props_no_long_lat_provided(): assert loc_url == EXPECTED_URL -def test_map_url_multiple_props_and_long_lat_provided(): +def test_google_map_url_multiple_props_and_long_lat_provided(): EXPECTED_URL = "https://www.google.com/maps/search/?api=1&query=41.862401%2C-87.616001" now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc) @@ -336,3 +336,58 @@ def test_map_url_invalid_map_engine_provided(): loc.to_maps_url("Fake Maps") assert "is not a valid or currently-supported map engine" in str(excinfo.value) + + +def test_bing_map_url_long_lat_provided(): + EXPECTED_URL = "https://bing.com/maps/default.aspx?where1=41.862401%2C-87.616001&lvl=16" + now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc) + + loc = stix2.v21.Location( + type="location", + id=LOCATION_ID, + created=now, + modified=now, + latitude=41.862401, + longitude=-87.616001, + ) + + loc_url = loc.to_maps_url("Bing Maps") + assert loc_url == EXPECTED_URL + + +def test_bing_map_url_multiple_props_no_long_lat_provided(): + EXPECTED_URL = "https://bing.com/maps/default.aspx?where1=1410+Museum+Campus+Drive%2C+Chicago%2C+IL+60605%2CUnited+States+of+America%2CNorth+America&lvl=16" + now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc) + + loc = stix2.v21.Location( + type="location", + id=LOCATION_ID, + created=now, + modified=now, + region="North America", + country="United States of America", + street_address="1410 Museum Campus Drive, Chicago, IL 60605", + ) + + loc_url = loc.to_maps_url("Bing Maps") + assert loc_url == EXPECTED_URL + + +def test_bing_map_url_multiple_props_and_long_lat_provided(): + EXPECTED_URL = "https://bing.com/maps/default.aspx?where1=41.862401%2C-87.616001&lvl=16" + now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc) + + loc = stix2.v21.Location( + type="location", + id=LOCATION_ID, + created=now, + modified=now, + region="North America", + country="United States of America", + street_address="1410 Museum Campus Drive, Chicago, IL 60605", + latitude=41.862401, + longitude=-87.616001, + ) + + loc_url = loc.to_maps_url("Bing Maps") + assert loc_url == EXPECTED_URL diff --git a/stix2/v21/sdo.py b/stix2/v21/sdo.py index 6fbb6f5..cff8ba6 100644 --- a/stix2/v21/sdo.py +++ b/stix2/v21/sdo.py @@ -276,20 +276,34 @@ class Location(STIXDomainObject): properties = ['street_address', 'city', 'country', 'region', 'administrative_area', 'postal_code'] params = [self.get(prop) for prop in properties if self.get(prop) is not None] - return self._to_maps_url_creator(map_engine, params) + return self._to_maps_url_dispatcher(map_engine, params) - def _to_maps_url_creator(self, map_engine, params): + def _to_maps_url_dispatcher(self, map_engine, params): if map_engine == "Google Maps": - url_base = "https://www.google.com/maps/search/?api=1&query=" - url_ending = params[0] - for i in range(1, len(params)): - url_ending = url_ending + "," + params[i] - - final_url = url_base + quote_plus(url_ending) - return final_url + return self._to_google_maps_url(params) + elif map_engine == "Bing Maps": + return self._to_bing_maps_url(params) else: raise ValueError(map_engine + " is not a valid or currently-supported map engine") + def _to_google_maps_url(self, params): + url_base = "https://www.google.com/maps/search/?api=1&query=" + url_ending = params[0] + for i in range(1, len(params)): + url_ending = url_ending + "," + params[i] + + final_url = url_base + quote_plus(url_ending) + return final_url + + def _to_bing_maps_url(self, params): + url_base = "https://bing.com/maps/default.aspx?where1=" + url_ending = params[0] + for i in range(1, len(params)): + url_ending = url_ending + "," + params[i] + + final_url = url_base + quote_plus(url_ending) + "&lvl=16" # level 16 zoom so long/lat searches shown more clearly + return final_url + class Malware(STIXDomainObject): # TODO: Add link From e976f0a9260d2be48b8cceeba96dbff4db5923d6 Mon Sep 17 00:00:00 2001 From: Chris Lenk Date: Fri, 8 Feb 2019 14:17:19 -0500 Subject: [PATCH 32/62] Trim location tests We can rely on defaults for some properties we aren't testing. --- stix2/test/v21/test_location.py | 56 +++++++-------------------------- 1 file changed, 12 insertions(+), 44 deletions(-) diff --git a/stix2/test/v21/test_location.py b/stix2/test/v21/test_location.py index c8bf0fc..c734334 100644 --- a/stix2/test/v21/test_location.py +++ b/stix2/test/v21/test_location.py @@ -50,7 +50,6 @@ def test_location_with_some_required_properties(): now = dt.datetime(2016, 4, 6, 20, 3, 0, tzinfo=pytz.utc) loc = stix2.v21.Location( - type="location", id=LOCATION_ID, created=now, modified=now, @@ -266,24 +265,19 @@ def test_location_lat_or_lon_dependency_missing(data, msg): def test_google_map_url_long_lat_provided(): - EXPECTED_URL = "https://www.google.com/maps/search/?api=1&query=41.862401%2C-87.616001" - now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc) + expected_url = "https://www.google.com/maps/search/?api=1&query=41.862401%2C-87.616001" loc = stix2.v21.Location( - type="location", - id=LOCATION_ID, - created=now, - modified=now, latitude=41.862401, longitude=-87.616001, ) loc_url = loc.to_maps_url() - assert loc_url == EXPECTED_URL + assert loc_url == expected_url def test_google_map_url_multiple_props_no_long_lat_provided(): - EXPECTED_URL = "https://www.google.com/maps/search/?api=1&query=1410+Museum+Campus+Drive%2C+Chicago%2C+IL+60605%2CUnited+States+of+America%2CNorth+America" + expected_url = "https://www.google.com/maps/search/?api=1&query=1410+Museum+Campus+Drive%2C+Chicago%2C+IL+60605%2CUnited+States+of+America%2CNorth+America" now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc) loc = stix2.v21.Location( @@ -297,18 +291,13 @@ def test_google_map_url_multiple_props_no_long_lat_provided(): ) loc_url = loc.to_maps_url() - assert loc_url == EXPECTED_URL + assert loc_url == expected_url def test_google_map_url_multiple_props_and_long_lat_provided(): - EXPECTED_URL = "https://www.google.com/maps/search/?api=1&query=41.862401%2C-87.616001" - now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc) + expected_url = "https://www.google.com/maps/search/?api=1&query=41.862401%2C-87.616001" loc = stix2.v21.Location( - type="location", - id=LOCATION_ID, - created=now, - modified=now, region="North America", country="United States of America", street_address="1410 Museum Campus Drive, Chicago, IL 60605", @@ -317,17 +306,11 @@ def test_google_map_url_multiple_props_and_long_lat_provided(): ) loc_url = loc.to_maps_url() - assert loc_url == EXPECTED_URL + assert loc_url == expected_url def test_map_url_invalid_map_engine_provided(): - now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc) - loc = stix2.v21.Location( - type="location", - id=LOCATION_ID, - created=now, - modified=now, latitude=41.862401, longitude=-87.616001, ) @@ -339,49 +322,34 @@ def test_map_url_invalid_map_engine_provided(): def test_bing_map_url_long_lat_provided(): - EXPECTED_URL = "https://bing.com/maps/default.aspx?where1=41.862401%2C-87.616001&lvl=16" - now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc) + expected_url = "https://bing.com/maps/default.aspx?where1=41.862401%2C-87.616001&lvl=16" loc = stix2.v21.Location( - type="location", - id=LOCATION_ID, - created=now, - modified=now, latitude=41.862401, longitude=-87.616001, ) loc_url = loc.to_maps_url("Bing Maps") - assert loc_url == EXPECTED_URL + assert loc_url == expected_url def test_bing_map_url_multiple_props_no_long_lat_provided(): - EXPECTED_URL = "https://bing.com/maps/default.aspx?where1=1410+Museum+Campus+Drive%2C+Chicago%2C+IL+60605%2CUnited+States+of+America%2CNorth+America&lvl=16" - now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc) + expected_url = "https://bing.com/maps/default.aspx?where1=1410+Museum+Campus+Drive%2C+Chicago%2C+IL+60605%2CUnited+States+of+America%2CNorth+America&lvl=16" loc = stix2.v21.Location( - type="location", - id=LOCATION_ID, - created=now, - modified=now, region="North America", country="United States of America", street_address="1410 Museum Campus Drive, Chicago, IL 60605", ) loc_url = loc.to_maps_url("Bing Maps") - assert loc_url == EXPECTED_URL + assert loc_url == expected_url def test_bing_map_url_multiple_props_and_long_lat_provided(): - EXPECTED_URL = "https://bing.com/maps/default.aspx?where1=41.862401%2C-87.616001&lvl=16" - now = dt.datetime(2019, 2, 7, 12, 34, 56, tzinfo=pytz.utc) + expected_url = "https://bing.com/maps/default.aspx?where1=41.862401%2C-87.616001&lvl=16" loc = stix2.v21.Location( - type="location", - id=LOCATION_ID, - created=now, - modified=now, region="North America", country="United States of America", street_address="1410 Museum Campus Drive, Chicago, IL 60605", @@ -390,4 +358,4 @@ def test_bing_map_url_multiple_props_and_long_lat_provided(): ) loc_url = loc.to_maps_url("Bing Maps") - assert loc_url == EXPECTED_URL + assert loc_url == expected_url From afe57f642d35ef0ef877a1820832c5e8a1494ba2 Mon Sep 17 00:00:00 2001 From: Chris Lenk Date: Fri, 8 Feb 2019 14:41:54 -0500 Subject: [PATCH 33/62] Add docstring for to_maps_url() --- stix2/v21/sdo.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/stix2/v21/sdo.py b/stix2/v21/sdo.py index cff8ba6..accbd67 100644 --- a/stix2/v21/sdo.py +++ b/stix2/v21/sdo.py @@ -266,6 +266,17 @@ class Location(STIXDomainObject): self._check_properties_dependency(['longitude'], ['latitude']) def to_maps_url(self, map_engine="Google Maps"): + """Return URL to this location in an online map engine. + + Google Maps is the default, but Bing maps are also supported. + + Args: + map_engine (str): Which map engine to find the location in + + Returns: + The URL of the location in the given map engine. + + """ params = [] latitude = self.get('latitude', None) From bddfb06b2a921efa3bdfc134126be736308f76d2 Mon Sep 17 00:00:00 2001 From: Chris Lenk Date: Wed, 13 Feb 2019 10:37:11 -0500 Subject: [PATCH 34/62] Update CHANGELOG for v1.1.2 --- CHANGELOG | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 5e47891..9911e84 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,10 @@ CHANGELOG ========= +1.1.2 - 2019-02-13 + +* #86 Adds helper function to Location objects to generate a URL to the location in an online map engine. + 1.1.1 - 2019-01-11 * #234 Update documentation structure to better navigate between v20/v21 objects From f8d4669f800291fd5977efaf924c9bb97b12052f Mon Sep 17 00:00:00 2001 From: Chris Lenk Date: Wed, 13 Feb 2019 10:37:38 -0500 Subject: [PATCH 35/62] =?UTF-8?q?Bump=20version:=201.1.1=20=E2=86=92=201.1?= =?UTF-8?q?.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- setup.cfg | 2 +- stix2/version.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.cfg b/setup.cfg index e5e52e4..ae45560 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 1.1.1 +current_version = 1.1.2 commit = True tag = True diff --git a/stix2/version.py b/stix2/version.py index a82b376..72f26f5 100644 --- a/stix2/version.py +++ b/stix2/version.py @@ -1 +1 @@ -__version__ = "1.1.1" +__version__ = "1.1.2" From e748923f1906cc5da95c236ecdc7c0378d5967a3 Mon Sep 17 00:00:00 2001 From: "Desai, Kartikey H" Date: Wed, 17 Apr 2019 10:08:34 -0400 Subject: [PATCH 36/62] Fixes #248 --- stix2/base.py | 4 ++-- stix2/test/v20/test_object_markings.py | 2 -- stix2/test/v21/test_object_markings.py | 2 -- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/stix2/base.py b/stix2/base.py index a6bafff..9fcdf56 100644 --- a/stix2/base.py +++ b/stix2/base.py @@ -143,12 +143,12 @@ class _STIXBase(collections.Mapping): if custom_props: self.__allow_custom = True - # Remove any keyword arguments whose value is None + # Remove any keyword arguments whose value is None or [] (i.e. empty list) setting_kwargs = {} props = kwargs.copy() props.update(custom_props) for prop_name, prop_value in props.items(): - if prop_value is not None: + if prop_value is not None and prop_value != []: setting_kwargs[prop_name] = prop_value # Detect any missing required properties diff --git a/stix2/test/v20/test_object_markings.py b/stix2/test/v20/test_object_markings.py index 495c45a..156c42d 100644 --- a/stix2/test/v20/test_object_markings.py +++ b/stix2/test/v20/test_object_markings.py @@ -107,7 +107,6 @@ def test_add_markings_combination(): "data", [ ([""]), (""), - ([]), ([MARKING_IDS[0], 456]), ], ) @@ -576,7 +575,6 @@ def test_set_marking(): @pytest.mark.parametrize( "data", [ - ([]), ([""]), (""), ([MARKING_IDS[4], 687]), diff --git a/stix2/test/v21/test_object_markings.py b/stix2/test/v21/test_object_markings.py index d43aad5..7b19d4f 100644 --- a/stix2/test/v21/test_object_markings.py +++ b/stix2/test/v21/test_object_markings.py @@ -106,7 +106,6 @@ def test_add_markings_combination(): "data", [ ([""]), (""), - ([]), ([MARKING_IDS[0], 456]), ], ) @@ -575,7 +574,6 @@ def test_set_marking(): @pytest.mark.parametrize( "data", [ - ([]), ([""]), (""), ([MARKING_IDS[4], 687]), From 84fc71add45dab3f4b7ff4508b3fe6392a3d77d8 Mon Sep 17 00:00:00 2001 From: "Desai, Kartikey H" Date: Fri, 19 Apr 2019 12:17:42 -0400 Subject: [PATCH 37/62] Add test to ensure fix. Fixes #248 --- stix2/test/v20/test_malware.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/stix2/test/v20/test_malware.py b/stix2/test/v20/test_malware.py index d0c6d7e..900a4b9 100644 --- a/stix2/test/v20/test_malware.py +++ b/stix2/test/v20/test_malware.py @@ -35,6 +35,22 @@ def test_malware_with_all_required_properties(): assert str(mal) == EXPECTED_MALWARE +def test_malware_with_empty_optional_field(): + now = dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc) + + mal = stix2.v20.Malware( + type="malware", + id=MALWARE_ID, + created=now, + modified=now, + labels=["ransomware"], + name="Cryptolocker", + external_references=[], + ) + + assert str(mal) == EXPECTED_MALWARE + + def test_malware_autogenerated_properties(malware): assert malware.type == 'malware' assert malware.id == 'malware--00000000-0000-4000-8000-000000000001' From 4bbabaecb2a2275a891c91f77cd94828be7ba9a3 Mon Sep 17 00:00:00 2001 From: Emmanuelle Vargas-Gonzalez Date: Mon, 22 Apr 2019 15:25:46 -0400 Subject: [PATCH 38/62] update marking API methods to allow/use the 'lang' property including utility methods that expand collapse markings --- stix2/markings/__init__.py | 42 ++++++++++----- stix2/markings/granular_markings.py | 84 ++++++++++++++++++++--------- stix2/markings/utils.py | 31 ++++++++--- 3 files changed, 110 insertions(+), 47 deletions(-) diff --git a/stix2/markings/__init__.py b/stix2/markings/__init__.py index 79d1012..b0dba6b 100644 --- a/stix2/markings/__init__.py +++ b/stix2/markings/__init__.py @@ -22,7 +22,7 @@ Note: from stix2.markings import granular_markings, object_markings -def get_markings(obj, selectors=None, inherited=False, descendants=False): +def get_markings(obj, selectors=None, inherited=False, descendants=False, marking_ref=True, lang=True): """ Get all markings associated to the field(s) specified by selectors. @@ -30,10 +30,13 @@ def get_markings(obj, selectors=None, inherited=False, descendants=False): obj: An SDO or SRO object. selectors: string or list of selectors strings relative to the SDO or SRO in which the properties appear. - inherited: If True, include object level markings and granular markings - inherited relative to the properties. - descendants: If True, include granular markings applied to any children - relative to the properties. + inherited (bool): If True, include object level markings and granular + markings inherited relative to the properties. + descendants (bool): If True, include granular markings applied to any + children relative to the properties. + marking_ref (bool): If False, excludes markings that use + ``marking_ref`` property. + lang (bool): If False, excludes markings that use ``lang`` property. Returns: list: Marking identifiers that matched the selectors expression. @@ -51,6 +54,8 @@ def get_markings(obj, selectors=None, inherited=False, descendants=False): selectors, inherited, descendants, + marking_ref, + lang ) if inherited: @@ -59,7 +64,7 @@ def get_markings(obj, selectors=None, inherited=False, descendants=False): return list(set(results)) -def set_markings(obj, marking, selectors=None): +def set_markings(obj, marking, selectors=None, marking_ref=True, lang=True): """ Remove all markings associated with selectors and appends a new granular marking. Refer to `clear_markings` and `add_markings` for details. @@ -70,6 +75,10 @@ def set_markings(obj, marking, selectors=None): properties selected by `selectors`. selectors: string or list of selectors strings relative to the SDO or SRO in which the properties appear. + marking_ref (bool): If False, markings that use the ``marking_ref`` + property will not be removed. + lang (bool): If False, markings that use the ``lang`` property + will not be removed. Returns: A new version of the given SDO or SRO with specified markings removed @@ -83,7 +92,7 @@ def set_markings(obj, marking, selectors=None): if selectors is None: return object_markings.set_markings(obj, marking) else: - return granular_markings.set_markings(obj, marking, selectors) + return granular_markings.set_markings(obj, marking, selectors, marking_ref, lang) def remove_markings(obj, marking, selectors=None): @@ -144,7 +153,7 @@ def add_markings(obj, marking, selectors=None): return granular_markings.add_markings(obj, marking, selectors) -def clear_markings(obj, selectors=None): +def clear_markings(obj, selectors=None, marking_ref=True, lang=True): """ Remove all markings associated with the selectors. @@ -152,6 +161,10 @@ def clear_markings(obj, selectors=None): obj: An SDO or SRO object. selectors: string or list of selectors strings relative to the SDO or SRO in which the field(s) appear(s). + marking_ref (bool): If False, markings that use the ``marking_ref`` + property will not be removed. + lang (bool): If False, markings that use the ``lang`` property + will not be removed. Raises: InvalidSelectorError: If `selectors` fail validation. @@ -169,7 +182,7 @@ def clear_markings(obj, selectors=None): if selectors is None: return object_markings.clear_markings(obj) else: - return granular_markings.clear_markings(obj, selectors) + return granular_markings.clear_markings(obj, selectors, marking_ref, lang) def is_marked(obj, marking=None, selectors=None, inherited=False, descendants=False): @@ -182,10 +195,11 @@ def is_marked(obj, marking=None, selectors=None, inherited=False, descendants=Fa properties selected by `selectors`. selectors: string or list of selectors strings relative to the SDO or SRO in which the field(s) appear(s). - inherited: If True, include object level markings and granular markings - inherited to determine if the properties is/are marked. - descendants: If True, include granular markings applied to any children - of the given selector to determine if the properties is/are marked. + inherited (bool): If True, include object level markings and granular + markings inherited to determine if the properties is/are marked. + descendants (bool): If True, include granular markings applied to any + children of the given selector to determine if the properties + is/are marked. Returns: bool: True if ``selectors`` is found on internal SDO or SRO collection. @@ -228,7 +242,7 @@ def is_marked(obj, marking=None, selectors=None, inherited=False, descendants=Fa return result -class _MarkingsMixin(): +class _MarkingsMixin(object): pass diff --git a/stix2/markings/granular_markings.py b/stix2/markings/granular_markings.py index 09c3d37..a1c8479 100644 --- a/stix2/markings/granular_markings.py +++ b/stix2/markings/granular_markings.py @@ -2,10 +2,10 @@ from stix2 import exceptions from stix2.markings import utils -from stix2.utils import new_version +from stix2.utils import new_version, is_marking -def get_markings(obj, selectors, inherited=False, descendants=False): +def get_markings(obj, selectors, inherited=False, descendants=False, marking_ref=True, lang=True): """ Get all granular markings associated to with the properties. @@ -13,10 +13,13 @@ def get_markings(obj, selectors, inherited=False, descendants=False): obj: An SDO or SRO object. selectors: string or list of selector strings relative to the SDO or SRO in which the properties appear. - inherited: If True, include markings inherited relative to the + inherited (bool): If True, include markings inherited relative to the properties. - descendants: If True, include granular markings applied to any children - relative to the properties. + descendants (bool): If True, include granular markings applied to any + children relative to the properties. + marking_ref (bool): If False, excludes markings that use + ``marking_ref`` property. + lang (bool): If False, excludes markings that use ``lang`` property. Raises: InvalidSelectorError: If `selectors` fail validation. @@ -43,13 +46,18 @@ def get_markings(obj, selectors, inherited=False, descendants=False): (user_selector.startswith(marking_selector) and inherited), # Catch inherited selectors. (marking_selector.startswith(user_selector) and descendants), ]): # Catch descendants selectors - refs = marking.get('marking_ref', []) - results.update([refs]) + ref = marking.get('marking_ref') + lng = marking.get('lang') + + if ref and marking_ref: + results.add(ref) + if lng and lang: + results.add(lng) return list(results) -def set_markings(obj, marking, selectors): +def set_markings(obj, marking, selectors, marking_ref=True, lang=True): """ Remove all granular markings associated with selectors and append a new granular marking. Refer to `clear_markings` and `add_markings` for details. @@ -60,19 +68,25 @@ def set_markings(obj, marking, selectors): SRO in which the properties appear. marking: identifier or list of marking identifiers that apply to the properties selected by `selectors`. + marking_ref (bool): If False, markings that use the ``marking_ref`` + property will not be removed. + lang (bool): If False, markings that use the ``lang`` property + will not be removed. Returns: A new version of the given SDO or SRO with specified markings removed and new ones added. """ - obj = clear_markings(obj, selectors) + obj = clear_markings(obj, selectors, marking_ref, lang) return add_markings(obj, marking, selectors) def remove_markings(obj, marking, selectors): """ - Remove a granular marking from the granular_markings collection. + Remove a granular marking from the granular_markings collection. The method + makes a best-effort attempt to distinguish between a marking-definition + or language granular marking. Args: obj: An SDO or SRO object. @@ -103,7 +117,10 @@ def remove_markings(obj, marking, selectors): to_remove = [] for m in marking: - to_remove.append({'marking_ref': m, 'selectors': selectors}) + if is_marking(m): + to_remove.append({'marking_ref': m, 'selectors': selectors}) + else: + to_remove.append({'lang': m, 'selectors': selectors}) remove = utils.build_granular_marking(to_remove).get('granular_markings') @@ -124,7 +141,9 @@ def remove_markings(obj, marking, selectors): def add_markings(obj, marking, selectors): """ - Append a granular marking to the granular_markings collection. + Append a granular marking to the granular_markings collection. The method + makes a best-effort attempt to distinguish between a marking-definition + or language granular marking. Args: obj: An SDO or SRO object. @@ -146,7 +165,10 @@ def add_markings(obj, marking, selectors): granular_marking = [] for m in marking: - granular_marking.append({'marking_ref': m, 'selectors': sorted(selectors)}) + if is_marking(m): + granular_marking.append({'marking_ref': m, 'selectors': sorted(selectors)}) + else: + granular_marking.append({'lang': m, 'selectors': sorted(selectors)}) if obj.get('granular_markings'): granular_marking.extend(obj.get('granular_markings')) @@ -156,7 +178,7 @@ def add_markings(obj, marking, selectors): return new_version(obj, granular_markings=granular_marking, allow_custom=True) -def clear_markings(obj, selectors): +def clear_markings(obj, selectors, marking_ref=True, lang=True): """ Remove all granular markings associated with the selectors. @@ -164,6 +186,10 @@ def clear_markings(obj, selectors): obj: An SDO or SRO object. selectors: string or list of selectors strings relative to the SDO or SRO in which the properties appear. + marking_ref (bool): If False, markings that use the ``marking_ref`` + property will not be removed. + lang (bool): If False, markings that use the ``lang`` property + will not be removed. Raises: InvalidSelectorError: If `selectors` fail validation. @@ -184,11 +210,12 @@ def clear_markings(obj, selectors): granular_markings = utils.expand_markings(granular_markings) - sdo = utils.build_granular_marking( - [{'selectors': selectors, 'marking_ref': 'N/A'}], - ) + granular_dict = utils.build_granular_marking([ + {'selectors': selectors, 'marking_ref': 'N/A'}, + {'selectors': selectors, 'lang': 'N/A'} + ]) - clear = sdo.get('granular_markings', []) + clear = granular_dict.get('granular_markings', []) if not any( clear_selector in sdo_selectors.get('selectors', []) @@ -201,10 +228,13 @@ def clear_markings(obj, selectors): for granular_marking in granular_markings: for s in selectors: if s in granular_marking.get('selectors', []): - marking_refs = granular_marking.get('marking_ref') + ref = granular_marking.get('marking_ref') + lng = granular_marking.get('lang') - if marking_refs: + if ref and marking_ref: granular_marking['marking_ref'] = '' + if lng and lang: + granular_marking['lang'] = '' granular_markings = utils.compress_markings(granular_markings) @@ -222,11 +252,12 @@ def is_marked(obj, marking=None, selectors=None, inherited=False, descendants=Fa obj: An SDO or SRO object. marking: identifier or list of marking identifiers that apply to the properties selected by `selectors`. - selectors: string or list of selectors strings relative to the SDO or - SRO in which the properties appear. - inherited: If True, return markings inherited from the given selector. - descendants: If True, return granular markings applied to any children - of the given selector. + selectors (bool): string or list of selectors strings relative to the + SDO or SRO in which the properties appear. + inherited (bool): If True, return markings inherited from the given + selector. + descendants (bool): If True, return granular markings applied to any + children of the given selector. Raises: InvalidSelectorError: If `selectors` fail validation. @@ -262,9 +293,12 @@ def is_marked(obj, marking=None, selectors=None, inherited=False, descendants=Fa (marking_selector.startswith(user_selector) and descendants), ]): # Catch descendants selectors marking_ref = granular_marking.get('marking_ref', '') + lang = granular_marking.get('lang', '') if marking and any(x == marking_ref for x in marking): markings.update([marking_ref]) + if marking and any(x == lang for x in marking): + markings.update([lang]) marked = True diff --git a/stix2/markings/utils.py b/stix2/markings/utils.py index d8bbf1d..7a6aae1 100644 --- a/stix2/markings/utils.py +++ b/stix2/markings/utils.py @@ -5,6 +5,7 @@ import collections import six from stix2 import exceptions +from stix2.utils import is_marking def _evaluate_expression(obj, selector): @@ -121,10 +122,15 @@ def compress_markings(granular_markings): if granular_marking.get('marking_ref'): map_[granular_marking.get('marking_ref')].update(granular_marking.get('selectors')) + if granular_marking.get('lang'): + map_[granular_marking.get('lang')].update(granular_marking.get('selectors')) + compressed = \ [ - {'marking_ref': marking_ref, 'selectors': sorted(selectors)} - for marking_ref, selectors in six.iteritems(map_) + {'marking_ref': item, 'selectors': sorted(selectors)} + if is_marking(item) else + {'lang': item, 'selectors': sorted(selectors)} + for item, selectors in six.iteritems(map_) ] return compressed @@ -174,13 +180,22 @@ def expand_markings(granular_markings): for marking in granular_markings: selectors = marking.get('selectors') marking_ref = marking.get('marking_ref') + lang = marking.get('lang') - expanded.extend( - [ - {'marking_ref': marking_ref, 'selectors': [selector]} - for selector in selectors - ], - ) + if marking_ref: + expanded.extend( + [ + {'marking_ref': marking_ref, 'selectors': [selector]} + for selector in selectors + ], + ) + if lang: + expanded.extend( + [ + {'lang': lang, 'selectors': [selector]} + for selector in selectors + ], + ) return expanded From 0c78acafd0d1e5c90088085767b3317c19d5e8fe Mon Sep 17 00:00:00 2001 From: Emmanuelle Vargas-Gonzalez Date: Mon, 22 Apr 2019 15:26:21 -0400 Subject: [PATCH 39/62] add tests to cover the language aspect of the markings --- stix2/test/v21/constants.py | 6 + stix2/test/v21/test_granular_markings.py | 221 ++++++++++++++++++++++- stix2/test/v21/test_markings.py | 48 ++++- 3 files changed, 272 insertions(+), 3 deletions(-) diff --git a/stix2/test/v21/constants.py b/stix2/test/v21/constants.py index bbce32c..b0ba1ef 100644 --- a/stix2/test/v21/constants.py +++ b/stix2/test/v21/constants.py @@ -31,6 +31,12 @@ MARKING_IDS = [ "marking-definition--68520ae2-fefe-43a9-84ee-2c2a934d2c7d", "marking-definition--2802dfb1-1019-40a8-8848-68d0ec0e417f", ] +MARKING_LANGS = [ + "en", + "es", + "de", + "ja", +] RELATIONSHIP_IDS = [ 'relationship--06520621-5352-4e6a-b976-e8fa3d437ffd', 'relationship--181c9c09-43e6-45dd-9374-3bec192f05ef', diff --git a/stix2/test/v21/test_granular_markings.py b/stix2/test/v21/test_granular_markings.py index 9f7234e..5d70063 100644 --- a/stix2/test/v21/test_granular_markings.py +++ b/stix2/test/v21/test_granular_markings.py @@ -5,7 +5,7 @@ from stix2.exceptions import MarkingNotFoundError from stix2.v21 import TLP_RED, Malware from .constants import MALWARE_MORE_KWARGS as MALWARE_KWARGS_CONST -from .constants import MARKING_IDS +from .constants import MARKING_IDS, MARKING_LANGS """Tests for the Data Markings API.""" @@ -111,6 +111,37 @@ def test_add_marking_mark_multiple_selector_multiple_refs(): assert m in after["granular_markings"] +def test_add_marking_mark_multiple_selector_multiple_refs_mixed(): + before = Malware( + **MALWARE_KWARGS + ) + after = Malware( + granular_markings=[ + { + "selectors": ["description", "name"], + "marking_ref": MARKING_IDS[0], + }, + { + "selectors": ["description", "name"], + "marking_ref": MARKING_IDS[1], + }, + { + "selectors": ["description", "name"], + "lang": MARKING_LANGS[0], + }, + { + "selectors": ["description", "name"], + "lang": MARKING_LANGS[1], + }, + ], + **MALWARE_KWARGS + ) + before = markings.add_markings(before, [MARKING_IDS[0], MARKING_IDS[1], MARKING_LANGS[0], MARKING_LANGS[1]], ["description", "name"]) + + for m in before["granular_markings"]: + assert m in after["granular_markings"] + + def test_add_marking_mark_another_property_same_marking(): before = Malware( granular_markings=[ @@ -376,6 +407,98 @@ def test_get_markings_positional_arguments_combinations(data): assert set(markings.get_markings(data, "x.z.foo2", False, True)) == set(["10"]) +GET_MARKINGS_TEST_DATA_LANGS = { + "a": 333, + "b": "value", + "c": [ + 17, + "list value", + { + "g": "nested", + "h": 45, + }, + ], + "x": { + "y": [ + "hello", + 88, + ], + "z": { + "foo1": "bar", + "foo2": 65, + }, + }, + "granular_markings": [ + { + "marking_ref": "m1", + "selectors": ["a"], + }, + { + "marking_ref": "m2", + "selectors": ["c"], + }, + { + "marking_ref": "m3", + "selectors": ["c.[1]"], + }, + { + "marking_ref": "m4", + "selectors": ["c.[2]"], + }, + { + "marking_ref": "m5", + "selectors": ["c.[2].g"], + }, + { + "marking_ref": "m6", + "selectors": ["x"], + }, + { + "lang": "l7", + "selectors": ["x.y"], + }, + { + "marking_ref": "m8", + "selectors": ["x.y.[1]"], + }, + { + "lang": "l9", + "selectors": ["x.z"], + }, + { + "marking_ref": "m9", + "selectors": ["x.z"], + }, + { + "marking_ref": "m10", + "selectors": ["x.z.foo2"], + }, + ], +} + + +@pytest.mark.parametrize("data", [GET_MARKINGS_TEST_DATA_LANGS]) +def test_get_markings_multiple_selectors(data): + """Test multiple selectors return combination of markings.""" + total = markings.get_markings(data, ["x.y", "x.z"]) + xy_markings = markings.get_markings(data, ["x.y"]) + xz_markings = markings.get_markings(data, ["x.z"]) + + assert set(xy_markings).issubset(total) + assert set(xz_markings).issubset(total) + assert set(xy_markings).union(xz_markings).issuperset(total) + + +@pytest.mark.parametrize("data", [GET_MARKINGS_TEST_DATA_LANGS]) +def test_get_markings_multiple_selectors_with_options(data): + """Test multiple selectors return combination of markings.""" + total = markings.get_markings(data, ["x.y", "x.z"], lang=False) + xz_markings = markings.get_markings(data, ["x.z"], marking_ref=False) + + assert len(total) == 1 + assert len(xz_markings) == 1 + + @pytest.mark.parametrize( "data", [ ( @@ -455,6 +578,38 @@ def test_remove_marking_mark_one_selector_from_multiple_ones(): assert m in after["granular_markings"] +def test_remove_marking_mark_one_selector_from_multiple_ones_mixed(): + after = Malware( + granular_markings=[ + { + "selectors": ["description"], + "marking_ref": MARKING_IDS[0], + }, + { + "selectors": ["description"], + "lang": MARKING_LANGS[0], + }, + ], + **MALWARE_KWARGS + ) + before = Malware( + granular_markings=[ + { + "selectors": ["description", "modified"], + "marking_ref": MARKING_IDS[0], + }, + { + "selectors": ["description", "modified"], + "lang": MARKING_LANGS[0], + }, + ], + **MALWARE_KWARGS + ) + before = markings.remove_markings(before, [MARKING_IDS[0], MARKING_LANGS[0]], ["modified"]) + for m in before["granular_markings"]: + assert m in after["granular_markings"] + + def test_remove_marking_mark_one_selector_markings_from_multiple_ones(): after = Malware( granular_markings=[ @@ -592,6 +747,10 @@ IS_MARKED_TEST_DATA = [ "selectors": ["malware_types", "description"], "marking_ref": MARKING_IDS[3], }, + { + "selectors": ["name"], + "lang": MARKING_LANGS[1], + }, ], **MALWARE_KWARGS ), @@ -609,6 +768,10 @@ IS_MARKED_TEST_DATA = [ "selectors": ["malware_types", "description"], "marking_ref": MARKING_IDS[3], }, + { + "selectors": ["name"], + "lang": MARKING_LANGS[1], + }, ], **MALWARE_KWARGS ), @@ -620,6 +783,7 @@ def test_is_marked_smoke(data): """Smoke test is_marked call does not fail.""" assert markings.is_marked(data, selectors=["description"]) assert markings.is_marked(data, selectors=["modified"]) is False + assert markings.is_marked(data, selectors=["name"]) @pytest.mark.parametrize( @@ -666,6 +830,7 @@ def test_is_marked_valid_selector_and_refs(data): """Test that a valid selector returns True when marking_refs match.""" assert markings.is_marked(data, [MARKING_IDS[1]], ["description"]) assert markings.is_marked(data, [MARKING_IDS[1]], ["modified"]) is False + assert markings.is_marked(data, [MARKING_LANGS[1]], ["name"]) @pytest.mark.parametrize("data", IS_MARKED_TEST_DATA) @@ -870,6 +1035,28 @@ def test_set_marking_mark_one_selector_multiple_refs(): assert m in after["granular_markings"] +def test_set_marking_mark_one_selector_multiple_lang_refs(): + before = Malware( + **MALWARE_KWARGS + ) + after = Malware( + granular_markings=[ + { + "selectors": ["description"], + "lang": MARKING_LANGS[0], + }, + { + "selectors": ["description"], + "lang": MARKING_LANGS[1], + }, + ], + **MALWARE_KWARGS + ) + before = markings.set_markings(before, [MARKING_LANGS[0], MARKING_LANGS[1]], ["description"]) + for m in before["granular_markings"]: + assert m in after["granular_markings"] + + def test_set_marking_mark_multiple_selector_one_refs(): before = Malware( granular_markings=[ @@ -894,6 +1081,38 @@ def test_set_marking_mark_multiple_selector_one_refs(): assert m in after["granular_markings"] +def test_set_marking_mark_multiple_mixed_markings(): + before = Malware( + granular_markings=[ + { + "selectors": ["description", "modified"], + "marking_ref": MARKING_IDS[1], + }, + { + "selectors": ["description", "modified"], + "lang": MARKING_LANGS[2], + }, + ], + **MALWARE_KWARGS + ) + after = Malware( + granular_markings=[ + { + "selectors": ["description", "modified"], + "marking_ref": MARKING_IDS[2], + }, + { + "selectors": ["description", "modified"], + "lang": MARKING_LANGS[3], + }, + ], + **MALWARE_KWARGS + ) + before = markings.set_markings(before, [MARKING_IDS[2], MARKING_LANGS[3]], ["description", "modified"]) + for m in before["granular_markings"]: + assert m in after["granular_markings"] + + def test_set_marking_mark_multiple_selector_multiple_refs_from_none(): before = Malware( **MALWARE_KWARGS diff --git a/stix2/test/v21/test_markings.py b/stix2/test/v21/test_markings.py index 7793889..7e0cf91 100644 --- a/stix2/test/v21/test_markings.py +++ b/stix2/test/v21/test_markings.py @@ -54,7 +54,7 @@ EXPECTED_GRANULAR_MARKING = """{ ] }""" -EXPECTED_CAMPAIGN_WITH_GRANULAR_MARKINGS = """{ +EXPECTED_CAMPAIGN_WITH_GRANULAR_REF_MARKINGS = """{ "type": "campaign", "spec_version": "2.1", "id": "campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", @@ -74,6 +74,27 @@ EXPECTED_CAMPAIGN_WITH_GRANULAR_MARKINGS = """{ }""" +EXPECTED_CAMPAIGN_WITH_GRANULAR_LANG_MARKINGS = """{ + "type": "campaign", + "spec_version": "2.1", + "id": "campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", + "created_by_ref": "identity--311b2d2d-f010-4473-83ec-1edf84858f4c", + "created": "2016-04-06T20:03:00.000Z", + "modified": "2016-04-06T20:03:00.000Z", + "name": "Bank Attack", + "description": "Weitere Informationen über Banküberfall", + "lang": "en", + "granular_markings": [ + { + "lang": "de", + "selectors": [ + "description" + ] + } + ] +}""" + + def test_marking_def_example_with_tlp(): assert str(TLP_WHITE) == EXPECTED_TLP_MARKING_DEFINITION @@ -161,7 +182,7 @@ def test_campaign_with_granular_markings_example(): ), ], ) - assert str(campaign) == EXPECTED_CAMPAIGN_WITH_GRANULAR_MARKINGS + assert str(campaign) == EXPECTED_CAMPAIGN_WITH_GRANULAR_REF_MARKINGS @pytest.mark.parametrize( @@ -273,3 +294,26 @@ def test_campaign_add_markings(): ) campaign = campaign.add_markings(TLP_WHITE) assert campaign.object_marking_refs[0] == TLP_WHITE.id + + +def test_campaign_with_granular_lang_markings_example(): + campaign = stix2.v21.Campaign( + id="campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", + created_by_ref=IDENTITY_ID, + created="2016-04-06T20:03:00Z", + modified="2016-04-06T20:03:00Z", + name="Bank Attack", + lang="en", + description="Weitere Informationen über Banküberfall", + granular_markings=[ + stix2.v21.GranularMarking( + lang="de", + selectors=["description"], + ), + ], + ) + + # In order to provide the same representation, we need to disable escaping + # in json.dumps(). https://docs.python.org/3/library/json.html#json.dumps + # or https://docs.python.org/2/library/json.html#json.dumps + assert campaign.serialize(pretty=True, ensure_ascii=False) == EXPECTED_CAMPAIGN_WITH_GRANULAR_LANG_MARKINGS From dbc63b7b9fcb71b9b9f0fbeee1591e363a660736 Mon Sep 17 00:00:00 2001 From: Emmanuelle Vargas-Gonzalez Date: Tue, 23 Apr 2019 07:43:56 -0400 Subject: [PATCH 40/62] pre-commit changes --- stix2/markings/__init__.py | 2 +- stix2/markings/granular_markings.py | 4 ++-- stix2/test/v21/test_granular_markings.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/stix2/markings/__init__.py b/stix2/markings/__init__.py index b0dba6b..6d09f81 100644 --- a/stix2/markings/__init__.py +++ b/stix2/markings/__init__.py @@ -55,7 +55,7 @@ def get_markings(obj, selectors=None, inherited=False, descendants=False, markin inherited, descendants, marking_ref, - lang + lang, ) if inherited: diff --git a/stix2/markings/granular_markings.py b/stix2/markings/granular_markings.py index a1c8479..5456f83 100644 --- a/stix2/markings/granular_markings.py +++ b/stix2/markings/granular_markings.py @@ -2,7 +2,7 @@ from stix2 import exceptions from stix2.markings import utils -from stix2.utils import new_version, is_marking +from stix2.utils import is_marking, new_version def get_markings(obj, selectors, inherited=False, descendants=False, marking_ref=True, lang=True): @@ -212,7 +212,7 @@ def clear_markings(obj, selectors, marking_ref=True, lang=True): granular_dict = utils.build_granular_marking([ {'selectors': selectors, 'marking_ref': 'N/A'}, - {'selectors': selectors, 'lang': 'N/A'} + {'selectors': selectors, 'lang': 'N/A'}, ]) clear = granular_dict.get('granular_markings', []) diff --git a/stix2/test/v21/test_granular_markings.py b/stix2/test/v21/test_granular_markings.py index 5d70063..e178f86 100644 --- a/stix2/test/v21/test_granular_markings.py +++ b/stix2/test/v21/test_granular_markings.py @@ -478,7 +478,7 @@ GET_MARKINGS_TEST_DATA_LANGS = { @pytest.mark.parametrize("data", [GET_MARKINGS_TEST_DATA_LANGS]) -def test_get_markings_multiple_selectors(data): +def test_get_markings_multiple_selectors_langs(data): """Test multiple selectors return combination of markings.""" total = markings.get_markings(data, ["x.y", "x.z"]) xy_markings = markings.get_markings(data, ["x.y"]) From f8857569d5c189c8d8267e8290052b927a97d7c9 Mon Sep 17 00:00:00 2001 From: Emmanuelle Vargas-Gonzalez Date: Tue, 23 Apr 2019 07:48:51 -0400 Subject: [PATCH 41/62] Add header to test file --- stix2/test/v21/test_markings.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/stix2/test/v21/test_markings.py b/stix2/test/v21/test_markings.py index 7e0cf91..a7dff22 100644 --- a/stix2/test/v21/test_markings.py +++ b/stix2/test/v21/test_markings.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- + import datetime as dt import pytest From c3aecd76ba37f7c1d3fbc33f8b59175a578df2f8 Mon Sep 17 00:00:00 2001 From: Emmanuelle Vargas-Gonzalez Date: Tue, 23 Apr 2019 09:27:21 -0400 Subject: [PATCH 42/62] update unnecesary property clean-up and add tests --- stix2/properties.py | 20 +++++++++++--------- stix2/test/v21/test_markings.py | 2 +- stix2/test/v21/test_properties.py | 5 +++++ 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/stix2/properties.py b/stix2/properties.py index 5de7a1e..f4060e5 100644 --- a/stix2/properties.py +++ b/stix2/properties.py @@ -183,11 +183,12 @@ class CallableValues(list): class StringProperty(Property): def __init__(self, **kwargs): - self.string_type = text_type super(StringProperty, self).__init__(**kwargs) def clean(self, value): - return self.string_type(value) + if not isinstance(value, string_types): + return text_type(value) + return value class TypeProperty(Property): @@ -439,21 +440,22 @@ class EnumProperty(StringProperty): super(EnumProperty, self).__init__(**kwargs) def clean(self, value): - value = super(EnumProperty, self).clean(value) - if value not in self.allowed: - raise ValueError("value '{}' is not valid for this enumeration.".format(value)) - return self.string_type(value) + cleaned_value = super(EnumProperty, self).clean(value) + if cleaned_value not in self.allowed: + raise ValueError("value '{}' is not valid for this enumeration.".format(cleaned_value)) + + return cleaned_value class PatternProperty(StringProperty): def clean(self, value): - str_value = super(PatternProperty, self).clean(value) - errors = run_validator(str_value) + cleaned_value = super(PatternProperty, self).clean(value) + errors = run_validator(cleaned_value) if errors: raise ValueError(str(errors[0])) - return self.string_type(value) + return cleaned_value class ObservableProperty(Property): diff --git a/stix2/test/v21/test_markings.py b/stix2/test/v21/test_markings.py index a7dff22..bd247e6 100644 --- a/stix2/test/v21/test_markings.py +++ b/stix2/test/v21/test_markings.py @@ -76,7 +76,7 @@ EXPECTED_CAMPAIGN_WITH_GRANULAR_REF_MARKINGS = """{ }""" -EXPECTED_CAMPAIGN_WITH_GRANULAR_LANG_MARKINGS = """{ +EXPECTED_CAMPAIGN_WITH_GRANULAR_LANG_MARKINGS = u"""{ "type": "campaign", "spec_version": "2.1", "id": "campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", diff --git a/stix2/test/v21/test_properties.py b/stix2/test/v21/test_properties.py index 298a8df..e4fa4a0 100644 --- a/stix2/test/v21/test_properties.py +++ b/stix2/test/v21/test_properties.py @@ -450,6 +450,11 @@ def test_enum_property_valid(value): assert enum_prop.clean('b') +def test_enum_property_clean(): + enum_prop = EnumProperty(['1']) + assert enum_prop.clean(1) == '1' + + def test_enum_property_invalid(): enum_prop = EnumProperty(['a', 'b', 'c']) with pytest.raises(ValueError): From fff0e9e7315bcabb898287625d65561d1c312211 Mon Sep 17 00:00:00 2001 From: Emmanuelle Vargas-Gonzalez Date: Fri, 3 May 2019 09:58:45 -0400 Subject: [PATCH 43/62] update test_datastore_filesystem.py to create proper tlp markings --- stix2/test/v20/test_datastore_filesystem.py | 4 ++++ stix2/test/v21/test_datastore_filesystem.py | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/stix2/test/v20/test_datastore_filesystem.py b/stix2/test/v20/test_datastore_filesystem.py index 86846c4..25de37e 100644 --- a/stix2/test/v20/test_datastore_filesystem.py +++ b/stix2/test/v20/test_datastore_filesystem.py @@ -450,6 +450,8 @@ def test_filesystem_attempt_stix_file_overwrite(fs_store): def test_filesystem_sink_marking(fs_sink): marking = stix2.v20.MarkingDefinition( + id="marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da", + created="2017-01-20T00:00:00.000Z", definition_type="tlp", definition=stix2.v20.TLPMarking(tlp="green"), ) @@ -583,6 +585,8 @@ def test_filesystem_store_add_invalid_object(fs_store): def test_filesystem_store_add_marking(fs_store): marking = stix2.v20.MarkingDefinition( + id="marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da", + created="2017-01-20T00:00:00.000Z", definition_type="tlp", definition=stix2.v20.TLPMarking(tlp="green"), ) diff --git a/stix2/test/v21/test_datastore_filesystem.py b/stix2/test/v21/test_datastore_filesystem.py index 2404f3f..34b1088 100644 --- a/stix2/test/v21/test_datastore_filesystem.py +++ b/stix2/test/v21/test_datastore_filesystem.py @@ -421,6 +421,8 @@ def test_filesystem_sink_add_objects_list(fs_sink, fs_source): def test_filesystem_sink_marking(fs_sink): marking = stix2.v21.MarkingDefinition( + id="marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da", + created="2017-01-20T00:00:00.000Z", definition_type="tlp", definition=stix2.v21.TLPMarking(tlp="green"), ) @@ -554,6 +556,8 @@ def test_filesystem_store_add_invalid_object(fs_store): def test_filesystem_store_add_marking(fs_store): marking = stix2.v21.MarkingDefinition( + id="marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da", + created="2017-01-20T00:00:00.000Z", definition_type="tlp", definition=stix2.v21.TLPMarking(tlp="green"), ) From 46c47a0d0874024a11a0f2556ced5e50fd11dbcd Mon Sep 17 00:00:00 2001 From: Emmanuelle Vargas-Gonzalez Date: Fri, 3 May 2019 09:59:07 -0400 Subject: [PATCH 44/62] new approach towards validation of tlp instances --- stix2/utils.py | 65 ++++++++++++++++++++++++++++++++++++++++++++- stix2/v20/common.py | 10 ++++++- stix2/v21/common.py | 10 ++++++- 3 files changed, 82 insertions(+), 3 deletions(-) diff --git a/stix2/utils.py b/stix2/utils.py index ffabed0..2a52b09 100644 --- a/stix2/utils.py +++ b/stix2/utils.py @@ -11,7 +11,7 @@ import pytz import stix2.base from .exceptions import ( - InvalidValueError, RevokeError, UnmodifiablePropertyError, + InvalidValueError, RevokeError, TLPMarkingDefinitionError, UnmodifiablePropertyError, ) # Sentinel value for properties that should be set to the current time. @@ -404,3 +404,66 @@ def is_marking(obj_or_id): result = obj_or_id.startswith("marking-definition--") return result + + +def check_tlp_marking(marking_obj, spec_version): + # Specific TLP Marking validation case. + + if marking_obj["definition_type"] == "tlp": + color = marking_obj["definition"]["tlp"] + + if color == "white": + if spec_version == '2.0': + w = ('{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "white"}, "definition_type": "tlp",' + ' "id": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", "type": "marking-definition"}') + else: + w = ('{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "white"}, "definition_type": "tlp",' + ' "id": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", "type": "marking-definition",' + ' "spec_version": "2.1"}') + if marking_obj["id"] != "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9": + raise TLPMarkingDefinitionError(marking_obj["id"], w) + elif format_datetime(marking_obj["created"]) != "2017-01-20T00:00:00.000Z": + raise TLPMarkingDefinitionError(format_datetime(marking_obj["created"]), w) + + elif color == "green": + if spec_version == '2.0': + g = ('{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "green"}, "definition_type": "tlp",' + ' "id": "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da", "type": "marking-definition"}') + else: + g = ('{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "green"}, "definition_type": "tlp",' + ' "id": "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da", "type": "marking-definition",' + ' "spec_version": "2.1"}') + if marking_obj["id"] != "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da": + raise TLPMarkingDefinitionError(marking_obj["id"], g) + elif format_datetime(marking_obj["created"]) != "2017-01-20T00:00:00.000Z": + raise TLPMarkingDefinitionError(format_datetime(marking_obj["created"]), g) + + elif color == "amber": + if spec_version == '2.0': + a = ('{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "amber"}, "definition_type": "tlp",' + ' "id": "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82", "type": "marking-definition"}') + else: + a = ('{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "amber"}, "definition_type": "tlp",' + ' "id": "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82", "type": "marking-definition",' + ' "spec_version": "2.1"}') + if marking_obj["id"] != "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82": + raise TLPMarkingDefinitionError(marking_obj["id"], a) + elif format_datetime(marking_obj["created"]) != "2017-01-20T00:00:00.000Z": + raise TLPMarkingDefinitionError(format_datetime(marking_obj["created"]), a) + + elif color == "red": + if spec_version == '2.0': + r = ('{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "red"}, "definition_type": "tlp",' + ' "id": "marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed", "type": "marking-definition"}') + else: + r = ('{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "red"}, "definition_type": "tlp",' + ' "id": "marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed", "type": "marking-definition",' + ' "spec_version": "2.1"}') + if marking_obj["id"] != "marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed": + raise TLPMarkingDefinitionError(marking_obj["id"], r) + elif format_datetime(marking_obj["created"]) != "2017-01-20T00:00:00.000Z": + raise TLPMarkingDefinitionError(format_datetime(marking_obj["created"]), r) + + else: + raise TLPMarkingDefinitionError(marking_obj["id"], "Does not match any TLP Marking definition") + diff --git a/stix2/v20/common.py b/stix2/v20/common.py index afd7812..afd8270 100644 --- a/stix2/v20/common.py +++ b/stix2/v20/common.py @@ -10,7 +10,7 @@ from ..properties import ( HashesProperty, IDProperty, ListProperty, Property, ReferenceProperty, SelectorProperty, StringProperty, TimestampProperty, TypeProperty, ) -from ..utils import NOW, _get_dict +from ..utils import NOW, _get_dict, check_tlp_marking class ExternalReference(_STIXBase): @@ -134,6 +134,14 @@ class MarkingDefinition(_STIXBase, _MarkingsMixin): super(MarkingDefinition, self).__init__(**kwargs) + def _check_object_constraints(self): + super(MarkingDefinition, self)._check_object_constraints() + check_tlp_marking(self, '2.0') + + def serialize(self, pretty=False, include_optional_defaults=False, **kwargs): + check_tlp_marking(self, '2.0') + return super(MarkingDefinition, self).serialize(pretty, include_optional_defaults, **kwargs) + OBJ_MAP_MARKING = { 'tlp': TLPMarking, diff --git a/stix2/v21/common.py b/stix2/v21/common.py index 0aded3b..5700ed4 100644 --- a/stix2/v21/common.py +++ b/stix2/v21/common.py @@ -11,7 +11,7 @@ from ..properties import ( IntegerProperty, ListProperty, Property, ReferenceProperty, SelectorProperty, StringProperty, TimestampProperty, TypeProperty, ) -from ..utils import NOW, _get_dict +from ..utils import NOW, _get_dict, check_tlp_marking class ExternalReference(_STIXBase): @@ -174,6 +174,14 @@ class MarkingDefinition(_STIXBase, _MarkingsMixin): super(MarkingDefinition, self).__init__(**kwargs) + def _check_object_constraints(self): + super(MarkingDefinition, self)._check_object_constraints() + check_tlp_marking(self, '2.1') + + def serialize(self, pretty=False, include_optional_defaults=False, **kwargs): + check_tlp_marking(self, '2.1') + return super(MarkingDefinition, self).serialize(pretty, include_optional_defaults, **kwargs) + OBJ_MAP_MARKING = { 'tlp': TLPMarking, From d6497f66fe9ae67f2cc73824df45949d5ff23257 Mon Sep 17 00:00:00 2001 From: Emmanuelle Vargas-Gonzalez Date: Fri, 3 May 2019 10:03:15 -0400 Subject: [PATCH 45/62] create a new exception for TLP validation and util method --- stix2/exceptions.py | 13 ++++++++++ stix2/utils.py | 60 ++++++++++++++++++++++++++++----------------- 2 files changed, 51 insertions(+), 22 deletions(-) diff --git a/stix2/exceptions.py b/stix2/exceptions.py index 231eeb6..f1f1c09 100644 --- a/stix2/exceptions.py +++ b/stix2/exceptions.py @@ -203,3 +203,16 @@ class MarkingNotFoundError(STIXError, AssertionError): def __str__(self): msg = "Marking {0} was not found in {1}!" return msg.format(self.key, self.cls.__class__.__name__) + + +class TLPMarkingDefinitionError(STIXError, AssertionError): + """Marking violation. The marking-definition for TLP MUST follow the mandated instances from the spec.""" + + def __init__(self, user_obj, spec_obj): + super(TLPMarkingDefinitionError, self).__init__() + self.user_obj = user_obj + self.spec_obj = spec_obj + + def __str__(self): + msg = "Marking {0} does not match spec marking {1}!" + return msg.format(self.user_obj, self.spec_obj) diff --git a/stix2/utils.py b/stix2/utils.py index 2a52b09..d273fce 100644 --- a/stix2/utils.py +++ b/stix2/utils.py @@ -11,7 +11,8 @@ import pytz import stix2.base from .exceptions import ( - InvalidValueError, RevokeError, TLPMarkingDefinitionError, UnmodifiablePropertyError, + InvalidValueError, RevokeError, TLPMarkingDefinitionError, + UnmodifiablePropertyError, ) # Sentinel value for properties that should be set to the current time. @@ -414,12 +415,16 @@ def check_tlp_marking(marking_obj, spec_version): if color == "white": if spec_version == '2.0': - w = ('{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "white"}, "definition_type": "tlp",' - ' "id": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", "type": "marking-definition"}') + w = ( + '{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "white"}, "definition_type": "tlp",' + ' "id": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", "type": "marking-definition"}' + ) else: - w = ('{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "white"}, "definition_type": "tlp",' - ' "id": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", "type": "marking-definition",' - ' "spec_version": "2.1"}') + w = ( + '{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "white"}, "definition_type": "tlp",' + ' "id": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", "type": "marking-definition",' + ' "spec_version": "2.1"}' + ) if marking_obj["id"] != "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9": raise TLPMarkingDefinitionError(marking_obj["id"], w) elif format_datetime(marking_obj["created"]) != "2017-01-20T00:00:00.000Z": @@ -427,12 +432,16 @@ def check_tlp_marking(marking_obj, spec_version): elif color == "green": if spec_version == '2.0': - g = ('{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "green"}, "definition_type": "tlp",' - ' "id": "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da", "type": "marking-definition"}') + g = ( + '{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "green"}, "definition_type": "tlp",' + ' "id": "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da", "type": "marking-definition"}' + ) else: - g = ('{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "green"}, "definition_type": "tlp",' - ' "id": "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da", "type": "marking-definition",' - ' "spec_version": "2.1"}') + g = ( + '{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "green"}, "definition_type": "tlp",' + ' "id": "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da", "type": "marking-definition",' + ' "spec_version": "2.1"}' + ) if marking_obj["id"] != "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da": raise TLPMarkingDefinitionError(marking_obj["id"], g) elif format_datetime(marking_obj["created"]) != "2017-01-20T00:00:00.000Z": @@ -440,12 +449,16 @@ def check_tlp_marking(marking_obj, spec_version): elif color == "amber": if spec_version == '2.0': - a = ('{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "amber"}, "definition_type": "tlp",' - ' "id": "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82", "type": "marking-definition"}') + a = ( + '{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "amber"}, "definition_type": "tlp",' + ' "id": "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82", "type": "marking-definition"}' + ) else: - a = ('{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "amber"}, "definition_type": "tlp",' - ' "id": "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82", "type": "marking-definition",' - ' "spec_version": "2.1"}') + a = ( + '{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "amber"}, "definition_type": "tlp",' + ' "id": "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82", "type": "marking-definition",' + ' "spec_version": "2.1"}' + ) if marking_obj["id"] != "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82": raise TLPMarkingDefinitionError(marking_obj["id"], a) elif format_datetime(marking_obj["created"]) != "2017-01-20T00:00:00.000Z": @@ -453,12 +466,16 @@ def check_tlp_marking(marking_obj, spec_version): elif color == "red": if spec_version == '2.0': - r = ('{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "red"}, "definition_type": "tlp",' - ' "id": "marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed", "type": "marking-definition"}') + r = ( + '{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "red"}, "definition_type": "tlp",' + ' "id": "marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed", "type": "marking-definition"}' + ) else: - r = ('{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "red"}, "definition_type": "tlp",' - ' "id": "marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed", "type": "marking-definition",' - ' "spec_version": "2.1"}') + r = ( + '{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "red"}, "definition_type": "tlp",' + ' "id": "marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed", "type": "marking-definition",' + ' "spec_version": "2.1"}' + ) if marking_obj["id"] != "marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed": raise TLPMarkingDefinitionError(marking_obj["id"], r) elif format_datetime(marking_obj["created"]) != "2017-01-20T00:00:00.000Z": @@ -466,4 +483,3 @@ def check_tlp_marking(marking_obj, spec_version): else: raise TLPMarkingDefinitionError(marking_obj["id"], "Does not match any TLP Marking definition") - From b3a601e4c86e9adc302112e45e2830f239c09cd8 Mon Sep 17 00:00:00 2001 From: Emmanuelle Vargas-Gonzalez Date: Fri, 3 May 2019 10:25:11 -0400 Subject: [PATCH 46/62] add new files for marking-definition tests --- stix2/test/v20/test_marking_definition.py | 131 ++++++++++++++++++++++ stix2/test/v21/test_marking_definition.py | 131 ++++++++++++++++++++++ 2 files changed, 262 insertions(+) create mode 100644 stix2/test/v20/test_marking_definition.py create mode 100644 stix2/test/v21/test_marking_definition.py diff --git a/stix2/test/v20/test_marking_definition.py b/stix2/test/v20/test_marking_definition.py new file mode 100644 index 0000000..9d03ebe --- /dev/null +++ b/stix2/test/v20/test_marking_definition.py @@ -0,0 +1,131 @@ + +import pytest + +from stix2 import exceptions +from stix2.v20 import ( + TLP_AMBER, TLP_GREEN, TLP_RED, TLP_WHITE, MarkingDefinition, TLPMarking, +) + + +def test_bad_id_marking_tlp_white(): + with pytest.raises(exceptions.TLPMarkingDefinitionError): + MarkingDefinition( + id='marking-definition--4c9faac1-3558-43d2-919e-95c88d3bc332', + definition_type='tlp', + definition=TLPMarking(tlp='white'), + ) + + +def test_bad_id_marking_tlp_green(): + with pytest.raises(exceptions.TLPMarkingDefinitionError): + MarkingDefinition( + id='marking-definition--93023361-d3cf-4666-bca2-8c017948dc3d', + definition_type='tlp', + definition=TLPMarking(tlp='green'), + ) + + +def test_bad_id_marking_tlp_amber(): + with pytest.raises(exceptions.TLPMarkingDefinitionError): + MarkingDefinition( + id='marking-definition--05e32101-a940-42ba-8fe9-39283b999ce4', + definition_type='tlp', + definition=TLPMarking(tlp='amber'), + ) + + +def test_bad_id_marking_tlp_red(): + with pytest.raises(exceptions.TLPMarkingDefinitionError): + MarkingDefinition( + id='marking-definition--9eceb00c-c158-43f4-87f8-1e3648de17e2', + definition_type='tlp', + definition=TLPMarking(tlp='red'), + ) + + +def test_bad_created_marking_tlp_white(): + with pytest.raises(exceptions.TLPMarkingDefinitionError): + MarkingDefinition( + id='marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9', + definition_type='tlp', + definition=TLPMarking(tlp='white'), + ) + + +def test_bad_created_marking_tlp_green(): + with pytest.raises(exceptions.TLPMarkingDefinitionError): + MarkingDefinition( + id='marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da', + definition_type='tlp', + definition=TLPMarking(tlp='green'), + ) + + +def test_bad_created_marking_tlp_amber(): + with pytest.raises(exceptions.TLPMarkingDefinitionError): + MarkingDefinition( + id='marking-definition--f88d31f6-486f-44da-b317-01333bde0b82', + definition_type='tlp', + definition=TLPMarking(tlp='amber'), + ) + + +def test_bad_created_marking_tlp_red(): + with pytest.raises(exceptions.TLPMarkingDefinitionError): + MarkingDefinition( + id='marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed', + definition_type='tlp', + definition=TLPMarking(tlp='red'), + ) + + +def test_successful_tlp_white(): + white = MarkingDefinition( + id='marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9', + created='2017-01-20T00:00:00.000Z', + definition_type='tlp', + definition=TLPMarking(tlp='white'), + ) + + assert white.serialize() in TLP_WHITE.serialize() + + +def test_successful_tlp_green(): + white = MarkingDefinition( + id='marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da', + created='2017-01-20T00:00:00.000Z', + definition_type='tlp', + definition=TLPMarking(tlp='green'), + ) + + assert white.serialize() in TLP_GREEN.serialize() + + +def test_successful_tlp_amber(): + white = MarkingDefinition( + id='marking-definition--f88d31f6-486f-44da-b317-01333bde0b82', + created='2017-01-20T00:00:00.000Z', + definition_type='tlp', + definition=TLPMarking(tlp='amber'), + ) + + assert white.serialize() in TLP_AMBER.serialize() + + +def test_successful_tlp_red(): + white = MarkingDefinition( + id='marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed', + created='2017-01-20T00:00:00.000Z', + definition_type='tlp', + definition=TLPMarking(tlp='red'), + ) + + assert white.serialize() in TLP_RED.serialize() + + +def test_unknown_tlp_marking(): + with pytest.raises(exceptions.TLPMarkingDefinitionError): + MarkingDefinition( + definition_type='tlp', + definition=TLPMarking(tlp='gray'), + ) diff --git a/stix2/test/v21/test_marking_definition.py b/stix2/test/v21/test_marking_definition.py new file mode 100644 index 0000000..2404ad1 --- /dev/null +++ b/stix2/test/v21/test_marking_definition.py @@ -0,0 +1,131 @@ + +import pytest + +from stix2 import exceptions +from stix2.v21 import ( + TLP_AMBER, TLP_GREEN, TLP_RED, TLP_WHITE, MarkingDefinition, TLPMarking, +) + + +def test_bad_id_marking_tlp_white(): + with pytest.raises(exceptions.TLPMarkingDefinitionError): + MarkingDefinition( + id='marking-definition--4c9faac1-3558-43d2-919e-95c88d3bc332', + definition_type='tlp', + definition=TLPMarking(tlp='white'), + ) + + +def test_bad_id_marking_tlp_green(): + with pytest.raises(exceptions.TLPMarkingDefinitionError): + MarkingDefinition( + id='marking-definition--93023361-d3cf-4666-bca2-8c017948dc3d', + definition_type='tlp', + definition=TLPMarking(tlp='green'), + ) + + +def test_bad_id_marking_tlp_amber(): + with pytest.raises(exceptions.TLPMarkingDefinitionError): + MarkingDefinition( + id='marking-definition--05e32101-a940-42ba-8fe9-39283b999ce4', + definition_type='tlp', + definition=TLPMarking(tlp='amber'), + ) + + +def test_bad_id_marking_tlp_red(): + with pytest.raises(exceptions.TLPMarkingDefinitionError): + MarkingDefinition( + id='marking-definition--9eceb00c-c158-43f4-87f8-1e3648de17e2', + definition_type='tlp', + definition=TLPMarking(tlp='red'), + ) + + +def test_bad_created_marking_tlp_white(): + with pytest.raises(exceptions.TLPMarkingDefinitionError): + MarkingDefinition( + id='marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9', + definition_type='tlp', + definition=TLPMarking(tlp='white'), + ) + + +def test_bad_created_marking_tlp_green(): + with pytest.raises(exceptions.TLPMarkingDefinitionError): + MarkingDefinition( + id='marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da', + definition_type='tlp', + definition=TLPMarking(tlp='green'), + ) + + +def test_bad_created_marking_tlp_amber(): + with pytest.raises(exceptions.TLPMarkingDefinitionError): + MarkingDefinition( + id='marking-definition--f88d31f6-486f-44da-b317-01333bde0b82', + definition_type='tlp', + definition=TLPMarking(tlp='amber'), + ) + + +def test_bad_created_marking_tlp_red(): + with pytest.raises(exceptions.TLPMarkingDefinitionError): + MarkingDefinition( + id='marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed', + definition_type='tlp', + definition=TLPMarking(tlp='red'), + ) + + +def test_successful_tlp_white(): + white = MarkingDefinition( + id='marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9', + created='2017-01-20T00:00:00.000Z', + definition_type='tlp', + definition=TLPMarking(tlp='white'), + ) + + assert white.serialize() in TLP_WHITE.serialize() + + +def test_successful_tlp_green(): + green = MarkingDefinition( + id='marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da', + created='2017-01-20T00:00:00.000Z', + definition_type='tlp', + definition=TLPMarking(tlp='green'), + ) + + assert green.serialize() in TLP_GREEN.serialize() + + +def test_successful_tlp_amber(): + amber = MarkingDefinition( + id='marking-definition--f88d31f6-486f-44da-b317-01333bde0b82', + created='2017-01-20T00:00:00.000Z', + definition_type='tlp', + definition=TLPMarking(tlp='amber'), + ) + + assert amber.serialize() in TLP_AMBER.serialize() + + +def test_successful_tlp_red(): + red = MarkingDefinition( + id='marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed', + created='2017-01-20T00:00:00.000Z', + definition_type='tlp', + definition=TLPMarking(tlp='red'), + ) + + assert red.serialize() in TLP_RED.serialize() + + +def test_unknown_tlp_marking(): + with pytest.raises(exceptions.TLPMarkingDefinitionError): + MarkingDefinition( + definition_type='tlp', + definition=TLPMarking(tlp='gray'), + ) From 4b21708e03027390c3dfca4b85b9356c9e44fc96 Mon Sep 17 00:00:00 2001 From: Emmanuelle Vargas-Gonzalez Date: Fri, 3 May 2019 11:05:32 -0400 Subject: [PATCH 47/62] modify test to cover exception message --- stix2/test/v20/test_marking_definition.py | 4 +++- stix2/test/v21/test_marking_definition.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/stix2/test/v20/test_marking_definition.py b/stix2/test/v20/test_marking_definition.py index 9d03ebe..106a455 100644 --- a/stix2/test/v20/test_marking_definition.py +++ b/stix2/test/v20/test_marking_definition.py @@ -71,13 +71,15 @@ def test_bad_created_marking_tlp_amber(): def test_bad_created_marking_tlp_red(): - with pytest.raises(exceptions.TLPMarkingDefinitionError): + with pytest.raises(exceptions.TLPMarkingDefinitionError) as excinfo: MarkingDefinition( id='marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed', definition_type='tlp', definition=TLPMarking(tlp='red'), ) + assert "marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed" in str(excinfo.value) + def test_successful_tlp_white(): white = MarkingDefinition( diff --git a/stix2/test/v21/test_marking_definition.py b/stix2/test/v21/test_marking_definition.py index 2404ad1..dd3325f 100644 --- a/stix2/test/v21/test_marking_definition.py +++ b/stix2/test/v21/test_marking_definition.py @@ -71,13 +71,15 @@ def test_bad_created_marking_tlp_amber(): def test_bad_created_marking_tlp_red(): - with pytest.raises(exceptions.TLPMarkingDefinitionError): + with pytest.raises(exceptions.TLPMarkingDefinitionError) as excinfo: MarkingDefinition( id='marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed', definition_type='tlp', definition=TLPMarking(tlp='red'), ) + assert "marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed" in str(excinfo.value) + def test_successful_tlp_white(): white = MarkingDefinition( From 8d842aeb94e626ea60a43c3bd12bfd5c005e2548 Mon Sep 17 00:00:00 2001 From: Emmanuelle Vargas-Gonzalez Date: Fri, 3 May 2019 14:48:16 -0400 Subject: [PATCH 48/62] update user guide on marking extraction via API --- docs/guide/markings.ipynb | 79 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/docs/guide/markings.ipynb b/docs/guide/markings.ipynb index 8230daf..270bfcd 100644 --- a/docs/guide/markings.ipynb +++ b/docs/guide/markings.ipynb @@ -1310,6 +1310,85 @@ "source": [ "malware.is_marked(TLP_WHITE.id, 'description')" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Extracting lang Data Markings or marking-definition Data Markings\n", + "\n", + "If you need a specific kind of marking, you can also filter them using the API. By default the library will get both types of markings by default. You can choose between `lang=True/False` or `marking_ref=True/False` depending on your use-case." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\n", + " \"type\": \"indicator\",\n", + " \"spec_version\": \"2.1\",\n", + " \"id\": \"indicator--634ef462-d6b5-48bc-9d9f-b46a6919227c\",\n", + " \"created\": \"2019-05-03T18:36:44.354Z\",\n", + " \"modified\": \"2019-05-03T18:36:44.354Z\",\n", + " \"description\": \"Una descripcion sobre este indicador\",\n", + " \"indicator_types\": [\n", + " \"malware\"\n", + " ],\n", + " \"pattern\": \"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\",\n", + " \"valid_from\": \"2019-05-03T18:36:44.354443Z\",\n", + " \"object_marking_refs\": [\n", + " \"marking-definition--f88d31f6-486f-44da-b317-01333bde0b82\"\n", + " ],\n", + " \"granular_markings\": [\n", + " {\n", + " \"lang\": \"es\",\n", + " \"selectors\": [\n", + " \"description\"\n", + " ]\n", + " },\n", + " {\n", + " \"marking_ref\": \"marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da\",\n", + " \"selectors\": [\n", + " \"description\"\n", + " ]\n", + " }\n", + " ]\n", + "}\n", + "['es', 'marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da']\n", + "['marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da']\n", + "['es']\n" + ] + } + ], + "source": [ + "from stix2 import v21\n", + "\n", + "v21_indicator = v21.Indicator(\n", + " description=\"Una descripcion sobre este indicador\",\n", + " pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\",\n", + " object_marking_refs=['marking-definition--f88d31f6-486f-44da-b317-01333bde0b82'],\n", + " indicator_types=['malware'],\n", + " granular_markings=[\n", + " {\n", + " 'selectors': ['description'],\n", + " 'lang': 'es'\n", + " },\n", + " {\n", + " 'selectors': ['description'],\n", + " 'marking_ref': 'marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da'\n", + " }\n", + " ]\n", + ")\n", + "print(v21_indicator)\n", + "print(v21_indicator.get_markings('description')) # Gets both lang and marking_ref markings for 'description'\n", + "print(v21_indicator.get_markings('description', lang=False)) # Exclude lang markings from results\n", + "print(v21_indicator.get_markings('description', marking_ref=False)) # Exclude marking-definition markings from results" + ] } ], "metadata": { From 851ed3e85ad09538f46478de247bd681b83d8680 Mon Sep 17 00:00:00 2001 From: Emmanuelle Vargas-Gonzalez Date: Fri, 3 May 2019 15:41:58 -0400 Subject: [PATCH 49/62] marking-definition --- docs/guide/markings.ipynb | 135 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 131 insertions(+), 4 deletions(-) diff --git a/docs/guide/markings.ipynb b/docs/guide/markings.ipynb index 270bfcd..44e023a 100644 --- a/docs/guide/markings.ipynb +++ b/docs/guide/markings.ipynb @@ -1315,7 +1315,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Extracting lang Data Markings or marking-definition Data Markings\n", + "# Extracting Lang Data Markings or marking-definition Data Markings\n", "\n", "If you need a specific kind of marking, you can also filter them using the API. By default the library will get both types of markings by default. You can choose between `lang=True/False` or `marking_ref=True/False` depending on your use-case." ] @@ -1385,9 +1385,136 @@ " ]\n", ")\n", "print(v21_indicator)\n", - "print(v21_indicator.get_markings('description')) # Gets both lang and marking_ref markings for 'description'\n", - "print(v21_indicator.get_markings('description', lang=False)) # Exclude lang markings from results\n", - "print(v21_indicator.get_markings('description', marking_ref=False)) # Exclude marking-definition markings from results" + "\n", + "# Gets both lang and marking_ref markings for 'description'\n", + "print(v21_indicator.get_markings('description'))\n", + "\n", + "# Exclude lang markings from results\n", + "print(v21_indicator.get_markings('description', lang=False))\n", + "\n", + "# Exclude marking-definition markings from results\n", + "print(v21_indicator.get_markings('description', marking_ref=False))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this same manner, calls to `clear_markings` and `set_markings` also have the ability to operate in for one or both types of markings." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\n", + " \"type\": \"indicator\",\n", + " \"spec_version\": \"2.1\",\n", + " \"id\": \"indicator--a612665a-2df4-4fd2-851c-7fbb8c92339a\",\n", + " \"created\": \"2019-05-03T19:13:59.010Z\",\n", + " \"modified\": \"2019-05-03T19:15:41.173Z\",\n", + " \"description\": \"Una descripcion sobre este indicador\",\n", + " \"indicator_types\": [\n", + " \"malware\"\n", + " ],\n", + " \"pattern\": \"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\",\n", + " \"valid_from\": \"2019-05-03T19:13:59.010624Z\",\n", + " \"object_marking_refs\": [\n", + " \"marking-definition--f88d31f6-486f-44da-b317-01333bde0b82\"\n", + " ]\n", + "}\n" + ] + } + ], + "source": [ + "print(v21_indicator.clear_markings(\"description\")) # By default, both types of markings will be removed" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\n", + " \"type\": \"indicator\",\n", + " \"spec_version\": \"2.1\",\n", + " \"id\": \"indicator--982aeb4d-4dd3-4b04-aa50-a1d00c31986c\",\n", + " \"created\": \"2019-05-03T19:19:26.542Z\",\n", + " \"modified\": \"2019-05-03T19:20:51.818Z\",\n", + " \"description\": \"Una descripcion sobre este indicador\",\n", + " \"indicator_types\": [\n", + " \"malware\"\n", + " ],\n", + " \"pattern\": \"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\",\n", + " \"valid_from\": \"2019-05-03T19:19:26.542267Z\",\n", + " \"object_marking_refs\": [\n", + " \"marking-definition--f88d31f6-486f-44da-b317-01333bde0b82\"\n", + " ],\n", + " \"granular_markings\": [\n", + " {\n", + " \"lang\": \"es\",\n", + " \"selectors\": [\n", + " \"description\"\n", + " ]\n", + " }\n", + " ]\n", + "}\n" + ] + } + ], + "source": [ + "# If lang is False, no lang markings will be removed\n", + "print(v21_indicator.clear_markings(\"description\", lang=False))" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\n", + " \"type\": \"indicator\",\n", + " \"spec_version\": \"2.1\",\n", + " \"id\": \"indicator--de0316d6-38e1-43c2-af4f-649305251864\",\n", + " \"created\": \"2019-05-03T19:40:21.459Z\",\n", + " \"modified\": \"2019-05-03T19:40:26.431Z\",\n", + " \"description\": \"Una descripcion sobre este indicador\",\n", + " \"indicator_types\": [\n", + " \"malware\"\n", + " ],\n", + " \"pattern\": \"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\",\n", + " \"valid_from\": \"2019-05-03T19:40:21.459582Z\",\n", + " \"object_marking_refs\": [\n", + " \"marking-definition--f88d31f6-486f-44da-b317-01333bde0b82\"\n", + " ],\n", + " \"granular_markings\": [\n", + " {\n", + " \"marking_ref\": \"marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da\",\n", + " \"selectors\": [\n", + " \"description\"\n", + " ]\n", + " }\n", + " ]\n", + "}\n" + ] + } + ], + "source": [ + "# If marking_ref is False, no marking-definition markings will be removed\n", + "print(v21_indicator.clear_markings(\"description\", marking_ref=False))" ] } ], From 47f8ed928260334292a9281c05ad9cb938031dfd Mon Sep 17 00:00:00 2001 From: Emmanuelle Vargas-Gonzalez Date: Wed, 8 May 2019 10:34:56 -0400 Subject: [PATCH 50/62] move check_tlp_marking to markings\utils.py --- stix2/markings/utils.py | 80 ++++++++++++++++++++++++++++++++++++++++- stix2/utils.py | 78 ---------------------------------------- 2 files changed, 79 insertions(+), 79 deletions(-) diff --git a/stix2/markings/utils.py b/stix2/markings/utils.py index d8bbf1d..a5abfa8 100644 --- a/stix2/markings/utils.py +++ b/stix2/markings/utils.py @@ -4,7 +4,7 @@ import collections import six -from stix2 import exceptions +from stix2 import exceptions, utils def _evaluate_expression(obj, selector): @@ -240,3 +240,81 @@ def iterpath(obj, path=None): path.pop() path.pop() + + +def check_tlp_marking(marking_obj, spec_version): + # Specific TLP Marking validation case. + + if marking_obj["definition_type"] == "tlp": + color = marking_obj["definition"]["tlp"] + + if color == "white": + if spec_version == '2.0': + w = ( + '{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "white"}, "definition_type": "tlp",' + ' "id": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", "type": "marking-definition"}' + ) + else: + w = ( + '{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "white"}, "definition_type": "tlp",' + ' "id": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", "type": "marking-definition",' + ' "spec_version": "2.1"}' + ) + if marking_obj["id"] != "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9": + raise exceptions.TLPMarkingDefinitionError(marking_obj["id"], w) + elif utils.format_datetime(marking_obj["created"]) != "2017-01-20T00:00:00.000Z": + raise exceptions.TLPMarkingDefinitionError(utils.format_datetime(marking_obj["created"]), w) + + elif color == "green": + if spec_version == '2.0': + g = ( + '{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "green"}, "definition_type": "tlp",' + ' "id": "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da", "type": "marking-definition"}' + ) + else: + g = ( + '{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "green"}, "definition_type": "tlp",' + ' "id": "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da", "type": "marking-definition",' + ' "spec_version": "2.1"}' + ) + if marking_obj["id"] != "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da": + raise exceptions.TLPMarkingDefinitionError(marking_obj["id"], g) + elif utils.format_datetime(marking_obj["created"]) != "2017-01-20T00:00:00.000Z": + raise exceptions.TLPMarkingDefinitionError(utils.format_datetime(marking_obj["created"]), g) + + elif color == "amber": + if spec_version == '2.0': + a = ( + '{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "amber"}, "definition_type": "tlp",' + ' "id": "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82", "type": "marking-definition"}' + ) + else: + a = ( + '{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "amber"}, "definition_type": "tlp",' + ' "id": "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82", "type": "marking-definition",' + ' "spec_version": "2.1"}' + ) + if marking_obj["id"] != "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82": + raise exceptions.TLPMarkingDefinitionError(marking_obj["id"], a) + elif utils.format_datetime(marking_obj["created"]) != "2017-01-20T00:00:00.000Z": + raise exceptions.TLPMarkingDefinitionError(utils.format_datetime(marking_obj["created"]), a) + + elif color == "red": + if spec_version == '2.0': + r = ( + '{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "red"}, "definition_type": "tlp",' + ' "id": "marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed", "type": "marking-definition"}' + ) + else: + r = ( + '{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "red"}, "definition_type": "tlp",' + ' "id": "marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed", "type": "marking-definition",' + ' "spec_version": "2.1"}' + ) + if marking_obj["id"] != "marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed": + raise exceptions.TLPMarkingDefinitionError(marking_obj["id"], r) + elif utils.format_datetime(marking_obj["created"]) != "2017-01-20T00:00:00.000Z": + raise exceptions.TLPMarkingDefinitionError(utils.format_datetime(marking_obj["created"]), r) + + else: + raise exceptions.TLPMarkingDefinitionError(marking_obj["id"], "Does not match any TLP Marking definition") diff --git a/stix2/utils.py b/stix2/utils.py index d273fce..7b43739 100644 --- a/stix2/utils.py +++ b/stix2/utils.py @@ -405,81 +405,3 @@ def is_marking(obj_or_id): result = obj_or_id.startswith("marking-definition--") return result - - -def check_tlp_marking(marking_obj, spec_version): - # Specific TLP Marking validation case. - - if marking_obj["definition_type"] == "tlp": - color = marking_obj["definition"]["tlp"] - - if color == "white": - if spec_version == '2.0': - w = ( - '{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "white"}, "definition_type": "tlp",' - ' "id": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", "type": "marking-definition"}' - ) - else: - w = ( - '{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "white"}, "definition_type": "tlp",' - ' "id": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9", "type": "marking-definition",' - ' "spec_version": "2.1"}' - ) - if marking_obj["id"] != "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9": - raise TLPMarkingDefinitionError(marking_obj["id"], w) - elif format_datetime(marking_obj["created"]) != "2017-01-20T00:00:00.000Z": - raise TLPMarkingDefinitionError(format_datetime(marking_obj["created"]), w) - - elif color == "green": - if spec_version == '2.0': - g = ( - '{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "green"}, "definition_type": "tlp",' - ' "id": "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da", "type": "marking-definition"}' - ) - else: - g = ( - '{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "green"}, "definition_type": "tlp",' - ' "id": "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da", "type": "marking-definition",' - ' "spec_version": "2.1"}' - ) - if marking_obj["id"] != "marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da": - raise TLPMarkingDefinitionError(marking_obj["id"], g) - elif format_datetime(marking_obj["created"]) != "2017-01-20T00:00:00.000Z": - raise TLPMarkingDefinitionError(format_datetime(marking_obj["created"]), g) - - elif color == "amber": - if spec_version == '2.0': - a = ( - '{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "amber"}, "definition_type": "tlp",' - ' "id": "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82", "type": "marking-definition"}' - ) - else: - a = ( - '{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "amber"}, "definition_type": "tlp",' - ' "id": "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82", "type": "marking-definition",' - ' "spec_version": "2.1"}' - ) - if marking_obj["id"] != "marking-definition--f88d31f6-486f-44da-b317-01333bde0b82": - raise TLPMarkingDefinitionError(marking_obj["id"], a) - elif format_datetime(marking_obj["created"]) != "2017-01-20T00:00:00.000Z": - raise TLPMarkingDefinitionError(format_datetime(marking_obj["created"]), a) - - elif color == "red": - if spec_version == '2.0': - r = ( - '{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "red"}, "definition_type": "tlp",' - ' "id": "marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed", "type": "marking-definition"}' - ) - else: - r = ( - '{"created": "2017-01-20T00:00:00.000Z", "definition": {"tlp": "red"}, "definition_type": "tlp",' - ' "id": "marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed", "type": "marking-definition",' - ' "spec_version": "2.1"}' - ) - if marking_obj["id"] != "marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed": - raise TLPMarkingDefinitionError(marking_obj["id"], r) - elif format_datetime(marking_obj["created"]) != "2017-01-20T00:00:00.000Z": - raise TLPMarkingDefinitionError(format_datetime(marking_obj["created"]), r) - - else: - raise TLPMarkingDefinitionError(marking_obj["id"], "Does not match any TLP Marking definition") From d5f0c46dd5468870289b8a1afb80a3db778d8a15 Mon Sep 17 00:00:00 2001 From: Emmanuelle Vargas-Gonzalez Date: Wed, 8 May 2019 10:35:53 -0400 Subject: [PATCH 51/62] re-organize imports in v20, v21 --- stix2/v20/common.py | 3 ++- stix2/v21/common.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/stix2/v20/common.py b/stix2/v20/common.py index afd8270..0a0cabc 100644 --- a/stix2/v20/common.py +++ b/stix2/v20/common.py @@ -6,11 +6,12 @@ import copy from ..base import _STIXBase from ..custom import _custom_marking_builder from ..markings import _MarkingsMixin +from ..markings.utils import check_tlp_marking from ..properties import ( HashesProperty, IDProperty, ListProperty, Property, ReferenceProperty, SelectorProperty, StringProperty, TimestampProperty, TypeProperty, ) -from ..utils import NOW, _get_dict, check_tlp_marking +from ..utils import NOW, _get_dict class ExternalReference(_STIXBase): diff --git a/stix2/v21/common.py b/stix2/v21/common.py index 5700ed4..13d0ff6 100644 --- a/stix2/v21/common.py +++ b/stix2/v21/common.py @@ -6,12 +6,13 @@ import copy from ..base import _STIXBase from ..custom import _custom_marking_builder from ..markings import _MarkingsMixin +from ..markings.utils import check_tlp_marking from ..properties import ( BooleanProperty, DictionaryProperty, HashesProperty, IDProperty, IntegerProperty, ListProperty, Property, ReferenceProperty, SelectorProperty, StringProperty, TimestampProperty, TypeProperty, ) -from ..utils import NOW, _get_dict, check_tlp_marking +from ..utils import NOW, _get_dict class ExternalReference(_STIXBase): From 9c34e2f8ca5c3fb0d329c9823f186b9e0400e08e Mon Sep 17 00:00:00 2001 From: Emmanuelle Vargas-Gonzalez Date: Wed, 8 May 2019 10:36:31 -0400 Subject: [PATCH 52/62] update tests to make sure we are testing the serialized instance correctly --- stix2/test/v20/test_marking_definition.py | 14 +++++++------- stix2/test/v21/test_marking_definition.py | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/stix2/test/v20/test_marking_definition.py b/stix2/test/v20/test_marking_definition.py index 106a455..20575fa 100644 --- a/stix2/test/v20/test_marking_definition.py +++ b/stix2/test/v20/test_marking_definition.py @@ -89,40 +89,40 @@ def test_successful_tlp_white(): definition=TLPMarking(tlp='white'), ) - assert white.serialize() in TLP_WHITE.serialize() + assert white.serialize(sort_keys=True) == TLP_WHITE.serialize(sort_keys=True) def test_successful_tlp_green(): - white = MarkingDefinition( + green = MarkingDefinition( id='marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da', created='2017-01-20T00:00:00.000Z', definition_type='tlp', definition=TLPMarking(tlp='green'), ) - assert white.serialize() in TLP_GREEN.serialize() + assert green.serialize(sort_keys=True) == TLP_GREEN.serialize(sort_keys=True) def test_successful_tlp_amber(): - white = MarkingDefinition( + amber = MarkingDefinition( id='marking-definition--f88d31f6-486f-44da-b317-01333bde0b82', created='2017-01-20T00:00:00.000Z', definition_type='tlp', definition=TLPMarking(tlp='amber'), ) - assert white.serialize() in TLP_AMBER.serialize() + assert amber.serialize(sort_keys=True) == TLP_AMBER.serialize(sort_keys=True) def test_successful_tlp_red(): - white = MarkingDefinition( + red = MarkingDefinition( id='marking-definition--5e57c739-391a-4eb3-b6be-7d15ca92d5ed', created='2017-01-20T00:00:00.000Z', definition_type='tlp', definition=TLPMarking(tlp='red'), ) - assert white.serialize() in TLP_RED.serialize() + assert red.serialize(sort_keys=True) == TLP_RED.serialize(sort_keys=True) def test_unknown_tlp_marking(): diff --git a/stix2/test/v21/test_marking_definition.py b/stix2/test/v21/test_marking_definition.py index dd3325f..c497e99 100644 --- a/stix2/test/v21/test_marking_definition.py +++ b/stix2/test/v21/test_marking_definition.py @@ -89,7 +89,7 @@ def test_successful_tlp_white(): definition=TLPMarking(tlp='white'), ) - assert white.serialize() in TLP_WHITE.serialize() + assert white.serialize(sort_keys=True) == TLP_WHITE.serialize(sort_keys=True) def test_successful_tlp_green(): @@ -100,7 +100,7 @@ def test_successful_tlp_green(): definition=TLPMarking(tlp='green'), ) - assert green.serialize() in TLP_GREEN.serialize() + assert green.serialize(sort_keys=True) == TLP_GREEN.serialize(sort_keys=True) def test_successful_tlp_amber(): @@ -111,7 +111,7 @@ def test_successful_tlp_amber(): definition=TLPMarking(tlp='amber'), ) - assert amber.serialize() in TLP_AMBER.serialize() + assert amber.serialize(sort_keys=True) == TLP_AMBER.serialize(sort_keys=True) def test_successful_tlp_red(): @@ -122,7 +122,7 @@ def test_successful_tlp_red(): definition=TLPMarking(tlp='red'), ) - assert red.serialize() in TLP_RED.serialize() + assert red.serialize(sort_keys=True) == TLP_RED.serialize(sort_keys=True) def test_unknown_tlp_marking(): From 00d99e38159d3fed6401d32a62a6a135498e1d79 Mon Sep 17 00:00:00 2001 From: Emmanuelle Vargas-Gonzalez Date: Wed, 8 May 2019 10:38:23 -0400 Subject: [PATCH 53/62] remove unused imports --- stix2/utils.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/stix2/utils.py b/stix2/utils.py index 7b43739..ffabed0 100644 --- a/stix2/utils.py +++ b/stix2/utils.py @@ -11,8 +11,7 @@ import pytz import stix2.base from .exceptions import ( - InvalidValueError, RevokeError, TLPMarkingDefinitionError, - UnmodifiablePropertyError, + InvalidValueError, RevokeError, UnmodifiablePropertyError, ) # Sentinel value for properties that should be set to the current time. From f79b3c98766b5e330fb0ef1c29e27eca6e5c9f23 Mon Sep 17 00:00:00 2001 From: "Desai, Kartikey H" Date: Fri, 10 May 2019 10:22:45 -0400 Subject: [PATCH 54/62] Add functionality to _valid_refs to accept actual cyber observable objects instead of just strings with their types --- stix2/base.py | 5 ++++- stix2/test/v21/test_observed_data.py | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/stix2/base.py b/stix2/base.py index 9fcdf56..a9a801e 100644 --- a/stix2/base.py +++ b/stix2/base.py @@ -308,7 +308,10 @@ class _Observable(_STIXBase): allowed_types = prop.valid_types try: - ref_type = self._STIXBase__valid_refs[ref] + try: + ref_type = self._STIXBase__valid_refs[ref].type + except AttributeError: + ref_type = self._STIXBase__valid_refs[ref] except TypeError: raise ValueError("'%s' must be created with _valid_refs as a dict, not a list." % self.__class__.__name__) diff --git a/stix2/test/v21/test_observed_data.py b/stix2/test/v21/test_observed_data.py index 5d0f9b1..864dd7a 100644 --- a/stix2/test/v21/test_observed_data.py +++ b/stix2/test/v21/test_observed_data.py @@ -940,6 +940,24 @@ def test_ip4_address_example(): assert ip4.resolves_to_refs == ["4", "5"] +def test_ip4_address_valid_refs(): + mac1 = stix2.v21.MACAddress( + value="a1:b2:c3:d4:e5:f6", + ) + mac2 = stix2.v21.MACAddress( + value="a7:b8:c9:d0:e1:f2", + ) + + ip4 = stix2.v21.IPv4Address( + _valid_refs={"1": mac1, "2": mac2}, + value="177.60.40.7", + resolves_to_refs=["1", "2"], + ) + + assert ip4.value == "177.60.40.7" + assert ip4.resolves_to_refs == ["1", "2"] + + def test_ip4_address_example_cidr(): ip4 = stix2.v21.IPv4Address(value="198.51.100.0/24") From 989f17e6732a6ac2e1a9c921977d38c19a152f94 Mon Sep 17 00:00:00 2001 From: Kartikey Desai Date: Fri, 10 May 2019 11:54:59 -0400 Subject: [PATCH 55/62] Add documentation for _valid_refs --- docs/guide/creating.ipynb | 213 ++++++++++++++++++++++++++++++++------ 1 file changed, 182 insertions(+), 31 deletions(-) diff --git a/docs/guide/creating.ipynb b/docs/guide/creating.ipynb index 83efb56..b1f92a8 100644 --- a/docs/guide/creating.ipynb +++ b/docs/guide/creating.ipynb @@ -144,12 +144,12 @@ ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n", ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "indicator",\n",
-       "    "id": "indicator--548af3be-39d7-4a3e-93c2-1a63cccf8951",\n",
-       "    "created": "2018-04-05T18:32:24.193Z",\n",
-       "    "modified": "2018-04-05T18:32:24.193Z",\n",
+       "    "id": "indicator--7e5fa3b3-dffd-4c57-a655-02b1c78539be",\n",
+       "    "created": "2019-05-10T15:28:49.358Z",\n",
+       "    "modified": "2019-05-10T15:28:49.358Z",\n",
        "    "name": "File hash for malware variant",\n",
        "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
-       "    "valid_from": "2018-04-05T18:32:24.193659Z",\n",
+       "    "valid_from": "2019-05-10T15:28:49.358947Z",\n",
        "    "labels": [\n",
        "        "malicious-activity"\n",
        "    ]\n",
@@ -465,9 +465,9 @@
        ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
        ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "malware",\n",
-       "    "id": "malware--3d7f0c1c-616a-4868-aa7b-150821d2a429",\n",
-       "    "created": "2018-04-05T18:32:46.584Z",\n",
-       "    "modified": "2018-04-05T18:32:46.584Z",\n",
+       "    "id": "malware--1b5d97a8-c4a6-4032-b6f4-a5e741036946",\n",
+       "    "created": "2019-05-10T15:29:37.208Z",\n",
+       "    "modified": "2019-05-10T15:29:37.208Z",\n",
        "    "name": "Poison Ivy",\n",
        "    "labels": [\n",
        "        "remote-access-trojan"\n",
@@ -588,12 +588,12 @@
        ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
        ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "relationship",\n",
-       "    "id": "relationship--34ddc7b4-4965-4615-b286-1c8bbaa1e7db",\n",
-       "    "created": "2018-04-05T18:32:49.474Z",\n",
-       "    "modified": "2018-04-05T18:32:49.474Z",\n",
+       "    "id": "relationship--aa324701-26d1-447e-b369-1347fb138f44",\n",
+       "    "created": "2019-05-10T15:29:44.848Z",\n",
+       "    "modified": "2019-05-10T15:29:44.848Z",\n",
        "    "relationship_type": "indicates",\n",
-       "    "source_ref": "indicator--548af3be-39d7-4a3e-93c2-1a63cccf8951",\n",
-       "    "target_ref": "malware--3d7f0c1c-616a-4868-aa7b-150821d2a429"\n",
+       "    "source_ref": "indicator--7e5fa3b3-dffd-4c57-a655-02b1c78539be",\n",
+       "    "target_ref": "malware--1b5d97a8-c4a6-4032-b6f4-a5e741036946"\n",
        "}\n",
        "
\n" ], @@ -700,12 +700,12 @@ ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n", ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "relationship",\n",
-       "    "id": "relationship--0a646403-f7e7-4cfd-b945-cab5cde05857",\n",
-       "    "created": "2018-04-05T18:32:51.417Z",\n",
-       "    "modified": "2018-04-05T18:32:51.417Z",\n",
+       "    "id": "relationship--de00dd44-7685-46b5-bf01-04003a2ee496",\n",
+       "    "created": "2019-05-10T15:29:47.422Z",\n",
+       "    "modified": "2019-05-10T15:29:47.422Z",\n",
        "    "relationship_type": "indicates",\n",
-       "    "source_ref": "indicator--548af3be-39d7-4a3e-93c2-1a63cccf8951",\n",
-       "    "target_ref": "malware--3d7f0c1c-616a-4868-aa7b-150821d2a429"\n",
+       "    "source_ref": "indicator--7e5fa3b3-dffd-4c57-a655-02b1c78539be",\n",
+       "    "target_ref": "malware--1b5d97a8-c4a6-4032-b6f4-a5e741036946"\n",
        "}\n",
        "
\n" ], @@ -810,26 +810,26 @@ ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n", ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "bundle",\n",
-       "    "id": "bundle--f83477e5-f853-47e1-a267-43f3aa1bd5b0",\n",
+       "    "id": "bundle--026ce7aa-1a14-4dc3-8dd3-8c2cd4eeaa66",\n",
        "    "spec_version": "2.0",\n",
        "    "objects": [\n",
        "        {\n",
        "            "type": "indicator",\n",
-       "            "id": "indicator--548af3be-39d7-4a3e-93c2-1a63cccf8951",\n",
-       "            "created": "2018-04-05T18:32:24.193Z",\n",
-       "            "modified": "2018-04-05T18:32:24.193Z",\n",
+       "            "id": "indicator--7e5fa3b3-dffd-4c57-a655-02b1c78539be",\n",
+       "            "created": "2019-05-10T15:28:49.358Z",\n",
+       "            "modified": "2019-05-10T15:28:49.358Z",\n",
        "            "name": "File hash for malware variant",\n",
        "            "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
-       "            "valid_from": "2018-04-05T18:32:24.193659Z",\n",
+       "            "valid_from": "2019-05-10T15:28:49.358947Z",\n",
        "            "labels": [\n",
        "                "malicious-activity"\n",
        "            ]\n",
        "        },\n",
        "        {\n",
        "            "type": "malware",\n",
-       "            "id": "malware--3d7f0c1c-616a-4868-aa7b-150821d2a429",\n",
-       "            "created": "2018-04-05T18:32:46.584Z",\n",
-       "            "modified": "2018-04-05T18:32:46.584Z",\n",
+       "            "id": "malware--1b5d97a8-c4a6-4032-b6f4-a5e741036946",\n",
+       "            "created": "2019-05-10T15:29:37.208Z",\n",
+       "            "modified": "2019-05-10T15:29:37.208Z",\n",
        "            "name": "Poison Ivy",\n",
        "            "labels": [\n",
        "                "remote-access-trojan"\n",
@@ -837,12 +837,12 @@
        "        },\n",
        "        {\n",
        "            "type": "relationship",\n",
-       "            "id": "relationship--34ddc7b4-4965-4615-b286-1c8bbaa1e7db",\n",
-       "            "created": "2018-04-05T18:32:49.474Z",\n",
-       "            "modified": "2018-04-05T18:32:49.474Z",\n",
+       "            "id": "relationship--aa324701-26d1-447e-b369-1347fb138f44",\n",
+       "            "created": "2019-05-10T15:29:44.848Z",\n",
+       "            "modified": "2019-05-10T15:29:44.848Z",\n",
        "            "relationship_type": "indicates",\n",
-       "            "source_ref": "indicator--548af3be-39d7-4a3e-93c2-1a63cccf8951",\n",
-       "            "target_ref": "malware--3d7f0c1c-616a-4868-aa7b-150821d2a429"\n",
+       "            "source_ref": "indicator--7e5fa3b3-dffd-4c57-a655-02b1c78539be",\n",
+       "            "target_ref": "malware--1b5d97a8-c4a6-4032-b6f4-a5e741036946"\n",
        "        }\n",
        "    ]\n",
        "}\n",
@@ -863,6 +863,157 @@
     "bundle = Bundle(indicator, malware, relationship)\n",
     "print(bundle)"
    ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Creating Cyber Observable References\n",
+    "Cyber Observable Objects have properties that can reference other Cyber Observable Objects. In order to create those references, use the ``_valid_refs`` property as shown in the following examples. There are two cases."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "#### Case 1: Specifying the type of the Cyber Observable Objects being referenced\n",
+    "In the following example, the IPv4Address object has its ``resolves_to_refs`` property specified. As per the spec, this property's value must be a list of reference(s) to MACAddress objects. In this case, those references are strings that state the type of the Cyber Observable Object being referenced, and are provided in ``_valid_refs``."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "
{\n",
+       "    "type": "ipv4-addr",\n",
+       "    "value": "177.60.40.7",\n",
+       "    "resolves_to_refs": [\n",
+       "        "1",\n",
+       "        "2"\n",
+       "    ]\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from stix2 import IPv4Address\n", + "\n", + "ip4 = IPv4Address(\n", + " _valid_refs={\"1\": \"mac-addr\", \"2\": \"mac-addr\"},\n", + " value=\"177.60.40.7\",\n", + " resolves_to_refs=[\"1\", \"2\"]\n", + ")\n", + "\n", + "print(ip4)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Case 2: Specifying the name of the Cyber Observable Objects being referenced\n", + "The following example is just like the one provided in Case 1 above, with one key difference: instead of using strings to specify the type of the Cyber Observable Objects being referenced in ``_valid_refs``, the referenced Cyber Observable Objects are created beforehand and then their names are provided in ``_valid_refs``." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from stix2 import MACAddress\n", + "\n", + "mac_addr_a = MACAddress(value=\"a1:b2:c3:d4:e5:f6\")\n", + "mac_addr_b = MACAddress(value=\"a7:b8:c9:d0:e1:f2\")\n", + "\n", + "ip4_valid_refs = IPv4Address(\n", + " _valid_refs={\"1\": mac_addr_a, \"2\": mac_addr_b},\n", + " value=\"177.60.40.7\",\n", + " resolves_to_refs=[\"1\", \"2\"]\n", + ")\n", + "\n", + "print(ip4_valid_refs)" + ] } ], "metadata": { @@ -881,7 +1032,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.5" + "version": "3.6.7" } }, "nbformat": 4, From 894630852702b2b3409911489050dc29ccd93829 Mon Sep 17 00:00:00 2001 From: Kartikey Desai Date: Fri, 10 May 2019 12:30:52 -0400 Subject: [PATCH 56/62] Updated documentation for _valid_refs --- docs/guide/creating.ipynb | 154 ++++++++++++++++++++++++++++++-------- 1 file changed, 122 insertions(+), 32 deletions(-) diff --git a/docs/guide/creating.ipynb b/docs/guide/creating.ipynb index b1f92a8..5be60ed 100644 --- a/docs/guide/creating.ipynb +++ b/docs/guide/creating.ipynb @@ -144,12 +144,12 @@ ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n", ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "indicator",\n",
-       "    "id": "indicator--7e5fa3b3-dffd-4c57-a655-02b1c78539be",\n",
-       "    "created": "2019-05-10T15:28:49.358Z",\n",
-       "    "modified": "2019-05-10T15:28:49.358Z",\n",
+       "    "id": "indicator--dd10c6df-572f-4494-97c4-245af992a0fe",\n",
+       "    "created": "2019-05-10T16:25:11.193Z",\n",
+       "    "modified": "2019-05-10T16:25:11.193Z",\n",
        "    "name": "File hash for malware variant",\n",
        "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
-       "    "valid_from": "2019-05-10T15:28:49.358947Z",\n",
+       "    "valid_from": "2019-05-10T16:25:11.193329Z",\n",
        "    "labels": [\n",
        "        "malicious-activity"\n",
        "    ]\n",
@@ -465,9 +465,9 @@
        ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
        ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "malware",\n",
-       "    "id": "malware--1b5d97a8-c4a6-4032-b6f4-a5e741036946",\n",
-       "    "created": "2019-05-10T15:29:37.208Z",\n",
-       "    "modified": "2019-05-10T15:29:37.208Z",\n",
+       "    "id": "malware--fbfbe336-cc8d-4b2e-8c87-567ed1bef476",\n",
+       "    "created": "2019-05-10T16:25:29.127Z",\n",
+       "    "modified": "2019-05-10T16:25:29.127Z",\n",
        "    "name": "Poison Ivy",\n",
        "    "labels": [\n",
        "        "remote-access-trojan"\n",
@@ -588,12 +588,12 @@
        ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
        ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "relationship",\n",
-       "    "id": "relationship--aa324701-26d1-447e-b369-1347fb138f44",\n",
-       "    "created": "2019-05-10T15:29:44.848Z",\n",
-       "    "modified": "2019-05-10T15:29:44.848Z",\n",
+       "    "id": "relationship--33be944d-2d23-4f73-b254-988cb7fbd2d5",\n",
+       "    "created": "2019-05-10T16:25:32.644Z",\n",
+       "    "modified": "2019-05-10T16:25:32.644Z",\n",
        "    "relationship_type": "indicates",\n",
-       "    "source_ref": "indicator--7e5fa3b3-dffd-4c57-a655-02b1c78539be",\n",
-       "    "target_ref": "malware--1b5d97a8-c4a6-4032-b6f4-a5e741036946"\n",
+       "    "source_ref": "indicator--dd10c6df-572f-4494-97c4-245af992a0fe",\n",
+       "    "target_ref": "malware--fbfbe336-cc8d-4b2e-8c87-567ed1bef476"\n",
        "}\n",
        "
\n" ], @@ -700,12 +700,12 @@ ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n", ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "relationship",\n",
-       "    "id": "relationship--de00dd44-7685-46b5-bf01-04003a2ee496",\n",
-       "    "created": "2019-05-10T15:29:47.422Z",\n",
-       "    "modified": "2019-05-10T15:29:47.422Z",\n",
+       "    "id": "relationship--d0d3ff20-d0f4-4807-b4dd-692724801ce3",\n",
+       "    "created": "2019-05-10T16:25:34.989Z",\n",
+       "    "modified": "2019-05-10T16:25:34.989Z",\n",
        "    "relationship_type": "indicates",\n",
-       "    "source_ref": "indicator--7e5fa3b3-dffd-4c57-a655-02b1c78539be",\n",
-       "    "target_ref": "malware--1b5d97a8-c4a6-4032-b6f4-a5e741036946"\n",
+       "    "source_ref": "indicator--dd10c6df-572f-4494-97c4-245af992a0fe",\n",
+       "    "target_ref": "malware--fbfbe336-cc8d-4b2e-8c87-567ed1bef476"\n",
        "}\n",
        "
\n" ], @@ -810,26 +810,26 @@ ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n", ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "bundle",\n",
-       "    "id": "bundle--026ce7aa-1a14-4dc3-8dd3-8c2cd4eeaa66",\n",
+       "    "id": "bundle--feaf8f9f-3342-4613-954b-ae22235f8d0b",\n",
        "    "spec_version": "2.0",\n",
        "    "objects": [\n",
        "        {\n",
        "            "type": "indicator",\n",
-       "            "id": "indicator--7e5fa3b3-dffd-4c57-a655-02b1c78539be",\n",
-       "            "created": "2019-05-10T15:28:49.358Z",\n",
-       "            "modified": "2019-05-10T15:28:49.358Z",\n",
+       "            "id": "indicator--dd10c6df-572f-4494-97c4-245af992a0fe",\n",
+       "            "created": "2019-05-10T16:25:11.193Z",\n",
+       "            "modified": "2019-05-10T16:25:11.193Z",\n",
        "            "name": "File hash for malware variant",\n",
        "            "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
-       "            "valid_from": "2019-05-10T15:28:49.358947Z",\n",
+       "            "valid_from": "2019-05-10T16:25:11.193329Z",\n",
        "            "labels": [\n",
        "                "malicious-activity"\n",
        "            ]\n",
        "        },\n",
        "        {\n",
        "            "type": "malware",\n",
-       "            "id": "malware--1b5d97a8-c4a6-4032-b6f4-a5e741036946",\n",
-       "            "created": "2019-05-10T15:29:37.208Z",\n",
-       "            "modified": "2019-05-10T15:29:37.208Z",\n",
+       "            "id": "malware--fbfbe336-cc8d-4b2e-8c87-567ed1bef476",\n",
+       "            "created": "2019-05-10T16:25:29.127Z",\n",
+       "            "modified": "2019-05-10T16:25:29.127Z",\n",
        "            "name": "Poison Ivy",\n",
        "            "labels": [\n",
        "                "remote-access-trojan"\n",
@@ -837,12 +837,12 @@
        "        },\n",
        "        {\n",
        "            "type": "relationship",\n",
-       "            "id": "relationship--aa324701-26d1-447e-b369-1347fb138f44",\n",
-       "            "created": "2019-05-10T15:29:44.848Z",\n",
-       "            "modified": "2019-05-10T15:29:44.848Z",\n",
+       "            "id": "relationship--33be944d-2d23-4f73-b254-988cb7fbd2d5",\n",
+       "            "created": "2019-05-10T16:25:32.644Z",\n",
+       "            "modified": "2019-05-10T16:25:32.644Z",\n",
        "            "relationship_type": "indicates",\n",
-       "            "source_ref": "indicator--7e5fa3b3-dffd-4c57-a655-02b1c78539be",\n",
-       "            "target_ref": "malware--1b5d97a8-c4a6-4032-b6f4-a5e741036946"\n",
+       "            "source_ref": "indicator--dd10c6df-572f-4494-97c4-245af992a0fe",\n",
+       "            "target_ref": "malware--fbfbe336-cc8d-4b2e-8c87-567ed1bef476"\n",
        "        }\n",
        "    ]\n",
        "}\n",
@@ -997,9 +997,99 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 17,
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "
{\n",
+       "    "type": "ipv4-addr",\n",
+       "    "value": "177.60.40.7",\n",
+       "    "resolves_to_refs": [\n",
+       "        "1",\n",
+       "        "2"\n",
+       "    ]\n",
+       "}\n",
+       "
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "from stix2 import MACAddress\n", "\n", From 1bf12221a002f5b30542c3070ccf160651c0daf0 Mon Sep 17 00:00:00 2001 From: Kartikey Desai Date: Mon, 13 May 2019 09:18:50 -0400 Subject: [PATCH 57/62] Update _valid_refs doc and add test to v20 test suite --- docs/guide/creating.ipynb | 64 ++++++++++++++-------------- stix2/test/v20/test_observed_data.py | 18 ++++++++ 2 files changed, 51 insertions(+), 31 deletions(-) diff --git a/docs/guide/creating.ipynb b/docs/guide/creating.ipynb index 5be60ed..92a3336 100644 --- a/docs/guide/creating.ipynb +++ b/docs/guide/creating.ipynb @@ -144,12 +144,12 @@ ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n", ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "indicator",\n",
-       "    "id": "indicator--dd10c6df-572f-4494-97c4-245af992a0fe",\n",
-       "    "created": "2019-05-10T16:25:11.193Z",\n",
-       "    "modified": "2019-05-10T16:25:11.193Z",\n",
+       "    "id": "indicator--2f3d4926-163d-4aef-bcd2-19dea96916ae",\n",
+       "    "created": "2019-05-13T13:14:48.509Z",\n",
+       "    "modified": "2019-05-13T13:14:48.509Z",\n",
        "    "name": "File hash for malware variant",\n",
        "    "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
-       "    "valid_from": "2019-05-10T16:25:11.193329Z",\n",
+       "    "valid_from": "2019-05-13T13:14:48.509629Z",\n",
        "    "labels": [\n",
        "        "malicious-activity"\n",
        "    ]\n",
@@ -465,9 +465,9 @@
        ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
        ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "malware",\n",
-       "    "id": "malware--fbfbe336-cc8d-4b2e-8c87-567ed1bef476",\n",
-       "    "created": "2019-05-10T16:25:29.127Z",\n",
-       "    "modified": "2019-05-10T16:25:29.127Z",\n",
+       "    "id": "malware--1f2aba70-f0ae-49cd-9267-6fcb1e43be67",\n",
+       "    "created": "2019-05-13T13:15:04.698Z",\n",
+       "    "modified": "2019-05-13T13:15:04.698Z",\n",
        "    "name": "Poison Ivy",\n",
        "    "labels": [\n",
        "        "remote-access-trojan"\n",
@@ -588,12 +588,12 @@
        ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
        ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "relationship",\n",
-       "    "id": "relationship--33be944d-2d23-4f73-b254-988cb7fbd2d5",\n",
-       "    "created": "2019-05-10T16:25:32.644Z",\n",
-       "    "modified": "2019-05-10T16:25:32.644Z",\n",
+       "    "id": "relationship--80c174fa-36d1-47c2-9a9d-ce0c636bedcc",\n",
+       "    "created": "2019-05-13T13:15:13.152Z",\n",
+       "    "modified": "2019-05-13T13:15:13.152Z",\n",
        "    "relationship_type": "indicates",\n",
-       "    "source_ref": "indicator--dd10c6df-572f-4494-97c4-245af992a0fe",\n",
-       "    "target_ref": "malware--fbfbe336-cc8d-4b2e-8c87-567ed1bef476"\n",
+       "    "source_ref": "indicator--2f3d4926-163d-4aef-bcd2-19dea96916ae",\n",
+       "    "target_ref": "malware--1f2aba70-f0ae-49cd-9267-6fcb1e43be67"\n",
        "}\n",
        "
\n" ], @@ -700,12 +700,12 @@ ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n", ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "relationship",\n",
-       "    "id": "relationship--d0d3ff20-d0f4-4807-b4dd-692724801ce3",\n",
-       "    "created": "2019-05-10T16:25:34.989Z",\n",
-       "    "modified": "2019-05-10T16:25:34.989Z",\n",
+       "    "id": "relationship--47395d23-dedd-45d4-8db1-c9ffaf44493d",\n",
+       "    "created": "2019-05-13T13:15:16.566Z",\n",
+       "    "modified": "2019-05-13T13:15:16.566Z",\n",
        "    "relationship_type": "indicates",\n",
-       "    "source_ref": "indicator--dd10c6df-572f-4494-97c4-245af992a0fe",\n",
-       "    "target_ref": "malware--fbfbe336-cc8d-4b2e-8c87-567ed1bef476"\n",
+       "    "source_ref": "indicator--2f3d4926-163d-4aef-bcd2-19dea96916ae",\n",
+       "    "target_ref": "malware--1f2aba70-f0ae-49cd-9267-6fcb1e43be67"\n",
        "}\n",
        "
\n" ], @@ -810,26 +810,26 @@ ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n", ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
{\n",
        "    "type": "bundle",\n",
-       "    "id": "bundle--feaf8f9f-3342-4613-954b-ae22235f8d0b",\n",
+       "    "id": "bundle--388c9b2c-936c-420a-baa5-04f48d682a01",\n",
        "    "spec_version": "2.0",\n",
        "    "objects": [\n",
        "        {\n",
        "            "type": "indicator",\n",
-       "            "id": "indicator--dd10c6df-572f-4494-97c4-245af992a0fe",\n",
-       "            "created": "2019-05-10T16:25:11.193Z",\n",
-       "            "modified": "2019-05-10T16:25:11.193Z",\n",
+       "            "id": "indicator--2f3d4926-163d-4aef-bcd2-19dea96916ae",\n",
+       "            "created": "2019-05-13T13:14:48.509Z",\n",
+       "            "modified": "2019-05-13T13:14:48.509Z",\n",
        "            "name": "File hash for malware variant",\n",
        "            "pattern": "[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']",\n",
-       "            "valid_from": "2019-05-10T16:25:11.193329Z",\n",
+       "            "valid_from": "2019-05-13T13:14:48.509629Z",\n",
        "            "labels": [\n",
        "                "malicious-activity"\n",
        "            ]\n",
        "        },\n",
        "        {\n",
        "            "type": "malware",\n",
-       "            "id": "malware--fbfbe336-cc8d-4b2e-8c87-567ed1bef476",\n",
-       "            "created": "2019-05-10T16:25:29.127Z",\n",
-       "            "modified": "2019-05-10T16:25:29.127Z",\n",
+       "            "id": "malware--1f2aba70-f0ae-49cd-9267-6fcb1e43be67",\n",
+       "            "created": "2019-05-13T13:15:04.698Z",\n",
+       "            "modified": "2019-05-13T13:15:04.698Z",\n",
        "            "name": "Poison Ivy",\n",
        "            "labels": [\n",
        "                "remote-access-trojan"\n",
@@ -837,12 +837,12 @@
        "        },\n",
        "        {\n",
        "            "type": "relationship",\n",
-       "            "id": "relationship--33be944d-2d23-4f73-b254-988cb7fbd2d5",\n",
-       "            "created": "2019-05-10T16:25:32.644Z",\n",
-       "            "modified": "2019-05-10T16:25:32.644Z",\n",
+       "            "id": "relationship--80c174fa-36d1-47c2-9a9d-ce0c636bedcc",\n",
+       "            "created": "2019-05-13T13:15:13.152Z",\n",
+       "            "modified": "2019-05-13T13:15:13.152Z",\n",
        "            "relationship_type": "indicates",\n",
-       "            "source_ref": "indicator--dd10c6df-572f-4494-97c4-245af992a0fe",\n",
-       "            "target_ref": "malware--fbfbe336-cc8d-4b2e-8c87-567ed1bef476"\n",
+       "            "source_ref": "indicator--2f3d4926-163d-4aef-bcd2-19dea96916ae",\n",
+       "            "target_ref": "malware--1f2aba70-f0ae-49cd-9267-6fcb1e43be67"\n",
        "        }\n",
        "    ]\n",
        "}\n",
@@ -869,7 +869,9 @@
    "metadata": {},
    "source": [
     "### Creating Cyber Observable References\n",
-    "Cyber Observable Objects have properties that can reference other Cyber Observable Objects. In order to create those references, use the ``_valid_refs`` property as shown in the following examples. There are two cases."
+    "Cyber Observable Objects have properties that can reference other Cyber Observable Objects. In order to create those references, use the ``_valid_refs`` property as shown in the following examples. It should be noted that ``_valid_refs`` is necessary when creating references to Cyber Observable Objects since some embedded references can only point to certain types, and ``_valid_refs`` helps ensure consistency. \n",
+    "\n",
+    "There are two cases."
    ]
   },
   {
diff --git a/stix2/test/v20/test_observed_data.py b/stix2/test/v20/test_observed_data.py
index 84cdf72..95daf22 100644
--- a/stix2/test/v20/test_observed_data.py
+++ b/stix2/test/v20/test_observed_data.py
@@ -960,6 +960,24 @@ def test_ip4_address_example():
     assert ip4.resolves_to_refs == ["4", "5"]
 
 
+def test_ip4_address_valid_refs():
+    mac1 = stix2.v20.MACAddress(
+        value="a1:b2:c3:d4:e5:f6",
+    )
+    mac2 = stix2.v20.MACAddress(
+        value="a7:b8:c9:d0:e1:f2",
+    )
+
+    ip4 = stix2.v20.IPv4Address(
+        _valid_refs={"1": mac1, "2": mac2},
+        value="177.60.40.7",
+        resolves_to_refs=["1", "2"],
+    )
+
+    assert ip4.value == "177.60.40.7"
+    assert ip4.resolves_to_refs == ["1", "2"]
+
+
 def test_ip4_address_example_cidr():
     ip4 = stix2.v20.IPv4Address(value="198.51.100.0/24")
 

From a61344a8aafeaca7831a36f4ec78095d9af5f634 Mon Sep 17 00:00:00 2001
From: "Desai, Kartikey H" 
Date: Tue, 14 May 2019 13:48:54 -0400
Subject: [PATCH 58/62] Add get_obj function to bundle.py to make accessing
 bundles easier

---
 stix2/test/v21/test_bundle.py | 2 ++
 stix2/v21/bundle.py           | 3 +++
 2 files changed, 5 insertions(+)

diff --git a/stix2/test/v21/test_bundle.py b/stix2/test/v21/test_bundle.py
index 7adea92..dc8ae53 100644
--- a/stix2/test/v21/test_bundle.py
+++ b/stix2/test/v21/test_bundle.py
@@ -183,6 +183,8 @@ def test_parse_bundle(version):
     assert bundle.objects[0].type == 'indicator'
     assert bundle.objects[1].type == 'malware'
     assert bundle.objects[2].type == 'relationship'
+    assert bundle.get_obj('malware--00000000-0000-4000-8000-000000000003').type == 'malware'
+    assert bundle.get_obj('blah blah') is None
 
 
 def test_parse_unknown_type():
diff --git a/stix2/v21/bundle.py b/stix2/v21/bundle.py
index c9e083a..9cf0557 100644
--- a/stix2/v21/bundle.py
+++ b/stix2/v21/bundle.py
@@ -33,3 +33,6 @@ class Bundle(_STIXBase):
         self._properties['objects'].contained.allow_custom = kwargs.get('allow_custom', False)
 
         super(Bundle, self).__init__(**kwargs)
+
+    def get_obj(self, obj_uuid):
+        return next((elem for elem in self.objects if elem['id'] == obj_uuid), None)

From 45d3020518bb97b67235d5e41a9ea5d032450b42 Mon Sep 17 00:00:00 2001
From: "Desai, Kartikey H" 
Date: Fri, 17 May 2019 14:21:35 -0500
Subject: [PATCH 59/62] Fixes #257

---
 stix2/test/v21/test_bundle.py | 19 +++++++++++++++++--
 stix2/v21/bundle.py           | 14 +++++++++++++-
 2 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/stix2/test/v21/test_bundle.py b/stix2/test/v21/test_bundle.py
index dc8ae53..3a8e996 100644
--- a/stix2/test/v21/test_bundle.py
+++ b/stix2/test/v21/test_bundle.py
@@ -183,8 +183,23 @@ def test_parse_bundle(version):
     assert bundle.objects[0].type == 'indicator'
     assert bundle.objects[1].type == 'malware'
     assert bundle.objects[2].type == 'relationship'
-    assert bundle.get_obj('malware--00000000-0000-4000-8000-000000000003').type == 'malware'
-    assert bundle.get_obj('blah blah') is None
+    assert bundle['type'] == "bundle"
+    assert len(bundle["indicator--00000000-0000-4000-8000-000000000001"]) == 1
+
+
+def test_bundle_obj_id_not_found():
+    bundle = stix2.parse(EXPECTED_BUNDLE)
+
+    assert bundle.type == "bundle"
+    assert bundle.id.startswith("bundle--")
+    assert type(bundle.objects[0]) is stix2.v21.Indicator
+    assert bundle.objects[0].type == 'indicator'
+    assert bundle.objects[1].type == 'malware'
+    assert bundle.objects[2].type == 'relationship'
+
+    with pytest.raises(KeyError) as excinfo:
+        bundle.get_obj('blah blah')
+    assert "does not match the id property of any of the bundle" in str(excinfo.value)
 
 
 def test_parse_unknown_type():
diff --git a/stix2/v21/bundle.py b/stix2/v21/bundle.py
index 9cf0557..77b78c1 100644
--- a/stix2/v21/bundle.py
+++ b/stix2/v21/bundle.py
@@ -35,4 +35,16 @@ class Bundle(_STIXBase):
         super(Bundle, self).__init__(**kwargs)
 
     def get_obj(self, obj_uuid):
-        return next((elem for elem in self.objects if elem['id'] == obj_uuid), None)
+        found_objs = [elem for elem in self.objects if elem.id == obj_uuid]
+        if found_objs == []:
+            raise KeyError("'%s' does not match the id property of any of the bundle's objects" % obj_uuid)
+        return found_objs
+
+    def __getitem__(self, key):
+        try:
+            return super(Bundle, self).__getitem__(key)
+        except KeyError:
+            try:
+                return self.get_obj(key)
+            except KeyError:
+                raise KeyError("'%s' is neither a valid bundle property nor does it match the id property of any of the bundle's objects" % key)

From 86790a736f1169eb28b82a734ffc3cf5645602ed Mon Sep 17 00:00:00 2001
From: "Desai, Kartikey H" 
Date: Mon, 20 May 2019 15:29:01 -0500
Subject: [PATCH 60/62] Fixes #257

---
 stix2/test/v20/test_bundle.py |  39 ++++++++++++
 stix2/test/v21/test_bundle.py | 117 +++++++++++++++++++++++++++++-----
 stix2/v20/bundle.py           |  18 ++++++
 stix2/v21/bundle.py           |  11 ++--
 4 files changed, 164 insertions(+), 21 deletions(-)

diff --git a/stix2/test/v20/test_bundle.py b/stix2/test/v20/test_bundle.py
index 72523bb..992cde9 100644
--- a/stix2/test/v20/test_bundle.py
+++ b/stix2/test/v20/test_bundle.py
@@ -236,3 +236,42 @@ def test_bundle_with_different_spec_objects():
         stix2.v20.Bundle(objects=data)
 
     assert "Spec version 2.0 bundles don't yet support containing objects of a different spec version." in str(excinfo.value)
+
+
+def test_bundle_obj_id_found():
+    bundle = stix2.parse(EXPECTED_BUNDLE)
+
+    mal_list = bundle.get_obj("malware--00000000-0000-4000-8000-000000000003")
+    assert bundle.objects[1] == mal_list[0]
+    assert len(mal_list) == 1
+
+
+def test_bundle_getitem_overload_property_found():
+    bundle = stix2.parse(EXPECTED_BUNDLE)
+
+    assert bundle.type == "bundle"
+    assert bundle['type'] == "bundle"
+
+
+def test_bundle_getitem_overload_obj_id_found():
+    bundle = stix2.parse(EXPECTED_BUNDLE)
+
+    mal_list = bundle["malware--00000000-0000-4000-8000-000000000003"]
+    assert bundle.objects[1] == mal_list[0]
+    assert len(mal_list) == 1
+
+
+def test_bundle_obj_id_not_found():
+    bundle = stix2.parse(EXPECTED_BUNDLE)
+
+    with pytest.raises(KeyError) as excinfo:
+        bundle.get_obj('non existent')
+    assert "does not match the id property of any of the bundle" in str(excinfo.value)
+
+
+def test_bundle_getitem_overload_obj_id_not_found():
+    bundle = stix2.parse(EXPECTED_BUNDLE)
+
+    with pytest.raises(KeyError) as excinfo:
+        bundle['non existent']
+    assert "neither a valid bundle property nor does it match the id property" in str(excinfo.value)
diff --git a/stix2/test/v21/test_bundle.py b/stix2/test/v21/test_bundle.py
index 3a8e996..4f33fb5 100644
--- a/stix2/test/v21/test_bundle.py
+++ b/stix2/test/v21/test_bundle.py
@@ -183,23 +183,6 @@ def test_parse_bundle(version):
     assert bundle.objects[0].type == 'indicator'
     assert bundle.objects[1].type == 'malware'
     assert bundle.objects[2].type == 'relationship'
-    assert bundle['type'] == "bundle"
-    assert len(bundle["indicator--00000000-0000-4000-8000-000000000001"]) == 1
-
-
-def test_bundle_obj_id_not_found():
-    bundle = stix2.parse(EXPECTED_BUNDLE)
-
-    assert bundle.type == "bundle"
-    assert bundle.id.startswith("bundle--")
-    assert type(bundle.objects[0]) is stix2.v21.Indicator
-    assert bundle.objects[0].type == 'indicator'
-    assert bundle.objects[1].type == 'malware'
-    assert bundle.objects[2].type == 'relationship'
-
-    with pytest.raises(KeyError) as excinfo:
-        bundle.get_obj('blah blah')
-    assert "does not match the id property of any of the bundle" in str(excinfo.value)
 
 
 def test_parse_unknown_type():
@@ -224,3 +207,103 @@ def test_stix_object_property():
 
     identity = stix2.v21.Identity(name="test", identity_class="individual")
     assert prop.clean(identity) is identity
+
+
+def test_bundle_obj_id_found():
+    bundle = stix2.parse(EXPECTED_BUNDLE)
+
+    mal_list = bundle.get_obj("malware--00000000-0000-4000-8000-000000000003")
+    assert bundle.objects[1] == mal_list[0]
+    assert len(mal_list) == 1
+
+
+@pytest.mark.parametrize(
+    "bundle_data", [{
+        "type": "bundle",
+        "id": "bundle--00000000-0000-4000-8000-000000000007",
+        "objects": [
+            {
+                "type": "indicator",
+                "spec_version": "2.1",
+                "id": "indicator--00000000-0000-4000-8000-000000000001",
+                "created": "2017-01-01T12:34:56.000Z",
+                "modified": "2017-01-01T12:34:56.000Z",
+                "indicator_types": [
+                    "malicious-activity",
+                ],
+                "pattern": "[file:hashes.MD5 = 'd41d8cd98f00b204e9800998ecf8427e']",
+                "valid_from": "2017-01-01T12:34:56Z",
+            },
+            {
+                "type": "malware",
+                "spec_version": "2.1",
+                "id": "malware--00000000-0000-4000-8000-000000000003",
+                "created": "2017-01-01T12:34:56.000Z",
+                "modified": "2017-01-01T12:34:56.000Z",
+                "name": "Cryptolocker1",
+                "malware_types": [
+                    "ransomware",
+                ],
+            },
+            {
+                "type": "malware",
+                "spec_version": "2.1",
+                "id": "malware--00000000-0000-4000-8000-000000000003",
+                "created": "2017-01-01T12:34:56.000Z",
+                "modified": "2017-12-21T12:34:56.000Z",
+                "name": "CryptolockerOne",
+                "malware_types": [
+                    "ransomware",
+                ],
+            },
+            {
+                "type": "relationship",
+                "spec_version": "2.1",
+                "id": "relationship--00000000-0000-4000-8000-000000000005",
+                "created": "2017-01-01T12:34:56.000Z",
+                "modified": "2017-01-01T12:34:56.000Z",
+                "relationship_type": "indicates",
+                "source_ref": "indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7",
+                "target_ref": "malware--9c4638ec-f1de-4ddb-abf4-1b760417654e",
+            },
+        ],
+    }],
+)
+def test_bundle_objs_ids_found(bundle_data):
+    bundle = stix2.parse(bundle_data)
+
+    mal_list = bundle.get_obj("malware--00000000-0000-4000-8000-000000000003")
+    assert bundle.objects[1] == mal_list[0]
+    assert bundle.objects[2] == mal_list[1]
+    assert len(mal_list) == 2
+
+
+def test_bundle_getitem_overload_property_found():
+    bundle = stix2.parse(EXPECTED_BUNDLE)
+
+    assert bundle.type == "bundle"
+    assert bundle['type'] == "bundle"
+
+
+def test_bundle_getitem_overload_obj_id_found():
+    bundle = stix2.parse(EXPECTED_BUNDLE)
+
+    mal_list = bundle["malware--00000000-0000-4000-8000-000000000003"]
+    assert bundle.objects[1] == mal_list[0]
+    assert len(mal_list) == 1
+
+
+def test_bundle_obj_id_not_found():
+    bundle = stix2.parse(EXPECTED_BUNDLE)
+
+    with pytest.raises(KeyError) as excinfo:
+        bundle.get_obj('non existent')
+    assert "does not match the id property of any of the bundle" in str(excinfo.value)
+
+
+def test_bundle_getitem_overload_obj_id_not_found():
+    bundle = stix2.parse(EXPECTED_BUNDLE)
+
+    with pytest.raises(KeyError) as excinfo:
+        bundle['non existent']
+    assert "neither a valid bundle property nor does it match the id property" in str(excinfo.value)
diff --git a/stix2/v20/bundle.py b/stix2/v20/bundle.py
index 76386ef..dd2bb2c 100644
--- a/stix2/v20/bundle.py
+++ b/stix2/v20/bundle.py
@@ -35,3 +35,21 @@ class Bundle(_STIXBase):
         self._properties['objects'].contained.allow_custom = kwargs.get('allow_custom', False)
 
         super(Bundle, self).__init__(**kwargs)
+
+    def get_obj(self, obj_uuid):
+        if "objects" in self._inner:
+            found_objs = [elem for elem in self.objects if elem.id == obj_uuid]
+            if found_objs == []:
+                raise KeyError("'%s' does not match the id property of any of the bundle's objects" % obj_uuid)
+            return found_objs
+        else:
+            raise KeyError("There are no objects in this empty bundle")
+
+    def __getitem__(self, key):
+        try:
+            return super(Bundle, self).__getitem__(key)
+        except KeyError:
+            try:
+                return self.get_obj(key)
+            except KeyError:
+                raise KeyError("'%s' is neither a valid bundle property nor does it match the id property of any of the bundle's objects" % key)
diff --git a/stix2/v21/bundle.py b/stix2/v21/bundle.py
index 77b78c1..352cf3b 100644
--- a/stix2/v21/bundle.py
+++ b/stix2/v21/bundle.py
@@ -35,10 +35,13 @@ class Bundle(_STIXBase):
         super(Bundle, self).__init__(**kwargs)
 
     def get_obj(self, obj_uuid):
-        found_objs = [elem for elem in self.objects if elem.id == obj_uuid]
-        if found_objs == []:
-            raise KeyError("'%s' does not match the id property of any of the bundle's objects" % obj_uuid)
-        return found_objs
+        if "objects" in self._inner:
+            found_objs = [elem for elem in self.objects if elem.id == obj_uuid]
+            if found_objs == []:
+                raise KeyError("'%s' does not match the id property of any of the bundle's objects" % obj_uuid)
+            return found_objs
+        else:
+            raise KeyError("There are no objects in this empty bundle")
 
     def __getitem__(self, key):
         try:

From ce86db2a126fbb02c50b8146b8dfcce1ca561caf Mon Sep 17 00:00:00 2001
From: "Desai, Kartikey H" 
Date: Mon, 20 May 2019 15:36:35 -0500
Subject: [PATCH 61/62] Fixes #257

---
 stix2/test/v20/test_bundle.py | 58 +++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/stix2/test/v20/test_bundle.py b/stix2/test/v20/test_bundle.py
index 992cde9..806421a 100644
--- a/stix2/test/v20/test_bundle.py
+++ b/stix2/test/v20/test_bundle.py
@@ -246,6 +246,64 @@ def test_bundle_obj_id_found():
     assert len(mal_list) == 1
 
 
+@pytest.mark.parametrize(
+    "bundle_data", [{
+        "type": "bundle",
+        "id": "bundle--00000000-0000-4000-8000-000000000007",
+        "spec_version": "2.0",
+        "objects": [
+            {
+                "type": "indicator",
+                "id": "indicator--00000000-0000-4000-8000-000000000001",
+                "created": "2017-01-01T12:34:56.000Z",
+                "modified": "2017-01-01T12:34:56.000Z",
+                "pattern": "[file:hashes.MD5 = 'd41d8cd98f00b204e9800998ecf8427e']",
+                "valid_from": "2017-01-01T12:34:56Z",
+                "labels": [
+                    "malicious-activity",
+                ],
+            },
+            {
+                "type": "malware",
+                "id": "malware--00000000-0000-4000-8000-000000000003",
+                "created": "2017-01-01T12:34:56.000Z",
+                "modified": "2017-01-01T12:34:56.000Z",
+                "name": "Cryptolocker1",
+                "labels": [
+                    "ransomware",
+                ],
+            },
+            {
+                "type": "malware",
+                "id": "malware--00000000-0000-4000-8000-000000000003",
+                "created": "2017-01-01T12:34:56.000Z",
+                "modified": "2017-12-21T12:34:56.000Z",
+                "name": "CryptolockerOne",
+                "labels": [
+                    "ransomware",
+                ],
+            },
+            {
+                "type": "relationship",
+                "id": "relationship--00000000-0000-4000-8000-000000000005",
+                "created": "2017-01-01T12:34:56.000Z",
+                "modified": "2017-01-01T12:34:56.000Z",
+                "relationship_type": "indicates",
+                "source_ref": "indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7",
+                "target_ref": "malware--9c4638ec-f1de-4ddb-abf4-1b760417654e",
+            },
+        ],
+    }],
+)
+def test_bundle_objs_ids_found(bundle_data):
+    bundle = stix2.parse(bundle_data)
+
+    mal_list = bundle.get_obj("malware--00000000-0000-4000-8000-000000000003")
+    assert bundle.objects[1] == mal_list[0]
+    assert bundle.objects[2] == mal_list[1]
+    assert len(mal_list) == 2
+
+
 def test_bundle_getitem_overload_property_found():
     bundle = stix2.parse(EXPECTED_BUNDLE)
 

From a6fa3ff1d736b6bd330028258003eb655d4d1fd9 Mon Sep 17 00:00:00 2001
From: Chris Lenk 
Date: Wed, 22 May 2019 11:05:01 -0400
Subject: [PATCH 62/62] Slightly change bundle error message

---
 stix2/test/v20/test_bundle.py | 2 +-
 stix2/test/v21/test_bundle.py | 2 +-
 stix2/v20/bundle.py           | 2 +-
 stix2/v21/bundle.py           | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/stix2/test/v20/test_bundle.py b/stix2/test/v20/test_bundle.py
index 806421a..57c189e 100644
--- a/stix2/test/v20/test_bundle.py
+++ b/stix2/test/v20/test_bundle.py
@@ -332,4 +332,4 @@ def test_bundle_getitem_overload_obj_id_not_found():
 
     with pytest.raises(KeyError) as excinfo:
         bundle['non existent']
-    assert "neither a valid bundle property nor does it match the id property" in str(excinfo.value)
+    assert "neither a property on the bundle nor does it match the id property" in str(excinfo.value)
diff --git a/stix2/test/v21/test_bundle.py b/stix2/test/v21/test_bundle.py
index 4f33fb5..47d0a7a 100644
--- a/stix2/test/v21/test_bundle.py
+++ b/stix2/test/v21/test_bundle.py
@@ -306,4 +306,4 @@ def test_bundle_getitem_overload_obj_id_not_found():
 
     with pytest.raises(KeyError) as excinfo:
         bundle['non existent']
-    assert "neither a valid bundle property nor does it match the id property" in str(excinfo.value)
+    assert "neither a property on the bundle nor does it match the id property" in str(excinfo.value)
diff --git a/stix2/v20/bundle.py b/stix2/v20/bundle.py
index dd2bb2c..be419da 100644
--- a/stix2/v20/bundle.py
+++ b/stix2/v20/bundle.py
@@ -52,4 +52,4 @@ class Bundle(_STIXBase):
             try:
                 return self.get_obj(key)
             except KeyError:
-                raise KeyError("'%s' is neither a valid bundle property nor does it match the id property of any of the bundle's objects" % key)
+                raise KeyError("'%s' is neither a property on the bundle nor does it match the id property of any of the bundle's objects" % key)
diff --git a/stix2/v21/bundle.py b/stix2/v21/bundle.py
index 352cf3b..3ed6024 100644
--- a/stix2/v21/bundle.py
+++ b/stix2/v21/bundle.py
@@ -50,4 +50,4 @@ class Bundle(_STIXBase):
             try:
                 return self.get_obj(key)
             except KeyError:
-                raise KeyError("'%s' is neither a valid bundle property nor does it match the id property of any of the bundle's objects" % key)
+                raise KeyError("'%s' is neither a property on the bundle nor does it match the id property of any of the bundle's objects" % key)