commit
e1a88a4840
|
@ -450,6 +450,14 @@
|
|||
"mem.source.filters.add([f1,f2])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"##### Note: The `defanged` property is now always included (implicitly) for STIX 2.1 Cyber Observable Objects (SCOs)\n",
|
||||
"This is important to remember if you are writing a filter that involves checking the `objects` property of a STIX 2.1 `ObservedData` object. If any of the objects associated with the `objects` property are STIX 2.1 SCOs, then your filter must include the `defanged` property. For an example, refer to `filters[14]` & `filters[15]` in stix2/test/v21/test_datastore_filters.py "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
|
@ -726,21 +734,21 @@
|
|||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "cti-python-stix2",
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "cti-python-stix2"
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 2
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython2",
|
||||
"version": "2.7.12"
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.7"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
|
105
stix2/base.py
105
stix2/base.py
|
@ -3,10 +3,13 @@
|
|||
import collections
|
||||
import copy
|
||||
import datetime as dt
|
||||
import uuid
|
||||
|
||||
import simplejson as json
|
||||
import six
|
||||
|
||||
from stix2.canonicalization.Canonicalize import canonicalize
|
||||
|
||||
from .exceptions import (
|
||||
AtLeastOnePropertyError, DependentPropertiesError, ExtraPropertiesError,
|
||||
ImmutableError, InvalidObjRefError, InvalidValueError,
|
||||
|
@ -112,10 +115,15 @@ class _STIXBase(collections.Mapping):
|
|||
def _check_at_least_one_property(self, list_of_properties=None):
|
||||
if not list_of_properties:
|
||||
list_of_properties = sorted(list(self.__class__._properties.keys()))
|
||||
if 'type' in list_of_properties:
|
||||
list_of_properties.remove('type')
|
||||
if isinstance(self, _Observable):
|
||||
props_to_remove = ["type", "id", "defanged", "spec_version"]
|
||||
else:
|
||||
props_to_remove = ["type"]
|
||||
|
||||
list_of_properties = [prop for prop in list_of_properties if prop not in props_to_remove]
|
||||
current_properties = self.properties_populated()
|
||||
list_of_properties_populated = set(list_of_properties).intersection(current_properties)
|
||||
|
||||
if list_of_properties and (not list_of_properties_populated or list_of_properties_populated == set(['extensions'])):
|
||||
raise AtLeastOnePropertyError(self.__class__, list_of_properties)
|
||||
|
||||
|
@ -300,9 +308,26 @@ class _Observable(_STIXBase):
|
|||
self.__allow_custom = kwargs.get('allow_custom', False)
|
||||
self._properties['extensions'].allow_custom = kwargs.get('allow_custom', False)
|
||||
|
||||
try:
|
||||
# Since `spec_version` is optional, this is how we check for a 2.1 SCO
|
||||
self._id_contributing_properties
|
||||
|
||||
if 'id' not in kwargs:
|
||||
possible_id = self._generate_id(kwargs)
|
||||
if possible_id is not None:
|
||||
kwargs['id'] = possible_id
|
||||
except AttributeError:
|
||||
# End up here if handling a 2.0 SCO, and don't need to do anything further
|
||||
pass
|
||||
|
||||
super(_Observable, self).__init__(**kwargs)
|
||||
|
||||
def _check_ref(self, ref, prop, prop_name):
|
||||
"""
|
||||
Only for checking `*_ref` or `*_refs` properties in spec_version 2.0
|
||||
STIX Cyber Observables (SCOs)
|
||||
"""
|
||||
|
||||
if '*' in self._STIXBase__valid_refs:
|
||||
return # don't check if refs are valid
|
||||
|
||||
|
@ -331,12 +356,52 @@ class _Observable(_STIXBase):
|
|||
if prop_name not in kwargs:
|
||||
return
|
||||
|
||||
from .properties import ObjectReferenceProperty
|
||||
if prop_name.endswith('_ref'):
|
||||
ref = kwargs[prop_name]
|
||||
self._check_ref(ref, prop, prop_name)
|
||||
elif prop_name.endswith('_refs'):
|
||||
for ref in kwargs[prop_name]:
|
||||
if isinstance(prop, ObjectReferenceProperty):
|
||||
ref = kwargs[prop_name]
|
||||
self._check_ref(ref, prop, prop_name)
|
||||
elif prop_name.endswith('_refs'):
|
||||
if isinstance(prop.contained, ObjectReferenceProperty):
|
||||
for ref in kwargs[prop_name]:
|
||||
self._check_ref(ref, prop, prop_name)
|
||||
|
||||
def _generate_id(self, kwargs):
|
||||
required_prefix = self._type + "--"
|
||||
namespace = uuid.UUID("00abedb4-aa42-466c-9c01-fed23315a9b7")
|
||||
|
||||
properties_to_use = self._id_contributing_properties
|
||||
if properties_to_use:
|
||||
streamlined_obj_vals = []
|
||||
if "hashes" in kwargs and "hashes" in properties_to_use:
|
||||
possible_hash = _choose_one_hash(kwargs["hashes"])
|
||||
if possible_hash:
|
||||
streamlined_obj_vals.append(possible_hash)
|
||||
for key in properties_to_use:
|
||||
if key != "hashes" and key in kwargs:
|
||||
if isinstance(kwargs[key], dict) or isinstance(kwargs[key], _STIXBase):
|
||||
temp_deep_copy = copy.deepcopy(dict(kwargs[key]))
|
||||
_recursive_stix_to_dict(temp_deep_copy)
|
||||
streamlined_obj_vals.append(temp_deep_copy)
|
||||
elif isinstance(kwargs[key], list) and isinstance(kwargs[key][0], _STIXBase):
|
||||
for obj in kwargs[key]:
|
||||
temp_deep_copy = copy.deepcopy(dict(obj))
|
||||
_recursive_stix_to_dict(temp_deep_copy)
|
||||
streamlined_obj_vals.append(temp_deep_copy)
|
||||
else:
|
||||
streamlined_obj_vals.append(kwargs[key])
|
||||
|
||||
if streamlined_obj_vals:
|
||||
data = canonicalize(streamlined_obj_vals, utf8=False)
|
||||
|
||||
# try/except here to enable python 2 compatibility
|
||||
try:
|
||||
return required_prefix + six.text_type(uuid.uuid5(namespace, data))
|
||||
except UnicodeDecodeError:
|
||||
return required_prefix + six.text_type(uuid.uuid5(namespace, six.binary_type(data)))
|
||||
|
||||
# We return None if there are no values specified for any of the id-contributing-properties
|
||||
return None
|
||||
|
||||
|
||||
class _Extension(_STIXBase):
|
||||
|
@ -346,6 +411,34 @@ class _Extension(_STIXBase):
|
|||
self._check_at_least_one_property()
|
||||
|
||||
|
||||
def _choose_one_hash(hash_dict):
|
||||
if "MD5" in hash_dict:
|
||||
return {"MD5": hash_dict["MD5"]}
|
||||
elif "SHA-1" in hash_dict:
|
||||
return {"SHA-1": hash_dict["SHA-1"]}
|
||||
elif "SHA-256" in hash_dict:
|
||||
return {"SHA-256": hash_dict["SHA-256"]}
|
||||
elif "SHA-512" in hash_dict:
|
||||
return {"SHA-512": hash_dict["SHA-512"]}
|
||||
else:
|
||||
k = next(iter(hash_dict), None)
|
||||
if k is not None:
|
||||
return {k: hash_dict[k]}
|
||||
|
||||
|
||||
def _cls_init(cls, obj, kwargs):
|
||||
if getattr(cls, '__init__', object.__init__) is not object.__init__:
|
||||
cls.__init__(obj, **kwargs)
|
||||
|
||||
|
||||
def _recursive_stix_to_dict(input_dict):
|
||||
for key in input_dict:
|
||||
if isinstance(input_dict[key], dict):
|
||||
_recursive_stix_to_dict(input_dict[key])
|
||||
elif isinstance(input_dict[key], _STIXBase):
|
||||
input_dict[key] = dict(input_dict[key])
|
||||
|
||||
# There may stil be nested _STIXBase objects
|
||||
_recursive_stix_to_dict(input_dict[key])
|
||||
else:
|
||||
return
|
||||
|
|
|
@ -0,0 +1,512 @@
|
|||
##############################################################################
|
||||
# #
|
||||
# Copyright 2006-2019 WebPKI.org (http://webpki.org). #
|
||||
# #
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); #
|
||||
# you may not use this file except in compliance with the License. #
|
||||
# You may obtain a copy of the License at #
|
||||
# #
|
||||
# https://www.apache.org/licenses/LICENSE-2.0 #
|
||||
# #
|
||||
# Unless required by applicable law or agreed to in writing, software #
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||
# See the License for the specific language governing permissions and #
|
||||
# limitations under the License. #
|
||||
# #
|
||||
##############################################################################
|
||||
|
||||
#################################################
|
||||
# JCS compatible JSON serializer for Python 3.x #
|
||||
#################################################
|
||||
|
||||
# This file has been modified to be compatible with Python 2.x as well
|
||||
|
||||
import re
|
||||
|
||||
import six
|
||||
|
||||
from stix2.canonicalization.NumberToJson import convert2Es6Format
|
||||
|
||||
try:
|
||||
from _json import encode_basestring_ascii as c_encode_basestring_ascii
|
||||
except ImportError:
|
||||
c_encode_basestring_ascii = None
|
||||
try:
|
||||
from _json import encode_basestring as c_encode_basestring
|
||||
except ImportError:
|
||||
c_encode_basestring = None
|
||||
try:
|
||||
from _json import make_encoder as c_make_encoder
|
||||
except ImportError:
|
||||
c_make_encoder = None
|
||||
|
||||
ESCAPE = re.compile(r'[\x00-\x1f\\"\b\f\n\r\t]')
|
||||
ESCAPE_ASCII = re.compile(r'([\\"]|[^\ -~])')
|
||||
HAS_UTF8 = re.compile(b'[\x80-\xff]')
|
||||
ESCAPE_DCT = {
|
||||
'\\': '\\\\',
|
||||
'"': '\\"',
|
||||
'\b': '\\b',
|
||||
'\f': '\\f',
|
||||
'\n': '\\n',
|
||||
'\r': '\\r',
|
||||
'\t': '\\t',
|
||||
}
|
||||
for i in range(0x20):
|
||||
ESCAPE_DCT.setdefault(chr(i), '\\u{0:04x}'.format(i))
|
||||
|
||||
INFINITY = float('inf')
|
||||
|
||||
|
||||
def py_encode_basestring(s):
|
||||
"""Return a JSON representation of a Python string
|
||||
|
||||
"""
|
||||
def replace(match):
|
||||
return ESCAPE_DCT[match.group(0)]
|
||||
return '"' + ESCAPE.sub(replace, s) + '"'
|
||||
|
||||
|
||||
encode_basestring = (c_encode_basestring or py_encode_basestring)
|
||||
|
||||
|
||||
def py_encode_basestring_ascii(s):
|
||||
"""Return an ASCII-only JSON representation of a Python string
|
||||
|
||||
"""
|
||||
def replace(match):
|
||||
s = match.group(0)
|
||||
try:
|
||||
return ESCAPE_DCT[s]
|
||||
except KeyError:
|
||||
n = ord(s)
|
||||
if n < 0x10000:
|
||||
return '\\u{0:04x}'.format(n)
|
||||
else:
|
||||
# surrogate pair
|
||||
n -= 0x10000
|
||||
s1 = 0xd800 | ((n >> 10) & 0x3ff)
|
||||
s2 = 0xdc00 | (n & 0x3ff)
|
||||
return '\\u{0:04x}\\u{1:04x}'.format(s1, s2)
|
||||
return '"' + ESCAPE_ASCII.sub(replace, s) + '"'
|
||||
|
||||
|
||||
encode_basestring_ascii = (
|
||||
c_encode_basestring_ascii or py_encode_basestring_ascii
|
||||
)
|
||||
|
||||
|
||||
class JSONEncoder(object):
|
||||
"""Extensible JSON <http://json.org> encoder for Python data structures.
|
||||
|
||||
Supports the following objects and types by default:
|
||||
|
||||
+-------------------+---------------+
|
||||
| Python | JSON |
|
||||
+===================+===============+
|
||||
| dict | object |
|
||||
+-------------------+---------------+
|
||||
| list, tuple | array |
|
||||
+-------------------+---------------+
|
||||
| str | string |
|
||||
+-------------------+---------------+
|
||||
| int, float | number |
|
||||
+-------------------+---------------+
|
||||
| True | true |
|
||||
+-------------------+---------------+
|
||||
| False | false |
|
||||
+-------------------+---------------+
|
||||
| None | null |
|
||||
+-------------------+---------------+
|
||||
|
||||
To extend this to recognize other objects, subclass and implement a
|
||||
``.default()`` method with another method that returns a serializable
|
||||
object for ``o`` if possible, otherwise it should call the superclass
|
||||
implementation (to raise ``TypeError``).
|
||||
|
||||
"""
|
||||
item_separator = ', '
|
||||
key_separator = ': '
|
||||
|
||||
def __init__(
|
||||
self, skipkeys=False, ensure_ascii=False,
|
||||
check_circular=True, allow_nan=True, sort_keys=True,
|
||||
indent=None, separators=(',', ':'), default=None,
|
||||
):
|
||||
"""Constructor for JSONEncoder, with sensible defaults.
|
||||
|
||||
If skipkeys is false, then it is a TypeError to attempt
|
||||
encoding of keys that are not str, int, float or None. If
|
||||
skipkeys is True, such items are simply skipped.
|
||||
|
||||
If ensure_ascii is true, the output is guaranteed to be str
|
||||
objects with all incoming non-ASCII characters escaped. If
|
||||
ensure_ascii is false, the output can contain non-ASCII characters.
|
||||
|
||||
If check_circular is true, then lists, dicts, and custom encoded
|
||||
objects will be checked for circular references during encoding to
|
||||
prevent an infinite recursion (which would cause an OverflowError).
|
||||
Otherwise, no such check takes place.
|
||||
|
||||
If allow_nan is true, then NaN, Infinity, and -Infinity will be
|
||||
encoded as such. This behavior is not JSON specification compliant,
|
||||
but is consistent with most JavaScript based encoders and decoders.
|
||||
Otherwise, it will be a ValueError to encode such floats.
|
||||
|
||||
If sort_keys is true, then the output of dictionaries will be
|
||||
sorted by key; this is useful for regression tests to ensure
|
||||
that JSON serializations can be compared on a day-to-day basis.
|
||||
|
||||
If indent is a non-negative integer, then JSON array
|
||||
elements and object members will be pretty-printed with that
|
||||
indent level. An indent level of 0 will only insert newlines.
|
||||
None is the most compact representation.
|
||||
|
||||
If specified, separators should be an (item_separator, key_separator)
|
||||
tuple. The default is (', ', ': ') if *indent* is ``None`` and
|
||||
(',', ': ') otherwise. To get the most compact JSON representation,
|
||||
you should specify (',', ':') to eliminate whitespace.
|
||||
|
||||
If specified, default is a function that gets called for objects
|
||||
that can't otherwise be serialized. It should return a JSON encodable
|
||||
version of the object or raise a ``TypeError``.
|
||||
|
||||
"""
|
||||
|
||||
self.skipkeys = skipkeys
|
||||
self.ensure_ascii = ensure_ascii
|
||||
self.check_circular = check_circular
|
||||
self.allow_nan = allow_nan
|
||||
self.sort_keys = sort_keys
|
||||
self.indent = indent
|
||||
if separators is not None:
|
||||
self.item_separator, self.key_separator = separators
|
||||
elif indent is not None:
|
||||
self.item_separator = ','
|
||||
if default is not None:
|
||||
self.default = default
|
||||
|
||||
def default(self, o):
|
||||
"""Implement this method in a subclass such that it returns
|
||||
a serializable object for ``o``, or calls the base implementation
|
||||
(to raise a ``TypeError``).
|
||||
|
||||
For example, to support arbitrary iterators, you could
|
||||
implement default like this::
|
||||
|
||||
def default(self, o):
|
||||
try:
|
||||
iterable = iter(o)
|
||||
except TypeError:
|
||||
pass
|
||||
else:
|
||||
return list(iterable)
|
||||
# Let the base class default method raise the TypeError
|
||||
return JSONEncoder.default(self, o)
|
||||
|
||||
"""
|
||||
raise TypeError(
|
||||
"Object of type '%s' is not JSON serializable" %
|
||||
o.__class__.__name__,
|
||||
)
|
||||
|
||||
def encode(self, o):
|
||||
"""Return a JSON string representation of a Python data structure.
|
||||
|
||||
>>> from json.encoder import JSONEncoder
|
||||
>>> JSONEncoder().encode({"foo": ["bar", "baz"]})
|
||||
'{"foo": ["bar", "baz"]}'
|
||||
|
||||
"""
|
||||
# This is for extremely simple cases and benchmarks.
|
||||
if isinstance(o, str):
|
||||
if self.ensure_ascii:
|
||||
return encode_basestring_ascii(o)
|
||||
else:
|
||||
return encode_basestring(o)
|
||||
# This doesn't pass the iterator directly to ''.join() because the
|
||||
# exceptions aren't as detailed. The list call should be roughly
|
||||
# equivalent to the PySequence_Fast that ''.join() would do.
|
||||
chunks = self.iterencode(o, _one_shot=False)
|
||||
if not isinstance(chunks, (list, tuple)):
|
||||
chunks = list(chunks)
|
||||
return ''.join(chunks)
|
||||
|
||||
def iterencode(self, o, _one_shot=False):
|
||||
"""Encode the given object and yield each string
|
||||
representation as available.
|
||||
|
||||
For example::
|
||||
|
||||
for chunk in JSONEncoder().iterencode(bigobject):
|
||||
mysocket.write(chunk)
|
||||
|
||||
"""
|
||||
if self.check_circular:
|
||||
markers = {}
|
||||
else:
|
||||
markers = None
|
||||
if self.ensure_ascii:
|
||||
_encoder = encode_basestring_ascii
|
||||
else:
|
||||
_encoder = encode_basestring
|
||||
|
||||
def floatstr(
|
||||
o, allow_nan=self.allow_nan,
|
||||
_repr=float.__repr__, _inf=INFINITY, _neginf=-INFINITY,
|
||||
):
|
||||
# Check for specials. Note that this type of test is processor
|
||||
# and/or platform-specific, so do tests which don't depend on the
|
||||
# internals.
|
||||
|
||||
if o != o:
|
||||
text = 'NaN'
|
||||
elif o == _inf:
|
||||
text = 'Infinity'
|
||||
elif o == _neginf:
|
||||
text = '-Infinity'
|
||||
else:
|
||||
return _repr(o)
|
||||
|
||||
if not allow_nan:
|
||||
raise ValueError(
|
||||
"Out of range float values are not JSON compliant: " +
|
||||
repr(o),
|
||||
)
|
||||
|
||||
return text
|
||||
|
||||
if (
|
||||
_one_shot and c_make_encoder is not None
|
||||
and self.indent is None
|
||||
):
|
||||
_iterencode = c_make_encoder(
|
||||
markers, self.default, _encoder, self.indent,
|
||||
self.key_separator, self.item_separator, self.sort_keys,
|
||||
self.skipkeys, self.allow_nan,
|
||||
)
|
||||
else:
|
||||
_iterencode = _make_iterencode(
|
||||
markers, self.default, _encoder, self.indent, floatstr,
|
||||
self.key_separator, self.item_separator, self.sort_keys,
|
||||
self.skipkeys, _one_shot,
|
||||
)
|
||||
return _iterencode(o, 0)
|
||||
|
||||
|
||||
def _make_iterencode(
|
||||
markers, _default, _encoder, _indent, _floatstr,
|
||||
_key_separator, _item_separator, _sort_keys, _skipkeys, _one_shot,
|
||||
# HACK: hand-optimized bytecode; turn globals into locals
|
||||
ValueError=ValueError,
|
||||
dict=dict,
|
||||
float=float,
|
||||
id=id,
|
||||
int=int,
|
||||
isinstance=isinstance,
|
||||
list=list,
|
||||
str=str,
|
||||
tuple=tuple,
|
||||
_intstr=int.__str__,
|
||||
):
|
||||
|
||||
if _indent is not None and not isinstance(_indent, str):
|
||||
_indent = ' ' * _indent
|
||||
|
||||
def _iterencode_list(lst, _current_indent_level):
|
||||
if not lst:
|
||||
yield '[]'
|
||||
return
|
||||
if markers is not None:
|
||||
markerid = id(lst)
|
||||
if markerid in markers:
|
||||
raise ValueError("Circular reference detected")
|
||||
markers[markerid] = lst
|
||||
buf = '['
|
||||
if _indent is not None:
|
||||
_current_indent_level += 1
|
||||
newline_indent = '\n' + _indent * _current_indent_level
|
||||
separator = _item_separator + newline_indent
|
||||
buf += newline_indent
|
||||
else:
|
||||
newline_indent = None
|
||||
separator = _item_separator
|
||||
first = True
|
||||
for value in lst:
|
||||
if first:
|
||||
first = False
|
||||
else:
|
||||
buf = separator
|
||||
if isinstance(value, str):
|
||||
yield buf + _encoder(value)
|
||||
elif value is None:
|
||||
yield buf + 'null'
|
||||
elif value is True:
|
||||
yield buf + 'true'
|
||||
elif value is False:
|
||||
yield buf + 'false'
|
||||
elif isinstance(value, int):
|
||||
# Subclasses of int/float may override __str__, but we still
|
||||
# want to encode them as integers/floats in JSON. One example
|
||||
# within the standard library is IntEnum.
|
||||
yield buf + convert2Es6Format(value)
|
||||
elif isinstance(value, float):
|
||||
# see comment above for int
|
||||
yield buf + convert2Es6Format(value)
|
||||
else:
|
||||
yield buf
|
||||
if isinstance(value, (list, tuple)):
|
||||
chunks = _iterencode_list(value, _current_indent_level)
|
||||
elif isinstance(value, dict):
|
||||
chunks = _iterencode_dict(value, _current_indent_level)
|
||||
else:
|
||||
chunks = _iterencode(value, _current_indent_level)
|
||||
# Below line commented-out for python2 compatibility
|
||||
# yield from chunks
|
||||
for chunk in chunks:
|
||||
yield chunk
|
||||
if newline_indent is not None:
|
||||
_current_indent_level -= 1
|
||||
yield '\n' + _indent * _current_indent_level
|
||||
yield ']'
|
||||
if markers is not None:
|
||||
del markers[markerid]
|
||||
|
||||
def _iterencode_dict(dct, _current_indent_level):
|
||||
if not dct:
|
||||
yield '{}'
|
||||
return
|
||||
if markers is not None:
|
||||
markerid = id(dct)
|
||||
if markerid in markers:
|
||||
raise ValueError("Circular reference detected")
|
||||
markers[markerid] = dct
|
||||
yield '{'
|
||||
if _indent is not None:
|
||||
_current_indent_level += 1
|
||||
newline_indent = '\n' + _indent * _current_indent_level
|
||||
item_separator = _item_separator + newline_indent
|
||||
yield newline_indent
|
||||
else:
|
||||
newline_indent = None
|
||||
item_separator = _item_separator
|
||||
first = True
|
||||
if _sort_keys:
|
||||
items = sorted(dct.items(), key=lambda kv: kv[0].encode('utf-16_be'))
|
||||
else:
|
||||
items = dct.items()
|
||||
for key, value in items:
|
||||
# Replaced isinstance(key, str) with below to enable simultaneous python 2 & 3 compatibility
|
||||
if isinstance(key, six.string_types) or isinstance(key, six.binary_type):
|
||||
pass
|
||||
# JavaScript is weakly typed for these, so it makes sense to
|
||||
# also allow them. Many encoders seem to do something like this.
|
||||
elif isinstance(key, float):
|
||||
# see comment for int/float in _make_iterencode
|
||||
key = convert2Es6Format(key)
|
||||
elif key is True:
|
||||
key = 'true'
|
||||
elif key is False:
|
||||
key = 'false'
|
||||
elif key is None:
|
||||
key = 'null'
|
||||
elif isinstance(key, int):
|
||||
# see comment for int/float in _make_iterencode
|
||||
key = convert2Es6Format(key)
|
||||
elif _skipkeys:
|
||||
continue
|
||||
else:
|
||||
raise TypeError("key " + repr(key) + " is not a string")
|
||||
if first:
|
||||
first = False
|
||||
else:
|
||||
yield item_separator
|
||||
yield _encoder(key)
|
||||
yield _key_separator
|
||||
if isinstance(value, str):
|
||||
yield _encoder(value)
|
||||
elif value is None:
|
||||
yield 'null'
|
||||
elif value is True:
|
||||
yield 'true'
|
||||
elif value is False:
|
||||
yield 'false'
|
||||
elif isinstance(value, int):
|
||||
# see comment for int/float in _make_iterencode
|
||||
yield convert2Es6Format(value)
|
||||
elif isinstance(value, float):
|
||||
# see comment for int/float in _make_iterencode
|
||||
yield convert2Es6Format(value)
|
||||
else:
|
||||
if isinstance(value, (list, tuple)):
|
||||
chunks = _iterencode_list(value, _current_indent_level)
|
||||
elif isinstance(value, dict):
|
||||
chunks = _iterencode_dict(value, _current_indent_level)
|
||||
else:
|
||||
chunks = _iterencode(value, _current_indent_level)
|
||||
# Below line commented-out for python2 compatibility
|
||||
# yield from chunks
|
||||
for chunk in chunks:
|
||||
yield chunk
|
||||
if newline_indent is not None:
|
||||
_current_indent_level -= 1
|
||||
yield '\n' + _indent * _current_indent_level
|
||||
yield '}'
|
||||
if markers is not None:
|
||||
del markers[markerid]
|
||||
|
||||
def _iterencode(o, _current_indent_level):
|
||||
# Replaced isinstance(o, str) with below to enable simultaneous python 2 & 3 compatibility
|
||||
if isinstance(o, six.string_types) or isinstance(o, six.binary_type):
|
||||
yield _encoder(o)
|
||||
elif o is None:
|
||||
yield 'null'
|
||||
elif o is True:
|
||||
yield 'true'
|
||||
elif o is False:
|
||||
yield 'false'
|
||||
elif isinstance(o, int):
|
||||
# see comment for int/float in _make_iterencode
|
||||
yield convert2Es6Format(o)
|
||||
elif isinstance(o, float):
|
||||
# see comment for int/float in _make_iterencode
|
||||
yield convert2Es6Format(o)
|
||||
elif isinstance(o, (list, tuple)):
|
||||
# Below line commented-out for python2 compatibility
|
||||
# yield from _iterencode_list(o, _current_indent_level)
|
||||
for thing in _iterencode_list(o, _current_indent_level):
|
||||
yield thing
|
||||
elif isinstance(o, dict):
|
||||
# Below line commented-out for python2 compatibility
|
||||
# yield from _iterencode_dict(o, _current_indent_level)
|
||||
for thing in _iterencode_dict(o, _current_indent_level):
|
||||
yield thing
|
||||
else:
|
||||
if markers is not None:
|
||||
markerid = id(o)
|
||||
if markerid in markers:
|
||||
raise ValueError("Circular reference detected")
|
||||
markers[markerid] = o
|
||||
o = _default(o)
|
||||
# Below line commented-out for python2 compatibility
|
||||
# yield from _iterencode(o, _current_indent_level)
|
||||
for thing in _iterencode(o, _current_indent_level):
|
||||
yield thing
|
||||
if markers is not None:
|
||||
del markers[markerid]
|
||||
return _iterencode
|
||||
|
||||
|
||||
def canonicalize(obj, utf8=True):
|
||||
textVal = JSONEncoder(sort_keys=True).encode(obj)
|
||||
if utf8:
|
||||
return textVal.encode()
|
||||
return textVal
|
||||
|
||||
|
||||
def serialize(obj, utf8=True):
|
||||
textVal = JSONEncoder(sort_keys=False).encode(obj)
|
||||
if utf8:
|
||||
return textVal.encode()
|
||||
return textVal
|
|
@ -0,0 +1,95 @@
|
|||
##############################################################################
|
||||
# #
|
||||
# Copyright 2006-2019 WebPKI.org (http://webpki.org). #
|
||||
# #
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); #
|
||||
# you may not use this file except in compliance with the License. #
|
||||
# You may obtain a copy of the License at #
|
||||
# #
|
||||
# https://www.apache.org/licenses/LICENSE-2.0 #
|
||||
# #
|
||||
# Unless required by applicable law or agreed to in writing, software #
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, #
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
|
||||
# See the License for the specific language governing permissions and #
|
||||
# limitations under the License. #
|
||||
# #
|
||||
##############################################################################
|
||||
|
||||
|
||||
##################################################################
|
||||
# Convert a Python double/float into an ES6/V8 compatible string #
|
||||
##################################################################
|
||||
def convert2Es6Format(value):
|
||||
# Convert double/float to str using the native Python formatter
|
||||
fvalue = float(value)
|
||||
|
||||
# Zero is a special case. The following line takes "-0" case as well
|
||||
if fvalue == 0:
|
||||
return '0'
|
||||
|
||||
# The rest of the algorithm works on the textual representation only
|
||||
pyDouble = str(fvalue)
|
||||
|
||||
# The following line catches the "inf" and "nan" values returned by str(fvalue)
|
||||
if pyDouble.find('n') >= 0:
|
||||
raise ValueError("Invalid JSON number: " + pyDouble)
|
||||
|
||||
# Save sign separately, it doesn't have any role in the algorithm
|
||||
pySign = ''
|
||||
if pyDouble.find('-') == 0:
|
||||
pySign = '-'
|
||||
pyDouble = pyDouble[1:]
|
||||
|
||||
# Now we should only have valid non-zero values
|
||||
pyExpStr = ''
|
||||
pyExpVal = 0
|
||||
q = pyDouble.find('e')
|
||||
if q > 0:
|
||||
# Grab the exponent and remove it from the number
|
||||
pyExpStr = pyDouble[q:]
|
||||
if pyExpStr[2:3] == '0':
|
||||
# Supress leading zero on exponents
|
||||
pyExpStr = pyExpStr[:2] + pyExpStr[3:]
|
||||
pyDouble = pyDouble[0:q]
|
||||
pyExpVal = int(pyExpStr[1:])
|
||||
|
||||
# Split number in pyFirst + pyDot + pyLast
|
||||
pyFirst = pyDouble
|
||||
pyDot = ''
|
||||
pyLast = ''
|
||||
q = pyDouble.find('.')
|
||||
if q > 0:
|
||||
pyDot = '.'
|
||||
pyFirst = pyDouble[:q]
|
||||
pyLast = pyDouble[q + 1:]
|
||||
|
||||
# Now the string is split into: pySign + pyFirst + pyDot + pyLast + pyExpStr
|
||||
if pyLast == '0':
|
||||
# Always remove trailing .0
|
||||
pyDot = ''
|
||||
pyLast = ''
|
||||
|
||||
if pyExpVal > 0 and pyExpVal < 21:
|
||||
# Integers are shown as is with up to 21 digits
|
||||
pyFirst += pyLast
|
||||
pyLast = ''
|
||||
pyDot = ''
|
||||
pyExpStr = ''
|
||||
q = pyExpVal - len(pyFirst)
|
||||
while q >= 0:
|
||||
q -= 1
|
||||
pyFirst += '0'
|
||||
elif pyExpVal < 0 and pyExpVal > -7:
|
||||
# Small numbers are shown as 0.etc with e-6 as lower limit
|
||||
pyLast = pyFirst + pyLast
|
||||
pyFirst = '0'
|
||||
pyDot = '.'
|
||||
pyExpStr = ''
|
||||
q = pyExpVal
|
||||
while q < -1:
|
||||
q += 1
|
||||
pyLast = '0' + pyLast
|
||||
|
||||
# The resulting sub-strings are concatenated
|
||||
return pySign + pyFirst + pyDot + pyLast + pyExpStr
|
|
@ -15,7 +15,10 @@ import stix2
|
|||
|
||||
from .base import _Observable, _STIXBase
|
||||
from .core import STIX2_OBJ_MAPS, parse, parse_observable
|
||||
from .exceptions import CustomContentError, DictionaryKeyError
|
||||
from .exceptions import (
|
||||
CustomContentError, DictionaryKeyError, MissingPropertiesError,
|
||||
MutuallyExclusivePropertiesError,
|
||||
)
|
||||
from .utils import _get_dict, get_class_hierarchy_names, parse_into_datetime
|
||||
|
||||
ERROR_INVALID_ID = (
|
||||
|
@ -417,12 +420,28 @@ class HexProperty(Property):
|
|||
|
||||
class ReferenceProperty(Property):
|
||||
|
||||
def __init__(self, type=None, spec_version=stix2.DEFAULT_VERSION, **kwargs):
|
||||
def __init__(self, valid_types=None, invalid_types=None, spec_version=stix2.DEFAULT_VERSION, **kwargs):
|
||||
"""
|
||||
references sometimes must be to a specific object type
|
||||
"""
|
||||
self.required_prefix = type + "--" if type else None
|
||||
self.spec_version = spec_version
|
||||
|
||||
# These checks need to be done prior to the STIX object finishing construction
|
||||
# and thus we can't use base.py's _check_mutually_exclusive_properties()
|
||||
# in the typical location of _check_object_constraints() in sdo.py
|
||||
if valid_types and invalid_types:
|
||||
raise MutuallyExclusivePropertiesError(self.__class__, ['invalid_types', 'valid_types'])
|
||||
elif valid_types is None and invalid_types is None:
|
||||
raise MissingPropertiesError(self.__class__, ['invalid_types', 'valid_types'])
|
||||
|
||||
if valid_types and type(valid_types) is not list:
|
||||
valid_types = [valid_types]
|
||||
elif invalid_types and type(invalid_types) is not list:
|
||||
invalid_types = [invalid_types]
|
||||
|
||||
self.valid_types = valid_types
|
||||
self.invalid_types = invalid_types
|
||||
|
||||
super(ReferenceProperty, self).__init__(**kwargs)
|
||||
|
||||
def clean(self, value):
|
||||
|
@ -430,7 +449,27 @@ class ReferenceProperty(Property):
|
|||
value = value.id
|
||||
value = str(value)
|
||||
|
||||
_validate_id(value, self.spec_version, self.required_prefix)
|
||||
possible_prefix = value[:value.index('--') + 2]
|
||||
|
||||
if self.valid_types:
|
||||
if self.valid_types == ["only_SDO"]:
|
||||
self.valid_types = STIX2_OBJ_MAPS['v21']['objects'].keys()
|
||||
elif self.valid_types == ["only_SCO"]:
|
||||
self.valid_types = STIX2_OBJ_MAPS['v21']['observables'].keys()
|
||||
elif self.valid_types == ["only_SCO_&_SRO"]:
|
||||
self.valid_types = list(STIX2_OBJ_MAPS['v21']['observables'].keys()) + ['relationship', 'sighting']
|
||||
|
||||
if possible_prefix[:-2] in self.valid_types:
|
||||
required_prefix = possible_prefix
|
||||
else:
|
||||
raise ValueError("The type-specifying prefix '%s' for this property is not valid" % (possible_prefix))
|
||||
elif self.invalid_types:
|
||||
if possible_prefix[:-2] not in self.invalid_types:
|
||||
required_prefix = possible_prefix
|
||||
else:
|
||||
raise ValueError("An invalid type-specifying prefix '%s' was specified for this property" % (possible_prefix, value))
|
||||
|
||||
_validate_id(value, self.spec_version, required_prefix)
|
||||
|
||||
return value
|
||||
|
||||
|
|
|
@ -276,7 +276,7 @@ def test_boolean_property_invalid(value):
|
|||
|
||||
|
||||
def test_reference_property():
|
||||
ref_prop = ReferenceProperty(spec_version="2.0")
|
||||
ref_prop = ReferenceProperty(valid_types="my-type", spec_version="2.0")
|
||||
|
||||
assert ref_prop.clean("my-type--00000000-0000-4000-8000-000000000000")
|
||||
with pytest.raises(ValueError):
|
||||
|
@ -288,7 +288,7 @@ def test_reference_property():
|
|||
|
||||
|
||||
def test_reference_property_specific_type():
|
||||
ref_prop = ReferenceProperty("my-type", spec_version="2.0")
|
||||
ref_prop = ReferenceProperty(valid_types="my-type", spec_version="2.0")
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
ref_prop.clean("not-my-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf")
|
||||
|
|
|
@ -144,8 +144,8 @@ def test_deduplicate(stix_objs1):
|
|||
"type": "network-traffic",
|
||||
"src_ref": "1",
|
||||
"protocols": [
|
||||
"tcp",
|
||||
"http",
|
||||
"tcp",
|
||||
"http",
|
||||
],
|
||||
"extensions": {
|
||||
"http-request-ext": {
|
||||
|
|
|
@ -127,7 +127,7 @@ def test_register_observable_with_default_version():
|
|||
"1": {
|
||||
"type": "directory",
|
||||
"path": "/usr/home",
|
||||
"contains_refs": ["0"],
|
||||
"contains_refs": ["file--420bc087-8b53-5ae9-8210-20d27d5e96c8"],
|
||||
},
|
||||
},
|
||||
)
|
||||
|
@ -165,7 +165,7 @@ def test_register_observable_extension_with_default_version():
|
|||
"1": {
|
||||
"type": "directory",
|
||||
"path": "/usr/home",
|
||||
"contains_refs": ["0"],
|
||||
"contains_refs": ["file--420bc087-8b53-5ae9-8210-20d27d5e96c8"],
|
||||
},
|
||||
},
|
||||
)
|
||||
|
|
|
@ -86,7 +86,10 @@ stix_objs = [
|
|||
"objects": {
|
||||
"0": {
|
||||
"type": "file",
|
||||
"spec_version": "2.1",
|
||||
"id": "file--42a7175a-42cc-508f-8fa7-23b330aff876",
|
||||
"name": "HAL 9000.exe",
|
||||
"defanged": False,
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -109,8 +112,14 @@ filters = [
|
|||
Filter("object_marking_refs", "=", "marking-definition--613f2e26-0000-4000-8000-b8e91df99dc9"),
|
||||
Filter("granular_markings.selectors", "in", "description"),
|
||||
Filter("external_references.source_name", "=", "CVE"),
|
||||
Filter("objects", "=", {"0": {"type": "file", "name": "HAL 9000.exe"}}),
|
||||
Filter("objects", "contains", {"type": "file", "name": "HAL 9000.exe"}),
|
||||
Filter(
|
||||
"objects", "=",
|
||||
{"0": {"type": "file", "id": "file--42a7175a-42cc-508f-8fa7-23b330aff876", "name": "HAL 9000.exe", "spec_version": "2.1", "defanged": False}},
|
||||
),
|
||||
Filter(
|
||||
"objects", "contains",
|
||||
{"type": "file", "id": "file--42a7175a-42cc-508f-8fa7-23b330aff876", "name": "HAL 9000.exe", "spec_version": "2.1", "defanged": False},
|
||||
),
|
||||
Filter("labels", "contains", "heartbleed"),
|
||||
]
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import datetime as dt
|
||||
import re
|
||||
import uuid
|
||||
|
||||
import pytest
|
||||
import pytz
|
||||
|
@ -25,6 +26,8 @@ EXPECTED = """{
|
|||
"objects": {
|
||||
"0": {
|
||||
"type": "file",
|
||||
"id": "file--5956efbb-a7b0-566d-a7f9-a202eb05c70f",
|
||||
"spec_version": "2.1",
|
||||
"name": "foo.exe"
|
||||
}
|
||||
}
|
||||
|
@ -42,13 +45,19 @@ def test_observed_data_example():
|
|||
number_observed=50,
|
||||
objects={
|
||||
"0": {
|
||||
"name": "foo.exe",
|
||||
"type": "file",
|
||||
"id": "file--5956efbb-a7b0-566d-a7f9-a202eb05c70f",
|
||||
"name": "foo.exe",
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
assert str(observed_data) == EXPECTED
|
||||
assert observed_data.id == "observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf"
|
||||
assert observed_data.created_by_ref == "identity--311b2d2d-f010-4473-83ec-1edf84858f4c"
|
||||
assert observed_data.created == observed_data.modified == dt.datetime(2016, 4, 6, 19, 58, 16, tzinfo=pytz.utc)
|
||||
assert observed_data.first_observed == observed_data.last_observed == dt.datetime(2015, 12, 21, 19, 00, 00, tzinfo=pytz.utc)
|
||||
assert observed_data.number_observed == 50
|
||||
assert observed_data.objects['0'] == stix2.v21.File(name="foo.exe")
|
||||
|
||||
|
||||
EXPECTED_WITH_REF = """{
|
||||
|
@ -64,13 +73,17 @@ EXPECTED_WITH_REF = """{
|
|||
"objects": {
|
||||
"0": {
|
||||
"type": "file",
|
||||
"id": "file--5956efbb-a7b0-566d-a7f9-a202eb05c70f",
|
||||
"spec_version": "2.1",
|
||||
"name": "foo.exe"
|
||||
},
|
||||
"1": {
|
||||
"type": "directory",
|
||||
"id": "directory--536a61a4-0934-516b-9aad-fcbb75e0583a",
|
||||
"spec_version": "2.1",
|
||||
"path": "/usr/home",
|
||||
"contains_refs": [
|
||||
"0"
|
||||
"file--5956efbb-a7b0-566d-a7f9-a202eb05c70f"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -88,18 +101,25 @@ def test_observed_data_example_with_refs():
|
|||
number_observed=50,
|
||||
objects={
|
||||
"0": {
|
||||
"name": "foo.exe",
|
||||
"type": "file",
|
||||
"id": "file--5956efbb-a7b0-566d-a7f9-a202eb05c70f",
|
||||
"name": "foo.exe",
|
||||
},
|
||||
"1": {
|
||||
"type": "directory",
|
||||
"id": "directory--536a61a4-0934-516b-9aad-fcbb75e0583a",
|
||||
"path": "/usr/home",
|
||||
"contains_refs": ["0"],
|
||||
"contains_refs": ["file--5956efbb-a7b0-566d-a7f9-a202eb05c70f"],
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
assert str(observed_data) == EXPECTED_WITH_REF
|
||||
assert observed_data.id == "observed-data--b67d30ff-02ac-498a-92f9-32f845f448cf"
|
||||
assert observed_data.created_by_ref == "identity--311b2d2d-f010-4473-83ec-1edf84858f4c"
|
||||
assert observed_data.created == observed_data.modified == dt.datetime(2016, 4, 6, 19, 58, 16, tzinfo=pytz.utc)
|
||||
assert observed_data.first_observed == observed_data.last_observed == dt.datetime(2015, 12, 21, 19, 00, 00, tzinfo=pytz.utc)
|
||||
assert observed_data.number_observed == 50
|
||||
assert observed_data.objects['0'] == stix2.v21.File(name="foo.exe")
|
||||
assert observed_data.objects['1'] == stix2.v21.Directory(path="/usr/home", contains_refs=["file--5956efbb-a7b0-566d-a7f9-a202eb05c70f"])
|
||||
|
||||
|
||||
EXPECTED_OBJECT_REFS = """{
|
||||
|
@ -113,9 +133,9 @@ EXPECTED_OBJECT_REFS = """{
|
|||
"last_observed": "2015-12-21T19:00:00Z",
|
||||
"number_observed": 50,
|
||||
"object_refs": [
|
||||
"foo--758bf2c0-a6f1-56d1-872e-6b727467739a",
|
||||
"bar--d97ed5c4-3f33-46d9-b25b-c3d7b94d1457",
|
||||
"baz--eca0b3ba-8d76-11e9-a1fd-34415dabec0c"
|
||||
"file--758bf2c0-a6f1-56d1-872e-6b727467739a",
|
||||
"url--d97ed5c4-3f33-46d9-b25b-c3d7b94d1457",
|
||||
"mutex--eca0b3ba-8d76-11e9-a1fd-34415dabec0c"
|
||||
]
|
||||
}"""
|
||||
|
||||
|
@ -130,9 +150,9 @@ def test_observed_data_example_with_object_refs():
|
|||
last_observed="2015-12-21T19:00:00Z",
|
||||
number_observed=50,
|
||||
object_refs=[
|
||||
"foo--758bf2c0-a6f1-56d1-872e-6b727467739a",
|
||||
"bar--d97ed5c4-3f33-46d9-b25b-c3d7b94d1457",
|
||||
"baz--eca0b3ba-8d76-11e9-a1fd-34415dabec0c",
|
||||
"file--758bf2c0-a6f1-56d1-872e-6b727467739a",
|
||||
"url--d97ed5c4-3f33-46d9-b25b-c3d7b94d1457",
|
||||
"mutex--eca0b3ba-8d76-11e9-a1fd-34415dabec0c",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -156,9 +176,9 @@ def test_observed_data_object_constraint():
|
|||
},
|
||||
},
|
||||
object_refs=[
|
||||
"foo--758bf2c0-a6f1-56d1-872e-6b727467739a",
|
||||
"bar--d97ed5c4-3f33-46d9-b25b-c3d7b94d1457",
|
||||
"baz--eca0b3ba-8d76-11e9-a1fd-34415dabec0c",
|
||||
"file--758bf2c0-a6f1-56d1-872e-6b727467739a",
|
||||
"url--d97ed5c4-3f33-46d9-b25b-c3d7b94d1457",
|
||||
"mutex--eca0b3ba-8d76-11e9-a1fd-34415dabec0c",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -176,19 +196,20 @@ def test_observed_data_example_with_bad_refs():
|
|||
objects={
|
||||
"0": {
|
||||
"type": "file",
|
||||
"id": "file--5956efbb-a7b0-566d-a7f9-a202eb05c70f",
|
||||
"name": "foo.exe",
|
||||
},
|
||||
"1": {
|
||||
"type": "directory",
|
||||
"path": "/usr/home",
|
||||
"contains_refs": ["2"],
|
||||
"contains_refs": ["monkey--5956efbb-a7b0-566d-a7f9-a202eb05c70f"],
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
assert excinfo.value.cls == stix2.v21.ObservedData
|
||||
assert excinfo.value.prop_name == "objects"
|
||||
assert excinfo.value.reason == "Invalid object reference for 'Directory:contains_refs': '2' is not a valid object in local scope"
|
||||
assert excinfo.value.cls == stix2.v21.Directory
|
||||
assert excinfo.value.prop_name == "contains_refs"
|
||||
assert "The type-specifying prefix 'monkey--' for this property is not valid" in excinfo.value.reason
|
||||
|
||||
|
||||
def test_observed_data_example_with_non_dictionary():
|
||||
|
@ -244,6 +265,7 @@ def test_observed_data_example_with_empty_dictionary():
|
|||
"0": {
|
||||
"name": "foo.exe",
|
||||
"type": "file",
|
||||
"id": "file--5956efbb-a7b0-566d-a7f9-a202eb05c70f",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -342,17 +364,21 @@ def test_parse_autonomous_system_valid(data):
|
|||
"type": "email-addr",
|
||||
"value": "john@example.com",
|
||||
"display_name": "John Doe",
|
||||
"belongs_to_ref": "0"
|
||||
"belongs_to_ref": "user-account--fc07c1af-6b11-41f8-97a4-47920d866a91"
|
||||
}""",
|
||||
],
|
||||
)
|
||||
def test_parse_email_address(data):
|
||||
odata = stix2.parse_observable(data, {"0": "user-account"}, version='2.1')
|
||||
odata = stix2.parse_observable(data, version='2.1')
|
||||
assert odata.type == "email-addr"
|
||||
|
||||
odata_str = re.compile('"belongs_to_ref": "0"', re.DOTALL).sub('"belongs_to_ref": "3"', data)
|
||||
with pytest.raises(stix2.exceptions.InvalidObjRefError):
|
||||
stix2.parse_observable(odata_str, {"0": "user-account"}, version='2.1')
|
||||
odata_str = re.compile(
|
||||
'"belongs_to_ref": "user-account--fc07c1af-6b11-41f8-97a4-47920d866a91"', re.DOTALL,
|
||||
).sub(
|
||||
'"belongs_to_ref": "mutex--9be6365f-b89c-48c0-9340-6953f6595718"', data,
|
||||
)
|
||||
with pytest.raises(stix2.exceptions.InvalidValueError):
|
||||
stix2.parse_observable(odata_str, version='2.1')
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
@ -363,12 +389,12 @@ def test_parse_email_address(data):
|
|||
"is_multipart": true,
|
||||
"content_type": "multipart/mixed",
|
||||
"date": "2016-06-19T14:20:40.000Z",
|
||||
"from_ref": "1",
|
||||
"from_ref": "email-addr--d4ef7e1f-086d-5ff4-bce4-312ddc3eae76",
|
||||
"to_refs": [
|
||||
"2"
|
||||
"email-addr--8b0eb924-208c-5efd-80e5-84e2d610e54b"
|
||||
],
|
||||
"cc_refs": [
|
||||
"3"
|
||||
"email-addr--1766f860-5cf3-5697-8789-35f1242663d5"
|
||||
],
|
||||
"subject": "Check out this picture of a cat!",
|
||||
"additional_header_fields": {
|
||||
|
@ -385,12 +411,12 @@ def test_parse_email_address(data):
|
|||
{
|
||||
"content_type": "image/png",
|
||||
"content_disposition": "attachment; filename=\\"tabby.png\\"",
|
||||
"body_raw_ref": "4"
|
||||
"body_raw_ref": "artifact--80b04ad8-db52-464b-a85a-a44a5f3a60c5"
|
||||
},
|
||||
{
|
||||
"content_type": "application/zip",
|
||||
"content_disposition": "attachment; filename=\\"tabby_pics.zip\\"",
|
||||
"body_raw_ref": "5"
|
||||
"body_raw_ref": "file--e63474fc-b386-5630-a003-1b555e22f99b"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -398,15 +424,7 @@ def test_parse_email_address(data):
|
|||
],
|
||||
)
|
||||
def test_parse_email_message(data):
|
||||
valid_refs = {
|
||||
"0": "email-message",
|
||||
"1": "email-addr",
|
||||
"2": "email-addr",
|
||||
"3": "email-addr",
|
||||
"4": "artifact",
|
||||
"5": "file",
|
||||
}
|
||||
odata = stix2.parse_observable(data, valid_refs, version='2.1')
|
||||
odata = stix2.parse_observable(data, version='2.1')
|
||||
assert odata.type == "email-message"
|
||||
assert odata.body_multipart[0].content_disposition == "inline"
|
||||
|
||||
|
@ -416,8 +434,8 @@ def test_parse_email_message(data):
|
|||
"""
|
||||
{
|
||||
"type": "email-message",
|
||||
"from_ref": "0",
|
||||
"to_refs": ["1"],
|
||||
"from_ref": "email-addr--d4ef7e1f-086d-5ff4-bce4-312ddc3eae76",
|
||||
"to_refs": ["email-addr--8b0eb924-208c-5efd-80e5-84e2d610e54b"],
|
||||
"is_multipart": true,
|
||||
"date": "1997-11-21T15:55:06.000Z",
|
||||
"subject": "Saying Hello",
|
||||
|
@ -427,12 +445,8 @@ def test_parse_email_message(data):
|
|||
],
|
||||
)
|
||||
def test_parse_email_message_not_multipart(data):
|
||||
valid_refs = {
|
||||
"0": "email-addr",
|
||||
"1": "email-addr",
|
||||
}
|
||||
with pytest.raises(stix2.exceptions.DependentPropertiesError) as excinfo:
|
||||
stix2.parse_observable(data, valid_refs, version='2.1')
|
||||
stix2.parse_observable(data, version='2.1')
|
||||
|
||||
assert excinfo.value.cls == stix2.v21.EmailMessage
|
||||
assert excinfo.value.dependencies == [("is_multipart", "body")]
|
||||
|
@ -442,35 +456,38 @@ def test_parse_email_message_not_multipart(data):
|
|||
"data", [
|
||||
""""0": {
|
||||
"type": "file",
|
||||
"id": "file--ecd47d73-15e4-5250-afda-ef8897b22340",
|
||||
"hashes": {
|
||||
"SHA-256": "ceafbfd424be2ca4a5f0402cae090dda2fb0526cf521b60b60077c0f622b285a"
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"type": "file",
|
||||
"id": "file--65f2873d-38c2-56b4-bfa5-e3ef21e8a3c3",
|
||||
"hashes": {
|
||||
"SHA-256": "19c549ec2628b989382f6b280cbd7bb836a0b461332c0fe53511ce7d584b89d3"
|
||||
"SHA-1": "6e71b3cac15d32fe2d36c270887df9479c25c640"
|
||||
}
|
||||
},
|
||||
"2": {
|
||||
"type": "file",
|
||||
"id": "file--ef2d6dca-ec7d-5ab7-8dd9-ec9c0dee0eac",
|
||||
"hashes": {
|
||||
"SHA-256": "0969de02ecf8a5f003e3f6d063d848c8a193aada092623f8ce408c15bcb5f038"
|
||||
"SHA-512": "b7e98c78c24fb4c2c7b175e90474b21eae0ccf1b5ea4708b4e0f2d2940004419edc7161c18a1e71b2565df099ba017bcaa67a248e2989b6268ce078b88f2e210"
|
||||
}
|
||||
},
|
||||
"3": {
|
||||
"type": "file",
|
||||
"name": "foo.zip",
|
||||
"hashes": {
|
||||
"SHA-256": "35a01331e9ad96f751278b891b6ea09699806faedfa237d40513d92ad1b7100f"
|
||||
"SHA3-256": "35a01331e9ad96f751278b891b6ea09699806faedfa237d40513d92ad1b7100f"
|
||||
},
|
||||
"mime_type": "application/zip",
|
||||
"extensions": {
|
||||
"archive-ext": {
|
||||
"contains_refs": [
|
||||
"0",
|
||||
"1",
|
||||
"2"
|
||||
"file--ecd47d73-15e4-5250-afda-ef8897b22340",
|
||||
"file--65f2873d-38c2-56b4-bfa5-e3ef21e8a3c3",
|
||||
"file--ef2d6dca-ec7d-5ab7-8dd9-ec9c0dee0eac"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -481,7 +498,11 @@ def test_parse_file_archive(data):
|
|||
odata_str = OBJECTS_REGEX.sub('"objects": { %s }' % data, EXPECTED)
|
||||
odata = stix2.parse(odata_str, version="2.1")
|
||||
assert all(x in odata.objects["3"].extensions['archive-ext'].contains_refs
|
||||
for x in ["0", "1", "2"])
|
||||
for x in [
|
||||
"file--ecd47d73-15e4-5250-afda-ef8897b22340",
|
||||
"file--65f2873d-38c2-56b4-bfa5-e3ef21e8a3c3",
|
||||
"file--ef2d6dca-ec7d-5ab7-8dd9-ec9c0dee0eac",
|
||||
])
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
@ -492,12 +513,12 @@ def test_parse_file_archive(data):
|
|||
"is_multipart": true,
|
||||
"content_type": "multipart/mixed",
|
||||
"date": "2016-06-19T14:20:40.000Z",
|
||||
"from_ref": "1",
|
||||
"from_ref": "email-addr--d4ef7e1f-086d-5ff4-bce4-312ddc3eae76",
|
||||
"to_refs": [
|
||||
"2"
|
||||
"email-addr--8b0eb924-208c-5efd-80e5-84e2d610e54b"
|
||||
],
|
||||
"cc_refs": [
|
||||
"3"
|
||||
"email-addr--1766f860-5cf3-5697-8789-35f1242663d5"
|
||||
],
|
||||
"subject": "Check out this picture of a cat!",
|
||||
"additional_header_fields": {
|
||||
|
@ -518,7 +539,7 @@ def test_parse_file_archive(data):
|
|||
{
|
||||
"content_type": "application/zip",
|
||||
"content_disposition": "attachment; filename=\\"tabby_pics.zip\\"",
|
||||
"body_raw_ref": "5"
|
||||
"body_raw_ref": "file--e63474fc-b386-5630-a003-1b555e22f99b"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -526,16 +547,8 @@ def test_parse_file_archive(data):
|
|||
],
|
||||
)
|
||||
def test_parse_email_message_with_at_least_one_error(data):
|
||||
valid_refs = {
|
||||
"0": "email-message",
|
||||
"1": "email-addr",
|
||||
"2": "email-addr",
|
||||
"3": "email-addr",
|
||||
"4": "artifact",
|
||||
"5": "file",
|
||||
}
|
||||
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
|
||||
stix2.parse_observable(data, valid_refs, version='2.1')
|
||||
stix2.parse_observable(data, version='2.1')
|
||||
|
||||
assert excinfo.value.cls == stix2.v21.EmailMessage
|
||||
assert "At least one of the" in str(excinfo.value)
|
||||
|
@ -547,8 +560,8 @@ def test_parse_email_message_with_at_least_one_error(data):
|
|||
"""
|
||||
{
|
||||
"type": "network-traffic",
|
||||
"src_ref": "0",
|
||||
"dst_ref": "1",
|
||||
"src_ref": "ipv4-addr--e535b017-cc1c-566b-a3e2-f69f92ed9c4c",
|
||||
"dst_ref": "ipv4-addr--78327430-9ad9-5632-ae3d-8e2fce8f5483",
|
||||
"protocols": [
|
||||
"tcp"
|
||||
]
|
||||
|
@ -558,13 +571,12 @@ def test_parse_email_message_with_at_least_one_error(data):
|
|||
)
|
||||
def test_parse_basic_tcp_traffic(data):
|
||||
odata = stix2.parse_observable(
|
||||
data, {"0": "ipv4-addr", "1": "ipv4-addr"},
|
||||
version='2.1',
|
||||
data, version='2.1',
|
||||
)
|
||||
|
||||
assert odata.type == "network-traffic"
|
||||
assert odata.src_ref == "0"
|
||||
assert odata.dst_ref == "1"
|
||||
assert odata.src_ref == "ipv4-addr--e535b017-cc1c-566b-a3e2-f69f92ed9c4c"
|
||||
assert odata.dst_ref == "ipv4-addr--78327430-9ad9-5632-ae3d-8e2fce8f5483"
|
||||
assert odata.protocols == ["tcp"]
|
||||
|
||||
|
||||
|
@ -582,7 +594,7 @@ def test_parse_basic_tcp_traffic(data):
|
|||
"src_byte_count": 35779,
|
||||
"dst_byte_count": 935750,
|
||||
"encapsulates_refs": [
|
||||
"4"
|
||||
"network-traffic--016914c3-b680-5df2-81c4-bb9ccf8dc8b0"
|
||||
]
|
||||
}
|
||||
""",
|
||||
|
@ -590,7 +602,7 @@ def test_parse_basic_tcp_traffic(data):
|
|||
)
|
||||
def test_parse_basic_tcp_traffic_with_error(data):
|
||||
with pytest.raises(stix2.exceptions.AtLeastOnePropertyError) as excinfo:
|
||||
stix2.parse_observable(data, {"4": "network-traffic"}, version='2.1')
|
||||
stix2.parse_observable(data, version='2.1')
|
||||
|
||||
assert excinfo.value.cls == stix2.v21.NetworkTraffic
|
||||
assert excinfo.value.properties == ["dst_ref", "src_ref"]
|
||||
|
@ -636,16 +648,18 @@ def test_observed_data_with_process_example():
|
|||
objects={
|
||||
"0": {
|
||||
"type": "file",
|
||||
"id": "file--0d16c8d3-c177-5f5d-a022-b1bdac329bea",
|
||||
"hashes": {
|
||||
"SHA-256": "35a01331e9ad96f751278b891b6ea09699806faedfa237d40513d92ad1b7100f",
|
||||
},
|
||||
},
|
||||
"1": {
|
||||
"type": "process",
|
||||
"id": "process--f6c4a02c-23e1-4a6d-a0d7-d862e893817a",
|
||||
"pid": 1221,
|
||||
"created": "2016-01-20T14:11:25.55Z",
|
||||
"created_time": "2016-01-20T14:11:25.55Z",
|
||||
"command_line": "./gedit-bin --new-window",
|
||||
"image_ref": "0",
|
||||
"image_ref": "file--0d16c8d3-c177-5f5d-a022-b1bdac329bea",
|
||||
},
|
||||
},
|
||||
)
|
||||
|
@ -689,31 +703,33 @@ def test_artifact_mutual_exclusion_error():
|
|||
|
||||
|
||||
def test_directory_example():
|
||||
dir = stix2.v21.Directory(
|
||||
_valid_refs={"1": "file"},
|
||||
path='/usr/lib',
|
||||
created="2015-12-21T19:00:00Z",
|
||||
modified="2015-12-24T19:00:00Z",
|
||||
accessed="2015-12-21T20:00:00Z",
|
||||
contains_refs=["1"],
|
||||
f = stix2.v21.File(
|
||||
name="penguin.exe",
|
||||
)
|
||||
|
||||
assert dir.path == '/usr/lib'
|
||||
assert dir.created == dt.datetime(2015, 12, 21, 19, 0, 0, tzinfo=pytz.utc)
|
||||
assert dir.modified == dt.datetime(2015, 12, 24, 19, 0, 0, tzinfo=pytz.utc)
|
||||
assert dir.accessed == dt.datetime(2015, 12, 21, 20, 0, 0, tzinfo=pytz.utc)
|
||||
assert dir.contains_refs == ["1"]
|
||||
dir1 = stix2.v21.Directory(
|
||||
path='/usr/lib',
|
||||
ctime="2015-12-21T19:00:00Z",
|
||||
mtime="2015-12-24T19:00:00Z",
|
||||
atime="2015-12-21T20:00:00Z",
|
||||
contains_refs=[str(f.id)],
|
||||
)
|
||||
|
||||
assert dir1.path == '/usr/lib'
|
||||
assert dir1.ctime == dt.datetime(2015, 12, 21, 19, 0, 0, tzinfo=pytz.utc)
|
||||
assert dir1.mtime == dt.datetime(2015, 12, 24, 19, 0, 0, tzinfo=pytz.utc)
|
||||
assert dir1.atime == dt.datetime(2015, 12, 21, 20, 0, 0, tzinfo=pytz.utc)
|
||||
assert dir1.contains_refs == ["file--9d050a3b-72cd-5b57-bf18-024e74e1e5eb"]
|
||||
|
||||
|
||||
def test_directory_example_ref_error():
|
||||
with pytest.raises(stix2.exceptions.InvalidObjRefError) as excinfo:
|
||||
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
|
||||
stix2.v21.Directory(
|
||||
_valid_refs=[],
|
||||
path='/usr/lib',
|
||||
created="2015-12-21T19:00:00Z",
|
||||
modified="2015-12-24T19:00:00Z",
|
||||
accessed="2015-12-21T20:00:00Z",
|
||||
contains_refs=["1"],
|
||||
ctime="2015-12-21T19:00:00Z",
|
||||
mtime="2015-12-24T19:00:00Z",
|
||||
atime="2015-12-21T20:00:00Z",
|
||||
contains_refs=["domain-name--02af94ea-7e38-5718-87c3-5cc023e3d49d"],
|
||||
)
|
||||
|
||||
assert excinfo.value.cls == stix2.v21.Directory
|
||||
|
@ -721,22 +737,24 @@ def test_directory_example_ref_error():
|
|||
|
||||
|
||||
def test_domain_name_example():
|
||||
dn = stix2.v21.DomainName(
|
||||
_valid_refs={"1": 'domain-name'},
|
||||
value="example.com",
|
||||
resolves_to_refs=["1"],
|
||||
dn1 = stix2.v21.DomainName(
|
||||
value="mitre.org",
|
||||
)
|
||||
|
||||
assert dn.value == "example.com"
|
||||
assert dn.resolves_to_refs == ["1"]
|
||||
dn2 = stix2.v21.DomainName(
|
||||
value="example.com",
|
||||
resolves_to_refs=[str(dn1.id)],
|
||||
)
|
||||
|
||||
assert dn2.value == "example.com"
|
||||
assert dn2.resolves_to_refs == ["domain-name--02af94ea-7e38-5718-87c3-5cc023e3d49d"]
|
||||
|
||||
|
||||
def test_domain_name_example_invalid_ref_type():
|
||||
with pytest.raises(stix2.exceptions.InvalidObjRefError) as excinfo:
|
||||
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
|
||||
stix2.v21.DomainName(
|
||||
_valid_refs={"1": "file"},
|
||||
value="example.com",
|
||||
resolves_to_refs=["1"],
|
||||
resolves_to_refs=["file--44a431e6-764b-5556-a3f5-bf655930a581"],
|
||||
)
|
||||
|
||||
assert excinfo.value.cls == stix2.v21.DomainName
|
||||
|
@ -752,9 +770,9 @@ def test_file_example():
|
|||
size=100,
|
||||
magic_number_hex="1C",
|
||||
mime_type="application/msword",
|
||||
created="2016-12-21T19:00:00Z",
|
||||
modified="2016-12-24T19:00:00Z",
|
||||
accessed="2016-12-21T20:00:00Z",
|
||||
ctime="2016-12-21T19:00:00Z",
|
||||
mtime="2016-12-24T19:00:00Z",
|
||||
atime="2016-12-21T20:00:00Z",
|
||||
)
|
||||
|
||||
assert f.name == "qwerty.dll"
|
||||
|
@ -762,9 +780,9 @@ def test_file_example():
|
|||
assert f.magic_number_hex == "1C"
|
||||
assert f.hashes["SHA-256"] == "ceafbfd424be2ca4a5f0402cae090dda2fb0526cf521b60b60077c0f622b285a"
|
||||
assert f.mime_type == "application/msword"
|
||||
assert f.created == dt.datetime(2016, 12, 21, 19, 0, 0, tzinfo=pytz.utc)
|
||||
assert f.modified == dt.datetime(2016, 12, 24, 19, 0, 0, tzinfo=pytz.utc)
|
||||
assert f.accessed == dt.datetime(2016, 12, 21, 20, 0, 0, tzinfo=pytz.utc)
|
||||
assert f.ctime == dt.datetime(2016, 12, 21, 19, 0, 0, tzinfo=pytz.utc)
|
||||
assert f.mtime == dt.datetime(2016, 12, 24, 19, 0, 0, tzinfo=pytz.utc)
|
||||
assert f.atime == dt.datetime(2016, 12, 21, 20, 0, 0, tzinfo=pytz.utc)
|
||||
|
||||
|
||||
def test_file_example_with_NTFSExt():
|
||||
|
@ -878,6 +896,7 @@ RASTER_IMAGE_EXT = """{
|
|||
"objects": {
|
||||
"0": {
|
||||
"type": "file",
|
||||
"id": "file--44a431e6-764b-5556-a3f5-bf655930a581",
|
||||
"name": "picture.jpg",
|
||||
"hashes": {
|
||||
"SHA-256": "35a01331e9ad96f751278b891b6ea09699806faedfa237d40513d92ad1b7100f"
|
||||
|
@ -989,18 +1008,17 @@ def test_file_example_encryption_error():
|
|||
assert "At least one of the (hashes, name)" in str(excinfo.value)
|
||||
|
||||
|
||||
def test_ip4_address_example():
|
||||
def test_ipv4_address_example():
|
||||
ip4 = stix2.v21.IPv4Address(
|
||||
_valid_refs={"4": "mac-addr", "5": "mac-addr"},
|
||||
value="198.51.100.3",
|
||||
resolves_to_refs=["4", "5"],
|
||||
resolves_to_refs=["mac-addr--a85820f7-d9b7-567a-a3a6-dedc34139342", "mac-addr--9a59b496-fdeb-510f-97b5-7137210bc699"],
|
||||
)
|
||||
|
||||
assert ip4.value == "198.51.100.3"
|
||||
assert ip4.resolves_to_refs == ["4", "5"]
|
||||
assert ip4.resolves_to_refs == ["mac-addr--a85820f7-d9b7-567a-a3a6-dedc34139342", "mac-addr--9a59b496-fdeb-510f-97b5-7137210bc699"]
|
||||
|
||||
|
||||
def test_ip4_address_valid_refs():
|
||||
def test_ipv4_address_valid_refs():
|
||||
mac1 = stix2.v21.MACAddress(
|
||||
value="a1:b2:c3:d4:e5:f6",
|
||||
)
|
||||
|
@ -1009,22 +1027,21 @@ def test_ip4_address_valid_refs():
|
|||
)
|
||||
|
||||
ip4 = stix2.v21.IPv4Address(
|
||||
_valid_refs={"1": mac1, "2": mac2},
|
||||
value="177.60.40.7",
|
||||
resolves_to_refs=["1", "2"],
|
||||
resolves_to_refs=[str(mac1.id), str(mac2.id)],
|
||||
)
|
||||
|
||||
assert ip4.value == "177.60.40.7"
|
||||
assert ip4.resolves_to_refs == ["1", "2"]
|
||||
assert ip4.resolves_to_refs == ["mac-addr--a85820f7-d9b7-567a-a3a6-dedc34139342", "mac-addr--9a59b496-fdeb-510f-97b5-7137210bc699"]
|
||||
|
||||
|
||||
def test_ip4_address_example_cidr():
|
||||
def test_ipv4_address_example_cidr():
|
||||
ip4 = stix2.v21.IPv4Address(value="198.51.100.0/24")
|
||||
|
||||
assert ip4.value == "198.51.100.0/24"
|
||||
|
||||
|
||||
def test_ip6_address_example():
|
||||
def test_ipv6_address_example():
|
||||
ip6 = stix2.v21.IPv6Address(value="2001:0db8:85a3:0000:0000:8a2e:0370:7334")
|
||||
|
||||
assert ip6.value == "2001:0db8:85a3:0000:0000:8a2e:0370:7334"
|
||||
|
@ -1038,14 +1055,13 @@ def test_mac_address_example():
|
|||
|
||||
def test_network_traffic_example():
|
||||
nt = stix2.v21.NetworkTraffic(
|
||||
_valid_refs={"0": "ipv4-addr", "1": "ipv4-addr"},
|
||||
protocols="tcp",
|
||||
src_ref="0",
|
||||
dst_ref="1",
|
||||
protocols=["tcp"],
|
||||
src_ref="ipv4-addr--29a591d9-533a-5ecd-a5a1-cadee4411e88",
|
||||
dst_ref="ipv4-addr--6d39dd0b-1f74-5faf-8d76-d8762c2a57cb",
|
||||
)
|
||||
assert nt.protocols == ["tcp"]
|
||||
assert nt.src_ref == "0"
|
||||
assert nt.dst_ref == "1"
|
||||
assert nt.src_ref == "ipv4-addr--29a591d9-533a-5ecd-a5a1-cadee4411e88"
|
||||
assert nt.dst_ref == "ipv4-addr--6d39dd0b-1f74-5faf-8d76-d8762c2a57cb"
|
||||
|
||||
|
||||
def test_network_traffic_http_request_example():
|
||||
|
@ -1060,9 +1076,8 @@ def test_network_traffic_http_request_example():
|
|||
},
|
||||
)
|
||||
nt = stix2.v21.NetworkTraffic(
|
||||
_valid_refs={"0": "ipv4-addr"},
|
||||
protocols="tcp",
|
||||
src_ref="0",
|
||||
protocols=["tcp"],
|
||||
src_ref="ipv4-addr--29a591d9-533a-5ecd-a5a1-cadee4411e88",
|
||||
extensions={'http-request-ext': h},
|
||||
)
|
||||
assert nt.extensions['http-request-ext'].request_method == "get"
|
||||
|
@ -1076,9 +1091,8 @@ def test_network_traffic_http_request_example():
|
|||
def test_network_traffic_icmp_example():
|
||||
h = stix2.v21.ICMPExt(icmp_type_hex="08", icmp_code_hex="00")
|
||||
nt = stix2.v21.NetworkTraffic(
|
||||
_valid_refs={"0": "ipv4-addr"},
|
||||
protocols="tcp",
|
||||
src_ref="0",
|
||||
protocols=["tcp"],
|
||||
src_ref="ipv4-addr--29a591d9-533a-5ecd-a5a1-cadee4411e88",
|
||||
extensions={'icmp-ext': h},
|
||||
)
|
||||
assert nt.extensions['icmp-ext'].icmp_type_hex == "08"
|
||||
|
@ -1093,9 +1107,8 @@ def test_network_traffic_socket_example():
|
|||
socket_type="SOCK_STREAM",
|
||||
)
|
||||
nt = stix2.v21.NetworkTraffic(
|
||||
_valid_refs={"0": "ipv4-addr"},
|
||||
protocols="tcp",
|
||||
src_ref="0",
|
||||
protocols=["tcp"],
|
||||
src_ref="ipv4-addr--29a591d9-533a-5ecd-a5a1-cadee4411e88",
|
||||
extensions={'socket-ext': h},
|
||||
)
|
||||
assert nt.extensions['socket-ext'].is_listening
|
||||
|
@ -1107,9 +1120,8 @@ def test_network_traffic_socket_example():
|
|||
def test_network_traffic_tcp_example():
|
||||
h = stix2.v21.TCPExt(src_flags_hex="00000002")
|
||||
nt = stix2.v21.NetworkTraffic(
|
||||
_valid_refs={"0": "ipv4-addr"},
|
||||
protocols="tcp",
|
||||
src_ref="0",
|
||||
protocols=["tcp"],
|
||||
src_ref="ipv4-addr--29a591d9-533a-5ecd-a5a1-cadee4411e88",
|
||||
extensions={'tcp-ext': h},
|
||||
)
|
||||
assert nt.extensions['tcp-ext'].src_flags_hex == "00000002"
|
||||
|
@ -1123,11 +1135,10 @@ def test_mutex_example():
|
|||
|
||||
def test_process_example():
|
||||
p = stix2.v21.Process(
|
||||
_valid_refs={"0": "file"},
|
||||
pid=1221,
|
||||
created="2016-01-20T14:11:25.55Z",
|
||||
created_time="2016-01-20T14:11:25.55Z",
|
||||
command_line="./gedit-bin --new-window",
|
||||
image_ref="0",
|
||||
image_ref="file--ea587d87-5ed2-5625-a9ac-01fd64161fd8",
|
||||
)
|
||||
|
||||
assert p.command_line == "./gedit-bin --new-window"
|
||||
|
@ -1139,7 +1150,7 @@ def test_process_example_empty_error():
|
|||
|
||||
assert excinfo.value.cls == stix2.v21.Process
|
||||
properties_of_process = list(stix2.v21.Process._properties.keys())
|
||||
properties_of_process.remove("type")
|
||||
properties_of_process = [prop for prop in properties_of_process if prop not in ["type", "id", "defanged", "spec_version"]]
|
||||
assert excinfo.value.properties == sorted(properties_of_process)
|
||||
msg = "At least one of the ({1}) properties for {0} must be populated."
|
||||
msg = msg.format(
|
||||
|
@ -1363,18 +1374,20 @@ def test_new_version_with_related_objects():
|
|||
objects={
|
||||
'src_ip': {
|
||||
'type': 'ipv4-addr',
|
||||
'id': 'ipv4-addr--2b94bc65-17d4-54f6-9ffe-7d103551bb9f',
|
||||
'value': '127.0.0.1/32',
|
||||
},
|
||||
'domain': {
|
||||
'type': 'domain-name',
|
||||
'id': 'domain-name--220a2699-5ebf-5b57-bf02-424964bb19c0',
|
||||
'value': 'example.com',
|
||||
'resolves_to_refs': ['src_ip'],
|
||||
'resolves_to_refs': ['ipv4-addr--2b94bc65-17d4-54f6-9ffe-7d103551bb9f'],
|
||||
},
|
||||
},
|
||||
)
|
||||
new_version = data.new_version(last_observed="2017-12-12T12:00:00Z")
|
||||
assert new_version.last_observed.year == 2017
|
||||
assert new_version.objects['domain'].resolves_to_refs[0] == 'src_ip'
|
||||
assert new_version.objects['domain'].resolves_to_refs[0] == 'ipv4-addr--2b94bc65-17d4-54f6-9ffe-7d103551bb9f'
|
||||
|
||||
|
||||
def test_objects_deprecation():
|
||||
|
@ -1391,3 +1404,125 @@ def test_objects_deprecation():
|
|||
},
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def test_deterministic_id_same_extra_prop_vals():
|
||||
email_addr_1 = stix2.v21.EmailAddress(
|
||||
value="john@example.com",
|
||||
display_name="Johnny Doe",
|
||||
)
|
||||
|
||||
email_addr_2 = stix2.v21.EmailAddress(
|
||||
value="john@example.com",
|
||||
display_name="Johnny Doe",
|
||||
)
|
||||
|
||||
assert email_addr_1.id == email_addr_2.id
|
||||
|
||||
uuid_obj_1 = uuid.UUID(email_addr_1.id[-36:])
|
||||
assert uuid_obj_1.variant == uuid.RFC_4122
|
||||
assert uuid_obj_1.version == 5
|
||||
|
||||
uuid_obj_2 = uuid.UUID(email_addr_2.id[-36:])
|
||||
assert uuid_obj_2.variant == uuid.RFC_4122
|
||||
assert uuid_obj_2.version == 5
|
||||
|
||||
|
||||
def test_deterministic_id_diff_extra_prop_vals():
|
||||
email_addr_1 = stix2.v21.EmailAddress(
|
||||
value="john@example.com",
|
||||
display_name="Johnny Doe",
|
||||
)
|
||||
|
||||
email_addr_2 = stix2.v21.EmailAddress(
|
||||
value="john@example.com",
|
||||
display_name="Janey Doe",
|
||||
)
|
||||
|
||||
assert email_addr_1.id == email_addr_2.id
|
||||
|
||||
uuid_obj_1 = uuid.UUID(email_addr_1.id[-36:])
|
||||
assert uuid_obj_1.variant == uuid.RFC_4122
|
||||
assert uuid_obj_1.version == 5
|
||||
|
||||
uuid_obj_2 = uuid.UUID(email_addr_2.id[-36:])
|
||||
assert uuid_obj_2.variant == uuid.RFC_4122
|
||||
assert uuid_obj_2.version == 5
|
||||
|
||||
|
||||
def test_deterministic_id_diff_contributing_prop_vals():
|
||||
email_addr_1 = stix2.v21.EmailAddress(
|
||||
value="john@example.com",
|
||||
display_name="Johnny Doe",
|
||||
)
|
||||
|
||||
email_addr_2 = stix2.v21.EmailAddress(
|
||||
value="jane@example.com",
|
||||
display_name="Janey Doe",
|
||||
)
|
||||
|
||||
assert email_addr_1.id != email_addr_2.id
|
||||
|
||||
uuid_obj_1 = uuid.UUID(email_addr_1.id[-36:])
|
||||
assert uuid_obj_1.variant == uuid.RFC_4122
|
||||
assert uuid_obj_1.version == 5
|
||||
|
||||
uuid_obj_2 = uuid.UUID(email_addr_2.id[-36:])
|
||||
assert uuid_obj_2.variant == uuid.RFC_4122
|
||||
assert uuid_obj_2.version == 5
|
||||
|
||||
|
||||
def test_deterministic_id_no_contributing_props():
|
||||
email_msg_1 = stix2.v21.EmailMessage(
|
||||
is_multipart=False,
|
||||
)
|
||||
|
||||
email_msg_2 = stix2.v21.EmailMessage(
|
||||
is_multipart=False,
|
||||
)
|
||||
|
||||
assert email_msg_1.id != email_msg_2.id
|
||||
|
||||
uuid_obj_1 = uuid.UUID(email_msg_1.id[-36:])
|
||||
assert uuid_obj_1.variant == uuid.RFC_4122
|
||||
assert uuid_obj_1.version == 4
|
||||
|
||||
uuid_obj_2 = uuid.UUID(email_msg_2.id[-36:])
|
||||
assert uuid_obj_2.variant == uuid.RFC_4122
|
||||
assert uuid_obj_2.version == 4
|
||||
|
||||
|
||||
def test_ipv4_resolves_to_refs_deprecation():
|
||||
with pytest.warns(stix2.exceptions.STIXDeprecationWarning):
|
||||
|
||||
stix2.v21.IPv4Address(
|
||||
value="26.09.19.70",
|
||||
resolves_to_refs=["mac-addr--08900593-0265-52fc-93c0-5b4a942f5887"],
|
||||
)
|
||||
|
||||
|
||||
def test_ipv4_belongs_to_refs_deprecation():
|
||||
with pytest.warns(stix2.exceptions.STIXDeprecationWarning):
|
||||
|
||||
stix2.v21.IPv4Address(
|
||||
value="21.12.19.64",
|
||||
belongs_to_refs=["autonomous-system--52e0a49d-d683-5801-a7b8-145765a1e116"],
|
||||
)
|
||||
|
||||
|
||||
def test_ipv6_resolves_to_refs_deprecation():
|
||||
with pytest.warns(stix2.exceptions.STIXDeprecationWarning):
|
||||
|
||||
stix2.v21.IPv6Address(
|
||||
value="2001:0db8:85a3:0000:0000:8a2e:0370:7334",
|
||||
resolves_to_refs=["mac-addr--08900593-0265-52fc-93c0-5b4a942f5887"],
|
||||
)
|
||||
|
||||
|
||||
def test_ipv6_belongs_to_refs_deprecation():
|
||||
with pytest.warns(stix2.exceptions.STIXDeprecationWarning):
|
||||
|
||||
stix2.v21.IPv6Address(
|
||||
value="2001:0db8:85a3:0000:0000:8a2e:0370:7334",
|
||||
belongs_to_refs=["autonomous-system--52e0a49d-d683-5801-a7b8-145765a1e116"],
|
||||
)
|
||||
|
|
|
@ -271,7 +271,7 @@ def test_boolean_property_invalid(value):
|
|||
|
||||
|
||||
def test_reference_property():
|
||||
ref_prop = ReferenceProperty(spec_version="2.1")
|
||||
ref_prop = ReferenceProperty(valid_types="my-type", spec_version="2.1")
|
||||
|
||||
assert ref_prop.clean("my-type--00000000-0000-4000-8000-000000000000")
|
||||
with pytest.raises(ValueError):
|
||||
|
@ -283,7 +283,7 @@ def test_reference_property():
|
|||
|
||||
|
||||
def test_reference_property_specific_type():
|
||||
ref_prop = ReferenceProperty("my-type", spec_version="2.1")
|
||||
ref_prop = ReferenceProperty(valid_types="my-type", spec_version="2.1")
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
ref_prop.clean("not-my-type--8a8e8758-f92c-4058-ba38-f061cd42a0cf")
|
||||
|
|
|
@ -135,14 +135,16 @@ def test_deduplicate(stix_objs1):
|
|||
"0": {
|
||||
"name": "foo.exe",
|
||||
"type": "file",
|
||||
"id": "file--5956efbb-a7b0-566d-a7f9-a202eb05c70f",
|
||||
},
|
||||
"1": {
|
||||
"type": "ipv4-addr",
|
||||
"value": "198.51.100.3",
|
||||
"id": "ipv4-addr--1f8f4d63-9f33-5353-a3e3-e1b84c83a7b5",
|
||||
},
|
||||
"2": {
|
||||
"type": "network-traffic",
|
||||
"src_ref": "1",
|
||||
"src_ref": "ipv4-addr--1f8f4d63-9f33-5353-a3e3-e1b84c83a7b5",
|
||||
"protocols": [
|
||||
"tcp",
|
||||
"http",
|
||||
|
@ -161,7 +163,7 @@ def test_deduplicate(stix_objs1):
|
|||
},
|
||||
},
|
||||
},
|
||||
), ('1', {"type": "ipv4-addr", "value": "198.51.100.3"}), 1,
|
||||
), ('1', {"type": "ipv4-addr", "value": "198.51.100.3", "id": "ipv4-addr--1f8f4d63-9f33-5353-a3e3-e1b84c83a7b5"}), 1,
|
||||
),
|
||||
(
|
||||
{
|
||||
|
|
|
@ -49,7 +49,7 @@ class GranularMarking(_STIXBase):
|
|||
"""
|
||||
|
||||
_properties = OrderedDict([
|
||||
('marking_ref', ReferenceProperty(required=True, spec_version='2.0', type='marking-definition')),
|
||||
('marking_ref', ReferenceProperty(valid_types='marking-definition', spec_version='2.0', required=True)),
|
||||
('selectors', ListProperty(SelectorProperty, required=True)),
|
||||
])
|
||||
|
||||
|
@ -105,10 +105,10 @@ class MarkingDefinition(_STIXBase, _MarkingsMixin):
|
|||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
|
||||
('created', TimestampProperty(default=lambda: NOW)),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.0'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.0'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
('definition_type', StringProperty(required=True)),
|
||||
('definition', MarkingProperty(required=True)),
|
||||
|
|
|
@ -23,7 +23,7 @@ class AttackPattern(STIXDomainObject):
|
|||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('name', StringProperty(required=True)),
|
||||
|
@ -32,7 +32,7 @@ class AttackPattern(STIXDomainObject):
|
|||
('revoked', BooleanProperty(default=lambda: False)),
|
||||
('labels', ListProperty(StringProperty)),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.0'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.0'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -46,7 +46,7 @@ class Campaign(STIXDomainObject):
|
|||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('name', StringProperty(required=True)),
|
||||
|
@ -58,7 +58,7 @@ class Campaign(STIXDomainObject):
|
|||
('revoked', BooleanProperty(default=lambda: False)),
|
||||
('labels', ListProperty(StringProperty)),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.0'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.0'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -72,7 +72,7 @@ class CourseOfAction(STIXDomainObject):
|
|||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('name', StringProperty(required=True)),
|
||||
|
@ -80,7 +80,7 @@ class CourseOfAction(STIXDomainObject):
|
|||
('revoked', BooleanProperty(default=lambda: False)),
|
||||
('labels', ListProperty(StringProperty)),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.0'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.0'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -94,7 +94,7 @@ class Identity(STIXDomainObject):
|
|||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('name', StringProperty(required=True)),
|
||||
|
@ -105,7 +105,7 @@ class Identity(STIXDomainObject):
|
|||
('revoked', BooleanProperty(default=lambda: False)),
|
||||
('labels', ListProperty(StringProperty)),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.0'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.0'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -119,7 +119,7 @@ class Indicator(STIXDomainObject):
|
|||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('name', StringProperty()),
|
||||
|
@ -131,7 +131,7 @@ class Indicator(STIXDomainObject):
|
|||
('revoked', BooleanProperty(default=lambda: False)),
|
||||
('labels', ListProperty(StringProperty, required=True)),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.0'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.0'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -145,7 +145,7 @@ class IntrusionSet(STIXDomainObject):
|
|||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('name', StringProperty(required=True)),
|
||||
|
@ -160,7 +160,7 @@ class IntrusionSet(STIXDomainObject):
|
|||
('revoked', BooleanProperty(default=lambda: False)),
|
||||
('labels', ListProperty(StringProperty)),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.0'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.0'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -174,7 +174,7 @@ class Malware(STIXDomainObject):
|
|||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('name', StringProperty(required=True)),
|
||||
|
@ -183,7 +183,7 @@ class Malware(STIXDomainObject):
|
|||
('revoked', BooleanProperty(default=lambda: False)),
|
||||
('labels', ListProperty(StringProperty, required=True)),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.0'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.0'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -197,7 +197,7 @@ class ObservedData(STIXDomainObject):
|
|||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('first_observed', TimestampProperty(required=True)),
|
||||
|
@ -207,7 +207,7 @@ class ObservedData(STIXDomainObject):
|
|||
('revoked', BooleanProperty(default=lambda: False)),
|
||||
('labels', ListProperty(StringProperty)),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.0'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.0'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -227,17 +227,17 @@ class Report(STIXDomainObject):
|
|||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
|
||||
('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(spec_version='2.0'), required=True)),
|
||||
('object_refs', ListProperty(ReferenceProperty(invalid_types=[""], spec_version='2.0'), required=True)),
|
||||
('revoked', BooleanProperty(default=lambda: False)),
|
||||
('labels', ListProperty(StringProperty, required=True)),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.0'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.0'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -251,7 +251,7 @@ class ThreatActor(STIXDomainObject):
|
|||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('name', StringProperty(required=True)),
|
||||
|
@ -267,7 +267,7 @@ class ThreatActor(STIXDomainObject):
|
|||
('revoked', BooleanProperty(default=lambda: False)),
|
||||
('labels', ListProperty(StringProperty, required=True)),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.0'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.0'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -281,7 +281,7 @@ class Tool(STIXDomainObject):
|
|||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('name', StringProperty(required=True)),
|
||||
|
@ -291,7 +291,7 @@ class Tool(STIXDomainObject):
|
|||
('revoked', BooleanProperty(default=lambda: False)),
|
||||
('labels', ListProperty(StringProperty, required=True)),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.0'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.0'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -305,7 +305,7 @@ class Vulnerability(STIXDomainObject):
|
|||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('name', StringProperty(required=True)),
|
||||
|
@ -313,7 +313,7 @@ class Vulnerability(STIXDomainObject):
|
|||
('revoked', BooleanProperty(default=lambda: False)),
|
||||
('labels', ListProperty(StringProperty)),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.0'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.0'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -352,7 +352,7 @@ def CustomObject(type='x-custom-type', properties=None):
|
|||
[
|
||||
('type', TypeProperty(type)),
|
||||
('id', IDProperty(type, spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
],
|
||||
|
@ -361,7 +361,7 @@ def CustomObject(type='x-custom-type', properties=None):
|
|||
('revoked', BooleanProperty(default=lambda: False)),
|
||||
('labels', ListProperty(StringProperty)),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.0'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.0'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
],
|
||||
sorted([x for x in properties if x[0].startswith('x_')], key=lambda x: x[0]),
|
||||
|
|
|
@ -16,21 +16,23 @@ class Relationship(STIXRelationshipObject):
|
|||
`the STIX 2.0 specification <http://docs.oasis-open.org/cti/stix/v2.0/cs01/part2-stix-objects/stix-v2.0-cs01-part2-stix-objects.html#_Toc496714340>`__.
|
||||
"""
|
||||
|
||||
_invalid_source_target_types = ['bundle', 'language-content', 'marking-definition', 'relationship', 'sighting']
|
||||
|
||||
_type = 'relationship'
|
||||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('relationship_type', StringProperty(required=True)),
|
||||
('description', StringProperty()),
|
||||
('source_ref', ReferenceProperty(spec_version='2.0', required=True)),
|
||||
('target_ref', ReferenceProperty(spec_version='2.0', required=True)),
|
||||
('source_ref', ReferenceProperty(invalid_types=_invalid_source_target_types, spec_version='2.0', required=True)),
|
||||
('target_ref', ReferenceProperty(invalid_types=_invalid_source_target_types, spec_version='2.0', required=True)),
|
||||
('revoked', BooleanProperty(default=lambda: False)),
|
||||
('labels', ListProperty(StringProperty)),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.0'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.0'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -59,20 +61,20 @@ class Sighting(STIXRelationshipObject):
|
|||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.0')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.0')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('first_seen', TimestampProperty()),
|
||||
('last_seen', TimestampProperty()),
|
||||
('count', IntegerProperty(min=0, max=999999999)),
|
||||
('sighting_of_ref', ReferenceProperty(spec_version='2.0', required=True)),
|
||||
('observed_data_refs', ListProperty(ReferenceProperty(type='observed-data', spec_version='2.0'))),
|
||||
('where_sighted_refs', ListProperty(ReferenceProperty(type='identity', spec_version='2.0'))),
|
||||
('sighting_of_ref', ReferenceProperty(valid_types="only_SDO", spec_version='2.0', required=True)),
|
||||
('observed_data_refs', ListProperty(ReferenceProperty(valid_types='observed-data', spec_version='2.0'))),
|
||||
('where_sighted_refs', ListProperty(ReferenceProperty(valid_types='identity', spec_version='2.0'))),
|
||||
('summary', BooleanProperty(default=lambda: False)),
|
||||
('revoked', BooleanProperty(default=lambda: False)),
|
||||
('labels', ListProperty(StringProperty)),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.0'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.0'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ class GranularMarking(_STIXBase):
|
|||
|
||||
_properties = OrderedDict([
|
||||
('lang', StringProperty()),
|
||||
('marking_ref', ReferenceProperty(type='marking-definition', spec_version='2.1')),
|
||||
('marking_ref', ReferenceProperty(valid_types='marking-definition', spec_version='2.1')),
|
||||
('selectors', ListProperty(SelectorProperty, required=True)),
|
||||
])
|
||||
|
||||
|
@ -74,10 +74,10 @@ class LanguageContent(_STIXBase):
|
|||
('type', TypeProperty(_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('object_ref', ReferenceProperty(spec_version='2.1', required=True)),
|
||||
('object_ref', ReferenceProperty(invalid_types=[""], spec_version='2.1', required=True)),
|
||||
# TODO: 'object_modified' it MUST be an exact match for the modified time of the STIX Object (SRO or SDO) being referenced.
|
||||
('object_modified', TimestampProperty(precision='millisecond')),
|
||||
# TODO: 'contents' https://docs.google.com/document/d/1ShNq4c3e1CkfANmD9O--mdZ5H0O_GLnjN28a_yrEaco/edit#heading=h.cfz5hcantmvx
|
||||
|
@ -86,7 +86,7 @@ class LanguageContent(_STIXBase):
|
|||
('labels', ListProperty(StringProperty)),
|
||||
('confidence', IntegerProperty()),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.1'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -145,10 +145,10 @@ class MarkingDefinition(_STIXBase, _MarkingsMixin):
|
|||
('type', TypeProperty(_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('id', IDProperty(_type)),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
|
||||
('created', TimestampProperty(default=lambda: NOW)),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.1'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
('definition_type', StringProperty(required=True)),
|
||||
('definition', MarkingProperty(required=True)),
|
||||
|
|
|
@ -7,16 +7,21 @@ Observable and do not have a ``_type`` attribute.
|
|||
|
||||
from collections import OrderedDict
|
||||
import itertools
|
||||
import warnings
|
||||
|
||||
from ..base import _Extension, _Observable, _STIXBase
|
||||
from ..custom import _custom_extension_builder, _custom_observable_builder
|
||||
from ..exceptions import AtLeastOnePropertyError, DependentPropertiesError
|
||||
from ..exceptions import (
|
||||
AtLeastOnePropertyError, DependentPropertiesError, STIXDeprecationWarning,
|
||||
)
|
||||
from ..properties import (
|
||||
BinaryProperty, BooleanProperty, CallableValues, DictionaryProperty,
|
||||
EmbeddedObjectProperty, EnumProperty, ExtensionsProperty, FloatProperty,
|
||||
HashesProperty, HexProperty, IntegerProperty, ListProperty,
|
||||
ObjectReferenceProperty, StringProperty, TimestampProperty, TypeProperty,
|
||||
HashesProperty, HexProperty, IDProperty, IntegerProperty, ListProperty,
|
||||
ObjectReferenceProperty, ReferenceProperty, StringProperty,
|
||||
TimestampProperty, TypeProperty,
|
||||
)
|
||||
from .common import GranularMarking
|
||||
|
||||
|
||||
class Artifact(_Observable):
|
||||
|
@ -28,6 +33,7 @@ class Artifact(_Observable):
|
|||
_type = 'artifact'
|
||||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('mime_type', StringProperty()),
|
||||
('payload_bin', BinaryProperty()),
|
||||
('url', StringProperty()),
|
||||
|
@ -35,11 +41,16 @@ class Artifact(_Observable):
|
|||
('encryption_algorithm', StringProperty()),
|
||||
('decryption_key', StringProperty()),
|
||||
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
('defanged', BooleanProperty(default=lambda: False)),
|
||||
])
|
||||
_id_contributing_properties = ["hashes", "payload_bin"]
|
||||
|
||||
def _check_object_constraints(self):
|
||||
super(Artifact, self)._check_object_constraints()
|
||||
self._check_mutually_exclusive_properties(['payload_bin', 'url'])
|
||||
self._check_mutually_exclusive_properties(['payload_bin', 'url'], at_least_one=False)
|
||||
self._check_properties_dependency(['hashes'], ['url'])
|
||||
|
||||
|
||||
|
@ -52,11 +63,17 @@ class AutonomousSystem(_Observable):
|
|||
_type = 'autonomous-system'
|
||||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('number', IntegerProperty(required=True)),
|
||||
('name', StringProperty()),
|
||||
('rir', StringProperty()),
|
||||
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
('defanged', BooleanProperty(default=lambda: False)),
|
||||
])
|
||||
_id_contributing_properties = ["number"]
|
||||
|
||||
|
||||
class Directory(_Observable):
|
||||
|
@ -68,15 +85,21 @@ class Directory(_Observable):
|
|||
_type = 'directory'
|
||||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('path', StringProperty(required=True)),
|
||||
('path_enc', StringProperty()),
|
||||
# these are not the created/modified timestamps of the object itself
|
||||
('created', TimestampProperty()),
|
||||
('modified', TimestampProperty()),
|
||||
('accessed', TimestampProperty()),
|
||||
('contains_refs', ListProperty(ObjectReferenceProperty(valid_types=['file', 'directory']))),
|
||||
('ctime', TimestampProperty()),
|
||||
('mtime', TimestampProperty()),
|
||||
('atime', TimestampProperty()),
|
||||
('contains_refs', ListProperty(ReferenceProperty(valid_types=['file', 'directory'], spec_version='2.1'))),
|
||||
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
('defanged', BooleanProperty(default=lambda: False)),
|
||||
])
|
||||
_id_contributing_properties = ["path"]
|
||||
|
||||
|
||||
class DomainName(_Observable):
|
||||
|
@ -88,10 +111,24 @@ class DomainName(_Observable):
|
|||
_type = 'domain-name'
|
||||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('value', StringProperty(required=True)),
|
||||
('resolves_to_refs', ListProperty(ObjectReferenceProperty(valid_types=['ipv4-addr', 'ipv6-addr', 'domain-name']))),
|
||||
('resolves_to_refs', ListProperty(ReferenceProperty(valid_types=['ipv4-addr', 'ipv6-addr', 'domain-name'], spec_version='2.1'))),
|
||||
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
('defanged', BooleanProperty(default=lambda: False)),
|
||||
])
|
||||
_id_contributing_properties = ["value"]
|
||||
|
||||
def _check_object_constraints(self):
|
||||
if self.get('resolves_to_refs'):
|
||||
warnings.warn(
|
||||
"The 'resolves_to_refs' property of domain-name is deprecated in "
|
||||
"STIX 2.1. Use the 'resolves-to' relationship type instead",
|
||||
STIXDeprecationWarning,
|
||||
)
|
||||
|
||||
|
||||
class EmailAddress(_Observable):
|
||||
|
@ -103,11 +140,17 @@ class EmailAddress(_Observable):
|
|||
_type = 'email-addr'
|
||||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('value', StringProperty(required=True)),
|
||||
('display_name', StringProperty()),
|
||||
('belongs_to_ref', ObjectReferenceProperty(valid_types='user-account')),
|
||||
('belongs_to_ref', ReferenceProperty(valid_types='user-account', spec_version='2.1')),
|
||||
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
('defanged', BooleanProperty(default=lambda: False)),
|
||||
])
|
||||
_id_contributing_properties = ["value"]
|
||||
|
||||
|
||||
class EmailMIMEComponent(_STIXBase):
|
||||
|
@ -137,22 +180,29 @@ class EmailMessage(_Observable):
|
|||
_type = 'email-message'
|
||||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('is_multipart', BooleanProperty(required=True)),
|
||||
('date', TimestampProperty()),
|
||||
('content_type', StringProperty()),
|
||||
('from_ref', ObjectReferenceProperty(valid_types='email-addr')),
|
||||
('sender_ref', ObjectReferenceProperty(valid_types='email-addr')),
|
||||
('to_refs', ListProperty(ObjectReferenceProperty(valid_types='email-addr'))),
|
||||
('cc_refs', ListProperty(ObjectReferenceProperty(valid_types='email-addr'))),
|
||||
('bcc_refs', ListProperty(ObjectReferenceProperty(valid_types='email-addr'))),
|
||||
('from_ref', ReferenceProperty(valid_types='email-addr', spec_version='2.1')),
|
||||
('sender_ref', ReferenceProperty(valid_types='email-addr', spec_version='2.1')),
|
||||
('to_refs', ListProperty(ReferenceProperty(valid_types='email-addr', spec_version='2.1'))),
|
||||
('cc_refs', ListProperty(ReferenceProperty(valid_types='email-addr', spec_version='2.1'))),
|
||||
('bcc_refs', ListProperty(ReferenceProperty(valid_types='email-addr', spec_version='2.1'))),
|
||||
('message_id', StringProperty()),
|
||||
('subject', StringProperty()),
|
||||
('received_lines', ListProperty(StringProperty)),
|
||||
('additional_header_fields', DictionaryProperty(spec_version='2.1')),
|
||||
('body', StringProperty()),
|
||||
('body_multipart', ListProperty(EmbeddedObjectProperty(type=EmailMIMEComponent))),
|
||||
('raw_email_ref', ObjectReferenceProperty(valid_types='artifact')),
|
||||
('raw_email_ref', ReferenceProperty(valid_types='artifact', spec_version='2.1')),
|
||||
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
('defanged', BooleanProperty(default=lambda: False)),
|
||||
])
|
||||
_id_contributing_properties = ["from_ref", "subject", "body"]
|
||||
|
||||
def _check_object_constraints(self):
|
||||
super(EmailMessage, self)._check_object_constraints()
|
||||
|
@ -170,7 +220,7 @@ class ArchiveExt(_Extension):
|
|||
|
||||
_type = 'archive-ext'
|
||||
_properties = OrderedDict([
|
||||
('contains_refs', ListProperty(ObjectReferenceProperty(valid_types='file'), required=True)),
|
||||
('contains_refs', ListProperty(ObjectReferenceProperty(valid_types=['file', 'directory']), required=True)),
|
||||
('comment', StringProperty()),
|
||||
])
|
||||
|
||||
|
@ -323,6 +373,7 @@ class File(_Observable):
|
|||
_type = 'file'
|
||||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('hashes', HashesProperty(spec_version='2.1')),
|
||||
('size', IntegerProperty(min=0)),
|
||||
('name', StringProperty()),
|
||||
|
@ -330,14 +381,19 @@ class File(_Observable):
|
|||
('magic_number_hex', HexProperty()),
|
||||
('mime_type', StringProperty()),
|
||||
# these are not the created/modified timestamps of the object itself
|
||||
('created', TimestampProperty()),
|
||||
('modified', TimestampProperty()),
|
||||
('accessed', TimestampProperty()),
|
||||
('parent_directory_ref', ObjectReferenceProperty(valid_types='directory')),
|
||||
('contains_refs', ListProperty(ObjectReferenceProperty)),
|
||||
('content_ref', ObjectReferenceProperty(valid_types='artifact')),
|
||||
('ctime', TimestampProperty()),
|
||||
('mtime', TimestampProperty()),
|
||||
('atime', TimestampProperty()),
|
||||
('parent_directory_ref', ReferenceProperty(valid_types='directory', spec_version='2.1')),
|
||||
('contains_refs', ListProperty(ReferenceProperty(invalid_types="", spec_version='2.1'))),
|
||||
('content_ref', ReferenceProperty(valid_types='artifact', spec_version='2.1')),
|
||||
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
('defanged', BooleanProperty(default=lambda: False)),
|
||||
])
|
||||
_id_contributing_properties = ["hashes", "name", "extensions"]
|
||||
|
||||
def _check_object_constraints(self):
|
||||
super(File, self)._check_object_constraints()
|
||||
|
@ -353,11 +409,32 @@ class IPv4Address(_Observable):
|
|||
_type = 'ipv4-addr'
|
||||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('value', StringProperty(required=True)),
|
||||
('resolves_to_refs', ListProperty(ObjectReferenceProperty(valid_types='mac-addr'))),
|
||||
('belongs_to_refs', ListProperty(ObjectReferenceProperty(valid_types='autonomous-system'))),
|
||||
('resolves_to_refs', ListProperty(ReferenceProperty(valid_types='mac-addr', spec_version='2.1'))),
|
||||
('belongs_to_refs', ListProperty(ReferenceProperty(valid_types='autonomous-system', spec_version='2.1'))),
|
||||
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
('defanged', BooleanProperty(default=lambda: False)),
|
||||
])
|
||||
_id_contributing_properties = ["value"]
|
||||
|
||||
def _check_object_constraints(self):
|
||||
if self.get('resolves_to_refs'):
|
||||
warnings.warn(
|
||||
"The 'resolves_to_refs' property of ipv4-addr is deprecated in "
|
||||
"STIX 2.1. Use the 'resolves-to' relationship type instead",
|
||||
STIXDeprecationWarning,
|
||||
)
|
||||
|
||||
if self.get('belongs_to_refs'):
|
||||
warnings.warn(
|
||||
"The 'belongs_to_refs' property of ipv4-addr is deprecated in "
|
||||
"STIX 2.1. Use the 'belongs-to' relationship type instead",
|
||||
STIXDeprecationWarning,
|
||||
)
|
||||
|
||||
|
||||
class IPv6Address(_Observable):
|
||||
|
@ -369,11 +446,32 @@ class IPv6Address(_Observable):
|
|||
_type = 'ipv6-addr'
|
||||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('value', StringProperty(required=True)),
|
||||
('resolves_to_refs', ListProperty(ObjectReferenceProperty(valid_types='mac-addr'))),
|
||||
('belongs_to_refs', ListProperty(ObjectReferenceProperty(valid_types='autonomous-system'))),
|
||||
('resolves_to_refs', ListProperty(ReferenceProperty(valid_types='mac-addr', spec_version='2.1'))),
|
||||
('belongs_to_refs', ListProperty(ReferenceProperty(valid_types='autonomous-system', spec_version='2.1'))),
|
||||
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
('defanged', BooleanProperty(default=lambda: False)),
|
||||
])
|
||||
_id_contributing_properties = ["value"]
|
||||
|
||||
def _check_object_constraints(self):
|
||||
if self.get('resolves_to_refs'):
|
||||
warnings.warn(
|
||||
"The 'resolves_to_refs' property of ipv6-addr is deprecated in "
|
||||
"STIX 2.1. Use the 'resolves-to' relationship type instead",
|
||||
STIXDeprecationWarning,
|
||||
)
|
||||
|
||||
if self.get('belongs_to_refs'):
|
||||
warnings.warn(
|
||||
"The 'belongs_to_refs' property of ipv6-addr is deprecated in "
|
||||
"STIX 2.1. Use the 'belongs-to' relationship type instead",
|
||||
STIXDeprecationWarning,
|
||||
)
|
||||
|
||||
|
||||
class MACAddress(_Observable):
|
||||
|
@ -385,9 +483,15 @@ class MACAddress(_Observable):
|
|||
_type = 'mac-addr'
|
||||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('value', StringProperty(required=True)),
|
||||
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
('defanged', BooleanProperty(default=lambda: False)),
|
||||
])
|
||||
_id_contributing_properties = ["value"]
|
||||
|
||||
|
||||
class Mutex(_Observable):
|
||||
|
@ -399,9 +503,15 @@ class Mutex(_Observable):
|
|||
_type = 'mutex'
|
||||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('name', StringProperty(required=True)),
|
||||
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
('defanged', BooleanProperty(default=lambda: False)),
|
||||
])
|
||||
_id_contributing_properties = ["name"]
|
||||
|
||||
|
||||
class HTTPRequestExt(_Extension):
|
||||
|
@ -505,11 +615,12 @@ class NetworkTraffic(_Observable):
|
|||
_type = 'network-traffic'
|
||||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('start', TimestampProperty()),
|
||||
('end', TimestampProperty()),
|
||||
('is_active', BooleanProperty()),
|
||||
('src_ref', ObjectReferenceProperty(valid_types=['ipv4-addr', 'ipv6-addr', 'mac-addr', 'domain-name'])),
|
||||
('dst_ref', ObjectReferenceProperty(valid_types=['ipv4-addr', 'ipv6-addr', 'mac-addr', 'domain-name'])),
|
||||
('src_ref', ReferenceProperty(valid_types=['ipv4-addr', 'ipv6-addr', 'mac-addr', 'domain-name'], spec_version='2.1')),
|
||||
('dst_ref', ReferenceProperty(valid_types=['ipv4-addr', 'ipv6-addr', 'mac-addr', 'domain-name'], spec_version='2.1')),
|
||||
('src_port', IntegerProperty(min=0, max=65535)),
|
||||
('dst_port', IntegerProperty(min=0, max=65535)),
|
||||
('protocols', ListProperty(StringProperty, required=True)),
|
||||
|
@ -518,12 +629,17 @@ class NetworkTraffic(_Observable):
|
|||
('src_packets', IntegerProperty(min=0)),
|
||||
('dst_packets', IntegerProperty(min=0)),
|
||||
('ipfix', DictionaryProperty(spec_version='2.1')),
|
||||
('src_payload_ref', ObjectReferenceProperty(valid_types='artifact')),
|
||||
('dst_payload_ref', ObjectReferenceProperty(valid_types='artifact')),
|
||||
('encapsulates_refs', ListProperty(ObjectReferenceProperty(valid_types='network-traffic'))),
|
||||
('encapsulates_by_ref', ObjectReferenceProperty(valid_types='network-traffic')),
|
||||
('src_payload_ref', ReferenceProperty(valid_types='artifact', spec_version='2.1')),
|
||||
('dst_payload_ref', ReferenceProperty(valid_types='artifact', spec_version='2.1')),
|
||||
('encapsulates_refs', ListProperty(ReferenceProperty(valid_types='network-traffic', spec_version='2.1'))),
|
||||
('encapsulated_by_ref', ReferenceProperty(valid_types='network-traffic', spec_version='2.1')),
|
||||
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
('defanged', BooleanProperty(default=lambda: False)),
|
||||
])
|
||||
_id_contributing_properties = ["start", "src_ref", "dst_ref", "src_port", "dst_port", "protocols"]
|
||||
|
||||
def _check_object_constraints(self):
|
||||
super(NetworkTraffic, self)._check_object_constraints()
|
||||
|
@ -624,20 +740,26 @@ class Process(_Observable):
|
|||
_type = 'process'
|
||||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('is_hidden', BooleanProperty()),
|
||||
('pid', IntegerProperty()),
|
||||
# this is not the created timestamps of the object itself
|
||||
('created', TimestampProperty()),
|
||||
('created_time', TimestampProperty()),
|
||||
('cwd', StringProperty()),
|
||||
('command_line', StringProperty()),
|
||||
('environment_variables', DictionaryProperty(spec_version='2.1')),
|
||||
('opened_connection_refs', ListProperty(ObjectReferenceProperty(valid_types='network-traffic'))),
|
||||
('creator_user_ref', ObjectReferenceProperty(valid_types='user-account')),
|
||||
('image_ref', ObjectReferenceProperty(valid_types='file')),
|
||||
('parent_ref', ObjectReferenceProperty(valid_types='process')),
|
||||
('child_refs', ListProperty(ObjectReferenceProperty('process'))),
|
||||
('opened_connection_refs', ListProperty(ReferenceProperty(valid_types='network-traffic', spec_version='2.1'))),
|
||||
('creator_user_ref', ReferenceProperty(valid_types='user-account', spec_version='2.1')),
|
||||
('image_ref', ReferenceProperty(valid_types='file', spec_version='2.1')),
|
||||
('parent_ref', ReferenceProperty(valid_types='process', spec_version='2.1')),
|
||||
('child_refs', ListProperty(ReferenceProperty(valid_types='process', spec_version='2.1'))),
|
||||
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
('defanged', BooleanProperty(default=lambda: False)),
|
||||
])
|
||||
_id_contributing_properties = []
|
||||
|
||||
def _check_object_constraints(self):
|
||||
# no need to check windows-service-ext, since it has a required property
|
||||
|
@ -663,13 +785,19 @@ class Software(_Observable):
|
|||
_type = 'software'
|
||||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('name', StringProperty(required=True)),
|
||||
('cpe', StringProperty()),
|
||||
('languages', ListProperty(StringProperty)),
|
||||
('vendor', StringProperty()),
|
||||
('version', StringProperty()),
|
||||
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
('defanged', BooleanProperty(default=lambda: False)),
|
||||
])
|
||||
_id_contributing_properties = ["name", "cpe", "vendor", "version"]
|
||||
|
||||
|
||||
class URL(_Observable):
|
||||
|
@ -681,9 +809,15 @@ class URL(_Observable):
|
|||
_type = 'url'
|
||||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('value', StringProperty(required=True)),
|
||||
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
('defanged', BooleanProperty(default=lambda: False)),
|
||||
])
|
||||
_id_contributing_properties = ["value"]
|
||||
|
||||
|
||||
class UNIXAccountExt(_Extension):
|
||||
|
@ -710,6 +844,7 @@ class UserAccount(_Observable):
|
|||
_type = 'user-account'
|
||||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('user_id', StringProperty()),
|
||||
('credential', StringProperty()),
|
||||
('account_login', StringProperty()),
|
||||
|
@ -725,7 +860,12 @@ class UserAccount(_Observable):
|
|||
('account_first_login', TimestampProperty()),
|
||||
('account_last_login', TimestampProperty()),
|
||||
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
('defanged', BooleanProperty(default=lambda: False)),
|
||||
])
|
||||
_id_contributing_properties = ["account_type", "user_id", "account_login"]
|
||||
|
||||
|
||||
class WindowsRegistryValueType(_STIXBase):
|
||||
|
@ -767,14 +907,20 @@ class WindowsRegistryKey(_Observable):
|
|||
_type = 'windows-registry-key'
|
||||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('key', StringProperty()),
|
||||
('values', ListProperty(EmbeddedObjectProperty(type=WindowsRegistryValueType))),
|
||||
# this is not the modified timestamps of the object itself
|
||||
('modified', TimestampProperty()),
|
||||
('creator_user_ref', ObjectReferenceProperty(valid_types='user-account')),
|
||||
('modified_time', TimestampProperty()),
|
||||
('creator_user_ref', ReferenceProperty(valid_types='user-account', spec_version='2.1')),
|
||||
('number_of_subkeys', IntegerProperty()),
|
||||
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
('defanged', BooleanProperty(default=lambda: False)),
|
||||
])
|
||||
_id_contributing_properties = ["key", "values"]
|
||||
|
||||
@property
|
||||
def values(self):
|
||||
|
@ -818,6 +964,7 @@ class X509Certificate(_Observable):
|
|||
_type = 'x509-certificate'
|
||||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('is_self_signed', BooleanProperty()),
|
||||
('hashes', HashesProperty(spec_version='2.1')),
|
||||
('version', StringProperty()),
|
||||
|
@ -832,7 +979,12 @@ class X509Certificate(_Observable):
|
|||
('subject_public_key_exponent', IntegerProperty()),
|
||||
('x509_v3_extensions', EmbeddedObjectProperty(type=X509V3ExtenstionsType)),
|
||||
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
('defanged', BooleanProperty(default=lambda: False)),
|
||||
])
|
||||
_id_contributing_properties = ["hashes", "serial_number"]
|
||||
|
||||
|
||||
def CustomObservable(type='x-custom-observable', properties=None):
|
||||
|
|
|
@ -30,7 +30,7 @@ class AttackPattern(STIXDomainObject):
|
|||
('type', TypeProperty(_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('name', StringProperty(required=True)),
|
||||
|
@ -42,7 +42,7 @@ class AttackPattern(STIXDomainObject):
|
|||
('confidence', IntegerProperty()),
|
||||
('lang', StringProperty()),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.1'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -58,7 +58,7 @@ class Campaign(STIXDomainObject):
|
|||
('type', TypeProperty(_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('name', StringProperty(required=True)),
|
||||
|
@ -72,7 +72,7 @@ class Campaign(STIXDomainObject):
|
|||
('confidence', IntegerProperty()),
|
||||
('lang', StringProperty()),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.1'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -98,7 +98,7 @@ class CourseOfAction(STIXDomainObject):
|
|||
('type', TypeProperty(_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('name', StringProperty(required=True)),
|
||||
|
@ -112,7 +112,7 @@ class CourseOfAction(STIXDomainObject):
|
|||
('confidence', IntegerProperty()),
|
||||
('lang', StringProperty()),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.1'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -138,18 +138,18 @@ class Grouping(STIXDomainObject):
|
|||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', 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(type='marking-definition', spec_version='2.1'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
('name', StringProperty()),
|
||||
('description', StringProperty()),
|
||||
('context', StringProperty(required=True)),
|
||||
('object_refs', ListProperty(ReferenceProperty, required=True)),
|
||||
('object_refs', ListProperty(ReferenceProperty(invalid_types=[""], spec_version='2.1'), required=True)),
|
||||
])
|
||||
|
||||
|
||||
|
@ -164,7 +164,7 @@ class Identity(STIXDomainObject):
|
|||
('type', TypeProperty(_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('name', StringProperty(required=True)),
|
||||
|
@ -178,7 +178,7 @@ class Identity(STIXDomainObject):
|
|||
('confidence', IntegerProperty()),
|
||||
('lang', StringProperty()),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.1'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -194,7 +194,7 @@ class Indicator(STIXDomainObject):
|
|||
('type', TypeProperty(_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('name', StringProperty()),
|
||||
|
@ -211,7 +211,7 @@ class Indicator(STIXDomainObject):
|
|||
('confidence', IntegerProperty()),
|
||||
('lang', StringProperty()),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.1'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -237,7 +237,7 @@ class Infrastructure(STIXDomainObject):
|
|||
('type', TypeProperty(_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('revoked', BooleanProperty(default=lambda: False)),
|
||||
|
@ -245,7 +245,7 @@ class Infrastructure(STIXDomainObject):
|
|||
('confidence', IntegerProperty()),
|
||||
('lang', StringProperty()),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.1'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
('name', StringProperty(required=True)),
|
||||
('description', StringProperty()),
|
||||
|
@ -278,7 +278,7 @@ class IntrusionSet(STIXDomainObject):
|
|||
('type', TypeProperty(_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('name', StringProperty(required=True)),
|
||||
|
@ -295,7 +295,7 @@ class IntrusionSet(STIXDomainObject):
|
|||
('confidence', IntegerProperty()),
|
||||
('lang', StringProperty()),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.1'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -321,7 +321,7 @@ class Location(STIXDomainObject):
|
|||
('type', TypeProperty(_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('name', StringProperty()),
|
||||
|
@ -340,7 +340,7 @@ class Location(STIXDomainObject):
|
|||
('confidence', IntegerProperty()),
|
||||
('lang', StringProperty()),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.1'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -429,7 +429,7 @@ class Malware(STIXDomainObject):
|
|||
('type', TypeProperty(_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('name', StringProperty()),
|
||||
|
@ -444,13 +444,13 @@ class Malware(STIXDomainObject):
|
|||
('architecture_execution_envs', ListProperty(StringProperty)),
|
||||
('implementation_languages', ListProperty(StringProperty)),
|
||||
('capabilities', ListProperty(StringProperty)),
|
||||
('sample_refs', ListProperty(ReferenceProperty(spec_version='2.1'))),
|
||||
('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(type='marking-definition', spec_version='2.1'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -484,19 +484,19 @@ class MalwareAnalysis(STIXDomainObject):
|
|||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', 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(type='marking-definition', spec_version='2.1'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
('product', StringProperty(required=True)),
|
||||
('version', StringProperty()),
|
||||
('host_vm_ref', ReferenceProperty(type='software', spec_version='2.1')),
|
||||
('operating_system_ref', ReferenceProperty(type='software', spec_version='2.1')),
|
||||
('installed_software_refs', ListProperty(ReferenceProperty(type='software', spec_version='2.1'))),
|
||||
('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'))),
|
||||
('configuration_version', StringProperty()),
|
||||
('modules', ListProperty(StringProperty)),
|
||||
('analysis_engine_version', StringProperty()),
|
||||
|
@ -505,7 +505,7 @@ class MalwareAnalysis(STIXDomainObject):
|
|||
('analysis_started', TimestampProperty()),
|
||||
('analysis_ended', TimestampProperty()),
|
||||
('av_result', StringProperty()),
|
||||
('analysis_sco_refs', ListProperty(ReferenceProperty(spec_version='2.1'))),
|
||||
('analysis_sco_refs', ListProperty(ReferenceProperty(valid_types="only_SCO", spec_version='2.1'))),
|
||||
])
|
||||
|
||||
def _check_object_constraints(self):
|
||||
|
@ -525,19 +525,19 @@ class Note(STIXDomainObject):
|
|||
('type', TypeProperty(_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('abstract', StringProperty()),
|
||||
('content', StringProperty(required=True)),
|
||||
('authors', ListProperty(StringProperty)),
|
||||
('object_refs', ListProperty(ReferenceProperty, required=True)),
|
||||
('object_refs', ListProperty(ReferenceProperty(invalid_types=[""], 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(type='marking-definition', spec_version='2.1'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -553,20 +553,20 @@ class ObservedData(STIXDomainObject):
|
|||
('type', TypeProperty(_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
|
||||
('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(min=1, max=999999999, required=True)),
|
||||
('objects', ObservableProperty(spec_version='2.1')),
|
||||
('object_refs', ListProperty(ReferenceProperty(spec_version="2.1"))),
|
||||
('object_refs', ListProperty(ReferenceProperty(valid_types="only_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(type='marking-definition', spec_version='2.1'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -609,7 +609,7 @@ class Opinion(STIXDomainObject):
|
|||
('type', TypeProperty(_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('explanation', StringProperty()),
|
||||
|
@ -625,13 +625,13 @@ class Opinion(STIXDomainObject):
|
|||
], required=True,
|
||||
),
|
||||
),
|
||||
('object_refs', ListProperty(ReferenceProperty, required=True)),
|
||||
('object_refs', ListProperty(ReferenceProperty(invalid_types=[""], 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(type='marking-definition', spec_version='2.1'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -647,20 +647,20 @@ class Report(STIXDomainObject):
|
|||
('type', TypeProperty(_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('name', StringProperty(required=True)),
|
||||
('description', StringProperty()),
|
||||
('report_types', ListProperty(StringProperty, required=True)),
|
||||
('published', TimestampProperty(required=True)),
|
||||
('object_refs', ListProperty(ReferenceProperty, required=True)),
|
||||
('object_refs', ListProperty(ReferenceProperty(invalid_types=[""], 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(type='marking-definition', spec_version='2.1'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -676,7 +676,7 @@ class ThreatActor(STIXDomainObject):
|
|||
('type', TypeProperty(_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('name', StringProperty(required=True)),
|
||||
|
@ -697,7 +697,7 @@ class ThreatActor(STIXDomainObject):
|
|||
('confidence', IntegerProperty()),
|
||||
('lang', StringProperty()),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.1'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -723,7 +723,7 @@ class Tool(STIXDomainObject):
|
|||
('type', TypeProperty(_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('name', StringProperty(required=True)),
|
||||
|
@ -737,7 +737,7 @@ class Tool(STIXDomainObject):
|
|||
('confidence', IntegerProperty()),
|
||||
('lang', StringProperty()),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.1'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -753,7 +753,7 @@ class Vulnerability(STIXDomainObject):
|
|||
('type', TypeProperty(_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('name', StringProperty(required=True)),
|
||||
|
@ -763,7 +763,7 @@ class Vulnerability(STIXDomainObject):
|
|||
('confidence', IntegerProperty()),
|
||||
('lang', StringProperty()),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.1'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -803,7 +803,7 @@ def CustomObject(type='x-custom-type', properties=None):
|
|||
('type', TypeProperty(type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('id', IDProperty(type, spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
],
|
||||
|
@ -814,7 +814,7 @@ def CustomObject(type='x-custom-type', properties=None):
|
|||
('confidence', IntegerProperty()),
|
||||
('lang', StringProperty()),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.1'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
],
|
||||
sorted([x for x in properties if x[0].startswith('x_')], key=lambda x: x[0]),
|
||||
|
|
|
@ -17,18 +17,20 @@ class Relationship(STIXRelationshipObject):
|
|||
`the STIX 2.1 specification <link here>`__.
|
||||
"""
|
||||
|
||||
_invalid_source_target_types = ['bundle', 'language-content', 'marking-definition', 'relationship', 'sighting']
|
||||
|
||||
_type = 'relationship'
|
||||
_properties = OrderedDict([
|
||||
('type', TypeProperty(_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('relationship_type', StringProperty(required=True)),
|
||||
('description', StringProperty()),
|
||||
('source_ref', ReferenceProperty(spec_version='2.1', required=True)),
|
||||
('target_ref', ReferenceProperty(spec_version='2.1', required=True)),
|
||||
('source_ref', ReferenceProperty(invalid_types=_invalid_source_target_types, spec_version='2.1', required=True)),
|
||||
('target_ref', ReferenceProperty(invalid_types=_invalid_source_target_types, spec_version='2.1', required=True)),
|
||||
('start_time', TimestampProperty()),
|
||||
('stop_time', TimestampProperty()),
|
||||
('revoked', BooleanProperty(default=lambda: False)),
|
||||
|
@ -36,7 +38,7 @@ class Relationship(STIXRelationshipObject):
|
|||
('confidence', IntegerProperty()),
|
||||
('lang', StringProperty()),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.1'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
@ -77,23 +79,23 @@ class Sighting(STIXRelationshipObject):
|
|||
('type', TypeProperty(_type)),
|
||||
('spec_version', StringProperty(fixed='2.1')),
|
||||
('id', IDProperty(_type, spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(type='identity', spec_version='2.1')),
|
||||
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
|
||||
('created', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')),
|
||||
('description', StringProperty()),
|
||||
('first_seen', TimestampProperty()),
|
||||
('last_seen', TimestampProperty()),
|
||||
('count', IntegerProperty(min=0, max=999999999)),
|
||||
('sighting_of_ref', ReferenceProperty(spec_version='2.1', required=True)),
|
||||
('observed_data_refs', ListProperty(ReferenceProperty(type='observed-data', spec_version='2.1'))),
|
||||
('where_sighted_refs', ListProperty(ReferenceProperty(type='identity', spec_version='2.1'))),
|
||||
('sighting_of_ref', ReferenceProperty(valid_types="only_SDO", spec_version='2.1', required=True)),
|
||||
('observed_data_refs', ListProperty(ReferenceProperty(valid_types='observed-data', spec_version='2.1'))),
|
||||
('where_sighted_refs', ListProperty(ReferenceProperty(valid_types='identity', spec_version='2.1'))),
|
||||
('summary', BooleanProperty()),
|
||||
('revoked', BooleanProperty(default=lambda: False)),
|
||||
('labels', ListProperty(StringProperty)),
|
||||
('confidence', IntegerProperty()),
|
||||
('lang', StringProperty()),
|
||||
('external_references', ListProperty(ExternalReference)),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.1'))),
|
||||
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
|
||||
('granular_markings', ListProperty(GranularMarking)),
|
||||
])
|
||||
|
||||
|
|
Loading…
Reference in New Issue