2017-02-10 22:35:02 +01:00
|
|
|
"""STIX 2.0 Domain Objects"""
|
|
|
|
|
2017-06-12 22:15:12 +02:00
|
|
|
import stix2
|
|
|
|
|
2017-02-10 22:35:02 +01:00
|
|
|
from .base import _STIXBase
|
2017-08-11 22:18:20 +02:00
|
|
|
from .common import COMMON_PROPERTIES, KillChainPhase
|
2017-07-14 20:55:57 +02:00
|
|
|
from .observables import ObservableProperty
|
2017-05-03 23:35:33 +02:00
|
|
|
from .properties import (IDProperty, IntegerProperty, ListProperty,
|
2017-07-14 22:02:29 +02:00
|
|
|
ReferenceProperty, StringProperty, TimestampProperty,
|
|
|
|
TypeProperty)
|
2017-02-10 22:35:02 +01:00
|
|
|
from .utils import NOW
|
|
|
|
|
|
|
|
|
2017-02-22 16:06:35 +01:00
|
|
|
class AttackPattern(_STIXBase):
|
|
|
|
|
|
|
|
_type = 'attack-pattern'
|
|
|
|
_properties = COMMON_PROPERTIES.copy()
|
|
|
|
_properties.update({
|
2017-02-24 17:46:21 +01:00
|
|
|
'type': TypeProperty(_type),
|
2017-02-24 17:20:24 +01:00
|
|
|
'id': IDProperty(_type),
|
2017-04-18 15:21:38 +02:00
|
|
|
'name': StringProperty(required=True),
|
|
|
|
'description': StringProperty(),
|
|
|
|
'kill_chain_phases': ListProperty(KillChainPhase),
|
2017-02-22 16:06:35 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
|
2017-02-23 16:11:56 +01:00
|
|
|
class Campaign(_STIXBase):
|
|
|
|
|
|
|
|
_type = 'campaign'
|
|
|
|
_properties = COMMON_PROPERTIES.copy()
|
|
|
|
_properties.update({
|
2017-02-24 17:46:21 +01:00
|
|
|
'type': TypeProperty(_type),
|
2017-02-24 17:20:24 +01:00
|
|
|
'id': IDProperty(_type),
|
2017-04-18 15:21:38 +02:00
|
|
|
'name': StringProperty(required=True),
|
|
|
|
'description': StringProperty(),
|
|
|
|
'aliases': ListProperty(StringProperty),
|
|
|
|
'first_seen': TimestampProperty(),
|
|
|
|
'last_seen': TimestampProperty(),
|
|
|
|
'objective': StringProperty(),
|
2017-02-23 16:11:56 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
class CourseOfAction(_STIXBase):
|
|
|
|
|
|
|
|
_type = 'course-of-action'
|
|
|
|
_properties = COMMON_PROPERTIES.copy()
|
|
|
|
_properties.update({
|
2017-02-24 17:46:21 +01:00
|
|
|
'type': TypeProperty(_type),
|
2017-02-24 17:20:24 +01:00
|
|
|
'id': IDProperty(_type),
|
2017-04-18 15:21:38 +02:00
|
|
|
'name': StringProperty(required=True),
|
|
|
|
'description': StringProperty(),
|
2017-02-23 16:11:56 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
class Identity(_STIXBase):
|
|
|
|
|
|
|
|
_type = 'identity'
|
|
|
|
_properties = COMMON_PROPERTIES.copy()
|
|
|
|
_properties.update({
|
2017-02-24 17:46:21 +01:00
|
|
|
'type': TypeProperty(_type),
|
2017-02-24 17:20:24 +01:00
|
|
|
'id': IDProperty(_type),
|
2017-04-18 15:21:38 +02:00
|
|
|
'name': StringProperty(required=True),
|
|
|
|
'description': StringProperty(),
|
|
|
|
'identity_class': StringProperty(required=True),
|
|
|
|
'sectors': ListProperty(StringProperty),
|
|
|
|
'contact_information': StringProperty(),
|
2017-02-23 16:11:56 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
|
2017-02-10 22:35:02 +01:00
|
|
|
class Indicator(_STIXBase):
|
|
|
|
|
|
|
|
_type = 'indicator'
|
|
|
|
_properties = COMMON_PROPERTIES.copy()
|
|
|
|
_properties.update({
|
2017-02-24 17:46:21 +01:00
|
|
|
'type': TypeProperty(_type),
|
2017-02-24 17:20:24 +01:00
|
|
|
'id': IDProperty(_type),
|
2017-04-18 15:21:38 +02:00
|
|
|
'labels': ListProperty(StringProperty, required=True),
|
|
|
|
'name': StringProperty(),
|
|
|
|
'description': StringProperty(),
|
|
|
|
'pattern': StringProperty(required=True),
|
|
|
|
'valid_from': TimestampProperty(default=lambda: NOW),
|
|
|
|
'valid_until': TimestampProperty(),
|
|
|
|
'kill_chain_phases': ListProperty(KillChainPhase),
|
2017-02-10 22:35:02 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
|
2017-02-22 16:06:35 +01:00
|
|
|
class IntrusionSet(_STIXBase):
|
|
|
|
|
|
|
|
_type = 'intrusion-set'
|
|
|
|
_properties = COMMON_PROPERTIES.copy()
|
|
|
|
_properties.update({
|
2017-02-24 17:46:21 +01:00
|
|
|
'type': TypeProperty(_type),
|
2017-02-24 17:20:24 +01:00
|
|
|
'id': IDProperty(_type),
|
2017-04-18 15:21:38 +02:00
|
|
|
'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),
|
2017-02-22 16:06:35 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
|
2017-02-10 22:35:02 +01:00
|
|
|
class Malware(_STIXBase):
|
|
|
|
|
|
|
|
_type = 'malware'
|
|
|
|
_properties = COMMON_PROPERTIES.copy()
|
|
|
|
_properties.update({
|
2017-02-24 17:46:21 +01:00
|
|
|
'type': TypeProperty(_type),
|
2017-02-24 17:20:24 +01:00
|
|
|
'id': IDProperty(_type),
|
2017-04-07 20:53:40 +02:00
|
|
|
'labels': ListProperty(StringProperty, required=True),
|
|
|
|
'name': StringProperty(required=True),
|
|
|
|
'description': StringProperty(),
|
2017-04-07 23:34:06 +02:00
|
|
|
'kill_chain_phases': ListProperty(KillChainPhase),
|
2017-02-10 22:35:02 +01:00
|
|
|
})
|
|
|
|
|
2017-02-22 16:06:35 +01:00
|
|
|
|
2017-02-23 16:11:56 +01:00
|
|
|
class ObservedData(_STIXBase):
|
|
|
|
|
|
|
|
_type = 'observed-data'
|
|
|
|
_properties = COMMON_PROPERTIES.copy()
|
|
|
|
_properties.update({
|
2017-02-24 17:46:21 +01:00
|
|
|
'type': TypeProperty(_type),
|
2017-02-24 17:20:24 +01:00
|
|
|
'id': IDProperty(_type),
|
2017-04-18 15:21:38 +02:00
|
|
|
'first_observed': TimestampProperty(required=True),
|
|
|
|
'last_observed': TimestampProperty(required=True),
|
|
|
|
'number_observed': IntegerProperty(required=True),
|
2017-05-03 23:35:33 +02:00
|
|
|
'objects': ObservableProperty(),
|
2017-02-23 16:11:56 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
class Report(_STIXBase):
|
|
|
|
|
|
|
|
_type = 'report'
|
|
|
|
_properties = COMMON_PROPERTIES.copy()
|
|
|
|
_properties.update({
|
2017-02-24 17:46:21 +01:00
|
|
|
'type': TypeProperty(_type),
|
2017-02-24 17:20:24 +01:00
|
|
|
'id': IDProperty(_type),
|
2017-04-18 15:21:38 +02:00
|
|
|
'labels': ListProperty(StringProperty, required=True),
|
|
|
|
'name': StringProperty(required=True),
|
|
|
|
'description': StringProperty(),
|
|
|
|
'published': TimestampProperty(),
|
2017-03-31 21:52:27 +02:00
|
|
|
'object_refs': ListProperty(ReferenceProperty),
|
2017-02-23 16:11:56 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
class ThreatActor(_STIXBase):
|
|
|
|
|
|
|
|
_type = 'threat-actor'
|
|
|
|
_properties = COMMON_PROPERTIES.copy()
|
|
|
|
_properties.update({
|
2017-02-24 17:46:21 +01:00
|
|
|
'type': TypeProperty(_type),
|
2017-02-24 17:20:24 +01:00
|
|
|
'id': IDProperty(_type),
|
2017-04-18 15:21:38 +02:00
|
|
|
'labels': ListProperty(StringProperty, required=True),
|
|
|
|
'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),
|
2017-02-23 16:11:56 +01:00
|
|
|
})
|
|
|
|
|
|
|
|
|
2017-02-22 16:06:35 +01:00
|
|
|
class Tool(_STIXBase):
|
|
|
|
|
|
|
|
_type = 'tool'
|
|
|
|
_properties = COMMON_PROPERTIES.copy()
|
|
|
|
_properties.update({
|
2017-02-24 17:46:21 +01:00
|
|
|
'type': TypeProperty(_type),
|
2017-02-24 17:20:24 +01:00
|
|
|
'id': IDProperty(_type),
|
2017-04-18 15:21:38 +02:00
|
|
|
'labels': ListProperty(StringProperty, required=True),
|
|
|
|
'name': StringProperty(required=True),
|
|
|
|
'description': StringProperty(),
|
|
|
|
'kill_chain_phases': ListProperty(KillChainPhase),
|
|
|
|
'tool_version': StringProperty(),
|
2017-02-22 16:06:35 +01:00
|
|
|
})
|
|
|
|
|
2017-02-23 16:11:56 +01:00
|
|
|
|
|
|
|
class Vulnerability(_STIXBase):
|
|
|
|
|
|
|
|
_type = 'vulnerability'
|
|
|
|
_properties = COMMON_PROPERTIES.copy()
|
|
|
|
_properties.update({
|
2017-02-24 17:46:21 +01:00
|
|
|
'type': TypeProperty(_type),
|
2017-02-24 17:20:24 +01:00
|
|
|
'id': IDProperty(_type),
|
2017-04-18 15:21:38 +02:00
|
|
|
'name': StringProperty(required=True),
|
|
|
|
'description': StringProperty(),
|
2017-02-23 16:11:56 +01:00
|
|
|
})
|
2017-06-12 22:15:12 +02:00
|
|
|
|
|
|
|
|
|
|
|
def CustomObject(type='x-custom-type', properties={}):
|
2017-06-13 16:26:43 +02:00
|
|
|
"""Custom STIX Object type decorator
|
|
|
|
|
|
|
|
Example 1:
|
|
|
|
|
2017-06-14 15:34:42 +02:00
|
|
|
@CustomObject('x-type-name', {
|
2017-06-13 16:26:43 +02:00
|
|
|
'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 2:
|
|
|
|
|
2017-06-14 15:34:42 +02:00
|
|
|
@CustomObject('x-type-name', {
|
2017-06-13 16:26:43 +02:00
|
|
|
'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.")
|
|
|
|
"""
|
2017-06-12 22:15:12 +02:00
|
|
|
|
|
|
|
def custom_builder(cls):
|
|
|
|
|
2017-06-13 16:26:43 +02:00
|
|
|
class _Custom(cls, _STIXBase):
|
2017-06-12 22:15:12 +02:00
|
|
|
_type = type
|
|
|
|
_properties = COMMON_PROPERTIES.copy()
|
|
|
|
_properties.update({
|
|
|
|
'id': IDProperty(_type),
|
|
|
|
'type': TypeProperty(_type),
|
|
|
|
})
|
|
|
|
_properties.update(properties)
|
2017-06-13 16:26:43 +02:00
|
|
|
|
|
|
|
def __init__(self, **kwargs):
|
|
|
|
_STIXBase.__init__(self, **kwargs)
|
|
|
|
cls.__init__(self, **kwargs)
|
|
|
|
|
2017-06-12 22:15:12 +02:00
|
|
|
stix2._register_type(_Custom)
|
|
|
|
return _Custom
|
|
|
|
|
|
|
|
return custom_builder
|