cti-python-stix2/stix2/v21/sdo.py

874 lines
42 KiB
Python
Raw Normal View History

2018-11-28 22:51:00 +01:00
"""STIX 2.1 Domain Objects."""
2017-02-10 22:35:02 +01:00
from collections import OrderedDict
from urllib.parse import quote_plus
import warnings
from stix2patterns.validator import run_validator
2019-02-06 22:16:50 +01:00
from ..custom import _custom_object_builder
from ..exceptions import (
InvalidValueError, PropertyPresenceError, STIXDeprecationWarning,
)
from ..properties import (
BooleanProperty, EnumProperty, ExtensionsProperty, FloatProperty,
IDProperty, IntegerProperty, ListProperty, ObservableProperty,
OpenVocabProperty, PatternProperty, ReferenceProperty, StringProperty,
TimestampProperty, TypeProperty,
)
from ..utils import NOW
from .base import _DomainObject
from .common import (
2021-07-07 02:40:50 +02:00
CustomExtension, ExternalReference, GranularMarking, KillChainPhase,
)
from .vocab import (
ATTACK_MOTIVATION, ATTACK_RESOURCE_LEVEL, GROUPING_CONTEXT, IDENTITY_CLASS,
IMPLEMENTATION_LANGUAGE, INDICATOR_TYPE, INDUSTRY_SECTOR,
INFRASTRUCTURE_TYPE, MALWARE_CAPABILITIES, MALWARE_RESULT, MALWARE_TYPE,
OPINION, PATTERN_TYPE, PROCESSOR_ARCHITECTURE, REGION, REPORT_TYPE,
THREAT_ACTOR_ROLE, THREAT_ACTOR_SOPHISTICATION, THREAT_ACTOR_TYPE,
TOOL_TYPE,
)
class AttackPattern(_DomainObject):
"""For more detailed information on this object's properties, see
2021-07-07 21:03:28 +02:00
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/os/stix-v2.1-os.html#_axjijf603msy>`__.
"""
_type = 'attack-pattern'
_properties = OrderedDict([
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('name', StringProperty(required=True)),
('description', StringProperty()),
('aliases', ListProperty(StringProperty)),
('kill_chain_phases', ListProperty(KillChainPhase)),
('revoked', BooleanProperty(default=lambda: False)),
('labels', ListProperty(StringProperty)),
('confidence', IntegerProperty()),
('lang', StringProperty()),
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
2020-11-10 02:58:34 +01:00
('extensions', ExtensionsProperty(spec_version='2.1')),
])
class Campaign(_DomainObject):
"""For more detailed information on this object's properties, see
2021-07-07 21:03:28 +02:00
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/os/stix-v2.1-os.html#_pcpvfz4ik6d6>`__.
"""
_type = 'campaign'
_properties = OrderedDict([
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('name', StringProperty(required=True)),
('description', StringProperty()),
('aliases', ListProperty(StringProperty)),
('first_seen', TimestampProperty()),
('last_seen', TimestampProperty()),
('objective', StringProperty()),
('revoked', BooleanProperty(default=lambda: False)),
('labels', ListProperty(StringProperty)),
('confidence', IntegerProperty()),
('lang', StringProperty()),
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
2020-11-10 02:58:34 +01:00
('extensions', ExtensionsProperty(spec_version='2.1')),
])
def _check_object_constraints(self):
Improved the exception class hierarchy: - Removed all plain python base classes (e.g. ValueError, TypeError) - Renamed InvalidPropertyConfigurationError -> PropertyPresenceError, since incorrect values could be considered a property config error, and I really just wanted this class to apply to presence (co-)constraint violations. - Added ObjectConfigurationError as a superclass of InvalidValueError, PropertyPresenceError, and any other exception that could be raised during _STIXBase object init, which is when the spec compliance checks happen. This class is intended to represent general spec violations. - Did some class reordering in exceptions.py, so all the ObjectConfigurationError subclasses were together. Changed how property "cleaning" errors were handled: - Previous docs said they should all be ValueErrors, but that would require extra exception check-and-replace complexity in the property implementations, so that requirement is removed. Doc is changed to just say that cleaning problems should cause exceptions to be raised. _STIXBase._check_property() now handles most exception types, not just ValueError. - Decided to try chaining the original clean error to the InvalidValueError, in case the extra diagnostics would be helpful in the future. This is done via 'six' adapter function and only works on python3. - A small amount of testing was removed, since it was looking at custom exception properties which became unavailable once the exception was replaced with InvalidValueError. Did another pass through unit tests to fix breakage caused by the changed exception class hierarchy. Removed unnecessary observable extension handling code from parse_observable(), since it was all duplicated in ExtensionsProperty. The redundant code in parse_observable() had different exception behavior than ExtensionsProperty, which makes the API inconsistent and unit tests more complicated. (Problems in ExtensionsProperty get replaced with InvalidValueError, but extensions problems handled directly in parse_observable() don't get the same replacement, and so the exception type is different.) Redid the workbench monkeypatching. The old way was impossible to make work, and had caused ugly ripple effect hackage in other parts of the codebase. Now, it replaces the global object maps with factory functions which behave the same way when called, as real classes. Had to fix up a few unit tests to get them all passing with this monkeypatching in place. Also remove all the xfail markings in the workbench test suite, since all tests now pass. Since workbench monkeypatching isn't currently affecting any unit tests, tox.ini was simplified to remove the special-casing for running the workbench tests. Removed the v20 workbench test suite, since the workbench currently only works with the latest stix object version.
2019-07-19 20:50:11 +02:00
super(Campaign, self)._check_object_constraints()
first_seen = self.get('first_seen')
last_seen = self.get('last_seen')
if first_seen and last_seen and last_seen < first_seen:
msg = "{0.id} 'last_seen' must be greater than or equal to 'first_seen'"
raise ValueError(msg.format(self))
class CourseOfAction(_DomainObject):
"""For more detailed information on this object's properties, see
2021-07-07 21:03:28 +02:00
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/os/stix-v2.1-os.html#_a925mpw39txn>`__.
"""
_type = 'course-of-action'
_properties = OrderedDict([
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('name', StringProperty(required=True)),
('description', StringProperty()),
('revoked', BooleanProperty(default=lambda: False)),
('labels', ListProperty(StringProperty)),
('confidence', IntegerProperty()),
('lang', StringProperty()),
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
2020-11-10 02:58:34 +01:00
('extensions', ExtensionsProperty(spec_version='2.1')),
])
class Grouping(_DomainObject):
"""For more detailed information on this object's properties, see
2021-07-07 21:03:28 +02:00
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/os/stix-v2.1-os.html#_t56pn7elv6u7>`__.
"""
_type = 'grouping'
_properties = OrderedDict([
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('name', StringProperty()),
('description', StringProperty()),
('context', OpenVocabProperty(GROUPING_CONTEXT, required=True)),
('object_refs', ListProperty(ReferenceProperty(valid_types=["SCO", "SDO", "SRO"], spec_version='2.1'), required=True)),
('revoked', BooleanProperty(default=lambda: False)),
('labels', ListProperty(StringProperty)),
('confidence', IntegerProperty()),
('lang', StringProperty()),
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
2020-11-10 02:58:34 +01:00
('extensions', ExtensionsProperty(spec_version='2.1')),
])
class Identity(_DomainObject):
"""For more detailed information on this object's properties, see
2021-07-07 21:03:28 +02:00
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/os/stix-v2.1-os.html#_wh296fiwpklp>`__.
"""
_type = 'identity'
_properties = OrderedDict([
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('name', StringProperty(required=True)),
('description', StringProperty()),
('roles', ListProperty(StringProperty)),
('identity_class', OpenVocabProperty(IDENTITY_CLASS)),
('sectors', ListProperty(OpenVocabProperty(INDUSTRY_SECTOR))),
('contact_information', StringProperty()),
('revoked', BooleanProperty(default=lambda: False)),
('labels', ListProperty(StringProperty)),
('confidence', IntegerProperty()),
('lang', StringProperty()),
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
2020-11-10 02:58:34 +01:00
('extensions', ExtensionsProperty(spec_version='2.1')),
2020-12-22 23:46:29 +01:00
])
class Incident(_DomainObject):
"""For more detailed information on this object's properties, see
2021-07-07 21:03:28 +02:00
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/os/stix-v2.1-os.html#_sczfhw64pjxt>`__.
2020-12-22 23:46:29 +01:00
"""
_type = 'incident'
_properties = OrderedDict([
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('name', StringProperty(required=True)),
('description', StringProperty()),
('kill_chain_phases', ListProperty(KillChainPhase)),
('revoked', BooleanProperty(default=lambda: False)),
('labels', ListProperty(StringProperty)),
('confidence', IntegerProperty()),
('lang', StringProperty()),
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
class Indicator(_DomainObject):
"""For more detailed information on this object's properties, see
2021-07-07 21:03:28 +02:00
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/os/stix-v2.1-os.html#_muftrcpnf89v>`__.
"""
2017-02-10 22:35:02 +01:00
_type = 'indicator'
_properties = OrderedDict([
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('name', StringProperty()),
('description', StringProperty()),
('indicator_types', ListProperty(OpenVocabProperty(INDICATOR_TYPE))),
('pattern', PatternProperty(required=True)),
('pattern_type', OpenVocabProperty(PATTERN_TYPE, required=True)),
('pattern_version', StringProperty()),
('valid_from', TimestampProperty(default=lambda: NOW)),
('valid_until', TimestampProperty()),
('kill_chain_phases', ListProperty(KillChainPhase)),
('revoked', BooleanProperty(default=lambda: False)),
('labels', ListProperty(StringProperty)),
('confidence', IntegerProperty()),
('lang', StringProperty()),
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
2020-11-10 02:58:34 +01:00
('extensions', ExtensionsProperty(spec_version='2.1')),
])
2017-02-10 22:35:02 +01:00
def __init__(self, *args, **kwargs):
if kwargs.get('pattern') and kwargs.get('pattern_type') == 'stix' and not kwargs.get('pattern_version'):
kwargs['pattern_version'] = '2.1'
2020-06-30 19:58:19 +02:00
super(Indicator, self).__init__(*args, **kwargs)
def _check_object_constraints(self):
Improved the exception class hierarchy: - Removed all plain python base classes (e.g. ValueError, TypeError) - Renamed InvalidPropertyConfigurationError -> PropertyPresenceError, since incorrect values could be considered a property config error, and I really just wanted this class to apply to presence (co-)constraint violations. - Added ObjectConfigurationError as a superclass of InvalidValueError, PropertyPresenceError, and any other exception that could be raised during _STIXBase object init, which is when the spec compliance checks happen. This class is intended to represent general spec violations. - Did some class reordering in exceptions.py, so all the ObjectConfigurationError subclasses were together. Changed how property "cleaning" errors were handled: - Previous docs said they should all be ValueErrors, but that would require extra exception check-and-replace complexity in the property implementations, so that requirement is removed. Doc is changed to just say that cleaning problems should cause exceptions to be raised. _STIXBase._check_property() now handles most exception types, not just ValueError. - Decided to try chaining the original clean error to the InvalidValueError, in case the extra diagnostics would be helpful in the future. This is done via 'six' adapter function and only works on python3. - A small amount of testing was removed, since it was looking at custom exception properties which became unavailable once the exception was replaced with InvalidValueError. Did another pass through unit tests to fix breakage caused by the changed exception class hierarchy. Removed unnecessary observable extension handling code from parse_observable(), since it was all duplicated in ExtensionsProperty. The redundant code in parse_observable() had different exception behavior than ExtensionsProperty, which makes the API inconsistent and unit tests more complicated. (Problems in ExtensionsProperty get replaced with InvalidValueError, but extensions problems handled directly in parse_observable() don't get the same replacement, and so the exception type is different.) Redid the workbench monkeypatching. The old way was impossible to make work, and had caused ugly ripple effect hackage in other parts of the codebase. Now, it replaces the global object maps with factory functions which behave the same way when called, as real classes. Had to fix up a few unit tests to get them all passing with this monkeypatching in place. Also remove all the xfail markings in the workbench test suite, since all tests now pass. Since workbench monkeypatching isn't currently affecting any unit tests, tox.ini was simplified to remove the special-casing for running the workbench tests. Removed the v20 workbench test suite, since the workbench currently only works with the latest stix object version.
2019-07-19 20:50:11 +02:00
super(Indicator, self)._check_object_constraints()
valid_from = self.get('valid_from')
valid_until = self.get('valid_until')
if valid_from and valid_until and valid_until <= valid_from:
msg = "{0.id} 'valid_until' must be greater than 'valid_from'"
raise ValueError(msg.format(self))
if self.get('pattern_type') == "stix":
try:
pat_ver = self.get('pattern_version')
except AttributeError:
pat_ver = '2.1'
errors = run_validator(self.get('pattern'), pat_ver)
if errors:
raise InvalidValueError(self.__class__, 'pattern', str(errors[0]))
2017-02-10 22:35:02 +01:00
class Infrastructure(_DomainObject):
"""For more detailed information on this object's properties, see
2021-07-07 21:03:28 +02:00
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/os/stix-v2.1-os.html#_jo3k1o6lr9>`__.
"""
_type = 'infrastructure'
_properties = OrderedDict([
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('name', StringProperty(required=True)),
('description', StringProperty()),
('infrastructure_types', ListProperty(OpenVocabProperty(INFRASTRUCTURE_TYPE))),
('aliases', ListProperty(StringProperty)),
('kill_chain_phases', ListProperty(KillChainPhase)),
('first_seen', TimestampProperty()),
('last_seen', TimestampProperty()),
('revoked', BooleanProperty(default=lambda: False)),
('labels', ListProperty(StringProperty)),
('confidence', IntegerProperty()),
('lang', StringProperty()),
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
2020-11-10 02:58:34 +01:00
('extensions', ExtensionsProperty(spec_version='2.1')),
])
def _check_object_constraints(self):
Improved the exception class hierarchy: - Removed all plain python base classes (e.g. ValueError, TypeError) - Renamed InvalidPropertyConfigurationError -> PropertyPresenceError, since incorrect values could be considered a property config error, and I really just wanted this class to apply to presence (co-)constraint violations. - Added ObjectConfigurationError as a superclass of InvalidValueError, PropertyPresenceError, and any other exception that could be raised during _STIXBase object init, which is when the spec compliance checks happen. This class is intended to represent general spec violations. - Did some class reordering in exceptions.py, so all the ObjectConfigurationError subclasses were together. Changed how property "cleaning" errors were handled: - Previous docs said they should all be ValueErrors, but that would require extra exception check-and-replace complexity in the property implementations, so that requirement is removed. Doc is changed to just say that cleaning problems should cause exceptions to be raised. _STIXBase._check_property() now handles most exception types, not just ValueError. - Decided to try chaining the original clean error to the InvalidValueError, in case the extra diagnostics would be helpful in the future. This is done via 'six' adapter function and only works on python3. - A small amount of testing was removed, since it was looking at custom exception properties which became unavailable once the exception was replaced with InvalidValueError. Did another pass through unit tests to fix breakage caused by the changed exception class hierarchy. Removed unnecessary observable extension handling code from parse_observable(), since it was all duplicated in ExtensionsProperty. The redundant code in parse_observable() had different exception behavior than ExtensionsProperty, which makes the API inconsistent and unit tests more complicated. (Problems in ExtensionsProperty get replaced with InvalidValueError, but extensions problems handled directly in parse_observable() don't get the same replacement, and so the exception type is different.) Redid the workbench monkeypatching. The old way was impossible to make work, and had caused ugly ripple effect hackage in other parts of the codebase. Now, it replaces the global object maps with factory functions which behave the same way when called, as real classes. Had to fix up a few unit tests to get them all passing with this monkeypatching in place. Also remove all the xfail markings in the workbench test suite, since all tests now pass. Since workbench monkeypatching isn't currently affecting any unit tests, tox.ini was simplified to remove the special-casing for running the workbench tests. Removed the v20 workbench test suite, since the workbench currently only works with the latest stix object version.
2019-07-19 20:50:11 +02:00
super(Infrastructure, self)._check_object_constraints()
first_seen = self.get('first_seen')
last_seen = self.get('last_seen')
if first_seen and last_seen and last_seen < first_seen:
msg = "{0.id} 'last_seen' must be greater than or equal to 'first_seen'"
raise ValueError(msg.format(self))
class IntrusionSet(_DomainObject):
"""For more detailed information on this object's properties, see
2021-07-07 21:03:28 +02:00
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/os/stix-v2.1-os.html#_5ol9xlbbnrdn>`__.
"""
_type = 'intrusion-set'
_properties = OrderedDict([
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('name', StringProperty(required=True)),
('description', StringProperty()),
('aliases', ListProperty(StringProperty)),
('first_seen', TimestampProperty()),
2018-02-23 14:24:26 +01:00
('last_seen', TimestampProperty()),
('goals', ListProperty(StringProperty)),
('resource_level', OpenVocabProperty(ATTACK_RESOURCE_LEVEL)),
('primary_motivation', OpenVocabProperty(ATTACK_MOTIVATION)),
('secondary_motivations', ListProperty(OpenVocabProperty(ATTACK_MOTIVATION))),
('revoked', BooleanProperty(default=lambda: False)),
('labels', ListProperty(StringProperty)),
('confidence', IntegerProperty()),
('lang', StringProperty()),
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
2020-11-10 02:58:34 +01:00
('extensions', ExtensionsProperty(spec_version='2.1')),
])
def _check_object_constraints(self):
Improved the exception class hierarchy: - Removed all plain python base classes (e.g. ValueError, TypeError) - Renamed InvalidPropertyConfigurationError -> PropertyPresenceError, since incorrect values could be considered a property config error, and I really just wanted this class to apply to presence (co-)constraint violations. - Added ObjectConfigurationError as a superclass of InvalidValueError, PropertyPresenceError, and any other exception that could be raised during _STIXBase object init, which is when the spec compliance checks happen. This class is intended to represent general spec violations. - Did some class reordering in exceptions.py, so all the ObjectConfigurationError subclasses were together. Changed how property "cleaning" errors were handled: - Previous docs said they should all be ValueErrors, but that would require extra exception check-and-replace complexity in the property implementations, so that requirement is removed. Doc is changed to just say that cleaning problems should cause exceptions to be raised. _STIXBase._check_property() now handles most exception types, not just ValueError. - Decided to try chaining the original clean error to the InvalidValueError, in case the extra diagnostics would be helpful in the future. This is done via 'six' adapter function and only works on python3. - A small amount of testing was removed, since it was looking at custom exception properties which became unavailable once the exception was replaced with InvalidValueError. Did another pass through unit tests to fix breakage caused by the changed exception class hierarchy. Removed unnecessary observable extension handling code from parse_observable(), since it was all duplicated in ExtensionsProperty. The redundant code in parse_observable() had different exception behavior than ExtensionsProperty, which makes the API inconsistent and unit tests more complicated. (Problems in ExtensionsProperty get replaced with InvalidValueError, but extensions problems handled directly in parse_observable() don't get the same replacement, and so the exception type is different.) Redid the workbench monkeypatching. The old way was impossible to make work, and had caused ugly ripple effect hackage in other parts of the codebase. Now, it replaces the global object maps with factory functions which behave the same way when called, as real classes. Had to fix up a few unit tests to get them all passing with this monkeypatching in place. Also remove all the xfail markings in the workbench test suite, since all tests now pass. Since workbench monkeypatching isn't currently affecting any unit tests, tox.ini was simplified to remove the special-casing for running the workbench tests. Removed the v20 workbench test suite, since the workbench currently only works with the latest stix object version.
2019-07-19 20:50:11 +02:00
super(IntrusionSet, self)._check_object_constraints()
first_seen = self.get('first_seen')
last_seen = self.get('last_seen')
if first_seen and last_seen and last_seen < first_seen:
msg = "{0.id} 'last_seen' must be greater than or equal to 'first_seen'"
raise ValueError(msg.format(self))
class Location(_DomainObject):
"""For more detailed information on this object's properties, see
2021-07-07 21:03:28 +02:00
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/os/stix-v2.1-os.html#_th8nitr8jb4k>`__.
"""
_type = 'location'
_properties = OrderedDict([
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('name', StringProperty()),
('description', StringProperty()),
('latitude', FloatProperty(min=-90.0, max=90.0)),
('longitude', FloatProperty(min=-180.0, max=180.0)),
('precision', FloatProperty(min=0.0)),
('region', OpenVocabProperty(REGION)),
('country', StringProperty()),
('administrative_area', StringProperty()),
('city', StringProperty()),
('street_address', StringProperty()),
('postal_code', StringProperty()),
('revoked', BooleanProperty(default=lambda: False)),
('labels', ListProperty(StringProperty)),
('confidence', IntegerProperty()),
('lang', StringProperty()),
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
2020-11-10 02:58:34 +01:00
('extensions', ExtensionsProperty(spec_version='2.1')),
])
2018-07-25 18:43:57 +02:00
def _check_object_constraints(self):
Improved the exception class hierarchy: - Removed all plain python base classes (e.g. ValueError, TypeError) - Renamed InvalidPropertyConfigurationError -> PropertyPresenceError, since incorrect values could be considered a property config error, and I really just wanted this class to apply to presence (co-)constraint violations. - Added ObjectConfigurationError as a superclass of InvalidValueError, PropertyPresenceError, and any other exception that could be raised during _STIXBase object init, which is when the spec compliance checks happen. This class is intended to represent general spec violations. - Did some class reordering in exceptions.py, so all the ObjectConfigurationError subclasses were together. Changed how property "cleaning" errors were handled: - Previous docs said they should all be ValueErrors, but that would require extra exception check-and-replace complexity in the property implementations, so that requirement is removed. Doc is changed to just say that cleaning problems should cause exceptions to be raised. _STIXBase._check_property() now handles most exception types, not just ValueError. - Decided to try chaining the original clean error to the InvalidValueError, in case the extra diagnostics would be helpful in the future. This is done via 'six' adapter function and only works on python3. - A small amount of testing was removed, since it was looking at custom exception properties which became unavailable once the exception was replaced with InvalidValueError. Did another pass through unit tests to fix breakage caused by the changed exception class hierarchy. Removed unnecessary observable extension handling code from parse_observable(), since it was all duplicated in ExtensionsProperty. The redundant code in parse_observable() had different exception behavior than ExtensionsProperty, which makes the API inconsistent and unit tests more complicated. (Problems in ExtensionsProperty get replaced with InvalidValueError, but extensions problems handled directly in parse_observable() don't get the same replacement, and so the exception type is different.) Redid the workbench monkeypatching. The old way was impossible to make work, and had caused ugly ripple effect hackage in other parts of the codebase. Now, it replaces the global object maps with factory functions which behave the same way when called, as real classes. Had to fix up a few unit tests to get them all passing with this monkeypatching in place. Also remove all the xfail markings in the workbench test suite, since all tests now pass. Since workbench monkeypatching isn't currently affecting any unit tests, tox.ini was simplified to remove the special-casing for running the workbench tests. Removed the v20 workbench test suite, since the workbench currently only works with the latest stix object version.
2019-07-19 20:50:11 +02:00
super(Location, self)._check_object_constraints()
2018-07-25 19:32:22 +02:00
if self.get('precision') is not None:
2018-07-25 18:43:57 +02:00
self._check_properties_dependency(['longitude', 'latitude'], ['precision'])
self._check_properties_dependency(['latitude'], ['longitude'])
self._check_properties_dependency(['longitude'], ['latitude'])
2018-07-25 18:43:57 +02:00
if not (
'region' in self
or 'country' in self
or (
'latitude' in self
and 'longitude' in self
)
):
Improved the exception class hierarchy: - Removed all plain python base classes (e.g. ValueError, TypeError) - Renamed InvalidPropertyConfigurationError -> PropertyPresenceError, since incorrect values could be considered a property config error, and I really just wanted this class to apply to presence (co-)constraint violations. - Added ObjectConfigurationError as a superclass of InvalidValueError, PropertyPresenceError, and any other exception that could be raised during _STIXBase object init, which is when the spec compliance checks happen. This class is intended to represent general spec violations. - Did some class reordering in exceptions.py, so all the ObjectConfigurationError subclasses were together. Changed how property "cleaning" errors were handled: - Previous docs said they should all be ValueErrors, but that would require extra exception check-and-replace complexity in the property implementations, so that requirement is removed. Doc is changed to just say that cleaning problems should cause exceptions to be raised. _STIXBase._check_property() now handles most exception types, not just ValueError. - Decided to try chaining the original clean error to the InvalidValueError, in case the extra diagnostics would be helpful in the future. This is done via 'six' adapter function and only works on python3. - A small amount of testing was removed, since it was looking at custom exception properties which became unavailable once the exception was replaced with InvalidValueError. Did another pass through unit tests to fix breakage caused by the changed exception class hierarchy. Removed unnecessary observable extension handling code from parse_observable(), since it was all duplicated in ExtensionsProperty. The redundant code in parse_observable() had different exception behavior than ExtensionsProperty, which makes the API inconsistent and unit tests more complicated. (Problems in ExtensionsProperty get replaced with InvalidValueError, but extensions problems handled directly in parse_observable() don't get the same replacement, and so the exception type is different.) Redid the workbench monkeypatching. The old way was impossible to make work, and had caused ugly ripple effect hackage in other parts of the codebase. Now, it replaces the global object maps with factory functions which behave the same way when called, as real classes. Had to fix up a few unit tests to get them all passing with this monkeypatching in place. Also remove all the xfail markings in the workbench test suite, since all tests now pass. Since workbench monkeypatching isn't currently affecting any unit tests, tox.ini was simplified to remove the special-casing for running the workbench tests. Removed the v20 workbench test suite, since the workbench currently only works with the latest stix object version.
2019-07-19 20:50:11 +02:00
raise PropertyPresenceError(
"Location objects must have the properties 'region', "
"'country', or 'latitude' and 'longitude'",
Improved the exception class hierarchy: - Removed all plain python base classes (e.g. ValueError, TypeError) - Renamed InvalidPropertyConfigurationError -> PropertyPresenceError, since incorrect values could be considered a property config error, and I really just wanted this class to apply to presence (co-)constraint violations. - Added ObjectConfigurationError as a superclass of InvalidValueError, PropertyPresenceError, and any other exception that could be raised during _STIXBase object init, which is when the spec compliance checks happen. This class is intended to represent general spec violations. - Did some class reordering in exceptions.py, so all the ObjectConfigurationError subclasses were together. Changed how property "cleaning" errors were handled: - Previous docs said they should all be ValueErrors, but that would require extra exception check-and-replace complexity in the property implementations, so that requirement is removed. Doc is changed to just say that cleaning problems should cause exceptions to be raised. _STIXBase._check_property() now handles most exception types, not just ValueError. - Decided to try chaining the original clean error to the InvalidValueError, in case the extra diagnostics would be helpful in the future. This is done via 'six' adapter function and only works on python3. - A small amount of testing was removed, since it was looking at custom exception properties which became unavailable once the exception was replaced with InvalidValueError. Did another pass through unit tests to fix breakage caused by the changed exception class hierarchy. Removed unnecessary observable extension handling code from parse_observable(), since it was all duplicated in ExtensionsProperty. The redundant code in parse_observable() had different exception behavior than ExtensionsProperty, which makes the API inconsistent and unit tests more complicated. (Problems in ExtensionsProperty get replaced with InvalidValueError, but extensions problems handled directly in parse_observable() don't get the same replacement, and so the exception type is different.) Redid the workbench monkeypatching. The old way was impossible to make work, and had caused ugly ripple effect hackage in other parts of the codebase. Now, it replaces the global object maps with factory functions which behave the same way when called, as real classes. Had to fix up a few unit tests to get them all passing with this monkeypatching in place. Also remove all the xfail markings in the workbench test suite, since all tests now pass. Since workbench monkeypatching isn't currently affecting any unit tests, tox.ini was simplified to remove the special-casing for running the workbench tests. Removed the v20 workbench test suite, since the workbench currently only works with the latest stix object version.
2019-07-19 20:50:11 +02:00
Location,
)
2019-02-06 22:16:50 +01:00
def to_maps_url(self, map_engine="Google Maps"):
2019-02-08 20:41:54 +01:00
"""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.
"""
2019-02-06 22:16:50 +01:00
params = []
latitude = self.get('latitude', None)
longitude = self.get('longitude', None)
if latitude is not None and longitude is not None:
2019-02-06 22:16:50 +01:00
params.extend([str(latitude), str(longitude)])
else:
properties = ['street_address', 'city', 'country', 'region', 'administrative_area', 'postal_code']
2019-02-06 22:16:50 +01:00
params = [self.get(prop) for prop in properties if self.get(prop) is not None]
return self._to_maps_url_dispatcher(map_engine, params)
2019-02-06 22:16:50 +01:00
def _to_maps_url_dispatcher(self, map_engine, params):
2019-02-06 22:16:50 +01:00
if map_engine == "Google Maps":
return self._to_google_maps_url(params)
elif map_engine == "Bing Maps":
return self._to_bing_maps_url(params)
2019-02-06 22:16:50 +01:00
else:
raise ValueError(map_engine + " is not a valid or currently-supported map engine")
2019-02-06 22:16:50 +01:00
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(_DomainObject):
"""For more detailed information on this object's properties, see
2021-07-07 21:03:28 +02:00
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/os/stix-v2.1-os.html#_s5l7katgbp09>`__.
"""
2017-02-10 22:35:02 +01:00
_type = 'malware'
_properties = OrderedDict([
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('name', StringProperty()),
('description', StringProperty()),
('malware_types', ListProperty(OpenVocabProperty(MALWARE_TYPE))),
('is_family', BooleanProperty(required=True)),
('aliases', ListProperty(StringProperty)),
('kill_chain_phases', ListProperty(KillChainPhase)),
('first_seen', TimestampProperty()),
('last_seen', TimestampProperty()),
('operating_system_refs', ListProperty(ReferenceProperty(valid_types='software', spec_version='2.1'))),
('architecture_execution_envs', ListProperty(OpenVocabProperty(PROCESSOR_ARCHITECTURE))),
('implementation_languages', ListProperty(OpenVocabProperty(IMPLEMENTATION_LANGUAGE))),
('capabilities', ListProperty(OpenVocabProperty(MALWARE_CAPABILITIES))),
('sample_refs', ListProperty(ReferenceProperty(valid_types=['artifact', 'file'], spec_version='2.1'))),
('revoked', BooleanProperty(default=lambda: False)),
('labels', ListProperty(StringProperty)),
('confidence', IntegerProperty()),
('lang', StringProperty()),
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
2020-11-10 02:58:34 +01:00
('extensions', ExtensionsProperty(spec_version='2.1')),
])
def _check_object_constraints(self):
Improved the exception class hierarchy: - Removed all plain python base classes (e.g. ValueError, TypeError) - Renamed InvalidPropertyConfigurationError -> PropertyPresenceError, since incorrect values could be considered a property config error, and I really just wanted this class to apply to presence (co-)constraint violations. - Added ObjectConfigurationError as a superclass of InvalidValueError, PropertyPresenceError, and any other exception that could be raised during _STIXBase object init, which is when the spec compliance checks happen. This class is intended to represent general spec violations. - Did some class reordering in exceptions.py, so all the ObjectConfigurationError subclasses were together. Changed how property "cleaning" errors were handled: - Previous docs said they should all be ValueErrors, but that would require extra exception check-and-replace complexity in the property implementations, so that requirement is removed. Doc is changed to just say that cleaning problems should cause exceptions to be raised. _STIXBase._check_property() now handles most exception types, not just ValueError. - Decided to try chaining the original clean error to the InvalidValueError, in case the extra diagnostics would be helpful in the future. This is done via 'six' adapter function and only works on python3. - A small amount of testing was removed, since it was looking at custom exception properties which became unavailable once the exception was replaced with InvalidValueError. Did another pass through unit tests to fix breakage caused by the changed exception class hierarchy. Removed unnecessary observable extension handling code from parse_observable(), since it was all duplicated in ExtensionsProperty. The redundant code in parse_observable() had different exception behavior than ExtensionsProperty, which makes the API inconsistent and unit tests more complicated. (Problems in ExtensionsProperty get replaced with InvalidValueError, but extensions problems handled directly in parse_observable() don't get the same replacement, and so the exception type is different.) Redid the workbench monkeypatching. The old way was impossible to make work, and had caused ugly ripple effect hackage in other parts of the codebase. Now, it replaces the global object maps with factory functions which behave the same way when called, as real classes. Had to fix up a few unit tests to get them all passing with this monkeypatching in place. Also remove all the xfail markings in the workbench test suite, since all tests now pass. Since workbench monkeypatching isn't currently affecting any unit tests, tox.ini was simplified to remove the special-casing for running the workbench tests. Removed the v20 workbench test suite, since the workbench currently only works with the latest stix object version.
2019-07-19 20:50:11 +02:00
super(Malware, self)._check_object_constraints()
first_seen = self.get('first_seen')
last_seen = self.get('last_seen')
if first_seen and last_seen and last_seen < first_seen:
msg = "{0.id} 'last_seen' must be greater than or equal to 'first_seen'"
raise ValueError(msg.format(self))
if self.is_family and "name" not in self:
Improved the exception class hierarchy: - Removed all plain python base classes (e.g. ValueError, TypeError) - Renamed InvalidPropertyConfigurationError -> PropertyPresenceError, since incorrect values could be considered a property config error, and I really just wanted this class to apply to presence (co-)constraint violations. - Added ObjectConfigurationError as a superclass of InvalidValueError, PropertyPresenceError, and any other exception that could be raised during _STIXBase object init, which is when the spec compliance checks happen. This class is intended to represent general spec violations. - Did some class reordering in exceptions.py, so all the ObjectConfigurationError subclasses were together. Changed how property "cleaning" errors were handled: - Previous docs said they should all be ValueErrors, but that would require extra exception check-and-replace complexity in the property implementations, so that requirement is removed. Doc is changed to just say that cleaning problems should cause exceptions to be raised. _STIXBase._check_property() now handles most exception types, not just ValueError. - Decided to try chaining the original clean error to the InvalidValueError, in case the extra diagnostics would be helpful in the future. This is done via 'six' adapter function and only works on python3. - A small amount of testing was removed, since it was looking at custom exception properties which became unavailable once the exception was replaced with InvalidValueError. Did another pass through unit tests to fix breakage caused by the changed exception class hierarchy. Removed unnecessary observable extension handling code from parse_observable(), since it was all duplicated in ExtensionsProperty. The redundant code in parse_observable() had different exception behavior than ExtensionsProperty, which makes the API inconsistent and unit tests more complicated. (Problems in ExtensionsProperty get replaced with InvalidValueError, but extensions problems handled directly in parse_observable() don't get the same replacement, and so the exception type is different.) Redid the workbench monkeypatching. The old way was impossible to make work, and had caused ugly ripple effect hackage in other parts of the codebase. Now, it replaces the global object maps with factory functions which behave the same way when called, as real classes. Had to fix up a few unit tests to get them all passing with this monkeypatching in place. Also remove all the xfail markings in the workbench test suite, since all tests now pass. Since workbench monkeypatching isn't currently affecting any unit tests, tox.ini was simplified to remove the special-casing for running the workbench tests. Removed the v20 workbench test suite, since the workbench currently only works with the latest stix object version.
2019-07-19 20:50:11 +02:00
raise PropertyPresenceError(
"'name' is a required property for malware families",
Improved the exception class hierarchy: - Removed all plain python base classes (e.g. ValueError, TypeError) - Renamed InvalidPropertyConfigurationError -> PropertyPresenceError, since incorrect values could be considered a property config error, and I really just wanted this class to apply to presence (co-)constraint violations. - Added ObjectConfigurationError as a superclass of InvalidValueError, PropertyPresenceError, and any other exception that could be raised during _STIXBase object init, which is when the spec compliance checks happen. This class is intended to represent general spec violations. - Did some class reordering in exceptions.py, so all the ObjectConfigurationError subclasses were together. Changed how property "cleaning" errors were handled: - Previous docs said they should all be ValueErrors, but that would require extra exception check-and-replace complexity in the property implementations, so that requirement is removed. Doc is changed to just say that cleaning problems should cause exceptions to be raised. _STIXBase._check_property() now handles most exception types, not just ValueError. - Decided to try chaining the original clean error to the InvalidValueError, in case the extra diagnostics would be helpful in the future. This is done via 'six' adapter function and only works on python3. - A small amount of testing was removed, since it was looking at custom exception properties which became unavailable once the exception was replaced with InvalidValueError. Did another pass through unit tests to fix breakage caused by the changed exception class hierarchy. Removed unnecessary observable extension handling code from parse_observable(), since it was all duplicated in ExtensionsProperty. The redundant code in parse_observable() had different exception behavior than ExtensionsProperty, which makes the API inconsistent and unit tests more complicated. (Problems in ExtensionsProperty get replaced with InvalidValueError, but extensions problems handled directly in parse_observable() don't get the same replacement, and so the exception type is different.) Redid the workbench monkeypatching. The old way was impossible to make work, and had caused ugly ripple effect hackage in other parts of the codebase. Now, it replaces the global object maps with factory functions which behave the same way when called, as real classes. Had to fix up a few unit tests to get them all passing with this monkeypatching in place. Also remove all the xfail markings in the workbench test suite, since all tests now pass. Since workbench monkeypatching isn't currently affecting any unit tests, tox.ini was simplified to remove the special-casing for running the workbench tests. Removed the v20 workbench test suite, since the workbench currently only works with the latest stix object version.
2019-07-19 20:50:11 +02:00
Malware,
)
class MalwareAnalysis(_DomainObject):
2019-06-26 23:06:26 +02:00
"""For more detailed information on this object's properties, see
2021-07-07 21:03:28 +02:00
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/os/stix-v2.1-os.html#_6hdrixb3ua4j>`__.
2019-06-26 23:06:26 +02:00
"""
_type = 'malware-analysis'
_properties = OrderedDict([
('type', TypeProperty(_type, spec_version='2.1')),
2019-06-26 23:06:26 +02:00
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
2019-06-26 23:06:26 +02:00
('product', StringProperty(required=True)),
('version', StringProperty()),
('host_vm_ref', ReferenceProperty(valid_types='software', spec_version='2.1')),
('operating_system_ref', ReferenceProperty(valid_types='software', spec_version='2.1')),
('installed_software_refs', ListProperty(ReferenceProperty(valid_types='software', spec_version='2.1'))),
2019-06-26 23:06:26 +02:00
('configuration_version', StringProperty()),
('modules', ListProperty(StringProperty)),
2019-06-26 23:06:26 +02:00
('analysis_engine_version', StringProperty()),
('analysis_definition_version', StringProperty()),
('submitted', TimestampProperty()),
('analysis_started', TimestampProperty()),
('analysis_ended', TimestampProperty()),
('result_name', StringProperty()),
('result', OpenVocabProperty(MALWARE_RESULT)),
('analysis_sco_refs', ListProperty(ReferenceProperty(valid_types="SCO", spec_version='2.1'))),
('sample_ref', ReferenceProperty(valid_types="SCO", spec_version='2.1')),
('revoked', BooleanProperty(default=lambda: False)),
('labels', ListProperty(StringProperty)),
('confidence', IntegerProperty()),
('lang', StringProperty()),
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
2020-11-10 02:58:34 +01:00
('extensions', ExtensionsProperty(spec_version='2.1')),
2019-06-26 23:06:26 +02:00
])
def _check_object_constraints(self):
super(MalwareAnalysis, self)._check_object_constraints()
self._check_at_least_one_property(["result", "analysis_sco_refs"])
2019-06-26 23:06:26 +02:00
class Note(_DomainObject):
"""For more detailed information on this object's properties, see
2021-07-07 21:03:28 +02:00
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/os/stix-v2.1-os.html#_gudodcg1sbb9>`__.
"""
_type = 'note'
_properties = OrderedDict([
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('abstract', StringProperty()),
('content', StringProperty(required=True)),
('authors', ListProperty(StringProperty)),
('object_refs', ListProperty(ReferenceProperty(valid_types=["SCO", "SDO", "SRO"], spec_version='2.1'), required=True)),
('revoked', BooleanProperty(default=lambda: False)),
('labels', ListProperty(StringProperty)),
('confidence', IntegerProperty()),
('lang', StringProperty()),
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
2020-11-10 02:58:34 +01:00
('extensions', ExtensionsProperty(spec_version='2.1')),
])
2017-02-10 22:35:02 +01:00
class ObservedData(_DomainObject):
"""For more detailed information on this object's properties, see
2021-07-07 21:03:28 +02:00
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/os/stix-v2.1-os.html#_p49j1fwoxldc>`__.
"""
_type = 'observed-data'
_properties = OrderedDict([
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('first_observed', TimestampProperty(required=True)),
('last_observed', TimestampProperty(required=True)),
('number_observed', IntegerProperty(min=1, max=999999999, required=True)),
('objects', ObservableProperty(spec_version='2.1')),
2020-11-10 02:58:34 +01:00
('object_refs', ListProperty(ReferenceProperty(valid_types=["SCO", "SRO"], spec_version='2.1'))),
('revoked', BooleanProperty(default=lambda: False)),
('labels', ListProperty(StringProperty)),
('confidence', IntegerProperty()),
('lang', StringProperty()),
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
2020-11-10 02:58:34 +01:00
('extensions', ExtensionsProperty(spec_version='2.1')),
])
def __init__(self, *args, **kwargs):
if "objects" in kwargs:
warnings.warn(
"The 'objects' property of observed-data is deprecated in "
"STIX 2.1.",
STIXDeprecationWarning,
)
super(ObservedData, self).__init__(*args, **kwargs)
def _check_object_constraints(self):
Improved the exception class hierarchy: - Removed all plain python base classes (e.g. ValueError, TypeError) - Renamed InvalidPropertyConfigurationError -> PropertyPresenceError, since incorrect values could be considered a property config error, and I really just wanted this class to apply to presence (co-)constraint violations. - Added ObjectConfigurationError as a superclass of InvalidValueError, PropertyPresenceError, and any other exception that could be raised during _STIXBase object init, which is when the spec compliance checks happen. This class is intended to represent general spec violations. - Did some class reordering in exceptions.py, so all the ObjectConfigurationError subclasses were together. Changed how property "cleaning" errors were handled: - Previous docs said they should all be ValueErrors, but that would require extra exception check-and-replace complexity in the property implementations, so that requirement is removed. Doc is changed to just say that cleaning problems should cause exceptions to be raised. _STIXBase._check_property() now handles most exception types, not just ValueError. - Decided to try chaining the original clean error to the InvalidValueError, in case the extra diagnostics would be helpful in the future. This is done via 'six' adapter function and only works on python3. - A small amount of testing was removed, since it was looking at custom exception properties which became unavailable once the exception was replaced with InvalidValueError. Did another pass through unit tests to fix breakage caused by the changed exception class hierarchy. Removed unnecessary observable extension handling code from parse_observable(), since it was all duplicated in ExtensionsProperty. The redundant code in parse_observable() had different exception behavior than ExtensionsProperty, which makes the API inconsistent and unit tests more complicated. (Problems in ExtensionsProperty get replaced with InvalidValueError, but extensions problems handled directly in parse_observable() don't get the same replacement, and so the exception type is different.) Redid the workbench monkeypatching. The old way was impossible to make work, and had caused ugly ripple effect hackage in other parts of the codebase. Now, it replaces the global object maps with factory functions which behave the same way when called, as real classes. Had to fix up a few unit tests to get them all passing with this monkeypatching in place. Also remove all the xfail markings in the workbench test suite, since all tests now pass. Since workbench monkeypatching isn't currently affecting any unit tests, tox.ini was simplified to remove the special-casing for running the workbench tests. Removed the v20 workbench test suite, since the workbench currently only works with the latest stix object version.
2019-07-19 20:50:11 +02:00
super(ObservedData, self)._check_object_constraints()
first_observed = self.get('first_observed')
last_observed = self.get('last_observed')
if first_observed and last_observed and last_observed < first_observed:
msg = "{0.id} 'last_observed' must be greater than or equal to 'first_observed'"
raise ValueError(msg.format(self))
self._check_mutually_exclusive_properties(
["objects", "object_refs"],
)
class Opinion(_DomainObject):
"""For more detailed information on this object's properties, see
2021-07-07 21:03:28 +02:00
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/os/stix-v2.1-os.html#_ht1vtzfbtzda>`__.
"""
_type = 'opinion'
_properties = OrderedDict([
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('explanation', StringProperty()),
('authors', ListProperty(StringProperty)),
('opinion', EnumProperty(OPINION, required=True)),
('object_refs', ListProperty(ReferenceProperty(valid_types=["SCO", "SDO", "SRO"], spec_version='2.1'), required=True)),
('revoked', BooleanProperty(default=lambda: False)),
('labels', ListProperty(StringProperty)),
('confidence', IntegerProperty()),
('lang', StringProperty()),
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
2020-11-10 02:58:34 +01:00
('extensions', ExtensionsProperty(spec_version='2.1')),
])
class Report(_DomainObject):
"""For more detailed information on this object's properties, see
2021-07-07 21:03:28 +02:00
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/os/stix-v2.1-os.html#_n8bjzg1ysgdq>`__.
"""
_type = 'report'
_properties = OrderedDict([
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('name', StringProperty(required=True)),
('description', StringProperty()),
('report_types', ListProperty(OpenVocabProperty(REPORT_TYPE))),
('published', TimestampProperty(required=True)),
('object_refs', ListProperty(ReferenceProperty(valid_types=["SCO", "SDO", "SRO"], spec_version='2.1'), required=True)),
('revoked', BooleanProperty(default=lambda: False)),
('labels', ListProperty(StringProperty)),
('confidence', IntegerProperty()),
('lang', StringProperty()),
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
2020-11-10 02:58:34 +01:00
('extensions', ExtensionsProperty(spec_version='2.1')),
])
class ThreatActor(_DomainObject):
"""For more detailed information on this object's properties, see
2021-07-07 21:03:28 +02:00
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/os/stix-v2.1-os.html#_k017w16zutw>`__.
"""
_type = 'threat-actor'
_properties = OrderedDict([
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('name', StringProperty(required=True)),
('description', StringProperty()),
('threat_actor_types', ListProperty(OpenVocabProperty(THREAT_ACTOR_TYPE))),
('aliases', ListProperty(StringProperty)),
('first_seen', TimestampProperty()),
('last_seen', TimestampProperty()),
('roles', ListProperty(OpenVocabProperty(THREAT_ACTOR_ROLE))),
('goals', ListProperty(StringProperty)),
('sophistication', OpenVocabProperty(THREAT_ACTOR_SOPHISTICATION)),
('resource_level', OpenVocabProperty(ATTACK_RESOURCE_LEVEL)),
('primary_motivation', OpenVocabProperty(ATTACK_MOTIVATION)),
('secondary_motivations', ListProperty(OpenVocabProperty(ATTACK_MOTIVATION))),
('personal_motivations', ListProperty(OpenVocabProperty(ATTACK_MOTIVATION))),
('revoked', BooleanProperty(default=lambda: False)),
('labels', ListProperty(StringProperty)),
('confidence', IntegerProperty()),
('lang', StringProperty()),
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
2020-11-10 02:58:34 +01:00
('extensions', ExtensionsProperty(spec_version='2.1')),
])
def _check_object_constraints(self):
Improved the exception class hierarchy: - Removed all plain python base classes (e.g. ValueError, TypeError) - Renamed InvalidPropertyConfigurationError -> PropertyPresenceError, since incorrect values could be considered a property config error, and I really just wanted this class to apply to presence (co-)constraint violations. - Added ObjectConfigurationError as a superclass of InvalidValueError, PropertyPresenceError, and any other exception that could be raised during _STIXBase object init, which is when the spec compliance checks happen. This class is intended to represent general spec violations. - Did some class reordering in exceptions.py, so all the ObjectConfigurationError subclasses were together. Changed how property "cleaning" errors were handled: - Previous docs said they should all be ValueErrors, but that would require extra exception check-and-replace complexity in the property implementations, so that requirement is removed. Doc is changed to just say that cleaning problems should cause exceptions to be raised. _STIXBase._check_property() now handles most exception types, not just ValueError. - Decided to try chaining the original clean error to the InvalidValueError, in case the extra diagnostics would be helpful in the future. This is done via 'six' adapter function and only works on python3. - A small amount of testing was removed, since it was looking at custom exception properties which became unavailable once the exception was replaced with InvalidValueError. Did another pass through unit tests to fix breakage caused by the changed exception class hierarchy. Removed unnecessary observable extension handling code from parse_observable(), since it was all duplicated in ExtensionsProperty. The redundant code in parse_observable() had different exception behavior than ExtensionsProperty, which makes the API inconsistent and unit tests more complicated. (Problems in ExtensionsProperty get replaced with InvalidValueError, but extensions problems handled directly in parse_observable() don't get the same replacement, and so the exception type is different.) Redid the workbench monkeypatching. The old way was impossible to make work, and had caused ugly ripple effect hackage in other parts of the codebase. Now, it replaces the global object maps with factory functions which behave the same way when called, as real classes. Had to fix up a few unit tests to get them all passing with this monkeypatching in place. Also remove all the xfail markings in the workbench test suite, since all tests now pass. Since workbench monkeypatching isn't currently affecting any unit tests, tox.ini was simplified to remove the special-casing for running the workbench tests. Removed the v20 workbench test suite, since the workbench currently only works with the latest stix object version.
2019-07-19 20:50:11 +02:00
super(ThreatActor, self)._check_object_constraints()
first_observed = self.get('first_seen')
last_observed = self.get('last_seen')
if first_observed and last_observed and last_observed < first_observed:
msg = "{0.id} 'last_seen' must be greater than or equal to 'first_seen'"
raise ValueError(msg.format(self))
class Tool(_DomainObject):
"""For more detailed information on this object's properties, see
2021-07-07 21:03:28 +02:00
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/os/stix-v2.1-os.html#_z4voa9ndw8v>`__.
"""
_type = 'tool'
_properties = OrderedDict([
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('name', StringProperty(required=True)),
('description', StringProperty()),
('tool_types', ListProperty(OpenVocabProperty(TOOL_TYPE))),
('aliases', ListProperty(StringProperty)),
('kill_chain_phases', ListProperty(KillChainPhase)),
('tool_version', StringProperty()),
('revoked', BooleanProperty(default=lambda: False)),
('labels', ListProperty(StringProperty)),
('confidence', IntegerProperty()),
('lang', StringProperty()),
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
2020-11-10 02:58:34 +01:00
('extensions', ExtensionsProperty(spec_version='2.1')),
])
class Vulnerability(_DomainObject):
"""For more detailed information on this object's properties, see
2021-07-07 21:03:28 +02:00
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/os/stix-v2.1-os.html#_q5ytzmajn6re>`__.
"""
_type = 'vulnerability'
_properties = OrderedDict([
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('name', StringProperty(required=True)),
('description', StringProperty()),
('revoked', BooleanProperty(default=lambda: False)),
('labels', ListProperty(StringProperty)),
('confidence', IntegerProperty()),
('lang', StringProperty()),
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
2020-11-10 02:58:34 +01:00
('extensions', ExtensionsProperty(spec_version='2.1')),
])
def CustomObject(type='x-custom-type', properties=None, extension_name=None, is_sdo=True):
"""Custom STIX Object type decorator.
Example:
>>> from stix2.v21 import CustomObject
>>> from stix2.properties import IntegerProperty, StringProperty
>>> @CustomObject('x-type-name', [
... ('property1', StringProperty(required=True)),
... ('property2', IntegerProperty()),
... ])
... class MyNewObjectType():
... pass
Supply an ``__init__()`` function to add any special validations to the custom
type. Don't call ``super().__init__()`` though - doing so will cause an error.
Example:
>>> from stix2.v21 import CustomObject
>>> from stix2.properties import IntegerProperty, StringProperty
>>> @CustomObject('x-type-name', [
... ('property1', StringProperty(required=True)),
... ('property2', IntegerProperty()),
... ])
... class MyNewObjectType():
... def __init__(self, property2=None, **kwargs):
... if property2 and property2 < 10:
... raise ValueError("'property2' is too small.")
"""
def wrapper(cls):
extension_properties = [x for x in properties if not x[0].startswith('x_')]
_properties = (
[
('type', TypeProperty(type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
]
+ extension_properties
+ [
('revoked', BooleanProperty(default=lambda: False)),
('labels', ListProperty(StringProperty)),
('confidence', IntegerProperty()),
('lang', StringProperty()),
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('extensions', ExtensionsProperty(spec_version='2.1')),
]
+ sorted((x for x in properties if x[0].startswith('x_')), key=lambda x: x[0])
)
if extension_name:
@CustomExtension(type=extension_name, properties={})
class NameExtension:
if is_sdo:
extension_type = 'new-sdo'
else:
extension_type = 'new-sro'
extension = extension_name.split('--')[1]
extension = extension.replace('-', '')
NameExtension.__name__ = 'ExtensionDefinition' + extension
cls.with_extension = extension_name
return _custom_object_builder(cls, type, _properties, '2.1', _DomainObject)
return wrapper