2018-11-28 22:51:00 +01:00
|
|
|
"""Functions and class wrappers for interacting with STIX2 data at a high level.
|
2018-03-22 15:55:10 +01:00
|
|
|
|
|
|
|
.. autofunction:: create
|
|
|
|
.. autofunction:: set_default_creator
|
|
|
|
.. autofunction:: set_default_created
|
|
|
|
.. autofunction:: set_default_external_refs
|
|
|
|
.. autofunction:: set_default_object_marking_refs
|
|
|
|
.. autofunction:: get
|
|
|
|
.. autofunction:: all_versions
|
|
|
|
.. autofunction:: query
|
|
|
|
.. autofunction:: creator_of
|
|
|
|
.. autofunction:: relationships
|
|
|
|
.. autofunction:: related_to
|
2018-03-30 17:53:15 +02:00
|
|
|
.. autofunction:: save
|
2018-03-22 15:55:10 +01:00
|
|
|
.. autofunction:: add_filters
|
|
|
|
.. autofunction:: add_filter
|
|
|
|
.. autofunction:: parse
|
|
|
|
.. autofunction:: add_data_source
|
|
|
|
.. autofunction:: add_data_sources
|
|
|
|
|
2017-11-29 14:58:01 +01:00
|
|
|
"""
|
|
|
|
|
2018-03-23 18:13:41 +01:00
|
|
|
import stix2
|
2017-11-30 01:25:52 +01:00
|
|
|
from . import AttackPattern as _AttackPattern
|
|
|
|
from . import Campaign as _Campaign
|
|
|
|
from . import CourseOfAction as _CourseOfAction
|
|
|
|
from . import Identity as _Identity
|
|
|
|
from . import Indicator as _Indicator
|
|
|
|
from . import IntrusionSet as _IntrusionSet
|
|
|
|
from . import Malware as _Malware
|
|
|
|
from . import ObservedData as _ObservedData
|
|
|
|
from . import Report as _Report
|
|
|
|
from . import ThreatActor as _ThreatActor
|
|
|
|
from . import Tool as _Tool
|
|
|
|
from . import Vulnerability as _Vulnerability
|
2018-07-13 17:10:05 +02:00
|
|
|
from . import ( # noqa: F401
|
|
|
|
AlternateDataStream, ArchiveExt, Artifact, AutonomousSystem,
|
|
|
|
Bundle, CustomExtension, CustomMarking, CustomObservable,
|
|
|
|
Directory, DomainName, EmailAddress, EmailMessage,
|
|
|
|
EmailMIMEComponent, Environment, ExternalReference, File,
|
|
|
|
FileSystemSource, Filter, GranularMarking, HTTPRequestExt,
|
|
|
|
ICMPExt, IPv4Address, IPv6Address, KillChainPhase, MACAddress,
|
|
|
|
MarkingDefinition, MemoryStore, Mutex, NetworkTraffic, NTFSExt,
|
|
|
|
parse_observable, PDFExt, Process, RasterImageExt, Relationship,
|
|
|
|
Sighting, SocketExt, Software, StatementMarking,
|
|
|
|
TAXIICollectionSource, TCPExt, TLP_AMBER, TLP_GREEN, TLP_RED,
|
|
|
|
TLP_WHITE, TLPMarking, UNIXAccountExt, URL, UserAccount,
|
|
|
|
WindowsPEBinaryExt, WindowsPEOptionalHeaderType,
|
|
|
|
WindowsPESection, WindowsProcessExt, WindowsRegistryKey,
|
|
|
|
WindowsRegistryValueType, WindowsServiceExt, X509Certificate,
|
|
|
|
X509V3ExtenstionsType
|
|
|
|
)
|
2018-04-13 17:08:03 +02:00
|
|
|
from .datastore.filters import FilterSet
|
2017-11-29 14:58:01 +01:00
|
|
|
|
2018-03-14 17:47:28 +01:00
|
|
|
# Use an implicit MemoryStore
|
2017-11-29 14:58:01 +01:00
|
|
|
_environ = Environment(store=MemoryStore())
|
|
|
|
|
|
|
|
create = _environ.create
|
2018-03-19 18:32:02 +01:00
|
|
|
set_default_creator = _environ.set_default_creator
|
|
|
|
set_default_created = _environ.set_default_created
|
|
|
|
set_default_external_refs = _environ.set_default_external_refs
|
|
|
|
set_default_object_marking_refs = _environ.set_default_object_marking_refs
|
2017-11-29 14:58:01 +01:00
|
|
|
get = _environ.get
|
|
|
|
all_versions = _environ.all_versions
|
|
|
|
query = _environ.query
|
|
|
|
creator_of = _environ.creator_of
|
|
|
|
relationships = _environ.relationships
|
|
|
|
related_to = _environ.related_to
|
2018-03-30 17:53:15 +02:00
|
|
|
save = _environ.add
|
2017-11-29 14:58:01 +01:00
|
|
|
add_filters = _environ.add_filters
|
|
|
|
add_filter = _environ.add_filter
|
|
|
|
parse = _environ.parse
|
|
|
|
add_data_source = _environ.source.add_data_source
|
2018-03-14 17:47:28 +01:00
|
|
|
add_data_sources = _environ.source.add_data_sources
|
2017-11-29 14:58:01 +01:00
|
|
|
|
|
|
|
|
2017-11-29 20:12:54 +01:00
|
|
|
# Wrap SDOs with helper functions
|
|
|
|
|
|
|
|
|
2018-07-13 17:10:05 +02:00
|
|
|
STIX_OBJS = [
|
|
|
|
_AttackPattern, _Campaign, _CourseOfAction, _Identity,
|
|
|
|
_Indicator, _IntrusionSet, _Malware, _ObservedData, _Report,
|
|
|
|
_ThreatActor, _Tool, _Vulnerability,
|
|
|
|
]
|
2017-11-30 01:25:52 +01:00
|
|
|
|
2018-03-22 15:55:10 +01:00
|
|
|
STIX_OBJ_DOCS = """
|
|
|
|
|
|
|
|
.. method:: created_by(*args, **kwargs)
|
|
|
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
.. method:: relationships(*args, **kwargs)
|
|
|
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
.. method:: related(*args, **kwargs)
|
|
|
|
|
|
|
|
{}
|
|
|
|
|
2018-07-13 17:10:05 +02:00
|
|
|
""".format(
|
|
|
|
_environ.creator_of.__doc__,
|
|
|
|
_environ.relationships.__doc__,
|
|
|
|
_environ.related_to.__doc__
|
|
|
|
)
|
2018-03-22 15:55:10 +01:00
|
|
|
|
2017-11-30 01:25:52 +01:00
|
|
|
|
2018-03-21 18:56:50 +01:00
|
|
|
def _created_by_wrapper(self, *args, **kwargs):
|
2017-11-29 20:12:54 +01:00
|
|
|
return _environ.creator_of(self, *args, **kwargs)
|
|
|
|
|
|
|
|
|
2018-03-21 18:56:50 +01:00
|
|
|
def _relationships_wrapper(self, *args, **kwargs):
|
2017-11-29 20:12:54 +01:00
|
|
|
return _environ.relationships(self, *args, **kwargs)
|
|
|
|
|
|
|
|
|
2018-03-21 18:56:50 +01:00
|
|
|
def _related_wrapper(self, *args, **kwargs):
|
2017-11-29 20:12:54 +01:00
|
|
|
return _environ.related_to(self, *args, **kwargs)
|
|
|
|
|
|
|
|
|
2018-05-16 18:14:33 +02:00
|
|
|
def _observed_data_init(self, *args, **kwargs):
|
|
|
|
self.__allow_custom = kwargs.get('allow_custom', False)
|
|
|
|
self._properties['objects'].allow_custom = kwargs.get('allow_custom', False)
|
2018-05-11 23:28:55 +02:00
|
|
|
super(self.__class__, self).__init__(*args, **kwargs)
|
|
|
|
|
|
|
|
|
2018-03-21 18:56:50 +01:00
|
|
|
def _constructor_wrapper(obj_type):
|
2017-11-30 01:25:52 +01:00
|
|
|
# Use an intermediate wrapper class so the implicit environment will create objects that have our wrapper functions
|
2018-05-11 23:28:55 +02:00
|
|
|
class_dict = dict(
|
2018-03-21 18:56:50 +01:00
|
|
|
created_by=_created_by_wrapper,
|
|
|
|
relationships=_relationships_wrapper,
|
|
|
|
related=_related_wrapper,
|
2017-11-30 01:25:52 +01:00
|
|
|
**obj_type.__dict__
|
2018-05-11 23:28:55 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
# Avoid TypeError about super() in ObservedData
|
|
|
|
if 'ObservedData' in obj_type.__name__:
|
|
|
|
class_dict['__init__'] = _observed_data_init
|
|
|
|
|
|
|
|
wrapped_type = type(obj_type.__name__, obj_type.__bases__, class_dict)
|
2017-11-30 01:25:52 +01:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def new_constructor(cls, *args, **kwargs):
|
2018-03-23 18:13:41 +01:00
|
|
|
x = _environ.create(wrapped_type, *args, **kwargs)
|
|
|
|
return x
|
2017-11-30 01:25:52 +01:00
|
|
|
return new_constructor
|
|
|
|
|
2017-11-29 20:12:54 +01:00
|
|
|
|
2018-03-23 18:13:41 +01:00
|
|
|
def _setup_workbench():
|
|
|
|
# Create wrapper classes whose constructors call the implicit environment's create()
|
|
|
|
for obj_type in STIX_OBJS:
|
|
|
|
new_class_dict = {
|
|
|
|
'__new__': _constructor_wrapper(obj_type),
|
2018-07-13 17:10:05 +02:00
|
|
|
'__doc__': 'Workbench wrapper around the `{0} <stix2.v20.sdo.rst#stix2.v20.sdo.{0}>`__ object. {1}'.format(obj_type.__name__, STIX_OBJ_DOCS),
|
2018-03-23 18:13:41 +01:00
|
|
|
}
|
|
|
|
new_class = type(obj_type.__name__, (), new_class_dict)
|
2018-03-22 15:55:10 +01:00
|
|
|
|
2018-03-23 18:13:41 +01:00
|
|
|
# Add our new class to this module's globals and to the library-wide mapping.
|
|
|
|
# This allows parse() to use the wrapped classes.
|
|
|
|
globals()[obj_type.__name__] = new_class
|
|
|
|
stix2.OBJ_MAP[obj_type._type] = new_class
|
|
|
|
new_class = None
|
|
|
|
|
|
|
|
|
|
|
|
_setup_workbench()
|
2017-11-29 20:12:54 +01:00
|
|
|
|
|
|
|
|
2017-11-29 14:58:01 +01:00
|
|
|
# Functions to get all objects of a specific type
|
|
|
|
|
|
|
|
|
2018-04-05 16:07:35 +02:00
|
|
|
def attack_patterns(filters=None):
|
2018-03-22 15:55:10 +01:00
|
|
|
"""Retrieve all Attack Pattern objects.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
filters (list, optional): A list of additional filters to apply to
|
|
|
|
the query.
|
|
|
|
|
|
|
|
"""
|
2018-04-13 17:08:03 +02:00
|
|
|
filter_list = FilterSet(filters)
|
|
|
|
filter_list.add(Filter('type', '=', 'attack-pattern'))
|
2018-04-04 20:02:39 +02:00
|
|
|
return query(filter_list)
|
2017-11-29 14:58:01 +01:00
|
|
|
|
|
|
|
|
2018-04-05 16:07:35 +02:00
|
|
|
def campaigns(filters=None):
|
2018-03-22 15:55:10 +01:00
|
|
|
"""Retrieve all Campaign objects.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
filters (list, optional): A list of additional filters to apply to
|
|
|
|
the query.
|
|
|
|
|
|
|
|
"""
|
2018-04-13 17:08:03 +02:00
|
|
|
filter_list = FilterSet(filters)
|
|
|
|
filter_list.add(Filter('type', '=', 'campaign'))
|
2018-04-04 20:02:39 +02:00
|
|
|
return query(filter_list)
|
2017-11-29 14:58:01 +01:00
|
|
|
|
|
|
|
|
2018-04-05 16:07:35 +02:00
|
|
|
def courses_of_action(filters=None):
|
2018-03-22 15:55:10 +01:00
|
|
|
"""Retrieve all Course of Action objects.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
filters (list, optional): A list of additional filters to apply to
|
|
|
|
the query.
|
|
|
|
|
|
|
|
"""
|
2018-04-13 17:08:03 +02:00
|
|
|
filter_list = FilterSet(filters)
|
|
|
|
filter_list.add(Filter('type', '=', 'course-of-action'))
|
2018-04-04 20:02:39 +02:00
|
|
|
return query(filter_list)
|
2017-11-29 14:58:01 +01:00
|
|
|
|
|
|
|
|
2018-04-05 16:07:35 +02:00
|
|
|
def identities(filters=None):
|
2018-03-22 15:55:10 +01:00
|
|
|
"""Retrieve all Identity objects.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
filters (list, optional): A list of additional filters to apply to
|
|
|
|
the query.
|
|
|
|
|
|
|
|
"""
|
2018-04-13 17:08:03 +02:00
|
|
|
filter_list = FilterSet(filters)
|
|
|
|
filter_list.add(Filter('type', '=', 'identity'))
|
2018-04-04 20:02:39 +02:00
|
|
|
return query(filter_list)
|
2017-11-29 14:58:01 +01:00
|
|
|
|
|
|
|
|
2018-04-05 16:07:35 +02:00
|
|
|
def indicators(filters=None):
|
2018-03-22 15:55:10 +01:00
|
|
|
"""Retrieve all Indicator objects.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
filters (list, optional): A list of additional filters to apply to
|
|
|
|
the query.
|
|
|
|
|
|
|
|
"""
|
2018-04-13 17:08:03 +02:00
|
|
|
filter_list = FilterSet(filters)
|
|
|
|
filter_list.add(Filter('type', '=', 'indicator'))
|
2018-04-04 20:02:39 +02:00
|
|
|
return query(filter_list)
|
2017-11-29 14:58:01 +01:00
|
|
|
|
|
|
|
|
2018-04-05 16:07:35 +02:00
|
|
|
def intrusion_sets(filters=None):
|
2018-03-22 15:55:10 +01:00
|
|
|
"""Retrieve all Intrusion Set objects.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
filters (list, optional): A list of additional filters to apply to
|
|
|
|
the query.
|
|
|
|
|
|
|
|
"""
|
2018-04-13 17:08:03 +02:00
|
|
|
filter_list = FilterSet(filters)
|
|
|
|
filter_list.add(Filter('type', '=', 'intrusion-set'))
|
2018-04-04 20:02:39 +02:00
|
|
|
return query(filter_list)
|
2017-11-29 14:58:01 +01:00
|
|
|
|
|
|
|
|
2018-04-05 16:07:35 +02:00
|
|
|
def malware(filters=None):
|
2018-03-22 15:55:10 +01:00
|
|
|
"""Retrieve all Malware objects.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
filters (list, optional): A list of additional filters to apply to
|
|
|
|
the query.
|
|
|
|
|
|
|
|
"""
|
2018-04-13 17:08:03 +02:00
|
|
|
filter_list = FilterSet(filters)
|
|
|
|
filter_list.add(Filter('type', '=', 'malware'))
|
2018-04-04 20:02:39 +02:00
|
|
|
return query(filter_list)
|
2017-11-29 14:58:01 +01:00
|
|
|
|
|
|
|
|
2018-04-05 16:07:35 +02:00
|
|
|
def observed_data(filters=None):
|
2018-03-22 15:55:10 +01:00
|
|
|
"""Retrieve all Observed Data objects.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
filters (list, optional): A list of additional filters to apply to
|
|
|
|
the query.
|
|
|
|
|
|
|
|
"""
|
2018-04-13 17:08:03 +02:00
|
|
|
filter_list = FilterSet(filters)
|
|
|
|
filter_list.add(Filter('type', '=', 'observed-data'))
|
2018-04-04 20:02:39 +02:00
|
|
|
return query(filter_list)
|
2017-11-29 14:58:01 +01:00
|
|
|
|
|
|
|
|
2018-04-05 16:07:35 +02:00
|
|
|
def reports(filters=None):
|
2018-03-22 15:55:10 +01:00
|
|
|
"""Retrieve all Report objects.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
filters (list, optional): A list of additional filters to apply to
|
|
|
|
the query.
|
|
|
|
|
|
|
|
"""
|
2018-04-13 17:08:03 +02:00
|
|
|
filter_list = FilterSet(filters)
|
2018-04-13 20:21:44 +02:00
|
|
|
filter_list.add(Filter('type', '=', 'report'))
|
2018-04-04 20:02:39 +02:00
|
|
|
return query(filter_list)
|
2017-11-29 14:58:01 +01:00
|
|
|
|
|
|
|
|
2018-04-05 16:07:35 +02:00
|
|
|
def threat_actors(filters=None):
|
2018-03-22 15:55:10 +01:00
|
|
|
"""Retrieve all Threat Actor objects.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
filters (list, optional): A list of additional filters to apply to
|
|
|
|
the query.
|
|
|
|
|
|
|
|
"""
|
2018-04-13 17:08:03 +02:00
|
|
|
filter_list = FilterSet(filters)
|
|
|
|
filter_list.add(Filter('type', '=', 'threat-actor'))
|
2018-04-04 20:02:39 +02:00
|
|
|
return query(filter_list)
|
2017-11-29 14:58:01 +01:00
|
|
|
|
2018-03-14 19:33:45 +01:00
|
|
|
|
2018-04-05 16:07:35 +02:00
|
|
|
def tools(filters=None):
|
2018-03-22 15:55:10 +01:00
|
|
|
"""Retrieve all Tool objects.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
filters (list, optional): A list of additional filters to apply to
|
|
|
|
the query.
|
|
|
|
|
|
|
|
"""
|
2018-04-13 17:08:03 +02:00
|
|
|
filter_list = FilterSet(filters)
|
|
|
|
filter_list.add(Filter('type', '=', 'tool'))
|
2018-04-04 20:02:39 +02:00
|
|
|
return query(filter_list)
|
2018-03-14 19:33:45 +01:00
|
|
|
|
|
|
|
|
2018-04-05 16:07:35 +02:00
|
|
|
def vulnerabilities(filters=None):
|
2018-03-22 15:55:10 +01:00
|
|
|
"""Retrieve all Vulnerability objects.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
filters (list, optional): A list of additional filters to apply to
|
|
|
|
the query.
|
|
|
|
|
|
|
|
"""
|
2018-04-13 17:08:03 +02:00
|
|
|
filter_list = FilterSet(filters)
|
|
|
|
filter_list.add(Filter('type', '=', 'vulnerability'))
|
2018-04-04 20:02:39 +02:00
|
|
|
return query(filter_list)
|