"""STIX 2.1 Domain Objects""" from collections import OrderedDict import re from ..base import _STIXBase from ..core import _register_type from ..markings import _MarkingsMixin from ..utils import NOW, TYPE_REGEX from .common import ExternalReference, GranularMarking, KillChainPhase from .observables import ObservableProperty from .properties import (BooleanProperty, DictionaryProperty, EmbeddedObjectProperty, EnumProperty, FloatProperty, IDProperty, IntegerProperty, ListProperty, PatternProperty, ReferenceProperty, StringProperty, TimestampProperty, TypeProperty) class STIXDomainObject(_STIXBase, _MarkingsMixin): pass class AttackPattern(STIXDomainObject): # TODO: Add link """For more detailed information on this object's properties, see `the STIX 2.1 specification `__. """ _type = 'attack-pattern' _properties = OrderedDict([ ('type', TypeProperty(_type)), ('spec_version', StringProperty(fixed='2.1')), ('id', IDProperty(_type)), ('created_by_ref', ReferenceProperty(type='identity')), ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('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(type='marking-definition'))), ('granular_markings', ListProperty(GranularMarking)), ]) class Campaign(STIXDomainObject): # TODO: Add link """For more detailed information on this object's properties, see `the STIX 2.1 specification `__. """ _type = 'campaign' _properties = OrderedDict([ ('type', TypeProperty(_type)), ('spec_version', StringProperty(fixed='2.1')), ('id', IDProperty(_type)), ('created_by_ref', ReferenceProperty(type='identity')), ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('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(type='marking-definition'))), ('granular_markings', ListProperty(GranularMarking)), ]) class CourseOfAction(STIXDomainObject): # TODO: Add link """For more detailed information on this object's properties, see `the STIX 2.1 specification `__. """ _type = 'course-of-action' _properties = OrderedDict([ ('type', TypeProperty(_type)), ('spec_version', StringProperty(fixed='2.1')), ('id', IDProperty(_type)), ('created_by_ref', ReferenceProperty(type='identity')), ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('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(type='marking-definition'))), ('granular_markings', ListProperty(GranularMarking)), ]) class Identity(STIXDomainObject): # TODO: Add link """For more detailed information on this object's properties, see `the STIX 2.1 specification `__. """ _type = 'identity' _properties = OrderedDict([ ('type', TypeProperty(_type)), ('spec_version', StringProperty(fixed='2.1')), ('id', IDProperty(_type)), ('created_by_ref', ReferenceProperty(type='identity')), ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('name', StringProperty(required=True)), ('description', StringProperty()), ('identity_class', StringProperty(required=True)), ('sectors', ListProperty(StringProperty)), ('contact_information', StringProperty()), ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty)), ('confidence', IntegerProperty()), ('lang', StringProperty()), ('external_references', ListProperty(ExternalReference)), ('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition'))), ('granular_markings', ListProperty(GranularMarking)), ]) class Indicator(STIXDomainObject): # TODO: Add link """For more detailed information on this object's properties, see `the STIX 2.1 specification `__. """ _type = 'indicator' _properties = OrderedDict([ ('type', TypeProperty(_type)), ('spec_version', StringProperty(fixed='2.1')), ('id', IDProperty(_type)), ('created_by_ref', ReferenceProperty(type='identity')), ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('name', StringProperty()), ('description', StringProperty()), ('pattern', PatternProperty(required=True)), ('valid_from', TimestampProperty(default=lambda: NOW)), ('valid_until', TimestampProperty()), ('kill_chain_phases', ListProperty(KillChainPhase)), ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty, required=True)), ('confidence', IntegerProperty()), ('lang', StringProperty()), ('external_references', ListProperty(ExternalReference)), ('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition'))), ('granular_markings', ListProperty(GranularMarking)), ]) class IntrusionSet(STIXDomainObject): # TODO: Add link """For more detailed information on this object's properties, see `the STIX 2.1 specification `__. """ _type = 'intrusion-set' _properties = OrderedDict([ ('type', TypeProperty(_type)), ('spec_version', StringProperty(fixed='2.1')), ('id', IDProperty(_type)), ('created_by_ref', ReferenceProperty(type='identity')), ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('name', StringProperty(required=True)), ('description', StringProperty()), ('aliases', ListProperty(StringProperty)), ('first_seen', TimestampProperty()), ('last_seen', TimestampProperty()), ('goals', ListProperty(StringProperty)), ('resource_level', StringProperty()), ('primary_motivation', StringProperty()), ('secondary_motivations', ListProperty(StringProperty)), ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty)), ('confidence', IntegerProperty()), ('lang', StringProperty()), ('external_references', ListProperty(ExternalReference)), ('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition'))), ('granular_markings', ListProperty(GranularMarking)), ]) class Location(STIXDomainObject): # TODO: Add link """For more detailed information on this object's properties, see `the STIX 2.1 specification `__. """ _type = 'location' _properties = OrderedDict([ ('type', TypeProperty(_type)), ('spec_version', StringProperty(fixed='2.1')), ('id', IDProperty(_type)), ('created_by_ref', ReferenceProperty(type='identity')), ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('description', StringProperty()), ('latitude', FloatProperty()), ('longitude', FloatProperty()), ('precision', FloatProperty()), ('region', StringProperty()), ('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(type='marking-definition'))), ('granular_markings', ListProperty(GranularMarking)), ]) class AnalysisType(_STIXBase): _properties = OrderedDict([ ('start_time', TimestampProperty()), ('end_time', TimestampProperty()), ('analysis_tools', ObservableProperty()), ('analysis_environment', DictionaryProperty()), ('results', DictionaryProperty(required=True)) ]) class AVResultsType(_STIXBase): _properties = OrderedDict([ ('product', StringProperty()), ('engine_version', StringProperty()), ('definition_version', StringProperty()), ('submitted', TimestampProperty()), ('scanned', TimestampProperty()), ('result', StringProperty()), ('details', StringProperty()) ]) class Malware(STIXDomainObject): # TODO: Add link """For more detailed information on this object's properties, see `the STIX 2.1 specification `__. """ _type = 'malware' _properties = OrderedDict([ ('type', TypeProperty(_type)), ('spec_version', StringProperty(fixed='2.1')), ('id', IDProperty(_type)), ('created_by_ref', ReferenceProperty(type='identity')), ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('name', StringProperty(required=True)), ('description', StringProperty()), ('kill_chain_phases', ListProperty(KillChainPhase)), ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty, required=True)), ('confidence', IntegerProperty()), ('lang', StringProperty()), ('external_references', ListProperty(ExternalReference)), ('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition'))), ('granular_markings', ListProperty(GranularMarking)), ('is_family', BooleanProperty(required=True)), ('first_seen', TimestampProperty()), ('last_seen', TimestampProperty()), ('os_execution_envs', ListProperty(StringProperty)), ('architecture_execution_envs', ListProperty(StringProperty)), ('implementation_languages', ListProperty(StringProperty)), ('samples', ObservableProperty()), ('static_analysis_results', ListProperty(EmbeddedObjectProperty(AnalysisType))), ('dynamic_analysis_results', ListProperty(EmbeddedObjectProperty(AnalysisType))), ('av_results', ListProperty(EmbeddedObjectProperty(AVResultsType))), ('capabilities', ListProperty(StringProperty)) ]) class Note(STIXDomainObject): # TODO: Add link """For more detailed information on this object's properties, see `the STIX 2.1 specification `__. """ _type = 'note' _properties = OrderedDict([ ('type', TypeProperty(_type)), ('spec_version', StringProperty(fixed='2.1')), ('id', IDProperty(_type)), ('created_by_ref', ReferenceProperty(type='identity')), ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('summary', StringProperty()), ('description', StringProperty(required=True)), ('authors', ListProperty(StringProperty)), ('object_refs', ListProperty(ReferenceProperty, required=True)), ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty)), ('confidence', IntegerProperty()), ('lang', StringProperty()), ('external_references', ListProperty(ExternalReference)), ('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition'))), ('granular_markings', ListProperty(GranularMarking)), ]) class ObservedData(STIXDomainObject): # TODO: Add link """For more detailed information on this object's properties, see `the STIX 2.1 specification `__. """ _type = 'observed-data' _properties = OrderedDict([ ('type', TypeProperty(_type)), ('spec_version', StringProperty(fixed='2.1')), ('id', IDProperty(_type)), ('created_by_ref', ReferenceProperty(type='identity')), ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('first_observed', TimestampProperty(required=True)), ('last_observed', TimestampProperty(required=True)), ('number_observed', IntegerProperty(required=True)), ('objects', ObservableProperty(required=True)), ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty)), ('confidence', IntegerProperty()), ('lang', StringProperty()), ('external_references', ListProperty(ExternalReference)), ('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition'))), ('granular_markings', ListProperty(GranularMarking)), ]) def __init__(self, *args, **kwargs): self.__allow_custom = kwargs.get('allow_custom', False) self._properties['objects'].allow_custom = kwargs.get('allow_custom', False) super(ObservedData, self).__init__(*args, **kwargs) class Opinion(STIXDomainObject): # TODO: Add link """For more detailed information on this object's properties, see `the STIX 2.1 specification `__. """ _type = 'opinion' _properties = OrderedDict([ ('type', TypeProperty(_type)), ('spec_version', StringProperty(fixed='2.1')), ('id', IDProperty(_type)), ('created_by_ref', ReferenceProperty(type='identity')), ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('description', StringProperty()), ('authors', ListProperty(StringProperty)), ('object_refs', ListProperty(ReferenceProperty, required=True)), ('opinion', EnumProperty(allowed=[ 'strongly-disagree', 'disagree', 'neutral', 'agree', 'strongly-agree' ], required=True)), ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty)), ('confidence', IntegerProperty()), ('lang', StringProperty()), ('external_references', ListProperty(ExternalReference)), ('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition'))), ('granular_markings', ListProperty(GranularMarking)), ]) class Report(STIXDomainObject): # TODO: Add link """For more detailed information on this object's properties, see `the STIX 2.1 specification `__. """ _type = 'report' _properties = OrderedDict([ ('type', TypeProperty(_type)), ('spec_version', StringProperty(fixed='2.1')), ('id', IDProperty(_type)), ('created_by_ref', ReferenceProperty(type='identity')), ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('name', StringProperty(required=True)), ('description', StringProperty()), ('published', TimestampProperty(required=True)), ('object_refs', ListProperty(ReferenceProperty, required=True)), ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty, required=True)), ('confidence', IntegerProperty()), ('lang', StringProperty()), ('external_references', ListProperty(ExternalReference)), ('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition'))), ('granular_markings', ListProperty(GranularMarking)), ]) class ThreatActor(STIXDomainObject): # TODO: Add link """For more detailed information on this object's properties, see `the STIX 2.1 specification `__. """ _type = 'threat-actor' _properties = OrderedDict([ ('type', TypeProperty(_type)), ('spec_version', StringProperty(fixed='2.1')), ('id', IDProperty(_type)), ('created_by_ref', ReferenceProperty(type='identity')), ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('name', StringProperty(required=True)), ('description', StringProperty()), ('aliases', ListProperty(StringProperty)), ('roles', ListProperty(StringProperty)), ('goals', ListProperty(StringProperty)), ('sophistication', StringProperty()), ('resource_level', StringProperty()), ('primary_motivation', StringProperty()), ('secondary_motivations', ListProperty(StringProperty)), ('personal_motivations', ListProperty(StringProperty)), ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty, required=True)), ('confidence', IntegerProperty()), ('lang', StringProperty()), ('external_references', ListProperty(ExternalReference)), ('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition'))), ('granular_markings', ListProperty(GranularMarking)), ]) class Tool(STIXDomainObject): # TODO: Add link """For more detailed information on this object's properties, see `the STIX 2.1 specification `__. """ _type = 'tool' _properties = OrderedDict([ ('type', TypeProperty(_type)), ('spec_version', StringProperty(fixed='2.1')), ('id', IDProperty(_type)), ('created_by_ref', ReferenceProperty(type='identity')), ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('name', StringProperty(required=True)), ('description', StringProperty()), ('kill_chain_phases', ListProperty(KillChainPhase)), ('tool_version', StringProperty()), ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty, required=True)), ('confidence', IntegerProperty()), ('lang', StringProperty()), ('external_references', ListProperty(ExternalReference)), ('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition'))), ('granular_markings', ListProperty(GranularMarking)), ]) class Vulnerability(STIXDomainObject): # TODO: Add link """For more detailed information on this object's properties, see `the STIX 2.1 specification `__. """ _type = 'vulnerability' _properties = OrderedDict([ ('type', TypeProperty(_type)), ('spec_version', StringProperty(fixed='2.1')), ('id', IDProperty(_type)), ('created_by_ref', ReferenceProperty(type='identity')), ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('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(type='marking-definition'))), ('granular_markings', ListProperty(GranularMarking)), ]) def CustomObject(type='x-custom-type', properties=None): """Custom STIX Object type decorator. Example: >>> @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: >>> @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 custom_builder(cls): class _Custom(cls, STIXDomainObject): if not re.match(TYPE_REGEX, type): raise ValueError("Invalid type name '%s': must only contain the " "characters a-z (lowercase ASCII), 0-9, and hyphen (-)." % type) elif len(type) < 3 or len(type) > 250: raise ValueError("Invalid type name '%s': must be between 3 and 250 characters." % type) _type = type _properties = OrderedDict([ ('type', TypeProperty(_type)), ('spec_version', StringProperty(fixed='2.1')), ('id', IDProperty(_type)), ('created_by_ref', ReferenceProperty(type='identity')), ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')), ('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')), ]) if not properties or not isinstance(properties, list): raise ValueError("Must supply a list, containing tuples. For example, [('property1', IntegerProperty())]") _properties.update([x for x in properties if not x[0].startswith('x_')]) # This is to follow the general properties structure. _properties.update([ ('revoked', BooleanProperty(default=lambda: False)), ('labels', ListProperty(StringProperty)), ('confidence', IntegerProperty()), ('lang', StringProperty()), ('external_references', ListProperty(ExternalReference)), ('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition'))), ('granular_markings', ListProperty(GranularMarking)), ]) # Put all custom properties at the bottom, sorted alphabetically. _properties.update(sorted([x for x in properties if x[0].startswith('x_')], key=lambda x: x[0])) def __init__(self, **kwargs): _STIXBase.__init__(self, **kwargs) try: cls.__init__(self, **kwargs) except (AttributeError, TypeError) as e: # Don't accidentally catch errors raised in a custom __init__() if ("has no attribute '__init__'" in str(e) or str(e) == "object.__init__() takes no parameters"): return raise e _register_type(_Custom, version='2.1') return _Custom return custom_builder