Merge pull request #468 from oasis-open/dev-extensions-proposal

Extensions Support
pull/1/head
Rich Piazza 2021-07-07 16:10:01 -04:00 committed by GitHub
commit 3ce193aca6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
92 changed files with 2874 additions and 1028 deletions

View File

@ -39,7 +39,7 @@ be set automatically if not provided as keyword arguments.
pattern_type="stix",
pattern="[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']")
To parse a STIX JSON string into a Python STIX object, use ``parse()``:
To parse a STIX JSON string into a Python STIX object, use ``parse()``. To serialize a STIX object, use ``serialize()``:
.. code-block:: python
@ -61,15 +61,15 @@ To parse a STIX JSON string into a Python STIX object, use ``parse()``:
"valid_from": "2017-09-26T23:33:39.829952Z"
}""")
print(indicator)
print(indicator.serialize(pretty=True))
For more in-depth documentation, please see `https://stix2.readthedocs.io/ <https://stix2.readthedocs.io/>`__.
STIX 2 Technical Specification Support
--------------------------------------
This version of cti-python-stix2 brings support to `STIX Version 2.1 <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html>`__
published on 20 March 2020 currently at the Committee Specification (CS) level.
This version of cti-python-stix2 brings support to `STIX Version 2.1 <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html>`__
published on 25 January 2021 currently at the Committee Specification (CS) 02 level.
The stix2 Python library supports multiple versions of the STIX 2 Technical
Specification. The library will be updated to support new Committee

View File

@ -27,7 +27,7 @@ the repository on GitHub and clone your fork instead of the main repo:
git clone https://github.com/yourusername/cti-python-stix2.git
2. Install develoment-related dependencies:
2. Install development-related dependencies:
.. prompt:: bash
@ -107,7 +107,7 @@ run:
then look at the resulting report in ``htmlcov/index.html``.
All commits pushed to the ``master`` branch or submitted as a pull request are
tested with `Travis-CI <https://travis-ci.org/oasis-open/cti-python-stix2>`_
tested with `GitHub Actions <https://github.com/oasis-open/cti-python-stix2/actions>`_
automatically.
Adding a dependency

View File

@ -173,7 +173,7 @@
"indicator = Indicator(name=\"File hash for malware variant\",\n",
" pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\",\n",
" pattern_type=\"stix\")\n",
"print(indicator)"
"print(indicator.serialize(pretty=True))"
]
},
{
@ -503,7 +503,7 @@
"\n",
"malware = Malware(name=\"Poison Ivy\",\n",
" is_family=False)\n",
"print(malware)"
"print(malware.serialize(pretty=True))"
]
},
{
@ -627,7 +627,7 @@
"relationship = Relationship(relationship_type='indicates',\n",
" source_ref=indicator.id,\n",
" target_ref=malware.id)\n",
"print(relationship)"
"print(relationship.serialize(pretty=True))"
]
},
{
@ -736,7 +736,7 @@
],
"source": [
"relationship2 = Relationship(indicator, 'indicates', malware)\n",
"print(relationship2)"
"print(relationship2.serialize(pretty=True))"
]
},
{
@ -876,7 +876,7 @@
"from stix2 import Bundle\n",
"\n",
"bundle = Bundle(indicator, malware, relationship)\n",
"print(bundle)"
"print(bundle.serialize(pretty=True))"
]
},
{
@ -993,7 +993,7 @@
" resolves_to_refs=[\"mac-addr--43f380fd-37c6-476d-8643-60849bf9240e\"]\n",
")\n",
"\n",
"print(ip4)"
"print(ip4.serialize(pretty=True))"
]
},
{
@ -1111,7 +1111,7 @@
" resolves_to_refs=[mac_addr_a.id, mac_addr_b.id]\n",
")\n",
"\n",
"print(ip4_valid_refs)"
"print(ip4_valid_refs.serialize(pretty=True))"
]
}
],

View File

@ -201,7 +201,7 @@
" custom_properties={\n",
" \"x_foo\": \"bar\"\n",
" })\n",
"print(identity)"
"print(identity.serialize(pretty=True))"
]
},
{
@ -313,7 +313,7 @@
" identity_class=\"individual\",\n",
" x_foo=\"bar\",\n",
" allow_custom=True)\n",
"print(identity2)"
"print(identity2.serialize(pretty=True))"
]
},
{
@ -533,7 +533,7 @@
],
"source": [
"identity4 = identity3.new_version(x_foo=None)\n",
"print(identity4)"
"print(identity4.serialize(pretty=True))"
]
},
{
@ -671,7 +671,7 @@
"source": [
"animal = Animal(species=\"lion\",\n",
" animal_class=\"mammal\")\n",
"print(animal)"
"print(animal.serialize(pretty=True))"
]
},
{
@ -956,7 +956,7 @@
"\n",
"new_observable = NewObservable(a_property=\"something\",\n",
" property_2=10)\n",
"print(new_observable)"
"print(new_observable.serialize(pretty=True))"
]
},
{
@ -1458,13 +1458,13 @@
" pass\n",
"\n",
"new_observable_a = NewObservable2(a_property=\"A property\", property_2=2000)\n",
"print(new_observable_a)\n",
"print(new_observable_a.serialize(pretty=True))\n",
"\n",
"new_observable_b = NewObservable2(a_property=\"A property\", property_2=3000)\n",
"print(new_observable_b)\n",
"print(new_observable_b.serialize(pretty=True))\n",
"\n",
"new_observable_c = NewObservable2(a_property=\"A different property\", property_2=3000)\n",
"print(new_observable_c)"
"print(new_observable_c.serialize(pretty=True))"
]
},
{
@ -1588,7 +1588,7 @@
"\n",
"new_ext = NewExtension(property1=\"something\",\n",
" property2=10)\n",
"print(new_ext)"
"print(new_ext.serialize(pretty=True))"
]
},
{

View File

@ -332,11 +332,11 @@
"\n",
"# get an object that is only in the filesystem\n",
"intrusion_set = cs.get('intrusion-set--f3bdec95-3d62-42d9-a840-29630f6cdc1a')\n",
"print(intrusion_set)\n",
"print(intrusion_set.serialize(pretty=True))\n",
"\n",
"# get an object that is only in the TAXII collection\n",
"ind = cs.get('indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7')\n",
"print(ind)"
"print(ind.serialize(pretty=True))"
]
},
{
@ -593,7 +593,7 @@
}
],
"source": [
"print(mem.creator_of(mal))"
"print(mem.creator_of(mal).serialize(pretty=True))"
]
},
{

View File

@ -225,7 +225,7 @@
}
],
"source": [
"print(env.get(\"indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7\"))"
"print(env.get(\"indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7\").serialize(pretty=True))"
]
},
{
@ -360,7 +360,7 @@
"ind = factory.create(Indicator,\n",
" pattern_type=\"stix\",\n",
" pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\")\n",
"print(ind)"
"print(ind.serialize(pretty=True))"
]
},
{
@ -486,7 +486,7 @@
" created_by_ref=None,\n",
" pattern_type=\"stix\",\n",
" pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\")\n",
"print(ind2)"
"print(ind2.serialize(pretty=True))"
]
},
{
@ -593,7 +593,7 @@
" created_by_ref=\"identity--962cabe5-f7f3-438a-9169-585a8c971d12\",\n",
" pattern_type=\"stix\",\n",
" pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\")\n",
"print(ind3)"
"print(ind3.serialize(pretty=True))"
]
},
{
@ -712,7 +712,7 @@
" pattern_type=\"stix\",\n",
" pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\")\n",
"environ.add(i)\n",
"print(environ.get(i.id))"
"print(environ.get(i.id).serialize(pretty=True))"
]
}
],

930
docs/guide/extensions.ipynb Normal file
View File

@ -0,0 +1,930 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"nbsphinx": "hidden"
},
"outputs": [],
"source": [
"# Delete this cell to re-enable tracebacks\n",
"import sys\n",
"ipython = get_ipython()\n",
"\n",
"def hide_traceback(exc_tuple=None, filename=None, tb_offset=None,\n",
" exception_only=False, running_compiled_code=False):\n",
" etype, value, tb = sys.exc_info()\n",
" value.__cause__ = None # suppress chained exceptions\n",
" return ipython._showtraceback(etype, value, ipython.InteractiveTB.get_exception_only(etype, value))\n",
"\n",
"ipython.showtraceback = hide_traceback"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"nbsphinx": "hidden"
},
"outputs": [],
"source": [
"# JSON output syntax highlighting\n",
"from __future__ import print_function\n",
"from pygments import highlight\n",
"from pygments.lexers import JsonLexer, TextLexer\n",
"from pygments.formatters import HtmlFormatter\n",
"from IPython.display import display, HTML\n",
"from IPython.core.interactiveshell import InteractiveShell\n",
"\n",
"InteractiveShell.ast_node_interactivity = \"all\"\n",
"\n",
"def json_print(inpt):\n",
" string = str(inpt)\n",
" formatter = HtmlFormatter()\n",
" if string[0] == '{':\n",
" lexer = JsonLexer()\n",
" else:\n",
" lexer = TextLexer()\n",
" return HTML('<style type=\"text/css\">{}</style>{}'.format(\n",
" formatter.get_style_defs('.highlight'),\n",
" highlight(string, lexer, formatter)))\n",
"\n",
"globals()['print'] = json_print"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## STIX Extensions\n",
"\n",
"This page is specific for the STIX Extensions mechanism defined in STIX 2.1 CS 02. For the deprecated STIX Customization mechanisms see the [Custom](custom.ipynb) section.\n",
"\n",
"### Top Level Property Extensions\n",
"\n",
"The example below shows how to create an `indicator` object with a `top-level-property-extension`. "
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">pre { line-height: 125%; margin: 0; }\n",
"td.linenos pre { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }\n",
"span.linenos { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }\n",
"td.linenos pre.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }\n",
"span.linenos.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }\n",
".highlight .hll { background-color: #ffffcc }\n",
".highlight { background: #f8f8f8; }\n",
".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
".highlight .k { color: #008000; font-weight: bold } /* Keyword */\n",
".highlight .o { color: #666666 } /* Operator */\n",
".highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n",
".highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n",
".highlight .cp { color: #BC7A00 } /* Comment.Preproc */\n",
".highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n",
".highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */\n",
".highlight .cs { color: #408080; font-style: italic } /* Comment.Special */\n",
".highlight .gd { color: #A00000 } /* Generic.Deleted */\n",
".highlight .ge { font-style: italic } /* Generic.Emph */\n",
".highlight .gr { color: #FF0000 } /* Generic.Error */\n",
".highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n",
".highlight .gi { color: #00A000 } /* Generic.Inserted */\n",
".highlight .go { color: #888888 } /* Generic.Output */\n",
".highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n",
".highlight .gs { font-weight: bold } /* Generic.Strong */\n",
".highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n",
".highlight .gt { color: #0044DD } /* Generic.Traceback */\n",
".highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n",
".highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n",
".highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n",
".highlight .kp { color: #008000 } /* Keyword.Pseudo */\n",
".highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n",
".highlight .kt { color: #B00040 } /* Keyword.Type */\n",
".highlight .m { color: #666666 } /* Literal.Number */\n",
".highlight .s { color: #BA2121 } /* Literal.String */\n",
".highlight .na { color: #7D9029 } /* Name.Attribute */\n",
".highlight .nb { color: #008000 } /* Name.Builtin */\n",
".highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n",
".highlight .no { color: #880000 } /* Name.Constant */\n",
".highlight .nd { color: #AA22FF } /* Name.Decorator */\n",
".highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */\n",
".highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n",
".highlight .nf { color: #0000FF } /* Name.Function */\n",
".highlight .nl { color: #A0A000 } /* Name.Label */\n",
".highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n",
".highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */\n",
".highlight .nv { color: #19177C } /* Name.Variable */\n",
".highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n",
".highlight .w { color: #bbbbbb } /* Text.Whitespace */\n",
".highlight .mb { color: #666666 } /* Literal.Number.Bin */\n",
".highlight .mf { color: #666666 } /* Literal.Number.Float */\n",
".highlight .mh { color: #666666 } /* Literal.Number.Hex */\n",
".highlight .mi { color: #666666 } /* Literal.Number.Integer */\n",
".highlight .mo { color: #666666 } /* Literal.Number.Oct */\n",
".highlight .sa { color: #BA2121 } /* Literal.String.Affix */\n",
".highlight .sb { color: #BA2121 } /* Literal.String.Backtick */\n",
".highlight .sc { color: #BA2121 } /* Literal.String.Char */\n",
".highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */\n",
".highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n",
".highlight .s2 { color: #BA2121 } /* Literal.String.Double */\n",
".highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n",
".highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */\n",
".highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n",
".highlight .sx { color: #008000 } /* Literal.String.Other */\n",
".highlight .sr { color: #BB6688 } /* Literal.String.Regex */\n",
".highlight .s1 { color: #BA2121 } /* Literal.String.Single */\n",
".highlight .ss { color: #19177C } /* Literal.String.Symbol */\n",
".highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */\n",
".highlight .fm { color: #0000FF } /* Name.Function.Magic */\n",
".highlight .vc { color: #19177C } /* Name.Variable.Class */\n",
".highlight .vg { color: #19177C } /* Name.Variable.Global */\n",
".highlight .vi { color: #19177C } /* Name.Variable.Instance */\n",
".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;extension-definition&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;spec_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;extension-definition--dd73de4f-a7f3-49ea-8ec1-8e884196b7a8&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created_by_ref&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;identity--11b76a96-5d2b-45e0-8a5a-f6994f370731&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2014-02-20T09:16:08.000Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2014-02-20T09:16:08.000Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;New SDO 1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;description&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;This schema adds two properties to a STIX object at the toplevel&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;schema&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;https://www.example.com/schema-foo-1a/v1/&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;1.2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;extension_types&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n",
" <span class=\"s2\">&quot;toplevel-property-extension&quot;</span>\n",
" <span class=\"p\">],</span>\n",
" <span class=\"nt\">&quot;extension_properties&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n",
" <span class=\"s2\">&quot;toxicity&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"s2\">&quot;rank&quot;</span>\n",
" <span class=\"p\">]</span>\n",
"<span class=\"p\">}</span>\n",
"</pre></div>\n"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">pre { line-height: 125%; margin: 0; }\n",
"td.linenos pre { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }\n",
"span.linenos { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }\n",
"td.linenos pre.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }\n",
"span.linenos.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }\n",
".highlight .hll { background-color: #ffffcc }\n",
".highlight { background: #f8f8f8; }\n",
".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
".highlight .k { color: #008000; font-weight: bold } /* Keyword */\n",
".highlight .o { color: #666666 } /* Operator */\n",
".highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n",
".highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n",
".highlight .cp { color: #BC7A00 } /* Comment.Preproc */\n",
".highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n",
".highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */\n",
".highlight .cs { color: #408080; font-style: italic } /* Comment.Special */\n",
".highlight .gd { color: #A00000 } /* Generic.Deleted */\n",
".highlight .ge { font-style: italic } /* Generic.Emph */\n",
".highlight .gr { color: #FF0000 } /* Generic.Error */\n",
".highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n",
".highlight .gi { color: #00A000 } /* Generic.Inserted */\n",
".highlight .go { color: #888888 } /* Generic.Output */\n",
".highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n",
".highlight .gs { font-weight: bold } /* Generic.Strong */\n",
".highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n",
".highlight .gt { color: #0044DD } /* Generic.Traceback */\n",
".highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n",
".highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n",
".highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n",
".highlight .kp { color: #008000 } /* Keyword.Pseudo */\n",
".highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n",
".highlight .kt { color: #B00040 } /* Keyword.Type */\n",
".highlight .m { color: #666666 } /* Literal.Number */\n",
".highlight .s { color: #BA2121 } /* Literal.String */\n",
".highlight .na { color: #7D9029 } /* Name.Attribute */\n",
".highlight .nb { color: #008000 } /* Name.Builtin */\n",
".highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n",
".highlight .no { color: #880000 } /* Name.Constant */\n",
".highlight .nd { color: #AA22FF } /* Name.Decorator */\n",
".highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */\n",
".highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n",
".highlight .nf { color: #0000FF } /* Name.Function */\n",
".highlight .nl { color: #A0A000 } /* Name.Label */\n",
".highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n",
".highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */\n",
".highlight .nv { color: #19177C } /* Name.Variable */\n",
".highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n",
".highlight .w { color: #bbbbbb } /* Text.Whitespace */\n",
".highlight .mb { color: #666666 } /* Literal.Number.Bin */\n",
".highlight .mf { color: #666666 } /* Literal.Number.Float */\n",
".highlight .mh { color: #666666 } /* Literal.Number.Hex */\n",
".highlight .mi { color: #666666 } /* Literal.Number.Integer */\n",
".highlight .mo { color: #666666 } /* Literal.Number.Oct */\n",
".highlight .sa { color: #BA2121 } /* Literal.String.Affix */\n",
".highlight .sb { color: #BA2121 } /* Literal.String.Backtick */\n",
".highlight .sc { color: #BA2121 } /* Literal.String.Char */\n",
".highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */\n",
".highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n",
".highlight .s2 { color: #BA2121 } /* Literal.String.Double */\n",
".highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n",
".highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */\n",
".highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n",
".highlight .sx { color: #008000 } /* Literal.String.Other */\n",
".highlight .sr { color: #BB6688 } /* Literal.String.Regex */\n",
".highlight .s1 { color: #BA2121 } /* Literal.String.Single */\n",
".highlight .ss { color: #19177C } /* Literal.String.Symbol */\n",
".highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */\n",
".highlight .fm { color: #0000FF } /* Name.Function.Magic */\n",
".highlight .vc { color: #19177C } /* Name.Variable.Class */\n",
".highlight .vg { color: #19177C } /* Name.Variable.Global */\n",
".highlight .vi { color: #19177C } /* Name.Variable.Instance */\n",
".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;spec_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--e97bfccf-8970-4a3c-9cd1-5b5b97ed5d0c&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2014-02-20T09:16:08.989Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2014-02-20T09:16:08.989Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;File hash for Poison Ivy variant&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;description&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;This file hash indicates that a sample of Poison Ivy is present.&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;[file:hashes.&#39;SHA-256&#39; = &#39;ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c&#39;]&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern_type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;stix&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2014-02-20T09:00:00Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;labels&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n",
" <span class=\"s2\">&quot;malicious-activity&quot;</span>\n",
" <span class=\"p\">],</span>\n",
" <span class=\"nt\">&quot;extensions&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;extension-definition--dd73de4f-a7f3-49ea-8ec1-8e884196b7a8&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;extension_type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;toplevel-property-extension&quot;</span>\n",
" <span class=\"p\">}</span>\n",
" <span class=\"p\">},</span>\n",
" <span class=\"nt\">&quot;rank&quot;</span><span class=\"p\">:</span> <span class=\"mi\">5</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;toxicity&quot;</span><span class=\"p\">:</span> <span class=\"mi\">8</span>\n",
"<span class=\"p\">}</span>\n",
"</pre></div>\n"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import stix2\n",
"\n",
"extension_definition1 = stix2.v21.ExtensionDefinition(\n",
" id=\"extension-definition--dd73de4f-a7f3-49ea-8ec1-8e884196b7a8\",\n",
" created_by_ref=\"identity--11b76a96-5d2b-45e0-8a5a-f6994f370731\",\n",
" created=\"2014-02-20T09:16:08.000Z\",\n",
" modified=\"2014-02-20T09:16:08.000Z\",\n",
" name=\"New SDO 1\",\n",
" description=\"This schema adds two properties to a STIX object at the toplevel\",\n",
" schema=\"https://www.example.com/schema-foo-1a/v1/\",\n",
" version=\"1.2.1\",\n",
" extension_types=[\"toplevel-property-extension\"],\n",
" extension_properties=[\n",
" \"toxicity\",\n",
" \"rank\",\n",
" ],\n",
")\n",
"\n",
"indicator = stix2.v21.Indicator(\n",
" id='indicator--e97bfccf-8970-4a3c-9cd1-5b5b97ed5d0c',\n",
" created='2014-02-20T09:16:08.989000Z',\n",
" modified='2014-02-20T09:16:08.989000Z',\n",
" name='File hash for Poison Ivy variant',\n",
" description='This file hash indicates that a sample of Poison Ivy is present.',\n",
" labels=[\n",
" 'malicious-activity',\n",
" ],\n",
" rank=5,\n",
" toxicity=8,\n",
" pattern='[file:hashes.\\'SHA-256\\' = \\'ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c\\']',\n",
" pattern_type='stix',\n",
" valid_from='2014-02-20T09:00:00.000000Z',\n",
" extensions={\n",
" extension_definition1.id : {\n",
" 'extension_type': 'toplevel-property-extension',\n",
" },\n",
" }\n",
")\n",
"\n",
"print(extension_definition1.serialize(pretty=True))\n",
"print(indicator.serialize(pretty=True))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Using CustomExtension decorator\n",
"\n",
"However, in order to prevent repetitive instantiation of the same extension, the `@CustomExtension` decorator can be used to register the `extension-definition` with stix2. Use the `extension_type` class variable to define what kind of extension it is. Then its id can be passed into objects that use this extension."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">pre { line-height: 125%; margin: 0; }\n",
"td.linenos pre { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }\n",
"span.linenos { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }\n",
"td.linenos pre.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }\n",
"span.linenos.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }\n",
".highlight .hll { background-color: #ffffcc }\n",
".highlight { background: #f8f8f8; }\n",
".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
".highlight .k { color: #008000; font-weight: bold } /* Keyword */\n",
".highlight .o { color: #666666 } /* Operator */\n",
".highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n",
".highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n",
".highlight .cp { color: #BC7A00 } /* Comment.Preproc */\n",
".highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n",
".highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */\n",
".highlight .cs { color: #408080; font-style: italic } /* Comment.Special */\n",
".highlight .gd { color: #A00000 } /* Generic.Deleted */\n",
".highlight .ge { font-style: italic } /* Generic.Emph */\n",
".highlight .gr { color: #FF0000 } /* Generic.Error */\n",
".highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n",
".highlight .gi { color: #00A000 } /* Generic.Inserted */\n",
".highlight .go { color: #888888 } /* Generic.Output */\n",
".highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n",
".highlight .gs { font-weight: bold } /* Generic.Strong */\n",
".highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n",
".highlight .gt { color: #0044DD } /* Generic.Traceback */\n",
".highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n",
".highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n",
".highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n",
".highlight .kp { color: #008000 } /* Keyword.Pseudo */\n",
".highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n",
".highlight .kt { color: #B00040 } /* Keyword.Type */\n",
".highlight .m { color: #666666 } /* Literal.Number */\n",
".highlight .s { color: #BA2121 } /* Literal.String */\n",
".highlight .na { color: #7D9029 } /* Name.Attribute */\n",
".highlight .nb { color: #008000 } /* Name.Builtin */\n",
".highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n",
".highlight .no { color: #880000 } /* Name.Constant */\n",
".highlight .nd { color: #AA22FF } /* Name.Decorator */\n",
".highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */\n",
".highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n",
".highlight .nf { color: #0000FF } /* Name.Function */\n",
".highlight .nl { color: #A0A000 } /* Name.Label */\n",
".highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n",
".highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */\n",
".highlight .nv { color: #19177C } /* Name.Variable */\n",
".highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n",
".highlight .w { color: #bbbbbb } /* Text.Whitespace */\n",
".highlight .mb { color: #666666 } /* Literal.Number.Bin */\n",
".highlight .mf { color: #666666 } /* Literal.Number.Float */\n",
".highlight .mh { color: #666666 } /* Literal.Number.Hex */\n",
".highlight .mi { color: #666666 } /* Literal.Number.Integer */\n",
".highlight .mo { color: #666666 } /* Literal.Number.Oct */\n",
".highlight .sa { color: #BA2121 } /* Literal.String.Affix */\n",
".highlight .sb { color: #BA2121 } /* Literal.String.Backtick */\n",
".highlight .sc { color: #BA2121 } /* Literal.String.Char */\n",
".highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */\n",
".highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n",
".highlight .s2 { color: #BA2121 } /* Literal.String.Double */\n",
".highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n",
".highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */\n",
".highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n",
".highlight .sx { color: #008000 } /* Literal.String.Other */\n",
".highlight .sr { color: #BB6688 } /* Literal.String.Regex */\n",
".highlight .s1 { color: #BA2121 } /* Literal.String.Single */\n",
".highlight .ss { color: #19177C } /* Literal.String.Symbol */\n",
".highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */\n",
".highlight .fm { color: #0000FF } /* Name.Function.Magic */\n",
".highlight .vc { color: #19177C } /* Name.Variable.Class */\n",
".highlight .vg { color: #19177C } /* Name.Variable.Global */\n",
".highlight .vi { color: #19177C } /* Name.Variable.Instance */\n",
".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;spec_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--e97bfccf-8970-4a3c-9cd1-5b5b97ed5d0c&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2014-02-20T09:16:08.989Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2014-02-20T09:16:08.989Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;File hash for Poison Ivy variant&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;description&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;This file hash indicates that a sample of Poison Ivy is present.&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;[file:hashes.&#39;SHA-256&#39; = &#39;ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c&#39;]&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern_type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;stix&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2014-02-20T09:00:00Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;labels&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n",
" <span class=\"s2\">&quot;malicious-activity&quot;</span>\n",
" <span class=\"p\">],</span>\n",
" <span class=\"nt\">&quot;extensions&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;extension-definition--dd73de4f-a7f3-49ea-8ec1-8e884196b7a8&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;extension_type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;toplevel-property-extension&quot;</span>\n",
" <span class=\"p\">}</span>\n",
" <span class=\"p\">},</span>\n",
" <span class=\"nt\">&quot;rank&quot;</span><span class=\"p\">:</span> <span class=\"mi\">5</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;toxicity&quot;</span><span class=\"p\">:</span> <span class=\"mi\">8</span>\n",
"<span class=\"p\">}</span>\n",
"</pre></div>\n"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"TOPLEVEL_EXTENSION_DEFINITION_ID = 'extension-definition--dd73de4f-a7f3-49ea-8ec1-8e884196b7a8'\n",
"\n",
"@stix2.v21.CustomExtension(\n",
" TOPLEVEL_EXTENSION_DEFINITION_ID, [\n",
" ('rank', stix2.properties.IntegerProperty(required=True)),\n",
" ('toxicity', stix2.properties.IntegerProperty(required=True)),\n",
" ],\n",
")\n",
"class ExtensionTopLevel:\n",
" extension_type = 'toplevel-property-extension'\n",
"\n",
"indicator = stix2.v21.Indicator(\n",
" id='indicator--e97bfccf-8970-4a3c-9cd1-5b5b97ed5d0c',\n",
" created='2014-02-20T09:16:08.989000Z',\n",
" modified='2014-02-20T09:16:08.989000Z',\n",
" name='File hash for Poison Ivy variant',\n",
" description='This file hash indicates that a sample of Poison Ivy is present.',\n",
" labels=[\n",
" 'malicious-activity',\n",
" ],\n",
" rank=5,\n",
" toxicity=8,\n",
" pattern='[file:hashes.\\'SHA-256\\' = \\'ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c\\']',\n",
" pattern_type='stix',\n",
" valid_from='2014-02-20T09:00:00.000000Z',\n",
" extensions={\n",
" TOPLEVEL_EXTENSION_DEFINITION_ID : {\n",
" 'extension_type': 'toplevel-property-extension',\n",
" },\n",
" }\n",
")\n",
"\n",
"print(indicator.serialize(pretty=True))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Using CustomObservable for Extension Definition\n",
"\n",
"Similarly, when registering new objects via `@CustomObservable` you can pass the `extension-definition` id that defines this new SCO. \n",
"\n",
"---\n",
"**Note:**\n",
"Creating an instance of an extension-definition object **does not** mean it is registered in the library. Please use the appropriate decorator for this step: `@CustomExtension`, `@CustomObject`, `@CustomObservable`, `@CustomMarking`\n",
"\n",
"---"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">pre { line-height: 125%; margin: 0; }\n",
"td.linenos pre { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }\n",
"span.linenos { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }\n",
"td.linenos pre.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }\n",
"span.linenos.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }\n",
".highlight .hll { background-color: #ffffcc }\n",
".highlight { background: #f8f8f8; }\n",
".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
".highlight .k { color: #008000; font-weight: bold } /* Keyword */\n",
".highlight .o { color: #666666 } /* Operator */\n",
".highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n",
".highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n",
".highlight .cp { color: #BC7A00 } /* Comment.Preproc */\n",
".highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n",
".highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */\n",
".highlight .cs { color: #408080; font-style: italic } /* Comment.Special */\n",
".highlight .gd { color: #A00000 } /* Generic.Deleted */\n",
".highlight .ge { font-style: italic } /* Generic.Emph */\n",
".highlight .gr { color: #FF0000 } /* Generic.Error */\n",
".highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n",
".highlight .gi { color: #00A000 } /* Generic.Inserted */\n",
".highlight .go { color: #888888 } /* Generic.Output */\n",
".highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n",
".highlight .gs { font-weight: bold } /* Generic.Strong */\n",
".highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n",
".highlight .gt { color: #0044DD } /* Generic.Traceback */\n",
".highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n",
".highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n",
".highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n",
".highlight .kp { color: #008000 } /* Keyword.Pseudo */\n",
".highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n",
".highlight .kt { color: #B00040 } /* Keyword.Type */\n",
".highlight .m { color: #666666 } /* Literal.Number */\n",
".highlight .s { color: #BA2121 } /* Literal.String */\n",
".highlight .na { color: #7D9029 } /* Name.Attribute */\n",
".highlight .nb { color: #008000 } /* Name.Builtin */\n",
".highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n",
".highlight .no { color: #880000 } /* Name.Constant */\n",
".highlight .nd { color: #AA22FF } /* Name.Decorator */\n",
".highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */\n",
".highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n",
".highlight .nf { color: #0000FF } /* Name.Function */\n",
".highlight .nl { color: #A0A000 } /* Name.Label */\n",
".highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n",
".highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */\n",
".highlight .nv { color: #19177C } /* Name.Variable */\n",
".highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n",
".highlight .w { color: #bbbbbb } /* Text.Whitespace */\n",
".highlight .mb { color: #666666 } /* Literal.Number.Bin */\n",
".highlight .mf { color: #666666 } /* Literal.Number.Float */\n",
".highlight .mh { color: #666666 } /* Literal.Number.Hex */\n",
".highlight .mi { color: #666666 } /* Literal.Number.Integer */\n",
".highlight .mo { color: #666666 } /* Literal.Number.Oct */\n",
".highlight .sa { color: #BA2121 } /* Literal.String.Affix */\n",
".highlight .sb { color: #BA2121 } /* Literal.String.Backtick */\n",
".highlight .sc { color: #BA2121 } /* Literal.String.Char */\n",
".highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */\n",
".highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n",
".highlight .s2 { color: #BA2121 } /* Literal.String.Double */\n",
".highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n",
".highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */\n",
".highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n",
".highlight .sx { color: #008000 } /* Literal.String.Other */\n",
".highlight .sr { color: #BB6688 } /* Literal.String.Regex */\n",
".highlight .s1 { color: #BA2121 } /* Literal.String.Single */\n",
".highlight .ss { color: #19177C } /* Literal.String.Symbol */\n",
".highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */\n",
".highlight .fm { color: #0000FF } /* Name.Function.Magic */\n",
".highlight .vc { color: #19177C } /* Name.Variable.Class */\n",
".highlight .vg { color: #19177C } /* Name.Variable.Global */\n",
".highlight .vi { color: #19177C } /* Name.Variable.Instance */\n",
".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;my-favorite-sco&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;spec_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;my-favorite-sco--f9dbe89c-0030-4a9d-8b78-0dcd0a0de874&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;This is the name of my favorite SCO&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;some_network_protocol_field&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;value&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;extensions&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;extension-definition--150c1738-28c9-44d0-802d-70523218240b&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;extension_type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;new-sco&quot;</span>\n",
" <span class=\"p\">}</span>\n",
" <span class=\"p\">}</span>\n",
"<span class=\"p\">}</span>\n",
"</pre></div>\n"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"@stix2.v21.CustomObservable(\n",
" 'my-favorite-sco', [\n",
" ('name', stix2.properties.StringProperty(required=True)),\n",
" ('some_network_protocol_field', stix2.properties.StringProperty(required=True)),\n",
" ], ['name', 'some_network_protocol_field'], 'extension-definition--150c1738-28c9-44d0-802d-70523218240b',\n",
")\n",
"class MyFavSCO:\n",
" pass\n",
"\n",
"my_favorite_sco = MyFavSCO(\n",
" id='my-favorite-sco--f9dbe89c-0030-4a9d-8b78-0dcd0a0de874',\n",
" name='This is the name of my favorite SCO',\n",
" some_network_protocol_field='value',\n",
")\n",
"\n",
"print(my_favorite_sco.serialize(pretty=True))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Using CustomMarking for Extension Definition\n",
"\n",
"The example below shows the use for MarkingDefinition extensions. Currently this is only supported as a `property-extension`. Now, as another option to building the `extensions` as a dictionary, it can also be built with objects as shown below by extracting the registered class."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">pre { line-height: 125%; margin: 0; }\n",
"td.linenos pre { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }\n",
"span.linenos { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }\n",
"td.linenos pre.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }\n",
"span.linenos.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }\n",
".highlight .hll { background-color: #ffffcc }\n",
".highlight { background: #f8f8f8; }\n",
".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
".highlight .k { color: #008000; font-weight: bold } /* Keyword */\n",
".highlight .o { color: #666666 } /* Operator */\n",
".highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n",
".highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n",
".highlight .cp { color: #BC7A00 } /* Comment.Preproc */\n",
".highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n",
".highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */\n",
".highlight .cs { color: #408080; font-style: italic } /* Comment.Special */\n",
".highlight .gd { color: #A00000 } /* Generic.Deleted */\n",
".highlight .ge { font-style: italic } /* Generic.Emph */\n",
".highlight .gr { color: #FF0000 } /* Generic.Error */\n",
".highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n",
".highlight .gi { color: #00A000 } /* Generic.Inserted */\n",
".highlight .go { color: #888888 } /* Generic.Output */\n",
".highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n",
".highlight .gs { font-weight: bold } /* Generic.Strong */\n",
".highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n",
".highlight .gt { color: #0044DD } /* Generic.Traceback */\n",
".highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n",
".highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n",
".highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n",
".highlight .kp { color: #008000 } /* Keyword.Pseudo */\n",
".highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n",
".highlight .kt { color: #B00040 } /* Keyword.Type */\n",
".highlight .m { color: #666666 } /* Literal.Number */\n",
".highlight .s { color: #BA2121 } /* Literal.String */\n",
".highlight .na { color: #7D9029 } /* Name.Attribute */\n",
".highlight .nb { color: #008000 } /* Name.Builtin */\n",
".highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n",
".highlight .no { color: #880000 } /* Name.Constant */\n",
".highlight .nd { color: #AA22FF } /* Name.Decorator */\n",
".highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */\n",
".highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n",
".highlight .nf { color: #0000FF } /* Name.Function */\n",
".highlight .nl { color: #A0A000 } /* Name.Label */\n",
".highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n",
".highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */\n",
".highlight .nv { color: #19177C } /* Name.Variable */\n",
".highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n",
".highlight .w { color: #bbbbbb } /* Text.Whitespace */\n",
".highlight .mb { color: #666666 } /* Literal.Number.Bin */\n",
".highlight .mf { color: #666666 } /* Literal.Number.Float */\n",
".highlight .mh { color: #666666 } /* Literal.Number.Hex */\n",
".highlight .mi { color: #666666 } /* Literal.Number.Integer */\n",
".highlight .mo { color: #666666 } /* Literal.Number.Oct */\n",
".highlight .sa { color: #BA2121 } /* Literal.String.Affix */\n",
".highlight .sb { color: #BA2121 } /* Literal.String.Backtick */\n",
".highlight .sc { color: #BA2121 } /* Literal.String.Char */\n",
".highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */\n",
".highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n",
".highlight .s2 { color: #BA2121 } /* Literal.String.Double */\n",
".highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n",
".highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */\n",
".highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n",
".highlight .sx { color: #008000 } /* Literal.String.Other */\n",
".highlight .sr { color: #BB6688 } /* Literal.String.Regex */\n",
".highlight .s1 { color: #BA2121 } /* Literal.String.Single */\n",
".highlight .ss { color: #19177C } /* Literal.String.Symbol */\n",
".highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */\n",
".highlight .fm { color: #0000FF } /* Name.Function.Magic */\n",
".highlight .vc { color: #19177C } /* Name.Variable.Class */\n",
".highlight .vg { color: #19177C } /* Name.Variable.Global */\n",
".highlight .vi { color: #19177C } /* Name.Variable.Instance */\n",
".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;marking-definition&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;spec_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;marking-definition--28417f9f-1963-4e7f-914d-233f8fd4829f&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-03-31T21:54:46.652069Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;This is the name of my favorite Marking&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;extensions&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;extension-definition--a932fcc6-e032-176c-126f-cb970a5a1fff&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;extension_type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;property-extension&quot;</span>\n",
" <span class=\"p\">}</span>\n",
" <span class=\"p\">}</span>\n",
"<span class=\"p\">}</span>\n",
"</pre></div>\n"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from stix2 import registry\n",
"\n",
"MARKING_EXTENSION_ID = 'extension-definition--a932fcc6-e032-176c-126f-cb970a5a1fff'\n",
"\n",
"@stix2.v21.CustomMarking(\n",
" 'my-favorite-marking', [\n",
" ('some_marking_field', stix2.properties.StringProperty(required=True)),\n",
" ], MARKING_EXTENSION_ID,\n",
")\n",
"class MyFavMarking:\n",
" pass\n",
"\n",
"ext_class = registry.class_for_type(MARKING_EXTENSION_ID, '2.1')\n",
"\n",
"my_favorite_marking = MyFavMarking(\n",
" name='This is the name of my favorite Marking',\n",
" extensions={\n",
" MARKING_EXTENSION_ID: ext_class(some_marking_field='value')\n",
" }\n",
")\n",
"\n",
"print(my_favorite_marking.serialize(pretty=True))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Using CustomObject for Extension Definition\n",
"\n",
"Similar to the examples above, the same can be done for SDOs and SROs."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">pre { line-height: 125%; margin: 0; }\n",
"td.linenos pre { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }\n",
"span.linenos { color: #000000; background-color: #f0f0f0; padding: 0 5px 0 5px; }\n",
"td.linenos pre.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }\n",
"span.linenos.special { color: #000000; background-color: #ffffc0; padding: 0 5px 0 5px; }\n",
".highlight .hll { background-color: #ffffcc }\n",
".highlight { background: #f8f8f8; }\n",
".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
".highlight .k { color: #008000; font-weight: bold } /* Keyword */\n",
".highlight .o { color: #666666 } /* Operator */\n",
".highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n",
".highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n",
".highlight .cp { color: #BC7A00 } /* Comment.Preproc */\n",
".highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n",
".highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */\n",
".highlight .cs { color: #408080; font-style: italic } /* Comment.Special */\n",
".highlight .gd { color: #A00000 } /* Generic.Deleted */\n",
".highlight .ge { font-style: italic } /* Generic.Emph */\n",
".highlight .gr { color: #FF0000 } /* Generic.Error */\n",
".highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n",
".highlight .gi { color: #00A000 } /* Generic.Inserted */\n",
".highlight .go { color: #888888 } /* Generic.Output */\n",
".highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n",
".highlight .gs { font-weight: bold } /* Generic.Strong */\n",
".highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n",
".highlight .gt { color: #0044DD } /* Generic.Traceback */\n",
".highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n",
".highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n",
".highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n",
".highlight .kp { color: #008000 } /* Keyword.Pseudo */\n",
".highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n",
".highlight .kt { color: #B00040 } /* Keyword.Type */\n",
".highlight .m { color: #666666 } /* Literal.Number */\n",
".highlight .s { color: #BA2121 } /* Literal.String */\n",
".highlight .na { color: #7D9029 } /* Name.Attribute */\n",
".highlight .nb { color: #008000 } /* Name.Builtin */\n",
".highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n",
".highlight .no { color: #880000 } /* Name.Constant */\n",
".highlight .nd { color: #AA22FF } /* Name.Decorator */\n",
".highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */\n",
".highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n",
".highlight .nf { color: #0000FF } /* Name.Function */\n",
".highlight .nl { color: #A0A000 } /* Name.Label */\n",
".highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n",
".highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */\n",
".highlight .nv { color: #19177C } /* Name.Variable */\n",
".highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n",
".highlight .w { color: #bbbbbb } /* Text.Whitespace */\n",
".highlight .mb { color: #666666 } /* Literal.Number.Bin */\n",
".highlight .mf { color: #666666 } /* Literal.Number.Float */\n",
".highlight .mh { color: #666666 } /* Literal.Number.Hex */\n",
".highlight .mi { color: #666666 } /* Literal.Number.Integer */\n",
".highlight .mo { color: #666666 } /* Literal.Number.Oct */\n",
".highlight .sa { color: #BA2121 } /* Literal.String.Affix */\n",
".highlight .sb { color: #BA2121 } /* Literal.String.Backtick */\n",
".highlight .sc { color: #BA2121 } /* Literal.String.Char */\n",
".highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */\n",
".highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n",
".highlight .s2 { color: #BA2121 } /* Literal.String.Double */\n",
".highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n",
".highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */\n",
".highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n",
".highlight .sx { color: #008000 } /* Literal.String.Other */\n",
".highlight .sr { color: #BB6688 } /* Literal.String.Regex */\n",
".highlight .s1 { color: #BA2121 } /* Literal.String.Single */\n",
".highlight .ss { color: #19177C } /* Literal.String.Symbol */\n",
".highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */\n",
".highlight .fm { color: #0000FF } /* Name.Function.Magic */\n",
".highlight .vc { color: #19177C } /* Name.Variable.Class */\n",
".highlight .vg { color: #19177C } /* Name.Variable.Global */\n",
".highlight .vi { color: #19177C } /* Name.Variable.Instance */\n",
".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;my-favorite-sro&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;spec_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;my-favorite-sro--d6306d62-c08d-4d78-baf7-11e7a4c9bc36&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-03-31T22:43:42.807698Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-03-31T22:43:42.807698Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;My First SRO&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;some_source_ref&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;identity--b1da8c3e-34d8-470f-9d2b-392e275f1f7d&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;some_target_ref&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;identity--1ddfed54-e8cd-49c9-9c7d-8d1b03c94685&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;extensions&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;extension-definition--e96690a5-dc13-4f27-99dd-0f2188ad74ce&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;extension_type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;new-sro&quot;</span>\n",
" <span class=\"p\">}</span>\n",
" <span class=\"p\">}</span>\n",
"<span class=\"p\">}</span>\n",
"</pre></div>\n"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"invalid_refs = ['bundle', 'language-content', 'marking-definition', 'relationship', 'sighting', 'foobar']\n",
"\n",
"@stix2.v21.CustomObject(\n",
" 'my-favorite-sro', [\n",
" ('name', stix2.properties.StringProperty(required=False)),\n",
" ('some_source_ref', stix2.properties.ReferenceProperty(invalid_types=invalid_refs, spec_version='2.1', required=True)),\n",
" ('some_target_ref', stix2.properties.ReferenceProperty(invalid_types=invalid_refs, spec_version='2.1', required=True)),\n",
" ], extension_name='extension-definition--e96690a5-dc13-4f27-99dd-0f2188ad74ce', is_sdo=False,\n",
")\n",
"class MyFavSRO:\n",
" pass\n",
"\n",
"\n",
"my_favorite_sro = MyFavSRO(\n",
" name=\"My First SRO\",\n",
" some_source_ref=\"identity--b1da8c3e-34d8-470f-9d2b-392e275f1f7d\",\n",
" some_target_ref=\"identity--1ddfed54-e8cd-49c9-9c7d-8d1b03c94685\",\n",
")\n",
"\n",
"print(my_favorite_sro.serialize(pretty=True))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@ -262,7 +262,7 @@
"mal = fs.get(\"malware--92ec0cbd-2c30-44a2-b270-73f4ec949841\")\n",
"\n",
"# for visual purposes\n",
"print(mal)"
"print(mal.serialize(pretty=True))"
]
},
{

View File

@ -77,7 +77,12 @@
{
"data": {
"text/html": [
"<style type=\"text/css\">.highlight .hll { background-color: #ffffcc }\n",
"<style type=\"text/css\">pre { line-height: 125%; }\n",
"td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
".highlight .hll { background-color: #ffffcc }\n",
".highlight { background: #f8f8f8; }\n",
".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
@ -148,13 +153,13 @@
".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;spec_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--46498844-7689-4e7b-be25-b119d8401159&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T20:55:56.088861Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T20:55:56.088861Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--a315ce0b-1211-478e-812a-cd6d3eecc3c1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T13:59:48.911595Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T13:59:48.911595Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;[file:hashes.md5 = &#39;d41d8cd98f00b204e9800998ecf8427e&#39;]&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern_type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;stix&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T20:55:56.088861Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T13:59:48.911595Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;object_marking_refs&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n",
" <span class=\"s2\">&quot;marking-definition--f88d31f6-486f-44da-b317-01333bde0b82&quot;</span>\n",
" <span class=\"p\">]</span>\n",
@ -176,7 +181,7 @@
"indicator = Indicator(pattern_type=\"stix\",\n",
" pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\",\n",
" object_marking_refs=TLP_AMBER)\n",
"print(indicator)"
"print(indicator.serialize(pretty=True))"
]
},
{
@ -194,7 +199,12 @@
{
"data": {
"text/html": [
"<style type=\"text/css\">.highlight .hll { background-color: #ffffcc }\n",
"<style type=\"text/css\">pre { line-height: 125%; }\n",
"td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
".highlight .hll { background-color: #ffffcc }\n",
".highlight { background: #f8f8f8; }\n",
".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
@ -265,8 +275,8 @@
".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;marking-definition&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;spec_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;marking-definition--9a4efc30-a7ac-42d0-8776-16f390a0fd44&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T20:56:06.779241Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;marking-definition--4b8e86b5-d505-46a4-91b4-a8db17f4ff4d&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T13:59:50.587649Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;definition_type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;statement&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;definition&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;statement&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Copyright 2017, Example Corp&quot;</span>\n",
@ -290,7 +300,7 @@
" definition_type=\"statement\", \n",
" definition=StatementMarking(statement=\"Copyright 2017, Example Corp\")\n",
")\n",
"print(marking_definition)"
"print(marking_definition.serialize(pretty=True))"
]
},
{
@ -308,7 +318,12 @@
{
"data": {
"text/html": [
"<style type=\"text/css\">.highlight .hll { background-color: #ffffcc }\n",
"<style type=\"text/css\">pre { line-height: 125%; }\n",
"td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
".highlight .hll { background-color: #ffffcc }\n",
".highlight { background: #f8f8f8; }\n",
".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
@ -379,15 +394,15 @@
".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;spec_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--75d66696-9960-4229-ba89-2caac50891b3&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T20:56:29.80259Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T20:56:29.80259Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--91ed23a6-c5f0-4b16-8369-64cf39f974bf&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T13:59:52.602254Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T13:59:52.602254Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;[file:hashes.md5 = &#39;d41d8cd98f00b204e9800998ecf8427e&#39;]&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern_type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;stix&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T20:56:29.80259Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T13:59:52.602254Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;object_marking_refs&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n",
" <span class=\"s2\">&quot;marking-definition--9a4efc30-a7ac-42d0-8776-16f390a0fd44&quot;</span>\n",
" <span class=\"s2\">&quot;marking-definition--4b8e86b5-d505-46a4-91b4-a8db17f4ff4d&quot;</span>\n",
" <span class=\"p\">]</span>\n",
"<span class=\"p\">}</span>\n",
"</pre></div>\n"
@ -405,7 +420,7 @@
"indicator2 = Indicator(pattern_type=\"stix\",\n",
" pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\",\n",
" object_marking_refs=marking_definition)\n",
"print(indicator2)"
"print(indicator2.serialize(pretty=True))"
]
},
{
@ -416,7 +431,12 @@
{
"data": {
"text/html": [
"<style type=\"text/css\">.highlight .hll { background-color: #ffffcc }\n",
"<style type=\"text/css\">pre { line-height: 125%; }\n",
"td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
".highlight .hll { background-color: #ffffcc }\n",
".highlight { background: #f8f8f8; }\n",
".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
@ -487,13 +507,13 @@
".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;spec_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--757ea853-138c-44e2-bb00-e78eebfaa378&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T20:56:43.703563Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T20:56:43.703563Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--42ae262e-4839-4c1a-a50a-3a6690623a9d&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T13:59:54.207797Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T13:59:54.207797Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;[file:hashes.md5 = &#39;d41d8cd98f00b204e9800998ecf8427e&#39;]&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern_type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;stix&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T20:56:43.703563Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T13:59:54.207797Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;object_marking_refs&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n",
" <span class=\"s2\">&quot;marking-definition--f88d31f6-486f-44da-b317-01333bde0b82&quot;</span>\n",
" <span class=\"p\">]</span>\n",
@ -513,7 +533,7 @@
"indicator3 = Indicator(pattern_type=\"stix\",\n",
" pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\",\n",
" object_marking_refs=\"marking-definition--f88d31f6-486f-44da-b317-01333bde0b82\")\n",
"print(indicator3)"
"print(indicator3.serialize(pretty=True))"
]
},
{
@ -525,13 +545,18 @@
},
{
"cell_type": "code",
"execution_count": 8,
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">.highlight .hll { background-color: #ffffcc }\n",
"<style type=\"text/css\">pre { line-height: 125%; }\n",
"td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
".highlight .hll { background-color: #ffffcc }\n",
".highlight { background: #f8f8f8; }\n",
".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
@ -602,15 +627,15 @@
".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;malware&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;spec_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;malware--1752bbec-765a-4711-a304-f0e92ca902ae&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T21:21:07.148194Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T21:21:07.148194Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;malware--2658ac6a-44e9-44ea-8c8a-d67abae4d0d5&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T13:59:56.556801Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T13:59:56.556801Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Poison Ivy&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;description&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;A ransomware related to ...&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;is_family&quot;</span><span class=\"p\">:</span> <span class=\"kc\">false</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;granular_markings&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n",
" <span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;marking_ref&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;marking-definition--9a4efc30-a7ac-42d0-8776-16f390a0fd44&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;marking_ref&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;marking-definition--4b8e86b5-d505-46a4-91b4-a8db17f4ff4d&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;selectors&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n",
" <span class=\"s2\">&quot;description&quot;</span>\n",
" <span class=\"p\">]</span>\n",
@ -629,7 +654,7 @@
"<IPython.core.display.HTML object>"
]
},
"execution_count": 8,
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
@ -650,7 +675,7 @@
" \"marking_ref\": TLP_WHITE\n",
" }\n",
" ])\n",
"print(malware)"
"print(malware.serialize(pretty=True))"
]
},
{
@ -662,7 +687,7 @@
},
{
"cell_type": "code",
"execution_count": 9,
"execution_count": 8,
"metadata": {},
"outputs": [
{
@ -706,13 +731,18 @@
},
{
"cell_type": "code",
"execution_count": 10,
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">.highlight .hll { background-color: #ffffcc }\n",
"<style type=\"text/css\">pre { line-height: 125%; }\n",
"td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
".highlight .hll { background-color: #ffffcc }\n",
".highlight { background: #f8f8f8; }\n",
".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
@ -783,16 +813,16 @@
".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;spec_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--46498844-7689-4e7b-be25-b119d8401159&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T20:55:56.088861Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T21:21:39.898475Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--a315ce0b-1211-478e-812a-cd6d3eecc3c1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T13:59:48.911595Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T14:00:01.165749Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;[file:hashes.md5 = &#39;d41d8cd98f00b204e9800998ecf8427e&#39;]&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern_type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;stix&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T20:55:56.088861Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T13:59:48.911595Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;object_marking_refs&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n",
" <span class=\"s2\">&quot;marking-definition--f88d31f6-486f-44da-b317-01333bde0b82&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"s2\">&quot;marking-definition--9a4efc30-a7ac-42d0-8776-16f390a0fd44&quot;</span>\n",
" <span class=\"s2\">&quot;marking-definition--4b8e86b5-d505-46a4-91b4-a8db17f4ff4d&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"s2\">&quot;marking-definition--f88d31f6-486f-44da-b317-01333bde0b82&quot;</span>\n",
" <span class=\"p\">]</span>\n",
"<span class=\"p\">}</span>\n",
"</pre></div>\n"
@ -801,14 +831,14 @@
"<IPython.core.display.HTML object>"
]
},
"execution_count": 10,
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"indicator4 = indicator.add_markings(marking_definition)\n",
"print(indicator4)"
"print(indicator4.serialize(pretty=True))"
]
},
{
@ -820,13 +850,18 @@
},
{
"cell_type": "code",
"execution_count": 11,
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">.highlight .hll { background-color: #ffffcc }\n",
"<style type=\"text/css\">pre { line-height: 125%; }\n",
"td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
".highlight .hll { background-color: #ffffcc }\n",
".highlight { background: #f8f8f8; }\n",
".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
@ -897,13 +932,13 @@
".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;spec_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--46498844-7689-4e7b-be25-b119d8401159&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T20:55:56.088861Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T21:21:43.529702Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--a315ce0b-1211-478e-812a-cd6d3eecc3c1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T13:59:48.911595Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T14:00:03.00911Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;[file:hashes.md5 = &#39;d41d8cd98f00b204e9800998ecf8427e&#39;]&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern_type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;stix&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T20:55:56.088861Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T13:59:48.911595Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;object_marking_refs&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n",
" <span class=\"s2\">&quot;marking-definition--f88d31f6-486f-44da-b317-01333bde0b82&quot;</span>\n",
" <span class=\"p\">]</span>\n",
@ -914,14 +949,14 @@
"<IPython.core.display.HTML object>"
]
},
"execution_count": 11,
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"indicator5 = indicator4.remove_markings(marking_definition)\n",
"print(indicator5)"
"print(indicator5.serialize(pretty=True))"
]
},
{
@ -933,13 +968,18 @@
},
{
"cell_type": "code",
"execution_count": 12,
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">.highlight .hll { background-color: #ffffcc }\n",
"<style type=\"text/css\">pre { line-height: 125%; }\n",
"td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
".highlight .hll { background-color: #ffffcc }\n",
".highlight { background: #f8f8f8; }\n",
".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
@ -1010,16 +1050,16 @@
".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;spec_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--46498844-7689-4e7b-be25-b119d8401159&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T20:55:56.088861Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T21:21:47.703212Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--a315ce0b-1211-478e-812a-cd6d3eecc3c1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T13:59:48.911595Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T14:00:04.531083Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;[file:hashes.md5 = &#39;d41d8cd98f00b204e9800998ecf8427e&#39;]&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern_type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;stix&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T20:55:56.088861Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T13:59:48.911595Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;object_marking_refs&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n",
" <span class=\"s2\">&quot;marking-definition--9a4efc30-a7ac-42d0-8776-16f390a0fd44&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"s2\">&quot;marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da&quot;</span>\n",
" <span class=\"s2\">&quot;marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"s2\">&quot;marking-definition--4b8e86b5-d505-46a4-91b4-a8db17f4ff4d&quot;</span>\n",
" <span class=\"p\">]</span>\n",
"<span class=\"p\">}</span>\n",
"</pre></div>\n"
@ -1028,7 +1068,7 @@
"<IPython.core.display.HTML object>"
]
},
"execution_count": 12,
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
@ -1037,7 +1077,7 @@
"from stix2 import TLP_GREEN\n",
"\n",
"indicator6 = indicator5.set_markings([TLP_GREEN, marking_definition])\n",
"print(indicator6)"
"print(indicator6.serialize(pretty=True))"
]
},
{
@ -1049,13 +1089,18 @@
},
{
"cell_type": "code",
"execution_count": 13,
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">.highlight .hll { background-color: #ffffcc }\n",
"<style type=\"text/css\">pre { line-height: 125%; }\n",
"td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
".highlight .hll { background-color: #ffffcc }\n",
".highlight { background: #f8f8f8; }\n",
".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
@ -1126,13 +1171,13 @@
".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;spec_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--46498844-7689-4e7b-be25-b119d8401159&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T20:55:56.088861Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T21:21:53.287178Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--a315ce0b-1211-478e-812a-cd6d3eecc3c1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T13:59:48.911595Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T14:00:06.512465Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;[file:hashes.md5 = &#39;d41d8cd98f00b204e9800998ecf8427e&#39;]&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern_type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;stix&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T20:55:56.088861Z&quot;</span>\n",
" <span class=\"nt\">&quot;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T13:59:48.911595Z&quot;</span>\n",
"<span class=\"p\">}</span>\n",
"</pre></div>\n"
],
@ -1140,14 +1185,14 @@
"<IPython.core.display.HTML object>"
]
},
"execution_count": 13,
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"indicator7 = indicator5.clear_markings()\n",
"print(indicator7)"
"print(indicator7.serialize(pretty=True))"
]
},
{
@ -1168,17 +1213,17 @@
},
{
"cell_type": "code",
"execution_count": 14,
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['marking-definition--9a4efc30-a7ac-42d0-8776-16f390a0fd44',\n",
" 'marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da']"
"['marking-definition--34098fce-860f-48ae-8e50-ebd3cc5e41da',\n",
" 'marking-definition--4b8e86b5-d505-46a4-91b4-a8db17f4ff4d']"
]
},
"execution_count": 14,
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
@ -1196,7 +1241,7 @@
},
{
"cell_type": "code",
"execution_count": 15,
"execution_count": 14,
"metadata": {},
"outputs": [
{
@ -1205,7 +1250,7 @@
"['marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9']"
]
},
"execution_count": 15,
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
@ -1225,7 +1270,7 @@
},
{
"cell_type": "code",
"execution_count": 16,
"execution_count": 15,
"metadata": {},
"outputs": [
{
@ -1234,7 +1279,7 @@
"['marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9']"
]
},
"execution_count": 16,
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
@ -1252,7 +1297,7 @@
},
{
"cell_type": "code",
"execution_count": 17,
"execution_count": 16,
"metadata": {},
"outputs": [
{
@ -1261,7 +1306,7 @@
"True"
]
},
"execution_count": 17,
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
@ -1272,7 +1317,7 @@
},
{
"cell_type": "code",
"execution_count": 18,
"execution_count": 17,
"metadata": {},
"outputs": [
{
@ -1281,7 +1326,7 @@
"True"
]
},
"execution_count": 18,
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
@ -1292,7 +1337,7 @@
},
{
"cell_type": "code",
"execution_count": 19,
"execution_count": 18,
"metadata": {
"scrolled": true
},
@ -1303,7 +1348,7 @@
"False"
]
},
"execution_count": 19,
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
@ -1323,13 +1368,18 @@
},
{
"cell_type": "code",
"execution_count": 20,
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">.highlight .hll { background-color: #ffffcc }\n",
"<style type=\"text/css\">pre { line-height: 125%; }\n",
"td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
".highlight .hll { background-color: #ffffcc }\n",
".highlight { background: #f8f8f8; }\n",
".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
@ -1400,9 +1450,9 @@
".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;spec_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--f4004de9-a6d9-4c7b-823e-3d8199173c09&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T21:35:08.630228Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T21:35:08.630228Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--a2fd263a-ec46-4fff-84af-27419f0b9f15&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T14:02:31.991141Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T14:02:31.991141Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;description&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Una descripcion sobre este indicador&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;indicator_types&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n",
" <span class=\"s2\">&quot;malware&quot;</span>\n",
@ -1410,7 +1460,7 @@
" <span class=\"nt\">&quot;pattern&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;[file:hashes.md5 = &#39;d41d8cd98f00b204e9800998ecf8427e&#39;]&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern_type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;stix&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T21:35:08.630228Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T14:02:31.991141Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;object_marking_refs&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n",
" <span class=\"s2\">&quot;marking-definition--f88d31f6-486f-44da-b317-01333bde0b82&quot;</span>\n",
" <span class=\"p\">],</span>\n",
@ -1435,14 +1485,19 @@
"<IPython.core.display.HTML object>"
]
},
"execution_count": 20,
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">.highlight .hll { background-color: #ffffcc }\n",
"<style type=\"text/css\">pre { line-height: 125%; }\n",
"td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
".highlight .hll { background-color: #ffffcc }\n",
".highlight { background: #f8f8f8; }\n",
".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
@ -1517,14 +1572,19 @@
"<IPython.core.display.HTML object>"
]
},
"execution_count": 20,
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">.highlight .hll { background-color: #ffffcc }\n",
"<style type=\"text/css\">pre { line-height: 125%; }\n",
"td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
".highlight .hll { background-color: #ffffcc }\n",
".highlight { background: #f8f8f8; }\n",
".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
@ -1599,14 +1659,19 @@
"<IPython.core.display.HTML object>"
]
},
"execution_count": 20,
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"text/html": [
"<style type=\"text/css\">.highlight .hll { background-color: #ffffcc }\n",
"<style type=\"text/css\">pre { line-height: 125%; }\n",
"td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
".highlight .hll { background-color: #ffffcc }\n",
".highlight { background: #f8f8f8; }\n",
".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
@ -1681,7 +1746,7 @@
"<IPython.core.display.HTML object>"
]
},
"execution_count": 20,
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
@ -1706,7 +1771,7 @@
" }\n",
" ]\n",
")\n",
"print(v21_indicator)\n",
"print(v21_indicator.serialize(pretty=True))\n",
"\n",
"# Gets both lang and marking_ref markings for 'description'\n",
"print(v21_indicator.get_markings('description'))\n",
@ -1733,7 +1798,12 @@
{
"data": {
"text/html": [
"<style type=\"text/css\">.highlight .hll { background-color: #ffffcc }\n",
"<style type=\"text/css\">pre { line-height: 125%; }\n",
"td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
".highlight .hll { background-color: #ffffcc }\n",
".highlight { background: #f8f8f8; }\n",
".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
@ -1804,9 +1874,9 @@
".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;spec_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--f4004de9-a6d9-4c7b-823e-3d8199173c09&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T21:35:08.630228Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T21:35:14.54482Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--a2fd263a-ec46-4fff-84af-27419f0b9f15&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T14:02:31.991141Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T14:03:11.817032Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;description&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Una descripcion sobre este indicador&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;indicator_types&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n",
" <span class=\"s2\">&quot;malware&quot;</span>\n",
@ -1814,7 +1884,7 @@
" <span class=\"nt\">&quot;pattern&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;[file:hashes.md5 = &#39;d41d8cd98f00b204e9800998ecf8427e&#39;]&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern_type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;stix&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T21:35:08.630228Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T14:02:31.991141Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;object_marking_refs&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n",
" <span class=\"s2\">&quot;marking-definition--f88d31f6-486f-44da-b317-01333bde0b82&quot;</span>\n",
" <span class=\"p\">]</span>\n",
@ -1831,7 +1901,8 @@
}
],
"source": [
"print(v21_indicator.clear_markings(\"description\")) # By default, both types of markings will be removed"
"# By default, both types of markings will be removed\n",
"print(v21_indicator.clear_markings(\"description\").serialize(pretty=True))"
]
},
{
@ -1842,7 +1913,12 @@
{
"data": {
"text/html": [
"<style type=\"text/css\">.highlight .hll { background-color: #ffffcc }\n",
"<style type=\"text/css\">pre { line-height: 125%; }\n",
"td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
".highlight .hll { background-color: #ffffcc }\n",
".highlight { background: #f8f8f8; }\n",
".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
@ -1913,9 +1989,9 @@
".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;spec_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--f4004de9-a6d9-4c7b-823e-3d8199173c09&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T21:35:08.630228Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T21:35:39.298138Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--a2fd263a-ec46-4fff-84af-27419f0b9f15&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T14:02:31.991141Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T14:03:24.701927Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;description&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Una descripcion sobre este indicador&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;indicator_types&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n",
" <span class=\"s2\">&quot;malware&quot;</span>\n",
@ -1923,7 +1999,7 @@
" <span class=\"nt\">&quot;pattern&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;[file:hashes.md5 = &#39;d41d8cd98f00b204e9800998ecf8427e&#39;]&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern_type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;stix&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T21:35:08.630228Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T14:02:31.991141Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;object_marking_refs&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n",
" <span class=\"s2\">&quot;marking-definition--f88d31f6-486f-44da-b317-01333bde0b82&quot;</span>\n",
" <span class=\"p\">],</span>\n",
@ -1949,7 +2025,7 @@
],
"source": [
"# If lang is False, no lang markings will be removed\n",
"print(v21_indicator.clear_markings(\"description\", lang=False))"
"print(v21_indicator.clear_markings(\"description\", lang=False).serialize(pretty=True))"
]
},
{
@ -1960,7 +2036,12 @@
{
"data": {
"text/html": [
"<style type=\"text/css\">.highlight .hll { background-color: #ffffcc }\n",
"<style type=\"text/css\">pre { line-height: 125%; }\n",
"td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }\n",
"td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
"span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }\n",
".highlight .hll { background-color: #ffffcc }\n",
".highlight { background: #f8f8f8; }\n",
".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
@ -2031,9 +2112,9 @@
".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */</style><div class=\"highlight\"><pre><span></span><span class=\"p\">{</span>\n",
" <span class=\"nt\">&quot;type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;spec_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--f4004de9-a6d9-4c7b-823e-3d8199173c09&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T21:35:08.630228Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T21:35:42.684794Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;id&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;indicator--a2fd263a-ec46-4fff-84af-27419f0b9f15&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;created&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T14:02:31.991141Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;modified&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T14:03:29.751985Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;description&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Una descripcion sobre este indicador&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;indicator_types&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n",
" <span class=\"s2\">&quot;malware&quot;</span>\n",
@ -2041,7 +2122,7 @@
" <span class=\"nt\">&quot;pattern&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;[file:hashes.md5 = &#39;d41d8cd98f00b204e9800998ecf8427e&#39;]&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern_type&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;stix&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;pattern_version&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2.1&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2020-06-24T21:35:08.630228Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;valid_from&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2021-04-09T14:02:31.991141Z&quot;</span><span class=\"p\">,</span>\n",
" <span class=\"nt\">&quot;object_marking_refs&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span>\n",
" <span class=\"s2\">&quot;marking-definition--f88d31f6-486f-44da-b317-01333bde0b82&quot;</span>\n",
" <span class=\"p\">],</span>\n",
@ -2067,7 +2148,7 @@
],
"source": [
"# If marking_ref is False, no marking-definition markings will be removed\n",
"print(v21_indicator.clear_markings(\"description\", marking_ref=False))"
"print(v21_indicator.clear_markings(\"description\", marking_ref=False).serialize(pretty=True))"
]
}
],
@ -2087,7 +2168,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.0a6"
"version": "3.9.2"
}
},
"nbformat": 4,

View File

@ -187,7 +187,7 @@
"mem.add(ind)\n",
"\n",
"# for visual purposes\n",
"print(mem.get(ind.id))\n"
"print(mem.get(ind.id).serialize(pretty=True))\n"
]
},
{
@ -304,7 +304,7 @@
"mem.add([ind2,ind3, mal])\n",
"\n",
"# for visual purposes\n",
"print(mem.get(ind3.id))"
"print(mem.get(ind3.id).serialize(pretty=True))"
]
},
{
@ -412,7 +412,7 @@
"from stix2 import Filter\n",
"\n",
"mal = mem.query([Filter(\"malware_types\",\"=\", \"rootkit\")])[0]\n",
"print(mal)"
"print(mal.serialize(pretty=True))"
]
},
{
@ -533,7 +533,7 @@
"report = mem_2.get(\"malware--6cee28b8-4d42-4e72-bd77-ea47897672c0\")\n",
"\n",
"# for visual purposes\n",
"print(report)"
"print(report.serialize(pretty=True))"
]
}
],

View File

@ -282,7 +282,7 @@
"\n",
"obj = parse(input_string)\n",
"print(type(obj))\n",
"print(obj)"
"print(obj.serialize(pretty=True))"
]
},
{
@ -483,7 +483,7 @@
"\n",
"obj = parse(input_dict)\n",
"print(type(obj))\n",
"print(obj)"
"print(obj.serialize(pretty=True))"
]
},
{
@ -677,7 +677,7 @@
"\n",
"obj = parse(file_handle)\n",
"print(type(obj))\n",
"print(obj)"
"print(obj.serialize(pretty=True))"
]
},
{

View File

@ -1502,7 +1502,7 @@
"\n",
"ece14 = ObservationExpression(EqualityComparisonExpression(ObjectPath(\"file\", [\"name\"]), \"$$t00rzch$$.elf\"))\n",
"ind = Indicator(name=\"Cryptotorch\", pattern_type=\"stix\", pattern=ece14)\n",
"print(ind)"
"print(ind.serialize(pretty=True))"
]
}
],
@ -1522,7 +1522,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.0a6"
"version": "3.9.2"
}
},
"nbformat": 4,

View File

@ -173,14 +173,21 @@
" pattern_type=\"stix\",\n",
" pattern=\"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\")\n",
"\n",
"print(str(indicator))"
"print(indicator.serialize(pretty=True))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"However, the string representation can be slow, as it sorts properties to be in a more readable order. If you need performance and don't care about the human-readability of the output, use the object's `serialize()` function:"
"---\n",
"**New in 3.0.0:** \n",
"\n",
"Calling `str()` on a STIX object will call `serialize()` without any formatting options. The change was made to address the performance penalty induced by unknowingly calling with the pretty formatted option. As shown above, to get the same effect as `str()` had in past versions of the library, use the method directly and pass in the pretty argument `serialize(pretty=True)`.\n",
"\n",
"---\n",
"\n",
"However, the pretty formatted string representation can be slow, as it sorts properties to be in a more readable order. If you need performance and don't care about the human-readability of the output, use the object's `serialize()` function to pass in any arguments `json.dump()` would understand:"
]
},
{
@ -384,13 +391,6 @@
"source": [
"print(indicator.serialize(indent=4))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The only difference between this and the string representation from using `str()` is that this will not sort the keys. This works because the keyword arguments are passed to `json.dumps()` internally."
]
}
],
"metadata": {

View File

@ -557,10 +557,10 @@
"stix_obj_versions = tc_source.all_versions(\"indicator--6770298f-0fd8-471a-ab8c-1c658a46574e\")\n",
"\n",
"#for visual purposes\n",
"print(stix_obj)\n",
"print(stix_obj.serialize(pretty=True))\n",
"print(\"-------\")\n",
"for so in stix_obj_versions:\n",
" print(so)\n"
" print(so.serialize(pretty=True))\n"
]
},
{
@ -959,7 +959,7 @@
"\n",
"#for visual purposes\n",
"for indicator in indicators:\n",
" print(indicator)"
" print(indicator.serialize(pretty=True))"
]
},
{
@ -1113,7 +1113,7 @@
"# TAXIICollectionStore\n",
"stix_obj2 = tc_source.get(\"malware--c0931cc6-c75e-47e5-9036-78fabc95d4ec\")\n",
"\n",
"print(stix_obj2)"
"print(stix_obj2.serialize(pretty=True))"
]
},
{

View File

@ -356,7 +356,7 @@
" \"pattern\": \"[file:hashes.md5 = 'd41d8cd98f00b204e9800998ecf8427e']\",\n",
" \"valid_from\": \"2017-09-26T23:33:39.829952Z\"\n",
"}\"\"\", version=\"2.0\")\n",
"print(indicator)"
"print(indicator.serialize(pretty=True))"
]
},
{

View File

@ -185,7 +185,7 @@
"\n",
"indicator2 = indicator.new_version(name=\"File hash for Foobar malware\",\n",
" labels=[\"malicious-activity\"])\n",
"print(indicator2)"
"print(indicator2.serialize(pretty=True))"
]
},
{
@ -326,7 +326,7 @@
],
"source": [
"indicator3 = indicator.new_version(description=None)\n",
"print(indicator3)"
"print(indicator3.serialize(pretty=True))"
]
},
{
@ -443,7 +443,7 @@
],
"source": [
"indicator4 = indicator3.revoke()\n",
"print(indicator4)"
"print(indicator4.serialize(pretty=True))"
]
}
],

View File

@ -506,7 +506,7 @@
"source": [
"for i in indicators():\n",
" for obj in i.related():\n",
" print(obj)"
" print(obj.serialize(pretty=True))"
]
},
{
@ -621,7 +621,7 @@
"source": [
"malware = get('malware--c0931cc6-c75e-47e5-9036-78fabc95d4ec')\n",
"indicator = malware.related(filters=Filter('type', '=', 'indicator'))\n",
"print(indicator[0])"
"print(indicator[0].serialize(pretty=True))"
]
},
{

View File

@ -24,7 +24,7 @@ To accomplish these goals, and to incorporate lessons learned while developing
where users would create an object and then assign attributes to it, in
``stix2`` all properties must be provided when creating the object.
2. Where necessary, library objects should act like ``dict``'s. When treated as
a ``str``, the JSON reprentation of the object should be used.
a ``str``, the JSON representation of the object should be used.
3. Core Python data types (including numeric types, ``datetime``) should be used
when appropriate, and serialized to the correct format in JSON as specified
in the STIX 2 spec.

View File

@ -1,4 +1,4 @@
from taxii2client import Collection
from taxii2client.v21 import Collection
import stix2
@ -8,7 +8,7 @@ import stix2
def main():
collection = Collection(
"http://127.0.0.1:5000/trustgroup1/collections/52892447-4d7e-4f70-b94d-d7f22742ff63/",
"http://127.0.0.1:5000/trustgroup1/collections/91a7b528-80eb-42ed-a74d-c6fbd5a26116/",
user="admin", password="Password0",
)
@ -16,12 +16,12 @@ def main():
taxii = stix2.TAXIICollectionSource(collection)
# get (url watch indicator)
indicator_fw = taxii.get("indicator--00000000-0000-4000-8000-000000000001")
indicator_fw = taxii.get("indicator--6770298f-0fd8-471a-ab8c-1c658a46574e")
print("\n\n-------Queried for Indicator - got:")
print(indicator_fw.serialize(indent=4))
# all versions (url watch indicator - currently two)
indicator_fw_versions = taxii.all_versions("indicator--00000000-0000-4000-8000-000000000001")
indicator_fw_versions = taxii.all_versions("indicator--6770298f-0fd8-471a-ab8c-1c658a46574e")
print("\n\n------Queried for indicator (all_versions()) - got:")
for indicator in indicator_fw_versions:
print(indicator.serialize(indent=4))

View File

@ -1,5 +1,7 @@
"""Base classes for type definitions in the STIX2 library."""
import collections
import collections.abc
import copy
import itertools
import re
@ -17,23 +19,12 @@ from .exceptions import (
)
from .markings import _MarkingsMixin
from .markings.utils import validate
from .serialization import (
STIXJSONEncoder, STIXJSONIncludeOptionalDefaultsEncoder, fp_serialize,
serialize,
)
from .registry import class_for_type
from .serialization import STIXJSONEncoder, fp_serialize, serialize
from .utils import NOW, PREFIX_21_REGEX, get_timestamp
from .versioning import new_version as _new_version
from .versioning import revoke as _revoke
try:
from collections.abc import Mapping
except ImportError:
from collections import Mapping
# TODO: Remove STIXJSONEncoder, STIXJSONIncludeOptionalDefaultsEncoder, serialize from __all__ on next major release.
# Kept for backwards compatibility.
__all__ = ['STIXJSONEncoder', 'STIXJSONIncludeOptionalDefaultsEncoder', '_STIXBase', 'serialize']
DEFAULT_ERROR = "{type} must have {property}='{expected}'."
SCO_DET_ID_NAMESPACE = uuid.UUID("00abedb4-aa42-466c-9c01-fed23315a9b7")
@ -42,19 +33,9 @@ def get_required_properties(properties):
return (k for k, v in properties.items() if v.required)
class _STIXBase(Mapping):
class _STIXBase(collections.abc.Mapping):
"""Base class for STIX object types"""
def object_properties(self):
props = set(self._properties.keys())
custom_props = list(set(self._inner.keys()) - props)
custom_props.sort()
all_properties = list(self._properties.keys())
all_properties.extend(custom_props) # Any custom properties to the bottom
return all_properties
def _check_property(self, prop_name, prop, kwargs, allow_custom):
if prop_name not in kwargs:
if hasattr(prop, 'default'):
@ -80,7 +61,7 @@ class _STIXBase(Mapping):
return has_custom
# interproperty constraint methods
# inter-property constraint methods
def _check_mutually_exclusive_properties(self, list_of_properties, at_least_one=True):
current_properties = self.properties_populated()
@ -89,20 +70,34 @@ class _STIXBase(Mapping):
if count > 1 or (at_least_one and count == 0):
raise MutuallyExclusivePropertiesError(self.__class__, list_of_properties)
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()))
def _check_at_least_one_property(self, properties_checked=None):
"""
Check whether one or more of the given properties are present.
:param properties_checked: An iterable of the names of the properties
of interest, or None to check against a default list. The default
list includes all properties defined on the object, with some
hard-coded exceptions.
:raises AtLeastOnePropertyError: If none of the given properties are
present.
"""
if properties_checked is None:
property_exceptions = {"extensions", "type"}
if isinstance(self, _Observable):
props_to_remove = ["type", "id", "defanged", "spec_version"]
else:
props_to_remove = ["type"]
property_exceptions |= {"id", "defanged", "spec_version"}
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)
properties_checked = self._properties.keys() - property_exceptions
if list_of_properties and (not list_of_properties_populated or list_of_properties_populated == set(['extensions'])):
raise AtLeastOnePropertyError(self.__class__, list_of_properties)
elif not isinstance(properties_checked, set):
properties_checked = set(properties_checked)
if properties_checked:
properties_checked_assigned = properties_checked & self.keys()
if not properties_checked_assigned:
raise AtLeastOnePropertyError(
self.__class__, properties_checked,
)
def _check_properties_dependency(self, list_of_properties, list_of_dependent_properties):
failed_dependency_pairs = []
@ -123,20 +118,49 @@ class _STIXBase(Mapping):
# Use the same timestamp for any auto-generated datetimes
self.__now = get_timestamp()
# Detect any keyword arguments not allowed for a specific type
custom_props = kwargs.pop('custom_properties', {})
if custom_props and not isinstance(custom_props, dict):
raise ValueError("'custom_properties' must be a dictionary")
extra_kwargs = kwargs.keys() - self._properties.keys()
if extra_kwargs and not allow_custom:
raise ExtraPropertiesError(cls, extra_kwargs)
# Detect any keyword arguments representing customization.
# In STIX 2.1, this is complicated by "toplevel-property-extension"
# type extensions, which can add extra properties which are *not*
# considered custom.
extensions = kwargs.get("extensions")
registered_toplevel_extension_props = {}
has_unregistered_toplevel_extension = False
if extensions:
for ext_id, ext in extensions.items():
if ext.get("extension_type") == "toplevel-property-extension":
registered_ext_class = class_for_type(
ext_id, "2.1", "extensions",
)
if registered_ext_class:
registered_toplevel_extension_props.update(
registered_ext_class._toplevel_properties,
)
else:
has_unregistered_toplevel_extension = True
if has_unregistered_toplevel_extension:
# Must assume all extras are extension properties, not custom.
custom_kwargs = set()
else:
# All toplevel property extensions (if any) have been
# registered. So we can tell what their properties are and
# treat only those as not custom.
custom_kwargs = kwargs.keys() - self._properties.keys() \
- registered_toplevel_extension_props.keys()
if custom_kwargs and not allow_custom:
raise ExtraPropertiesError(cls, custom_kwargs)
if custom_props:
# loophole for custom_properties...
allow_custom = True
all_custom_prop_names = extra_kwargs | custom_props.keys() - \
all_custom_prop_names = (custom_kwargs | custom_props.keys()) - \
self._properties.keys()
if all_custom_prop_names:
if not isinstance(self, stix2.v20._STIXBase20):
@ -147,30 +171,52 @@ class _STIXBase(Mapping):
reason="Property name '%s' must begin with an alpha character." % prop_name,
)
# Remove any keyword arguments whose value is None or [] (i.e. empty list)
setting_kwargs = {
k: v
for k, v in itertools.chain(kwargs.items(), custom_props.items())
if v is not None and v != []
}
# defined_properties = all properties defined on this type, plus all
# properties defined on this instance as a result of toplevel property
# extensions.
defined_properties = collections.ChainMap(
self._properties, registered_toplevel_extension_props,
)
# Detect any missing required properties
required_properties = set(get_required_properties(self._properties))
missing_kwargs = required_properties - set(setting_kwargs)
if missing_kwargs:
raise MissingPropertiesError(cls, missing_kwargs)
assigned_properties = collections.ChainMap(kwargs, custom_props)
# Establish property order: spec-defined, toplevel extension, custom.
toplevel_extension_props = registered_toplevel_extension_props.keys() \
| (kwargs.keys() - self._properties.keys() - custom_kwargs)
property_order = itertools.chain(
self._properties,
toplevel_extension_props,
sorted(all_custom_prop_names),
)
setting_kwargs = {}
has_custom = bool(all_custom_prop_names)
for prop_name, prop_metadata in self._properties.items():
for prop_name in property_order:
prop_val = assigned_properties.get(prop_name)
if prop_val not in (None, []):
setting_kwargs[prop_name] = prop_val
prop = defined_properties.get(prop_name)
if prop:
temp_custom = self._check_property(
prop_name, prop_metadata, setting_kwargs, allow_custom,
prop_name, prop, setting_kwargs, allow_custom,
)
has_custom = has_custom or temp_custom
# Detect any missing required properties
required_properties = set(
get_required_properties(defined_properties),
)
missing_kwargs = required_properties - setting_kwargs.keys()
if missing_kwargs:
raise MissingPropertiesError(cls, missing_kwargs)
# Cache defaulted optional properties for serialization
defaulted = []
for name, prop in self._properties.items():
for name, prop in defined_properties.items():
try:
if (
not prop.required and not hasattr(prop, '_fixed_value') and
@ -231,14 +277,12 @@ class _STIXBase(Mapping):
super(_STIXBase, self).__setattr__(name, value)
def __str__(self):
return self.serialize(pretty=True)
# Note: use .serialize() or fp_serialize() directly if specific formatting options are needed.
return self.serialize()
def __repr__(self):
props = [(k, self[k]) for k in self.object_properties() if self.get(k)]
return '{0}({1})'.format(
self.__class__.__name__,
', '.join(['{0!s}={1!r}'.format(k, v) for k, v in props]),
)
props = ', '.join([f"{k}={self[k]!r}" for k in self])
return f'{self.__class__.__name__}({props})'
def __deepcopy__(self, memo):
# Assume: we can ignore the memo argument, because no object will ever contain the same sub-object multiple times.
@ -334,21 +378,8 @@ class _Observable(_STIXBase):
def __init__(self, **kwargs):
# the constructor might be called independently of an observed data object
self._STIXBase__valid_refs = kwargs.pop('_valid_refs', [])
self._properties['extensions'].allow_custom = kwargs.get('allow_custom', False)
super(_Observable, self).__init__(**kwargs)
if 'id' not in kwargs and not isinstance(self, stix2.v20._Observable):
# Specific to 2.1+ observables: generate a deterministic ID
id_ = self._generate_id()
# Spec says fall back to UUIDv4 if no contributing properties were
# given. That's what already happened (the following is actually
# overwriting the default uuidv4), so nothing to do here.
if id_ is not None:
# Can't assign to self (we're immutable), so slip the ID in
# more sneakily.
self._inner["id"] = id_
def _check_ref(self, ref, prop, prop_name):
"""
Only for checking `*_ref` or `*_refs` properties in spec_version 2.0
@ -481,7 +512,7 @@ def _make_json_serializable(value):
json_value = value # default assumption
if isinstance(value, Mapping):
if isinstance(value, collections.abc.Mapping):
json_value = {
k: _make_json_serializable(v)
for k, v in value.items()

View File

@ -1,9 +1,10 @@
from collections import OrderedDict
from .base import _cls_init
from .properties import EnumProperty
from .registration import (
_register_marking, _register_object, _register_observable,
_register_observable_extension,
_get_extension_class, _register_extension, _register_marking,
_register_object, _register_observable,
)
@ -29,6 +30,11 @@ def _custom_object_builder(cls, type, properties, version, base_class):
def __init__(self, **kwargs):
base_class.__init__(self, **kwargs)
_cls_init(cls, self, kwargs)
ext = getattr(self, 'with_extension', None)
if ext and version != '2.0':
if 'extensions' not in self._inner:
self._inner['extensions'] = {}
self._inner['extensions'][ext] = _get_extension_class(ext, version)()
_CustomObject.__name__ = cls.__name__
@ -47,6 +53,11 @@ def _custom_marking_builder(cls, type, properties, version, base_class):
def __init__(self, **kwargs):
base_class.__init__(self, **kwargs)
_cls_init(cls, self, kwargs)
ext = getattr(self, 'with_extension', None)
if ext and version != '2.0':
if 'extensions' not in self._inner:
self._inner['extensions'] = {}
self._inner['extensions'][ext] = _get_extension_class(ext, version)()
_CustomMarking.__name__ = cls.__name__
@ -70,6 +81,11 @@ def _custom_observable_builder(cls, type, properties, version, base_class, id_co
def __init__(self, **kwargs):
base_class.__init__(self, **kwargs)
_cls_init(cls, self, kwargs)
ext = getattr(self, 'with_extension', None)
if ext and version != '2.0':
if 'extensions' not in self._inner:
self._inner['extensions'] = {}
self._inner['extensions'][ext] = _get_extension_class(ext, version)()
_CustomObservable.__name__ = cls.__name__
@ -77,13 +93,47 @@ def _custom_observable_builder(cls, type, properties, version, base_class, id_co
return _CustomObservable
def _custom_extension_builder(cls, observable, type, properties, version, base_class):
prop_dict = _get_properties_dict(properties)
def _custom_extension_builder(cls, type, properties, version, base_class):
properties = _get_properties_dict(properties)
toplevel_properties = None
# Auto-create an "extension_type" property from the class attribute, if
# it exists. How to treat the other properties which were given depends on
# the extension type.
extension_type = getattr(cls, "extension_type", None)
if extension_type:
# I suppose I could also go with a plain string property, since the
# value is fixed... but an enum property seems more true to the
# property's semantics. Also, I can't import a vocab module for the
# enum values without circular import errors. :(
extension_type_prop = EnumProperty(
[
"new-sdo", "new-sco", "new-sro", "property-extension",
"toplevel-property-extension",
],
required=False,
fixed=extension_type,
)
nested_properties = {
"extension_type": extension_type_prop,
}
if extension_type == "toplevel-property-extension":
toplevel_properties = properties
else:
nested_properties.update(properties)
else:
nested_properties = properties
class _CustomExtension(cls, base_class):
_type = type
_properties = prop_dict
_properties = nested_properties
if extension_type == "toplevel-property-extension":
_toplevel_properties = toplevel_properties
def __init__(self, **kwargs):
base_class.__init__(self, **kwargs)
@ -91,5 +141,5 @@ def _custom_extension_builder(cls, observable, type, properties, version, base_c
_CustomExtension.__name__ = cls.__name__
_register_observable_extension(observable, _CustomExtension, version=version)
_register_extension(_CustomExtension, version=version)
return _CustomExtension

View File

@ -257,7 +257,7 @@ def iterpath(obj, path=None):
def check_tlp_marking(marking_obj, spec_version):
# Specific TLP Marking validation case.
if marking_obj["definition_type"] == "tlp":
if marking_obj.get("definition_type", "") == "tlp":
color = marking_obj["definition"]["tlp"]
if color == "white":

View File

@ -86,6 +86,14 @@ def dict_to_stix2(stix_dict, allow_custom=False, version=None):
# flag allows for unknown custom objects too, but will not
# be parsed into STIX object, returned as is
return stix_dict
for key_id, ext_def in stix_dict.get('extensions', {}).items():
if (
key_id.startswith('extension-definition--') and
'property-extension' not in ext_def.get('extension_type', '')
):
# prevents ParseError for unregistered objects when
# allow_custom=False and the extension defines a new object
return stix_dict
raise ParseError("Can't parse unknown object type '%s'! For custom types, use the CustomObject decorator." % obj_type)
return obj_class(allow_custom=allow_custom, **stix_dict)

View File

@ -56,7 +56,7 @@ class TimestampConstant(_Constant):
class IntegerConstant(_Constant):
"""Pattern interger constant
"""Pattern integer constant
Args:
value (int): integer value
@ -265,7 +265,7 @@ class BasicObjectPathComponent(_ObjectPathComponent):
"""Basic object path component (for an observation or expression)
By "Basic", implies that the object path component is not a
list, object reference or futher referenced property, i.e. terminal
list, object reference or further referenced property, i.e. terminal
component
Args:

View File

@ -2,6 +2,7 @@
import base64
import binascii
import collections.abc
import copy
import inspect
import re
@ -13,20 +14,15 @@ import stix2.hashes
from .base import _STIXBase
from .exceptions import CustomContentError, DictionaryKeyError, STIXError
from .parsing import parse, parse_observable
from .registry import STIX2_OBJ_MAPS
from .registry import class_for_type
from .utils import (
STIXTypeClass, _get_dict, get_class_hierarchy_names, get_type_from_id,
is_object, is_stix_type, parse_into_datetime, to_enum,
)
from .version import DEFAULT_VERSION
try:
from collections.abc import Mapping
except ImportError:
from collections import Mapping
TYPE_REGEX = re.compile(r'^\-?[a-z0-9]+(-[a-z0-9]+)*\-?$')
TYPE_21_REGEX = re.compile(r'^([a-z][a-z0-9]*)+(-[a-z0-9]+)*\-?$')
TYPE_REGEX = re.compile(r'^-?[a-z0-9]+(-[a-z0-9]+)*-?$')
TYPE_21_REGEX = re.compile(r'^([a-z][a-z0-9]*)+([a-z0-9-]+)*-?$')
ERROR_INVALID_ID = (
"not a valid STIX identifier, must match <object-type>--<UUID>: {}"
)
@ -125,7 +121,7 @@ class Property(object):
creating an object with that property. No default value exists for
these properties. (Default: ``False``)
fixed: This provides a constant default value. Users are free to
provide this value explicity when constructing an object (which
provide this value explicitly when constructing an object (which
allows you to copy **all** values from an existing object to a new
object), but if the user provides a value other than the ``fixed``
value, it will raise an error. This is semantically equivalent to
@ -184,7 +180,7 @@ class Property(object):
if required and default:
raise STIXError(
"Cant't use 'required' and 'default' together. 'required'"
"Can't use 'required' and 'default' together. 'required'"
"really means 'the user must provide this.'",
)
@ -250,7 +246,7 @@ class ListProperty(Property):
if isinstance(item, self.contained):
valid = item
elif isinstance(item, Mapping):
elif isinstance(item, collections.abc.Mapping):
# attempt a mapping-like usage...
valid = self.contained(allow_custom=allow_custom, **item)
@ -738,7 +734,7 @@ class ObservableProperty(Property):
if dictified == {}:
raise ValueError("The observable property must contain a non-empty dictionary")
valid_refs = dict((k, v['type']) for (k, v) in dictified.items())
valid_refs = {k: v['type'] for (k, v) in dictified.items()}
has_custom = False
for key, obj in dictified.items():
@ -771,8 +767,7 @@ class ExtensionsProperty(DictionaryProperty):
"""Property for representing extensions on Observable objects.
"""
def __init__(self, spec_version=DEFAULT_VERSION, enclosing_type=None, required=False):
self.enclosing_type = enclosing_type
def __init__(self, spec_version=DEFAULT_VERSION, required=False):
super(ExtensionsProperty, self).__init__(spec_version=spec_version, required=required)
def clean(self, value, allow_custom):
@ -786,17 +781,21 @@ class ExtensionsProperty(DictionaryProperty):
raise ValueError("The extensions property must contain a dictionary")
has_custom = False
specific_type_map = STIX2_OBJ_MAPS[self.spec_version]['observable-extensions'].get(self.enclosing_type, {})
for key, subvalue in dictified.items():
if key in specific_type_map:
cls = specific_type_map[key]
if type(subvalue) is dict:
cls = class_for_type(key, self.spec_version, "extensions")
if cls:
if isinstance(subvalue, dict):
ext = cls(allow_custom=allow_custom, **subvalue)
elif type(subvalue) is cls:
# If already an instance of an _Extension class, assume it's valid
elif isinstance(subvalue, cls):
# If already an instance of the registered class, assume
# it's valid
ext = subvalue
else:
raise ValueError("Cannot determine extension type.")
raise TypeError(
"Can't create extension '{}' from {}.".format(
key, type(subvalue),
),
)
has_custom = has_custom or ext.has_custom
@ -810,12 +809,24 @@ class ExtensionsProperty(DictionaryProperty):
dictified[key] = ext
else:
if allow_custom:
# If an unregistered "extension-definition--" style extension,
# we don't know what's supposed to be in it, so we can't
# determine whether there's anything custom. So, assume there
# are no customizations. If it's a different type of extension,
# non-registration implies customization (since all spec-defined
# extensions should be pre-registered with the library).
if key.startswith('extension-definition--'):
_validate_id(
key, self.spec_version, 'extension-definition--',
)
elif allow_custom:
has_custom = True
dictified[key] = subvalue
else:
raise CustomContentError("Can't parse unknown extension type: {}".format(key))
dictified[key] = subvalue
return dictified, has_custom
@ -828,8 +839,9 @@ class STIXObjectProperty(Property):
def clean(self, value, allow_custom):
# Any STIX Object (SDO, SRO, or Marking Definition) can be added to
# a bundle with no further checks.
stix2_classes = {'_DomainObject', '_RelationshipObject', 'MarkingDefinition'}
if any(
x in ('_DomainObject', '_RelationshipObject', 'MarkingDefinition')
x in stix2_classes
for x in get_class_hierarchy_names(value)
):
# A simple "is this a spec version 2.1+ object" test. For now,

View File

@ -1,14 +1,13 @@
import re
from . import registry
from .base import _DomainObject, _Observable
from . import registry, version
from .base import _DomainObject
from .exceptions import DuplicateRegistrationError
from .properties import _validate_type
from .utils import PREFIX_21_REGEX, get_class_hierarchy_names
from .version import DEFAULT_VERSION
def _register_object(new_type, version=DEFAULT_VERSION):
def _register_object(new_type, version=version.DEFAULT_VERSION):
"""Register a custom STIX Object type.
Args:
@ -32,7 +31,7 @@ def _register_object(new_type, version=DEFAULT_VERSION):
properties = new_type._properties
if not version:
version = DEFAULT_VERSION
version = version.DEFAULT_VERSION
if version == "2.1":
for prop_name, prop in properties.items():
@ -45,7 +44,7 @@ def _register_object(new_type, version=DEFAULT_VERSION):
OBJ_MAP[new_type._type] = new_type
def _register_marking(new_marking, version=DEFAULT_VERSION):
def _register_marking(new_marking, version=version.DEFAULT_VERSION):
"""Register a custom STIX Marking Definition type.
Args:
@ -59,7 +58,7 @@ def _register_marking(new_marking, version=DEFAULT_VERSION):
properties = new_marking._properties
if not version:
version = DEFAULT_VERSION
version = version.DEFAULT_VERSION
_validate_type(mark_type, version)
@ -74,7 +73,7 @@ def _register_marking(new_marking, version=DEFAULT_VERSION):
OBJ_MAP_MARKING[mark_type] = new_marking
def _register_observable(new_observable, version=DEFAULT_VERSION):
def _register_observable(new_observable, version=version.DEFAULT_VERSION):
"""Register a custom STIX Cyber Observable type.
Args:
@ -86,7 +85,7 @@ def _register_observable(new_observable, version=DEFAULT_VERSION):
properties = new_observable._properties
if not version:
version = DEFAULT_VERSION
version = version.DEFAULT_VERSION
if version == "2.0":
# If using STIX2.0, check properties ending in "_ref/s" are ObjectReferenceProperties
@ -133,27 +132,25 @@ def _register_observable(new_observable, version=DEFAULT_VERSION):
OBJ_MAP_OBSERVABLE[new_observable._type] = new_observable
def _register_observable_extension(
observable, new_extension, version=DEFAULT_VERSION,
def _get_extension_class(extension_uuid, version):
"""Retrieve a registered class Extension"""
return registry.STIX2_OBJ_MAPS[version]['extensions'].get(extension_uuid)
def _register_extension(
new_extension, version=version.DEFAULT_VERSION,
):
"""Register a custom extension to a STIX Cyber Observable type.
"""Register a custom extension to any STIX Object type.
Args:
observable: An observable class or instance
new_extension (class): A class to register in the Observables
Extensions map.
new_extension (class): A class to register in the Extensions map.
version (str): Which STIX2 version to use. (e.g. "2.0", "2.1").
Defaults to the latest supported version.
"""
obs_class = observable if isinstance(observable, type) else \
type(observable)
ext_type = new_extension._type
properties = new_extension._properties
if not issubclass(obs_class, _Observable):
raise ValueError("'observable' must be a valid Observable class!")
_validate_type(ext_type, version)
if not new_extension._properties:
@ -163,37 +160,18 @@ def _register_observable_extension(
)
if version == "2.1":
if not ext_type.endswith('-ext'):
if not (ext_type.endswith('-ext') or ext_type.startswith('extension-definition--')):
raise ValueError(
"Invalid extension type name '%s': must end with '-ext'." %
"Invalid extension type name '%s': must end with '-ext' or start with 'extension-definition--<UUID>'." %
ext_type,
)
for prop_name, prop_value in properties.items():
for prop_name in properties.keys():
if not re.match(PREFIX_21_REGEX, prop_name):
raise ValueError("Property name '%s' must begin with an alpha character." % prop_name)
try:
observable_type = observable._type
except AttributeError:
raise ValueError(
"Unknown observable type. Custom observables must be "
"created with the @CustomObservable decorator.",
)
EXT_MAP = registry.STIX2_OBJ_MAPS[version]['extensions']
OBJ_MAP_OBSERVABLE = registry.STIX2_OBJ_MAPS[version]['observables']
EXT_MAP = registry.STIX2_OBJ_MAPS[version]['observable-extensions']
try:
if ext_type in EXT_MAP[observable_type].keys():
raise DuplicateRegistrationError("Observable Extension", ext_type)
EXT_MAP[observable_type][ext_type] = new_extension
except KeyError:
if observable_type not in OBJ_MAP_OBSERVABLE:
raise ValueError(
"Unknown observable type '%s'. Custom observables "
"must be created with the @CustomObservable decorator."
% observable_type,
)
else:
EXT_MAP[observable_type] = {ext_type: new_extension}
if ext_type in EXT_MAP:
raise DuplicateRegistrationError("Extension", ext_type)
EXT_MAP[ext_type] = new_extension

View File

@ -37,7 +37,7 @@ def _collect_stix2_mappings():
STIX2_OBJ_MAPS[ver] = {}
STIX2_OBJ_MAPS[ver]['objects'] = mod.OBJ_MAP
STIX2_OBJ_MAPS[ver]['observables'] = mod.OBJ_MAP_OBSERVABLE
STIX2_OBJ_MAPS[ver]['observable-extensions'] = mod.EXT_MAP
STIX2_OBJ_MAPS[ver]['extensions'] = mod.EXT_MAP
elif re.match(r'^stix2\.v2[0-9]\.common$', name) and is_pkg is False:
ver = _stix_vid_to_version(stix_vid)
mod = importlib.import_module(name, str(top_level_module.__name__))
@ -49,7 +49,8 @@ def class_for_type(stix_type, stix_version, category=None):
Get the registered class which implements a particular STIX type for a
particular STIX version.
:param stix_type: A STIX type as a string
:param stix_type: A STIX type as a string, or for extension-definition
style extensions, the STIX ID of the definition.
:param stix_version: A STIX version as a string, e.g. "2.1"
:param category: An optional "category" value, which is just used directly
as a second key after the STIX version, and depends on how the types
@ -69,12 +70,11 @@ def class_for_type(stix_type, stix_version, category=None):
if class_map:
cls = class_map.get(stix_type)
else:
cls = cat_map["objects"].get(stix_type) \
or cat_map["observables"].get(stix_type) \
or cat_map["markings"].get(stix_type)
# Left "observable-extensions" out; it has a different
# substructure. A version->category->type lookup would result
# in another map, not a class. So it doesn't fit the pattern.
cls = (
cat_map["objects"].get(stix_type) or
cat_map["observables"].get(stix_type) or
cat_map["markings"].get(stix_type) or
cat_map["extensions"].get(stix_type)
)
return cls

View File

@ -1,6 +1,5 @@
"""STIX2 core serialization methods."""
import copy
import datetime as dt
import io
@ -24,7 +23,7 @@ class STIXJSONEncoder(json.JSONEncoder):
if isinstance(obj, (dt.date, dt.datetime)):
return format_datetime(obj)
elif isinstance(obj, stix2.base._STIXBase):
tmp_obj = dict(copy.deepcopy(obj))
tmp_obj = dict(obj)
for prop_name in obj._defaulted_optional_properties:
del tmp_obj[prop_name]
return tmp_obj
@ -177,7 +176,7 @@ def find_property_index(obj, search_key, search_value):
if isinstance(obj, stix2.base._STIXBase):
if search_key in obj and obj[search_key] == search_value:
idx = _find(obj.object_properties(), search_key)
idx = _find(list(obj), search_key)
else:
idx = _find_property_in_seq(obj.values(), search_key, search_value)
elif isinstance(obj, dict):

View File

@ -37,7 +37,7 @@ def test_attack_pattern_example():
description="...",
)
assert str(ap) == EXPECTED
assert ap.serialize(pretty=True) == EXPECTED
@pytest.mark.parametrize(
@ -111,6 +111,6 @@ def test_less_precise_timestamps():
description="...",
)
assert str(ap) == EXPECTED
assert ap.serialize(pretty=True) == EXPECTED
# TODO: Add other examples

View File

@ -120,7 +120,6 @@ def test_create_bundle_fp_serialize_pretty(indicator, malware, relationship):
bundle.fp_serialize(buffer, pretty=True)
assert str(bundle) == EXPECTED_BUNDLE
assert bundle.serialize(pretty=True) == EXPECTED_BUNDLE
assert buffer.getvalue() == EXPECTED_BUNDLE
@ -138,7 +137,7 @@ def test_create_bundle_fp_serialize_nonpretty(indicator, malware, relationship):
def test_create_bundle1(indicator, malware, relationship):
bundle = stix2.v20.Bundle(objects=[indicator, malware, relationship])
assert str(bundle) == EXPECTED_BUNDLE
assert bundle.serialize(pretty=True) == EXPECTED_BUNDLE
assert bundle.serialize(pretty=True) == EXPECTED_BUNDLE
@ -151,31 +150,31 @@ def test_create_bundle2(indicator, malware, relationship):
def test_create_bundle_with_positional_args(indicator, malware, relationship):
bundle = stix2.v20.Bundle(indicator, malware, relationship)
assert str(bundle) == EXPECTED_BUNDLE
assert bundle.serialize(pretty=True) == EXPECTED_BUNDLE
def test_create_bundle_with_positional_listarg(indicator, malware, relationship):
bundle = stix2.v20.Bundle([indicator, malware, relationship])
assert str(bundle) == EXPECTED_BUNDLE
assert bundle.serialize(pretty=True) == EXPECTED_BUNDLE
def test_create_bundle_with_listarg_and_positional_arg(indicator, malware, relationship):
bundle = stix2.v20.Bundle([indicator, malware], relationship)
assert str(bundle) == EXPECTED_BUNDLE
assert bundle.serialize(pretty=True) == EXPECTED_BUNDLE
def test_create_bundle_with_listarg_and_kwarg(indicator, malware, relationship):
bundle = stix2.v20.Bundle([indicator, malware], objects=[relationship])
assert str(bundle) == EXPECTED_BUNDLE
assert bundle.serialize(pretty=True) == EXPECTED_BUNDLE
def test_create_bundle_with_arg_listarg_and_kwarg(indicator, malware, relationship):
bundle = stix2.v20.Bundle([indicator], malware, objects=[relationship])
assert str(bundle) == EXPECTED_BUNDLE
assert bundle.serialize(pretty=True) == EXPECTED_BUNDLE
def test_create_bundle_invalid(indicator, malware, relationship):

View File

@ -21,7 +21,7 @@ EXPECTED = """{
def test_campaign_example():
campaign = stix2.v20.Campaign(**CAMPAIGN_MORE_KWARGS)
assert str(campaign) == EXPECTED
assert campaign.serialize(pretty=True) == EXPECTED
@pytest.mark.parametrize(

View File

@ -28,7 +28,7 @@ def test_course_of_action_example():
description="This is how to add a filter rule to block inbound access to TCP port 80 to the existing UDP 1434 filter ...",
)
assert str(coa) == EXPECTED
assert coa.serialize(pretty=True) == EXPECTED
@pytest.mark.parametrize(

View File

@ -480,8 +480,18 @@ class NewObservable():
def test_custom_observable_object_1():
no = NewObservable(property1='something')
no = NewObservable(
property1='something',
extensions={
'archive-ext': stix2.v20.observables.ArchiveExt(
contains_refs=['file--e277603e-1060-5ad4-9937-c26c97f1ca68'],
version='2.0',
comment='for real',
),
},
)
assert no.property1 == 'something'
assert no.extensions['archive-ext'].comment == 'for real'
def test_custom_observable_object_2():
@ -740,7 +750,7 @@ def test_observed_data_with_custom_observable_object():
@stix2.v20.CustomExtension(
stix2.v20.DomainName, 'x-new-ext', [
'x-new-ext', [
('property1', stix2.properties.StringProperty(required=True)),
('property2', stix2.properties.IntegerProperty()),
],
@ -785,7 +795,7 @@ def test_custom_extension_wrong_observable_type():
},
)
assert 'Cannot determine extension type' in excinfo.value.reason
assert "Can't create extension 'ntfs-ext' from" in excinfo.value.reason
@pytest.mark.parametrize(
@ -802,7 +812,7 @@ def test_custom_extension_wrong_observable_type():
)
def test_custom_extension_with_list_and_dict_properties_observable_type(data):
@stix2.v20.CustomExtension(
stix2.v20.UserAccount, 'some-extension', [
'some-extension', [
('keys', stix2.properties.ListProperty(stix2.properties.DictionaryProperty, required=True)),
],
)
@ -810,55 +820,13 @@ def test_custom_extension_with_list_and_dict_properties_observable_type(data):
pass
example = SomeCustomExtension(keys=[{'test123': 123, 'test345': 'aaaa'}])
assert data == str(example)
def test_custom_extension_invalid_observable():
# These extensions are being applied to improperly-created Observables.
# The Observable classes should have been created with the CustomObservable decorator.
class Foo(object):
pass
with pytest.raises(ValueError) as excinfo:
@stix2.v20.CustomExtension(
Foo, 'x-new-ext', [
('property1', stix2.properties.StringProperty(required=True)),
],
)
class FooExtension():
pass # pragma: no cover
assert str(excinfo.value) == "'observable' must be a valid Observable class!"
class Bar(stix2.v20.observables._Observable):
pass
with pytest.raises(ValueError) as excinfo:
@stix2.v20.CustomExtension(
Bar, 'x-new-ext', [
('property1', stix2.properties.StringProperty(required=True)),
],
)
class BarExtension():
pass
assert "Unknown observable type" in str(excinfo.value)
assert "Custom observables must be created with the @CustomObservable decorator." in str(excinfo.value)
class Baz(stix2.v20.observables._Observable):
_type = 'Baz'
with pytest.raises(ValueError) as excinfo:
@stix2.v20.CustomExtension(
Baz, 'x-new-ext', [
('property1', stix2.properties.StringProperty(required=True)),
],
)
class BazExtension():
pass
assert "Unknown observable type" in str(excinfo.value)
assert "Custom observables must be created with the @CustomObservable decorator." in str(excinfo.value)
assert data == example.serialize(pretty=True)
def test_custom_extension_invalid_type_name():
with pytest.raises(ValueError) as excinfo:
@stix2.v20.CustomExtension(
stix2.v20.File, 'x', {
'x', {
'property1': stix2.properties.StringProperty(required=True),
},
)
@ -868,7 +836,7 @@ def test_custom_extension_invalid_type_name():
with pytest.raises(ValueError) as excinfo:
@stix2.v20.CustomExtension(
stix2.File, 'x_new_ext', {
'x_new_ext', {
'property1': stix2.properties.StringProperty(required=True),
},
)
@ -879,28 +847,28 @@ def test_custom_extension_invalid_type_name():
def test_custom_extension_no_properties():
with pytest.raises(ValueError):
@stix2.v20.CustomExtension(stix2.v20.DomainName, 'x-new-ext2', None)
@stix2.v20.CustomExtension('x-new-ext2', None)
class BarExtension():
pass
def test_custom_extension_empty_properties():
with pytest.raises(ValueError):
@stix2.v20.CustomExtension(stix2.v20.DomainName, 'x-new-ext2', [])
@stix2.v20.CustomExtension('x-new-ext2', [])
class BarExtension():
pass
def test_custom_extension_dict_properties():
with pytest.raises(ValueError):
@stix2.v20.CustomExtension(stix2.v20.DomainName, 'x-new-ext2', {})
@stix2.v20.CustomExtension('x-new-ext2', {})
class BarExtension():
pass
def test_custom_extension_no_init_1():
@stix2.v20.CustomExtension(
stix2.v20.DomainName, 'x-new-extension', [
'x-new-extension', [
('property1', stix2.properties.StringProperty(required=True)),
],
)
@ -913,7 +881,7 @@ def test_custom_extension_no_init_1():
def test_custom_extension_no_init_2():
@stix2.v20.CustomExtension(
stix2.v20.DomainName, 'x-new-ext2', [
'x-new-ext2', [
('property1', stix2.properties.StringProperty(required=True)),
],
)
@ -1059,7 +1027,7 @@ def test_register_custom_object():
def test_extension_property_location():
assert 'extensions' in stix2.v20.OBJ_MAP_OBSERVABLE['x-new-observable']._properties
assert 'extensions' not in stix2.v20.EXT_MAP['domain-name']['x-new-ext']._properties
assert 'extensions' not in stix2.v20.EXT_MAP['x-new-ext']._properties
@pytest.mark.parametrize(
@ -1095,7 +1063,7 @@ def test_custom_object_nested_dictionary(data):
dictionary={'key': {'key_b': 'value', 'key_a': 'value'}},
)
assert data == str(example)
assert data == example.serialize(pretty=True)
@stix2.v20.CustomObject(
@ -1177,7 +1145,7 @@ def test_register_marking_with_version():
def test_register_observable_extension_with_version():
@stix2.v20.CustomExtension(
stix2.v20.UserAccount, 'some-extension-2', [
'some-extension-2', [
('keys', stix2.properties.StringProperty(required=True)),
],
)
@ -1186,13 +1154,13 @@ def test_register_observable_extension_with_version():
example = SomeCustomExtension2(keys='test123')
assert example._type in stix2.registry.STIX2_OBJ_MAPS['2.0']['observable-extensions']['user-account']
assert example._type in stix2.registry.STIX2_OBJ_MAPS['2.0']['extensions']
def test_register_duplicate_observable_extension():
with pytest.raises(DuplicateRegistrationError) as excinfo:
@stix2.v20.CustomExtension(
stix2.v20.UserAccount, 'some-extension-2', [
'some-extension-2', [
('property1', stix2.properties.StringProperty(required=True)),
('property2', stix2.properties.IntegerProperty()),
],

View File

@ -26,7 +26,7 @@ def test_external_reference_veris():
url="https://github.com/vz-risk/VCDB/blob/master/data/json/0001AA7F-C601-424A-B2B8-BE6C9F5164E7.json",
)
assert str(ref) == VERIS
assert ref.serialize(pretty=True) == VERIS
CAPEC = """{
@ -41,7 +41,7 @@ def test_external_reference_capec():
external_id="CAPEC-550",
)
assert str(ref) == CAPEC
assert ref.serialize(pretty=True) == CAPEC
assert re.match("ExternalReference\\(source_name=u?'capec', external_id=u?'CAPEC-550'\\)", repr(ref))
@ -59,7 +59,7 @@ def test_external_reference_capec_url():
url="http://capec.mitre.org/data/definitions/550.html",
)
assert str(ref) == CAPEC_URL
assert ref.serialize(pretty=True) == CAPEC_URL
THREAT_REPORT = """{
@ -76,7 +76,7 @@ def test_external_reference_threat_report():
url="http://www.example.com/threat-report.pdf",
)
assert str(ref) == THREAT_REPORT
assert ref.serialize(pretty=True) == THREAT_REPORT
BUGZILLA = """{
@ -93,7 +93,7 @@ def test_external_reference_bugzilla():
url="https://www.example.com/bugs/1370",
)
assert str(ref) == BUGZILLA
assert ref.serialize(pretty=True) == BUGZILLA
OFFLINE = """{
@ -108,7 +108,7 @@ def test_external_reference_offline():
description="Threat report",
)
assert str(ref) == OFFLINE
assert ref.serialize(pretty=True) == OFFLINE
assert re.match("ExternalReference\\(source_name=u?'ACME Threat Intel', description=u?'Threat report'\\)", repr(ref))
# Yikes! This works
assert eval("stix2." + repr(ref)) == ref

View File

@ -26,7 +26,7 @@ def test_identity_example():
identity_class="individual",
)
assert str(identity) == EXPECTED
assert identity.serialize(pretty=True) == EXPECTED
@pytest.mark.parametrize(
@ -74,6 +74,6 @@ def test_identity_with_custom():
)
assert identity.x_foo == "bar"
assert "x_foo" in identity.object_properties()
assert "x_foo" in identity
# TODO: Add other examples

View File

@ -28,6 +28,7 @@ EXPECTED_INDICATOR_REPR = "Indicator(" + " ".join(
modified='2017-01-01T00:00:01.000Z',
pattern="[file:hashes.MD5 = 'd41d8cd98f00b204e9800998ecf8427e']",
valid_from='1970-01-01T00:00:01Z',
revoked=False,
labels=['malicious-activity']
""".split(),
) + ")"
@ -48,7 +49,7 @@ def test_indicator_with_all_required_properties():
)
assert ind.revoked is False
assert str(ind) == EXPECTED_INDICATOR
assert ind.serialize(pretty=True) == EXPECTED_INDICATOR
rep = re.sub(r"(\[|=| )u('|\"|\\\'|\\\")", r"\g<1>\g<2>", repr(ind))
assert rep == EXPECTED_INDICATOR_REPR

View File

@ -38,7 +38,7 @@ def test_intrusion_set_example():
goals=["acquisition-theft", "harassment", "damage"],
)
assert str(intrusion_set) == EXPECTED
assert intrusion_set.serialize(pretty=True) == EXPECTED
@pytest.mark.parametrize(

View File

@ -16,7 +16,7 @@ def test_lockheed_martin_cyber_kill_chain():
phase_name="reconnaissance",
)
assert str(recon) == LMCO_RECON
assert recon.serialize(pretty=True) == LMCO_RECON
FOO_PRE_ATTACK = """{
@ -31,7 +31,7 @@ def test_kill_chain_example():
phase_name="pre-attack",
)
assert str(preattack) == FOO_PRE_ATTACK
assert preattack.serialize(pretty=True) == FOO_PRE_ATTACK
def test_kill_chain_required_properties():

View File

@ -33,7 +33,7 @@ def test_malware_with_all_required_properties():
name="Cryptolocker",
)
assert str(mal) == EXPECTED_MALWARE
assert mal.serialize(pretty=True) == EXPECTED_MALWARE
def test_malware_with_empty_optional_field():
@ -49,7 +49,7 @@ def test_malware_with_empty_optional_field():
external_references=[],
)
assert str(mal) == EXPECTED_MALWARE
assert mal.serialize(pretty=True) == EXPECTED_MALWARE
def test_malware_autogenerated_properties(malware):

View File

@ -21,7 +21,7 @@ EXPECTED_TLP_MARKING_DEFINITION = """{
EXPECTED_STATEMENT_MARKING_DEFINITION = """{
"type": "marking-definition",
"id": "marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9",
"created": "2017-01-20T00:00:00Z",
"created": "2017-01-20T00:00:00.000Z",
"definition_type": "statement",
"definition": {
"statement": "Copyright 2016, Example Corp"
@ -71,7 +71,7 @@ EXPECTED_CAMPAIGN_WITH_GRANULAR_MARKINGS = """{
def test_marking_def_example_with_tlp():
assert str(TLP_WHITE) == EXPECTED_TLP_MARKING_DEFINITION
assert TLP_WHITE.serialize(pretty=True) == EXPECTED_TLP_MARKING_DEFINITION
def test_marking_def_example_with_statement_positional_argument():
@ -82,7 +82,7 @@ def test_marking_def_example_with_statement_positional_argument():
definition=stix2.v20.StatementMarking(statement="Copyright 2016, Example Corp"),
)
assert str(marking_definition) == EXPECTED_STATEMENT_MARKING_DEFINITION
assert marking_definition.serialize(pretty=True) == EXPECTED_STATEMENT_MARKING_DEFINITION
def test_marking_def_example_with_kwargs_statement():
@ -94,7 +94,7 @@ def test_marking_def_example_with_kwargs_statement():
definition=stix2.v20.StatementMarking(**kwargs),
)
assert str(marking_definition) == EXPECTED_STATEMENT_MARKING_DEFINITION
assert marking_definition.serialize(pretty=True) == EXPECTED_STATEMENT_MARKING_DEFINITION
def test_marking_def_invalid_type():
@ -118,7 +118,7 @@ def test_campaign_with_markings_example():
description="Campaign by Green Group against a series of targets in the financial services sector.",
object_marking_refs=TLP_WHITE,
)
assert str(campaign) == EXPECTED_CAMPAIGN_WITH_OBJECT_MARKING
assert campaign.serialize(pretty=True) == EXPECTED_CAMPAIGN_WITH_OBJECT_MARKING
def test_granular_example():
@ -127,7 +127,7 @@ def test_granular_example():
selectors=["abc", "abc.[23]", "abc.def", "abc.[2].efg"],
)
assert str(granular_marking) == EXPECTED_GRANULAR_MARKING
assert granular_marking.serialize(pretty=True) == EXPECTED_GRANULAR_MARKING
def test_granular_example_with_bad_selector():
@ -159,7 +159,7 @@ def test_campaign_with_granular_markings_example():
),
],
)
assert str(campaign) == EXPECTED_CAMPAIGN_WITH_GRANULAR_MARKINGS
assert campaign.serialize(pretty=True) == EXPECTED_CAMPAIGN_WITH_GRANULAR_MARKINGS
@pytest.mark.parametrize(

View File

@ -47,7 +47,7 @@ def test_observed_data_example():
},
)
assert str(observed_data) == EXPECTED
assert observed_data.serialize(pretty=True) == EXPECTED
EXPECTED_WITH_REF = """{
@ -97,7 +97,7 @@ def test_observed_data_example_with_refs():
},
)
assert str(observed_data) == EXPECTED_WITH_REF
assert observed_data.serialize(pretty=True) == EXPECTED_WITH_REF
def test_observed_data_example_with_bad_refs():
@ -1117,6 +1117,7 @@ def test_process_example_empty_error():
assert excinfo.value.cls == stix2.v20.Process
properties_of_process = list(stix2.v20.Process._properties.keys())
properties_of_process.remove("type")
properties_of_process.remove("extensions")
assert excinfo.value.properties == sorted(properties_of_process)
msg = "At least one of the ({1}) properties for {0} must be populated."
msg = msg.format(

View File

@ -452,7 +452,7 @@ def test_embedded_property_dict_custom():
def test_extension_property_valid():
ext_prop = ExtensionsProperty(spec_version="2.0", enclosing_type='file')
ext_prop = ExtensionsProperty(spec_version="2.0")
result = ext_prop.clean(
{
'windows-pebinary-ext': {
@ -481,13 +481,13 @@ def test_extension_property_valid():
def test_extension_property_invalid1():
ext_prop = ExtensionsProperty(spec_version="2.0", enclosing_type='file')
ext_prop = ExtensionsProperty(spec_version="2.0")
with pytest.raises(ValueError):
ext_prop.clean(1, False)
def test_extension_property_invalid2():
ext_prop = ExtensionsProperty(spec_version="2.0", enclosing_type='file')
ext_prop = ExtensionsProperty(spec_version="2.0")
with pytest.raises(CustomContentError):
ext_prop.clean(
{
@ -509,7 +509,7 @@ def test_extension_property_invalid2():
def test_extension_property_invalid3():
ext_prop = ExtensionsProperty(spec_version="2.0", enclosing_type='file')
ext_prop = ExtensionsProperty(spec_version="2.0")
with pytest.raises(ExtraPropertiesError):
ext_prop.clean(
{
@ -537,20 +537,6 @@ def test_extension_property_invalid3():
assert result[1]
def test_extension_property_invalid_type():
ext_prop = ExtensionsProperty(spec_version="2.0", enclosing_type='indicator')
with pytest.raises(CustomContentError) as excinfo:
ext_prop.clean(
{
'windows-pebinary-ext': {
'pe_type': 'exe',
},
},
False,
)
assert "Can't parse unknown extension" in str(excinfo.value)
def test_extension_at_least_one_property_constraint():
with pytest.raises(AtLeastOnePropertyError):
stix2.v20.TCPExt()

View File

@ -32,7 +32,7 @@ def test_relationship_all_required_properties():
source_ref=INDICATOR_ID,
target_ref=MALWARE_ID,
)
assert str(rel) == EXPECTED_RELATIONSHIP
assert rel.serialize(pretty=True) == EXPECTED_RELATIONSHIP
def test_relationship_autogenerated_properties(relationship):

View File

@ -48,7 +48,7 @@ def test_report_example():
],
)
assert str(report) == EXPECTED
assert report.serialize(pretty=True) == EXPECTED
def test_report_example_objects_in_object_refs():
@ -68,7 +68,7 @@ def test_report_example_objects_in_object_refs():
],
)
assert str(report) == EXPECTED
assert report.serialize(pretty=True) == EXPECTED
def test_report_example_objects_in_object_refs_with_bad_id():

View File

@ -33,7 +33,7 @@ BAD_SIGHTING = """{
def test_sighting_all_required_properties():
now = dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc)
s = stix2.v20.Sighting(
sighting = stix2.v20.Sighting(
type='sighting',
id=SIGHTING_ID,
created=now,
@ -41,7 +41,7 @@ def test_sighting_all_required_properties():
sighting_of_ref=INDICATOR_ID,
where_sighted_refs=[IDENTITY_ID],
)
assert str(s) == EXPECTED_SIGHTING
assert sighting.serialize(pretty=True) == EXPECTED_SIGHTING
def test_sighting_bad_where_sighted_refs():

View File

@ -32,7 +32,7 @@ def test_threat_actor_example():
name="Evil Org",
)
assert str(threat_actor) == EXPECTED
assert threat_actor.serialize(pretty=True) == EXPECTED
@pytest.mark.parametrize(

View File

@ -43,7 +43,7 @@ def test_tool_example():
name="VNC",
)
assert str(tool) == EXPECTED
assert tool.serialize(pretty=True) == EXPECTED
@pytest.mark.parametrize(

View File

@ -36,7 +36,7 @@ def test_vulnerability_example():
],
)
assert str(vulnerability) == EXPECTED
assert vulnerability.serialize(pretty=True) == EXPECTED
@pytest.mark.parametrize(

View File

@ -9,6 +9,7 @@ CAMPAIGN_ID = "campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f"
COURSE_OF_ACTION_ID = "course-of-action--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f"
GROUPING_ID = "grouping--753abcde-3141-5926-ace5-0a810b1ff996"
IDENTITY_ID = "identity--311b2d2d-f010-4473-83ec-1edf84858f4c"
INCIDENT_ID = "incident--40fc3b35-0dc4-4afd-9927-288d44bfce20"
INDICATOR_ID = "indicator--a740531e-63ff-4e49-a9e1-a0a3eed0e3e7"
INFRASTRUCTURE_ID = "infrastructure--3000ae1b-784c-f03d-8abc-0a625b2ff018"
INTRUSION_SET_ID = "intrusion-set--4e78f46f-a023-4e5f-bc24-71b3ca22ec29"
@ -26,6 +27,12 @@ TOOL_ID = "tool--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f"
SIGHTING_ID = "sighting--bfbc19db-ec35-4e45-beed-f8bde2a772fb"
VULNERABILITY_ID = "vulnerability--0c7b5b88-8ff7-4a4d-aa9d-feb398cd0061"
EXTENSION_DEFINITION_IDS = [
"extension-definition--1f611280-fbe1-48e8-92ab-ff47ce02d5b7", # new-sdo
"extension-definition--368f4787-5b43-467c-9693-0c9de4289c4b", # property-extension
"extension-definition--dd73de4f-a7f3-49ea-8ec1-8e884196b7a8", # top-level-property-extension
"extension-definition--150c1738-28c9-44d0-802d-70523218240b", # new-sdo, new-sco, property-extension
]
MARKING_IDS = [
"marking-definition--613f2e26-407d-48c7-9eca-b8e91df99dc9",
"marking-definition--443eb5c3-a76c-4a0a-8caa-e93998e7bc09",

View File

@ -38,7 +38,7 @@ def test_attack_pattern_example():
description="...",
)
assert str(ap) == EXPECTED
assert ap.serialize(pretty=True) == EXPECTED
@pytest.mark.parametrize(
@ -114,7 +114,7 @@ def test_less_precise_timestamps():
description="...",
)
assert str(ap) == EXPECTED
assert ap.serialize(pretty=True) == EXPECTED
# TODO: Add other examples

View File

@ -130,7 +130,6 @@ def test_create_bundle_fp_serialize_pretty(indicator, malware, relationship):
bundle.fp_serialize(buffer, pretty=True)
assert str(bundle) == EXPECTED_BUNDLE
assert bundle.serialize(pretty=True) == EXPECTED_BUNDLE
assert buffer.getvalue() == EXPECTED_BUNDLE
@ -148,7 +147,7 @@ def test_create_bundle_fp_serialize_nonpretty(indicator, malware, relationship):
def test_create_bundle1(indicator, malware, relationship):
bundle = stix2.v21.Bundle(objects=[indicator, malware, relationship])
assert str(bundle) == EXPECTED_BUNDLE
assert bundle.serialize(pretty=True) == EXPECTED_BUNDLE
assert bundle.serialize(pretty=True) == EXPECTED_BUNDLE
@ -161,31 +160,31 @@ def test_create_bundle2(indicator, malware, relationship):
def test_create_bundle_with_positional_args(indicator, malware, relationship):
bundle = stix2.v21.Bundle(indicator, malware, relationship)
assert str(bundle) == EXPECTED_BUNDLE
assert bundle.serialize(pretty=True) == EXPECTED_BUNDLE
def test_create_bundle_with_positional_listarg(indicator, malware, relationship):
bundle = stix2.v21.Bundle([indicator, malware, relationship])
assert str(bundle) == EXPECTED_BUNDLE
assert bundle.serialize(pretty=True) == EXPECTED_BUNDLE
def test_create_bundle_with_listarg_and_positional_arg(indicator, malware, relationship):
bundle = stix2.v21.Bundle([indicator, malware], relationship)
assert str(bundle) == EXPECTED_BUNDLE
assert bundle.serialize(pretty=True) == EXPECTED_BUNDLE
def test_create_bundle_with_listarg_and_kwarg(indicator, malware, relationship):
bundle = stix2.v21.Bundle([indicator, malware], objects=[relationship])
assert str(bundle) == EXPECTED_BUNDLE
assert bundle.serialize(pretty=True) == EXPECTED_BUNDLE
def test_create_bundle_with_arg_listarg_and_kwarg(indicator, malware, relationship):
bundle = stix2.v21.Bundle([indicator], malware, objects=[relationship])
assert str(bundle) == EXPECTED_BUNDLE
assert bundle.serialize(pretty=True) == EXPECTED_BUNDLE
def test_create_bundle_invalid(indicator, malware, relationship):

View File

@ -24,7 +24,7 @@ def test_campaign_example():
**CAMPAIGN_MORE_KWARGS
)
assert str(campaign) == EXPECTED
assert campaign.serialize(pretty=True) == EXPECTED
@pytest.mark.parametrize(

View File

@ -42,7 +42,7 @@ COA_WITH_REF_DICT = json.loads(COA_WITH_REF_JSON)
)
def test_course_of_action_example(sdo_json, sdo_dict):
coa = stix2.v21.CourseOfAction(**sdo_dict)
assert str(coa) == sdo_json
assert coa.serialize(pretty=True) == sdo_json
@pytest.mark.parametrize(

View File

@ -1,3 +1,4 @@
import contextlib
import uuid
import pytest
@ -8,7 +9,9 @@ import stix2.registration
import stix2.registry
import stix2.v21
from ...exceptions import DuplicateRegistrationError, InvalidValueError
from ...exceptions import (
DuplicateRegistrationError, InvalidValueError, MissingPropertiesError,
)
from .constants import FAKE_TIME, IDENTITY_ID, MARKING_DEFINITION_ID
# Custom Properties in SDOs
@ -939,7 +942,7 @@ def test_custom_observable_object_no_id_contrib_props():
@stix2.v21.CustomExtension(
stix2.v21.DomainName, 'x-new-ext', [
'x-new-ext', [
('property1', stix2.properties.StringProperty(required=True)),
('property2', stix2.properties.IntegerProperty()),
],
@ -984,7 +987,7 @@ def test_custom_extension_wrong_observable_type():
},
)
assert 'Cannot determine extension type' in excinfo.value.reason
assert "Can't create extension 'ntfs-ext'" in excinfo.value.reason
@pytest.mark.parametrize(
@ -1001,7 +1004,7 @@ def test_custom_extension_wrong_observable_type():
)
def test_custom_extension_with_list_and_dict_properties_observable_type(data):
@stix2.v21.CustomExtension(
stix2.v21.UserAccount, 'x-some-extension-ext', [
'x-some-extension-ext', [
('keys', stix2.properties.ListProperty(stix2.properties.DictionaryProperty, required=True)),
],
)
@ -1009,55 +1012,13 @@ def test_custom_extension_with_list_and_dict_properties_observable_type(data):
pass
example = SomeCustomExtension(keys=[{'test123': 123, 'test345': 'aaaa'}])
assert data == str(example)
def test_custom_extension_invalid_observable():
# These extensions are being applied to improperly-created Observables.
# The Observable classes should have been created with the CustomObservable decorator.
class Foo(object):
pass
with pytest.raises(ValueError) as excinfo:
@stix2.v21.CustomExtension(
Foo, 'x-new-ext', [
('property1', stix2.properties.StringProperty(required=True)),
],
)
class FooExtension():
pass # pragma: no cover
assert str(excinfo.value) == "'observable' must be a valid Observable class!"
class Bar(stix2.v21.observables._Observable):
pass
with pytest.raises(ValueError) as excinfo:
@stix2.v21.CustomExtension(
Bar, 'x-new-ext', [
('property1', stix2.properties.StringProperty(required=True)),
],
)
class BarExtension():
pass
assert "Unknown observable type" in str(excinfo.value)
assert "Custom observables must be created with the @CustomObservable decorator." in str(excinfo.value)
class Baz(stix2.v21.observables._Observable):
_type = 'Baz'
with pytest.raises(ValueError) as excinfo:
@stix2.v21.CustomExtension(
Baz, 'x-new-ext', [
('property1', stix2.properties.StringProperty(required=True)),
],
)
class BazExtension():
pass
assert "Unknown observable type" in str(excinfo.value)
assert "Custom observables must be created with the @CustomObservable decorator." in str(excinfo.value)
assert data == example.serialize(pretty=True)
def test_custom_extension_invalid_type_name():
with pytest.raises(ValueError) as excinfo:
@stix2.v21.CustomExtension(
stix2.v21.File, 'x', {
'x', {
'property1': stix2.properties.StringProperty(required=True),
},
)
@ -1067,7 +1028,7 @@ def test_custom_extension_invalid_type_name():
with pytest.raises(ValueError) as excinfo:
@stix2.v21.CustomExtension(
stix2.v21.File, 'x_new_ext', {
'x_new_ext', {
'property1': stix2.properties.StringProperty(required=True),
},
)
@ -1077,7 +1038,7 @@ def test_custom_extension_invalid_type_name():
with pytest.raises(ValueError) as excinfo:
@stix2.v21.CustomExtension(
stix2.v21.File, '7x-new-ext', {
'7x-new-ext', {
'property1': stix2.properties.StringProperty(required=True),
},
)
@ -1088,28 +1049,28 @@ def test_custom_extension_invalid_type_name():
def test_custom_extension_no_properties():
with pytest.raises(ValueError):
@stix2.v21.CustomExtension(stix2.v21.DomainName, 'x-new2-ext', None)
@stix2.v21.CustomExtension('x-new2-ext', None)
class BarExtension():
pass
def test_custom_extension_empty_properties():
with pytest.raises(ValueError):
@stix2.v21.CustomExtension(stix2.v21.DomainName, 'x-new2-ext', [])
@stix2.v21.CustomExtension('x-new2-ext', [])
class BarExtension():
pass
def test_custom_extension_dict_properties():
with pytest.raises(ValueError):
@stix2.v21.CustomExtension(stix2.v21.DomainName, 'x-new2-ext', {})
@stix2.v21.CustomExtension('x-new2-ext', {})
class BarExtension():
pass
def test_custom_extension_no_init_1():
@stix2.v21.CustomExtension(
stix2.v21.DomainName, 'x-new-extension-ext', [
'x-new-extension-ext', [
('property1', stix2.properties.StringProperty(required=True)),
],
)
@ -1122,7 +1083,7 @@ def test_custom_extension_no_init_1():
def test_custom_extension_no_init_2():
@stix2.v21.CustomExtension(
stix2.v21.DomainName, 'x-new2-ext', [
'x-new2-ext', [
('property1', stix2.properties.StringProperty(required=True)),
],
)
@ -1136,7 +1097,7 @@ def test_custom_extension_no_init_2():
def test_invalid_custom_property_in_extension():
with pytest.raises(ValueError) as excinfo:
@stix2.v21.CustomExtension(
stix2.v21.DomainName, 'x-new3-ext', [
'x-new3-ext', [
('6property1', stix2.properties.StringProperty(required=True)),
],
)
@ -1270,6 +1231,41 @@ def test_parse_observable_with_unregistered_custom_extension(data):
assert not isinstance(parsed_ob['extensions']['x-foobar-ext'], stix2.base._STIXBase)
def test_unregistered_new_style_extension():
f_dict = {
"type": "file",
"name": "foo.txt",
"extensions": {
"extension-definition--31adb724-a9a4-44b6-8ec2-fd4b181c9507": {
"extension-type": "property-extension",
"a": 1,
"b": True,
},
},
}
f = stix2.parse(f_dict, allow_custom=False)
assert f.extensions[
"extension-definition--31adb724-a9a4-44b6-8ec2-fd4b181c9507"
]["a"] == 1
assert f.extensions[
"extension-definition--31adb724-a9a4-44b6-8ec2-fd4b181c9507"
]["b"]
assert not f.has_custom
f = stix2.parse(f_dict, allow_custom=True)
assert f.extensions[
"extension-definition--31adb724-a9a4-44b6-8ec2-fd4b181c9507"
]["a"] == 1
assert f.extensions[
"extension-definition--31adb724-a9a4-44b6-8ec2-fd4b181c9507"
]["b"]
assert not f.has_custom
def test_register_custom_object():
# Not the way to register custom object.
class CustomObject2(object):
@ -1282,7 +1278,7 @@ def test_register_custom_object():
def test_extension_property_location():
assert 'extensions' in stix2.v21.OBJ_MAP_OBSERVABLE['x-new-observable']._properties
assert 'extensions' not in stix2.v21.EXT_MAP['domain-name']['x-new-ext']._properties
assert 'extensions' not in stix2.v21.EXT_MAP['x-new-ext']._properties
@pytest.mark.parametrize(
@ -1319,7 +1315,7 @@ def test_custom_object_nested_dictionary(data):
dictionary={'key': {'key_b': 'value', 'key_a': 'value'}},
)
assert data == str(example)
assert data == example.serialize(pretty=True)
@stix2.v21.CustomObject(
@ -1387,7 +1383,7 @@ def test_register_duplicate_observable():
def test_register_observable_custom_extension():
@stix2.v21.CustomExtension(
stix2.v21.DomainName, 'x-new-2-ext', [
'x-new-2-ext', [
('property1', stix2.properties.StringProperty(required=True)),
('property2', stix2.properties.IntegerProperty()),
],
@ -1398,13 +1394,13 @@ def test_register_observable_custom_extension():
example = NewExtension2(property1="Hi there")
assert 'domain-name' in stix2.registry.STIX2_OBJ_MAPS['2.1']['observables']
assert example._type in stix2.registry.STIX2_OBJ_MAPS['2.1']['observable-extensions']['domain-name']
assert example._type in stix2.registry.STIX2_OBJ_MAPS['2.1']['extensions']
def test_register_duplicate_observable_extension():
with pytest.raises(DuplicateRegistrationError) as excinfo:
@stix2.v21.CustomExtension(
stix2.v21.DomainName, 'x-new-2-ext', [
'x-new-2-ext', [
('property1', stix2.properties.StringProperty(required=True)),
('property2', stix2.properties.IntegerProperty()),
],
@ -1414,6 +1410,476 @@ def test_register_duplicate_observable_extension():
assert "cannot be registered again" in str(excinfo.value)
def test_unregistered_top_level_extension_passes_with_allow_custom_false():
indicator = stix2.v21.Indicator(
id='indicator--e97bfccf-8970-4a3c-9cd1-5b5b97ed5d0c',
created='2014-02-20T09:16:08.989000Z',
modified='2014-02-20T09:16:08.989000Z',
name='File hash for Poison Ivy variant',
description='This file hash indicates that a sample of Poison Ivy is present.',
labels=[
'malicious-activity',
],
rank=5,
toxicity=8,
pattern='[file:hashes.\'SHA-256\' = \'ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c\']',
pattern_type='stix',
valid_from='2014-02-20T09:00:00.000000Z',
extensions={
'extension-definition--d83fce45-ef58-4c6c-a3f4-1fbc32e98c6e': {
'extension_type': 'toplevel-property-extension',
},
},
allow_custom=False,
)
assert indicator.rank == 5
assert indicator.toxicity == 8
assert indicator.extensions['extension-definition--d83fce45-ef58-4c6c-a3f4-1fbc32e98c6e']['extension_type'] == 'toplevel-property-extension'
assert isinstance(indicator.extensions['extension-definition--d83fce45-ef58-4c6c-a3f4-1fbc32e98c6e'], dict)
def test_unregistered_embedded_extension_passes_with_allow_custom_false():
indicator = stix2.v21.Indicator(
id='indicator--e97bfccf-8970-4a3c-9cd1-5b5b97ed5d0c',
created='2014-02-20T09:16:08.989000Z',
modified='2014-02-20T09:16:08.989000Z',
name='File hash for Poison Ivy variant',
description='This file hash indicates that a sample of Poison Ivy is present.',
labels=[
'malicious-activity',
],
pattern='[file:hashes.\'SHA-256\' = \'ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c\']',
pattern_type='stix',
valid_from='2014-02-20T09:00:00.000000Z',
extensions={
'extension-definition--d83fce45-ef58-4c6c-a3f4-1fbc32e98c6e': {
'extension_type': 'property-extension',
'rank': 5,
'toxicity': 8,
},
},
allow_custom=False,
)
assert indicator.extensions['extension-definition--d83fce45-ef58-4c6c-a3f4-1fbc32e98c6e']['rank'] == 5
assert indicator.extensions['extension-definition--d83fce45-ef58-4c6c-a3f4-1fbc32e98c6e']['toxicity'] == 8
assert indicator.extensions['extension-definition--d83fce45-ef58-4c6c-a3f4-1fbc32e98c6e']['extension_type'] == 'property-extension'
assert isinstance(indicator.extensions['extension-definition--d83fce45-ef58-4c6c-a3f4-1fbc32e98c6e'], dict)
def test_registered_top_level_extension_passes_with_allow_custom_false():
@stix2.v21.CustomExtension(
'extension-definition--d83fce45-ef58-4c6c-a3f4-1fbc32e98c6e', [
('rank', stix2.properties.IntegerProperty(required=True)),
('toxicity', stix2.properties.IntegerProperty(required=True)),
],
)
class ExtensionFoo1:
extension_type = 'toplevel-property-extension'
indicator = stix2.v21.Indicator(
id='indicator--e97bfccf-8970-4a3c-9cd1-5b5b97ed5d0c',
created='2014-02-20T09:16:08.989000Z',
modified='2014-02-20T09:16:08.989000Z',
name='File hash for Poison Ivy variant',
description='This file hash indicates that a sample of Poison Ivy is present.',
labels=[
'malicious-activity',
],
rank=5,
toxicity=8,
pattern='[file:hashes.\'SHA-256\' = \'ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c\']',
pattern_type='stix',
valid_from='2014-02-20T09:00:00.000000Z',
extensions={
'extension-definition--d83fce45-ef58-4c6c-a3f4-1fbc32e98c6e': {
'extension_type': 'toplevel-property-extension',
},
},
allow_custom=False,
)
assert indicator.rank == 5
assert indicator.toxicity == 8
assert indicator.extensions['extension-definition--d83fce45-ef58-4c6c-a3f4-1fbc32e98c6e']['extension_type'] == 'toplevel-property-extension'
assert isinstance(indicator.extensions['extension-definition--d83fce45-ef58-4c6c-a3f4-1fbc32e98c6e'], ExtensionFoo1)
def test_registered_embedded_extension_passes_with_allow_custom_false():
@stix2.v21.CustomExtension(
'extension-definition--d83fce45-ef58-4c6c-a3ff-1fbc32e98c6e', [
('rank', stix2.properties.IntegerProperty(required=True)),
('toxicity', stix2.properties.IntegerProperty(required=True)),
],
)
class ExtensionFoo1:
extension_type = "property-extension"
indicator = stix2.v21.Indicator(
id='indicator--e97bfccf-8970-4a3c-9cd1-5b5b97ed5d0c',
created='2014-02-20T09:16:08.989000Z',
modified='2014-02-20T09:16:08.989000Z',
name='File hash for Poison Ivy variant',
description='This file hash indicates that a sample of Poison Ivy is present.',
labels=[
'malicious-activity',
],
pattern='[file:hashes.\'SHA-256\' = \'ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c\']',
pattern_type='stix',
valid_from='2014-02-20T09:00:00.000000Z',
extensions={
'extension-definition--d83fce45-ef58-4c6c-a3ff-1fbc32e98c6e': {
'extension_type': 'property-extension',
'rank': 5,
'toxicity': 8,
},
},
allow_custom=False,
)
assert indicator.extensions['extension-definition--d83fce45-ef58-4c6c-a3ff-1fbc32e98c6e']['rank'] == 5
assert indicator.extensions['extension-definition--d83fce45-ef58-4c6c-a3ff-1fbc32e98c6e']['toxicity'] == 8
assert indicator.extensions['extension-definition--d83fce45-ef58-4c6c-a3ff-1fbc32e98c6e']['extension_type'] == 'property-extension'
assert isinstance(indicator.extensions['extension-definition--d83fce45-ef58-4c6c-a3ff-1fbc32e98c6e'], ExtensionFoo1)
def test_registered_new_extension_sdo_allow_custom_false():
@stix2.v21.CustomObject(
'my-favorite-sdo', [
('name', stix2.properties.StringProperty(required=True)),
('some_property_name1', stix2.properties.StringProperty(required=True)),
('some_property_name2', stix2.properties.StringProperty()),
], 'extension-definition--d83fce45-ef58-4c6c-a3f4-1fbc32e9999',
)
class MyFavSDO:
pass
my_favorite_sdo = {
'type': 'my-favorite-sdo',
'spec_version': '2.1',
'id': 'my-favorite-sdo--c5ba9dba-5ad9-4bbe-9825-df4cb8675774',
'created': '2014-02-20T09:16:08.989000Z',
'modified': '2014-02-20T09:16:08.989000Z',
'name': 'This is the name of my favorite',
'some_property_name1': 'value1',
'some_property_name2': 'value2',
# 'extensions': {
# 'extension-definition--d83fce45-ef58-4c6c-a3f4-1fbc32e9999': ExtensionDefinitiond83fce45ef584c6ca3f41fbc32e98c6e()
# }
}
sdo_object = stix2.parse(my_favorite_sdo)
assert isinstance(sdo_object, MyFavSDO)
assert isinstance(
sdo_object.extensions['extension-definition--d83fce45-ef58-4c6c-a3f4-1fbc32e9999'],
stix2.v21.EXT_MAP['extension-definition--d83fce45-ef58-4c6c-a3f4-1fbc32e9999'],
)
sdo_serialized = sdo_object.serialize()
assert '"extensions": {"extension-definition--d83fce45-ef58-4c6c-a3f4-1fbc32e9999": {"extension_type": "new-sdo"}}' in sdo_serialized
def test_registered_new_extension_sro_allow_custom_false():
@stix2.v21.CustomObject(
'my-favorite-sro', [
('name', stix2.properties.StringProperty(required=True)),
('some_property_name1', stix2.properties.StringProperty(required=True)),
('some_property_name2', stix2.properties.StringProperty()),
], 'extension-definition--e96690a5-dc13-4f27-99dd-0f2188ad74ce', False,
)
class MyFavSRO:
pass
my_favorite_sro = {
'type': 'my-favorite-sro',
'spec_version': '2.1',
'id': 'my-favorite-sro--c5ba9dba-5ad9-4bbe-9825-df4cb8675774',
'created': '2014-02-20T09:16:08.989000Z',
'modified': '2014-02-20T09:16:08.989000Z',
'name': 'This is the name of my favorite',
'some_property_name1': 'value1',
'some_property_name2': 'value2',
# 'extensions': {
# 'extension-definition--e96690a5-dc13-4f27-99dd-0f2188ad74ce': ExtensionDefinitiond83fce45ef584c6ca3f41fbc32e98c6e()
# }
}
sro_object = stix2.parse(my_favorite_sro)
assert isinstance(sro_object, MyFavSRO)
assert isinstance(
sro_object.extensions['extension-definition--e96690a5-dc13-4f27-99dd-0f2188ad74ce'],
stix2.v21.EXT_MAP['extension-definition--e96690a5-dc13-4f27-99dd-0f2188ad74ce'],
)
sdo_serialized = sro_object.serialize()
assert '"extensions": {"extension-definition--e96690a5-dc13-4f27-99dd-0f2188ad74ce": {"extension_type": "new-sro"}}' in sdo_serialized
def test_registered_new_extension_sco_allow_custom_false():
@stix2.v21.CustomObservable(
'my-favorite-sco', [
('name', stix2.properties.StringProperty(required=True)),
('some_network_protocol_field', stix2.properties.StringProperty(required=True)),
], ['name', 'some_network_protocol_field'], 'extension-definition--a932fcc6-e032-177c-126f-cb970a5a1fff',
)
class MyFavSCO:
pass
my_favorite_sco = {
'type': 'my-favorite-sco',
'spec_version': '2.1',
'id': 'my-favorite-sco--f9dbe89c-0030-4a9d-8b78-0dcd0a0de874',
'name': 'This is the name of my favorite SCO',
'some_network_protocol_field': 'value',
# 'extensions': {
# 'extension-definition--a932fcc6-e032-177c-126f-cb970a5a1fff': {
# 'is_extension_so': true
# }
# }
}
sco_object = stix2.parse(my_favorite_sco)
assert isinstance(sco_object, MyFavSCO)
assert isinstance(
sco_object.extensions['extension-definition--a932fcc6-e032-177c-126f-cb970a5a1fff'],
stix2.v21.EXT_MAP['extension-definition--a932fcc6-e032-177c-126f-cb970a5a1fff'],
)
sco_serialized = sco_object.serialize()
assert '"extensions": {"extension-definition--a932fcc6-e032-177c-126f-cb970a5a1fff": {"extension_type": "new-sco"}}' in sco_serialized
def test_registered_new_extension_marking_allow_custom_false():
@stix2.v21.CustomMarking(
'my-favorite-marking', [
('some_marking_field', stix2.properties.StringProperty(required=True)),
], 'extension-definition--a932fcc6-e032-176c-126f-cb970a5a1fff',
)
class MyFavMarking:
pass
my_favorite_marking = {
'type': 'marking-definition',
'spec_version': '2.1',
'id': 'marking-definition--f9dbe89c-0030-4a9d-8b78-0dcd0a0de874',
'name': 'This is the name of my favorite Marking',
'extensions': {
'extension-definition--a932fcc6-e032-176c-126f-cb970a5a1fff': {
'extension_type': 'property-extension',
'some_marking_field': 'value',
},
},
}
marking_object = stix2.parse(my_favorite_marking)
assert isinstance(marking_object, stix2.v21.MarkingDefinition)
assert isinstance(
marking_object.extensions['extension-definition--a932fcc6-e032-176c-126f-cb970a5a1fff'],
stix2.v21.EXT_MAP['extension-definition--a932fcc6-e032-176c-126f-cb970a5a1fff'],
)
marking_serialized = marking_object.serialize(sort_keys=True)
assert '"extensions": {"extension-definition--a932fcc6-e032-176c-126f-cb970a5a1fff": ' \
'{"extension_type": "property-extension", "some_marking_field": "value"}}' in marking_serialized
@contextlib.contextmanager
def _register_extension(ext, props):
ext_def_id = "extension-definition--" + str(uuid.uuid4())
stix2.v21.CustomExtension(
ext_def_id,
props,
)(ext)
try:
yield ext_def_id
finally:
# "unregister" the extension
del stix2.registry.STIX2_OBJ_MAPS["2.1"]["extensions"][ext_def_id]
def test_nested_ext_prop_meta():
class TestExt:
extension_type = "property-extension"
props = {
"intprop": stix2.properties.IntegerProperty(required=True),
"strprop": stix2.properties.StringProperty(
required=False, default=lambda: "foo",
),
}
with _register_extension(TestExt, props) as ext_def_id:
obj = stix2.v21.Identity(
name="test",
extensions={
ext_def_id: {
"extension_type": "property-extension",
"intprop": "1",
"strprop": 2,
},
},
)
assert obj.extensions[ext_def_id].extension_type == "property-extension"
assert obj.extensions[ext_def_id].intprop == 1
assert obj.extensions[ext_def_id].strprop == "2"
obj = stix2.v21.Identity(
name="test",
extensions={
ext_def_id: {
"extension_type": "property-extension",
"intprop": "1",
},
},
)
# Ensure default kicked in
assert obj.extensions[ext_def_id].strprop == "foo"
with pytest.raises(InvalidValueError):
stix2.v21.Identity(
name="test",
extensions={
ext_def_id: {
"extension_type": "property-extension",
# wrong value type
"intprop": "foo",
},
},
)
with pytest.raises(InvalidValueError):
stix2.v21.Identity(
name="test",
extensions={
ext_def_id: {
"extension_type": "property-extension",
# missing required property
"strprop": "foo",
},
},
)
with pytest.raises(InvalidValueError):
stix2.v21.Identity(
name="test",
extensions={
ext_def_id: {
"extension_type": "property-extension",
"intprop": 1,
# Use of undefined property
"foo": False,
},
},
)
with pytest.raises(InvalidValueError):
stix2.v21.Identity(
name="test",
extensions={
ext_def_id: {
# extension_type doesn't match with registration
"extension_type": "new-sdo",
"intprop": 1,
"strprop": "foo",
},
},
)
def test_toplevel_ext_prop_meta():
class TestExt:
extension_type = "toplevel-property-extension"
props = {
"intprop": stix2.properties.IntegerProperty(required=True),
"strprop": stix2.properties.StringProperty(
required=False, default=lambda: "foo",
),
}
with _register_extension(TestExt, props) as ext_def_id:
obj = stix2.v21.Identity(
name="test",
intprop="1",
strprop=2,
extensions={
ext_def_id: {
"extension_type": "toplevel-property-extension",
},
},
)
assert obj.extensions[ext_def_id].extension_type == "toplevel-property-extension"
assert obj.intprop == 1
assert obj.strprop == "2"
obj = stix2.v21.Identity(
name="test",
intprop=1,
extensions={
ext_def_id: {
"extension_type": "toplevel-property-extension",
},
},
)
# Ensure default kicked in
assert obj.strprop == "foo"
with pytest.raises(InvalidValueError):
stix2.v21.Identity(
name="test",
intprop="foo", # wrong value type
extensions={
ext_def_id: {
"extension_type": "toplevel-property-extension",
},
},
)
with pytest.raises(InvalidValueError):
stix2.v21.Identity(
name="test",
intprop=1,
extensions={
ext_def_id: {
"extension_type": "toplevel-property-extension",
# Use of undefined property
"foo": False,
},
},
)
with pytest.raises(InvalidValueError):
stix2.v21.Identity(
name="test",
intprop=1,
extensions={
ext_def_id: {
"extension_type": "toplevel-property-extension",
# Use of a defined property, but intended for the
# top level. This should still error out.
"strprop": 1,
},
},
)
with pytest.raises(MissingPropertiesError):
stix2.v21.Identity(
name="test",
strprop="foo", # missing required property
extensions={
ext_def_id: {
"extension_type": "toplevel-property-extension",
},
},
)
def test_allow_custom_propagation():
obj_dict = {
"type": "bundle",

View File

@ -43,11 +43,7 @@ def test_no_contrib_props_defined():
_properties = OrderedDict((
('type', TypeProperty(_type, spec_version='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
(
'extensions', ExtensionsProperty(
spec_version='2.1', enclosing_type=_type,
),
),
('extensions', ExtensionsProperty(spec_version='2.1')),
))
_id_contributing_properties = []
@ -64,11 +60,7 @@ def test_json_compatible_prop_values():
_properties = OrderedDict((
('type', TypeProperty(_type, spec_version='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
(
'extensions', ExtensionsProperty(
spec_version='2.1', enclosing_type=_type,
),
),
('extensions', ExtensionsProperty(spec_version='2.1')),
('string', StringProperty()),
('int', IntegerProperty()),
('float', FloatProperty()),
@ -104,11 +96,7 @@ def test_json_incompatible_timestamp_value():
_properties = OrderedDict((
('type', TypeProperty(_type, spec_version='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
(
'extensions', ExtensionsProperty(
spec_version='2.1', enclosing_type=_type,
),
),
('extensions', ExtensionsProperty(spec_version='2.1')),
('timestamp', TimestampProperty()),
))
_id_contributing_properties = ['timestamp']
@ -140,11 +128,7 @@ def test_embedded_object():
_properties = OrderedDict((
('type', TypeProperty(_type, spec_version='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
(
'extensions', ExtensionsProperty(
spec_version='2.1', enclosing_type=_type,
),
),
('extensions', ExtensionsProperty(spec_version='2.1')),
('sub_obj', EmbeddedObjectProperty(type=SubObj)),
))
_id_contributing_properties = ['sub_obj']
@ -171,11 +155,7 @@ def test_empty_hash():
_properties = OrderedDict((
('type', TypeProperty(_type, spec_version='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
(
'extensions', ExtensionsProperty(
spec_version='2.1', enclosing_type=_type,
),
),
('extensions', ExtensionsProperty(spec_version='2.1')),
('hashes', HashesProperty(HASHING_ALGORITHM)),
))
_id_contributing_properties = ['hashes']

View File

@ -0,0 +1,107 @@
import datetime as dt
import pytest
import pytz
import stix2
from .constants import EXTENSION_DEFINITION_IDS
EXPECTED = f"""{{
"type": "extension-definition",
"spec_version": "2.1",
"id": "{EXTENSION_DEFINITION_IDS[0]}",
"created_by_ref": "identity--11b76a96-5d2b-45e0-8a5a-f6994f370731",
"created": "2014-02-20T09:16:08.000Z",
"modified": "2014-02-20T09:16:08.000Z",
"name": "New SDO 1",
"description": "This schema creates a new object type called my-favorite-sdo-1",
"schema": "https://www.example.com/schema-my-favorite-sdo-1/v1/",
"version": "1.2.1",
"extension_types": [
"new-sdo"
]
}}"""
def test_extension_definition_example():
extension_definition = stix2.v21.ExtensionDefinition(
id=EXTENSION_DEFINITION_IDS[0],
created_by_ref="identity--11b76a96-5d2b-45e0-8a5a-f6994f370731",
created="2014-02-20T09:16:08.000Z",
modified="2014-02-20T09:16:08.000Z",
name="New SDO 1",
description="This schema creates a new object type called my-favorite-sdo-1",
schema="https://www.example.com/schema-my-favorite-sdo-1/v1/",
version="1.2.1",
extension_types=["new-sdo"],
)
assert extension_definition.serialize(pretty=True) == EXPECTED
@pytest.mark.parametrize(
"data", [
EXPECTED,
{
"id": f"{EXTENSION_DEFINITION_IDS[0]}",
"type": "extension-definition",
"spec_version": "2.1",
"created_by_ref": "identity--11b76a96-5d2b-45e0-8a5a-f6994f370731",
"created": "2014-02-20T09:16:08.000Z",
"modified": "2014-02-20T09:16:08.000Z",
"name": "New SDO 1",
"description": "This schema creates a new object type called my-favorite-sdo-1",
"schema": "https://www.example.com/schema-my-favorite-sdo-1/v1/",
"version": "1.2.1",
"extension_types": ["new-sdo"],
},
],
)
def test_parse_extension_definition(data):
extension_definition = stix2.parse(data, version="2.1")
assert extension_definition.type == 'extension-definition'
assert extension_definition.spec_version == '2.1'
assert extension_definition.id == EXTENSION_DEFINITION_IDS[0]
assert extension_definition.created == dt.datetime(2014, 2, 20, 9, 16, 8, tzinfo=pytz.utc)
assert extension_definition.modified == dt.datetime(2014, 2, 20, 9, 16, 8, tzinfo=pytz.utc)
assert extension_definition.name == 'New SDO 1'
assert extension_definition.description == 'This schema creates a new object type called my-favorite-sdo-1'
assert extension_definition.schema == 'https://www.example.com/schema-my-favorite-sdo-1/v1/'
assert extension_definition.version == '1.2.1'
assert extension_definition.extension_types == ['new-sdo']
def test_parse_no_type():
with pytest.raises(stix2.exceptions.ParseError):
stix2.parse(
"""{
"id": "{EXTENSION_DEFINITION_IDS[0]}",
"spec_version": "2.1",
"name": "New SDO 1",
"description": "This schema creates a new object type called my-favorite-sdo-1",
"created": "2014-02-20T09:16:08.989000Z",
"modified": "2014-02-20T09:16:08.989000Z",
"created_by_ref": "identity--11b76a96-5d2b-45e0-8a5a-f6994f370731",
"schema": "https://www.example.com/schema-my-favorite-sdo-1/v1/",
"version": "1.2.1",
"extension_types": [ "new-sdo" ]
}""", version="2.1",
)
def test_extension_definition_with_custom():
extension_definition = stix2.v21.ExtensionDefinition(
created_by_ref="identity--11b76a96-5d2b-45e0-8a5a-f6994f370731",
created="2014-02-20T09:16:08.000Z",
modified="2014-02-20T09:16:08.000Z",
name="New SDO 1",
description="This schema creates a new object type called my-favorite-sdo-1",
schema="https://www.example.com/schema-my-favorite-sdo-1/v1/",
version="1.2.1",
extension_types=["new-sdo"],
custom_properties={'x_foo': 'bar'},
)
assert extension_definition.x_foo == "bar"

View File

@ -26,7 +26,7 @@ def test_external_reference_veris():
url="https://github.com/vz-risk/VCDB/blob/master/data/json/0001AA7F-C601-424A-B2B8-BE6C9F5164E7.json",
)
assert str(ref) == VERIS
assert ref.serialize(pretty=True) == VERIS
CAPEC = """{
@ -41,7 +41,7 @@ def test_external_reference_capec():
external_id="CAPEC-550",
)
assert str(ref) == CAPEC
assert ref.serialize(pretty=True) == CAPEC
assert re.match("ExternalReference\\(source_name=u?'capec', external_id=u?'CAPEC-550'\\)", repr(ref))
@ -59,7 +59,7 @@ def test_external_reference_capec_url():
url="http://capec.mitre.org/data/definitions/550.html",
)
assert str(ref) == CAPEC_URL
assert ref.serialize(pretty=True) == CAPEC_URL
THREAT_REPORT = """{
@ -76,7 +76,7 @@ def test_external_reference_threat_report():
url="http://www.example.com/threat-report.pdf",
)
assert str(ref) == THREAT_REPORT
assert ref.serialize(pretty=True) == THREAT_REPORT
BUGZILLA = """{
@ -93,7 +93,7 @@ def test_external_reference_bugzilla():
url="https://www.example.com/bugs/1370",
)
assert str(ref) == BUGZILLA
assert ref.serialize(pretty=True) == BUGZILLA
OFFLINE = """{
@ -108,7 +108,7 @@ def test_external_reference_offline():
description="Threat report",
)
assert str(ref) == OFFLINE
assert ref.serialize(pretty=True) == OFFLINE
assert re.match("ExternalReference\\(source_name=u?'ACME Threat Intel', description=u?'Threat report'\\)", repr(ref))
# Yikes! This works
assert eval("stix2." + repr(ref)) == ref

View File

@ -38,7 +38,7 @@ def test_grouping_with_all_required_properties():
],
)
assert str(grp) == EXPECTED_GROUPING
assert grp.serialize(pretty=True) == EXPECTED_GROUPING
def test_grouping_autogenerated_properties(grouping):

View File

@ -27,7 +27,7 @@ def test_identity_example():
identity_class="individual",
)
assert str(identity) == EXPECTED
assert identity.serialize(pretty=True) == EXPECTED
@pytest.mark.parametrize(
@ -77,6 +77,5 @@ def test_identity_with_custom():
)
assert identity.x_foo == "bar"
assert "x_foo" in identity.object_properties()
# TODO: Add other examples

View File

@ -0,0 +1,80 @@
import datetime as dt
import pytest
import pytz
import stix2
from .constants import INCIDENT_ID
EXPECTED = """{
"type": "incident",
"spec_version": "2.1",
"id": "incident--40fc3b35-0dc4-4afd-9927-288d44bfce20",
"created": "2015-12-21T19:59:11.000Z",
"modified": "2015-12-21T19:59:11.000Z",
"name": "Breach of Cyber Tech Dynamics",
"description": "Intrusion into enterprise network"
}"""
def test_incident_example():
incident = stix2.v21.Incident(
id=INCIDENT_ID,
created="2015-12-21T19:59:11.000Z",
modified="2015-12-21T19:59:11.000Z",
name="Breach of Cyber Tech Dynamics",
description="Intrusion into enterprise network",
)
assert incident.serialize(pretty=True) == EXPECTED
@pytest.mark.parametrize(
"data", [
EXPECTED,
{
"created": "2015-12-21T19:59:11.000Z",
"id": INCIDENT_ID,
"description": "Intrusion into enterprise network",
"modified": "2015-12-21T19:59:11.000Z",
"name": "Breach of Cyber Tech Dynamics",
"spec_version": "2.1",
"type": "incident",
},
],
)
def test_parse_incident(data):
incident = stix2.parse(data, version="2.1")
assert incident.type == 'incident'
assert incident.spec_version == '2.1'
assert incident.id == INCIDENT_ID
assert incident.created == dt.datetime(2015, 12, 21, 19, 59, 11, tzinfo=pytz.utc)
assert incident.modified == dt.datetime(2015, 12, 21, 19, 59, 11, tzinfo=pytz.utc)
assert incident.name == 'Breach of Cyber Tech Dynamics'
assert incident.description == 'Intrusion into enterprise network'
def test_parse_no_type():
with pytest.raises(stix2.exceptions.ParseError):
stix2.parse(
"""
{
"id": "incident--40fc3b35-0dc4-4afd-9927-288d44bfce20",
"created": "2015-12-21T19:59:11.000Z",
"modified": "2015-12-21T19:59:11.000Z",
"name": "Breach of Cyber Tech Dynamics",
"description": "Intrusion into enterprise network"
}""", version="2.1",
)
def test_incident_with_custom():
incident = stix2.v21.Incident(
name="Breach of Cyber Tech Dynamics",
description="Intrusion into enterprise network",
custom_properties={'x_foo': 'bar'},
)
assert incident.x_foo == "bar"

View File

@ -30,7 +30,8 @@ EXPECTED_INDICATOR_REPR = "Indicator(" + " ".join(
pattern="[file:hashes.MD5 = 'd41d8cd98f00b204e9800998ecf8427e']",
pattern_type='stix',
pattern_version='2.1',
valid_from='1970-01-01T00:00:01Z'
valid_from='1970-01-01T00:00:01Z',
revoked=False
""".split(),
) + ")"
@ -50,7 +51,7 @@ def test_indicator_with_all_required_properties():
)
assert ind.revoked is False
assert str(ind) == EXPECTED_INDICATOR
assert ind.serialize(pretty=True) == EXPECTED_INDICATOR
rep = re.sub(r"(\[|=| )u('|\"|\\\'|\\\")", r"\g<1>\g<2>", repr(ind))
assert rep == EXPECTED_INDICATOR_REPR

View File

@ -28,7 +28,7 @@ def test_infrastructure_with_all_required_properties():
name="Poison Ivy C2",
)
assert str(infra) == EXPECTED_INFRASTRUCTURE
assert infra.serialize(pretty=True) == EXPECTED_INFRASTRUCTURE
def test_infrastructure_autogenerated_properties(infrastructure):

View File

@ -39,7 +39,7 @@ def test_intrusion_set_example():
goals=["acquisition-theft", "harassment", "damage"],
)
assert str(intrusion_set) == EXPECTED
assert intrusion_set.serialize(pretty=True) == EXPECTED
@pytest.mark.parametrize(

View File

@ -16,7 +16,7 @@ def test_lockheed_martin_cyber_kill_chain():
phase_name="reconnaissance",
)
assert str(recon) == LMCO_RECON
assert recon.serialize(pretty=True) == LMCO_RECON
FOO_PRE_ATTACK = """{
@ -31,7 +31,7 @@ def test_kill_chain_example():
phase_name="pre-attack",
)
assert str(preattack) == FOO_PRE_ATTACK
assert preattack.serialize(pretty=True) == FOO_PRE_ATTACK
def test_kill_chain_required_properties():

View File

@ -27,7 +27,8 @@ EXPECTED_LOCATION_1_REPR = "Location(" + " ".join(
created='2016-04-06T20:03:00.000Z',
modified='2016-04-06T20:03:00.000Z',
latitude=48.8566,
longitude=2.3522""".split(),
longitude=2.3522,
revoked=False""".split(),
) + ")"
EXPECTED_LOCATION_2 = """{
@ -47,14 +48,15 @@ EXPECTED_LOCATION_2_REPR = "Location(" + " ".join(
id='location--a6e9345f-5a15-4c29-8bb3-7dcc5d168d64',
created='2016-04-06T20:03:00.000Z',
modified='2016-04-06T20:03:00.000Z',
region='northern-america'""".split(),
region='northern-america',
revoked=False""".split(),
) + ")"
def test_location_with_some_required_properties():
now = dt.datetime(2016, 4, 6, 20, 3, 0, tzinfo=pytz.utc)
loc = stix2.v21.Location(
location = stix2.v21.Location(
id=LOCATION_ID,
created=now,
modified=now,
@ -62,8 +64,8 @@ def test_location_with_some_required_properties():
longitude=2.3522,
)
assert str(loc) == EXPECTED_LOCATION_1
rep = re.sub(r"(\[|=| )u('|\"|\\\'|\\\")", r"\g<1>\g<2>", repr(loc))
assert location.serialize(pretty=True) == EXPECTED_LOCATION_1
rep = re.sub(r"(\[|=| )u('|\"|\\\'|\\\")", r"\g<1>\g<2>", repr(location))
assert rep == EXPECTED_LOCATION_1_REPR

View File

@ -23,7 +23,7 @@ EXPECTED_MALWARE = """{
def test_malware_with_all_required_properties():
now = dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc)
mal = stix2.v21.Malware(
malware = stix2.v21.Malware(
type="malware",
id=MALWARE_ID,
created=now,
@ -32,7 +32,7 @@ def test_malware_with_all_required_properties():
is_family=False,
)
assert str(mal) == EXPECTED_MALWARE
assert malware.serialize(pretty=True) == EXPECTED_MALWARE
def test_malware_autogenerated_properties(malware):

View File

@ -48,9 +48,9 @@ MALWARE_ANALYSIS_DICT = json.loads(MALWARE_ANALYSIS_JSON)
def test_malware_analysis_example():
ma = stix2.v21.MalwareAnalysis(**MALWARE_ANALYSIS_DICT)
malware_analysis = stix2.v21.MalwareAnalysis(**MALWARE_ANALYSIS_DICT)
assert str(ma) == MALWARE_ANALYSIS_JSON
assert malware_analysis.serialize(pretty=True) == MALWARE_ANALYSIS_JSON
@pytest.mark.parametrize(

View File

@ -1,7 +1,7 @@
import pytest
from stix2 import exceptions
from stix2 import exceptions, parse
from stix2.v21 import (
TLP_AMBER, TLP_GREEN, TLP_RED, TLP_WHITE, MarkingDefinition, TLPMarking,
)
@ -143,3 +143,29 @@ def test_unknown_tlp_marking():
definition_type='tlp',
definition=TLPMarking(tlp='gray'),
)
def test_marking_definition_missing_definition():
my_favorite_marking = {
'type': 'marking-definition',
'spec_version': '2.1',
'id': 'marking-definition--f9dbe89c-0030-4a9d-8b78-0dcd0a0de874',
'name': 'This is the name of my favorite Marking',
'definition_type': 'foobar',
}
with pytest.raises(exceptions.PropertyPresenceError):
parse(my_favorite_marking)
def test_marking_definition_missing_definition_type():
my_favorite_marking = {
'type': 'marking-definition',
'spec_version': '2.1',
'id': 'marking-definition--f9dbe89c-0030-4a9d-8b78-0dcd0a0de874',
'name': 'This is the name of my favorite Marking',
'definition': {
'some_type': 'foobar',
},
}
with pytest.raises(exceptions.InvalidValueError):
parse(my_favorite_marking)

View File

@ -99,7 +99,7 @@ EXPECTED_CAMPAIGN_WITH_GRANULAR_LANG_MARKINGS = u"""{
def test_marking_def_example_with_tlp():
assert str(TLP_WHITE) == EXPECTED_TLP_MARKING_DEFINITION
assert TLP_WHITE.serialize(pretty=True) == EXPECTED_TLP_MARKING_DEFINITION
def test_marking_def_example_with_statement_positional_argument():
@ -110,7 +110,7 @@ def test_marking_def_example_with_statement_positional_argument():
definition=stix2.StatementMarking(statement="Copyright 2016, Example Corp"),
)
assert str(marking_definition) == EXPECTED_STATEMENT_MARKING_DEFINITION
assert marking_definition.serialize(pretty=True) == EXPECTED_STATEMENT_MARKING_DEFINITION
def test_marking_def_example_with_kwargs_statement():
@ -122,7 +122,7 @@ def test_marking_def_example_with_kwargs_statement():
definition=stix2.StatementMarking(**kwargs),
)
assert str(marking_definition) == EXPECTED_STATEMENT_MARKING_DEFINITION
assert marking_definition.serialize(pretty=True) == EXPECTED_STATEMENT_MARKING_DEFINITION
def test_marking_def_invalid_type():
@ -145,7 +145,7 @@ def test_campaign_with_markings_example():
description="Campaign by Green Group against a series of targets in the financial services sector.",
object_marking_refs=TLP_WHITE,
)
assert str(campaign) == EXPECTED_CAMPAIGN_WITH_OBJECT_MARKING
assert campaign.serialize(pretty=True) == EXPECTED_CAMPAIGN_WITH_OBJECT_MARKING
def test_granular_example():
@ -154,7 +154,7 @@ def test_granular_example():
selectors=["abc", "abc.[23]", "abc.def", "abc.[2].efg"],
)
assert str(granular_marking) == EXPECTED_GRANULAR_MARKING
assert granular_marking.serialize(pretty=True) == EXPECTED_GRANULAR_MARKING
def test_granular_example_with_bad_selector():
@ -185,7 +185,7 @@ def test_campaign_with_granular_markings_example():
),
],
)
assert str(campaign) == EXPECTED_CAMPAIGN_WITH_GRANULAR_REF_MARKINGS
assert campaign.serialize(pretty=True) == EXPECTED_CAMPAIGN_WITH_GRANULAR_REF_MARKINGS
@pytest.mark.parametrize(

View File

@ -48,6 +48,7 @@ EXPECTED_OPINION_REPR = "Note(" + " ".join((
content='%s',
authors=['John Doe'],
object_refs=['campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f'],
revoked=False,
external_references=[ExternalReference(source_name='job-tracker', external_id='job-id-1234')]
""" % CONTENT
).split()) + ")"
@ -73,7 +74,7 @@ def test_note_with_required_properties():
],
)
assert str(note) == EXPECTED_NOTE
assert note.serialize(pretty=True) == EXPECTED_NOTE
rep = re.sub(r"(\[|=| )u('|\"|\\\'|\\\")", r"\g<1>\g<2>", repr(note))
assert rep == EXPECTED_OPINION_REPR

View File

@ -155,7 +155,7 @@ def test_observed_data_example_with_object_refs():
],
)
assert str(observed_data) == EXPECTED_OBJECT_REFS
assert observed_data.serialize(pretty=True) == EXPECTED_OBJECT_REFS
def test_observed_data_object_constraint():
@ -1218,8 +1218,8 @@ def test_process_example_empty_error():
stix2.v21.Process()
assert excinfo.value.cls == stix2.v21.Process
properties_of_process = list(stix2.v21.Process._properties.keys())
properties_of_process = [prop for prop in properties_of_process if prop not in ["type", "id", "defanged", "spec_version"]]
properties_of_process = stix2.v21.Process._properties.keys()
properties_of_process -= {"type", "id", "defanged", "spec_version", "extensions"}
assert excinfo.value.properties == sorted(properties_of_process)
msg = "At least one of the ({1}) properties for {0} must be populated."
msg = msg.format(

View File

@ -38,7 +38,8 @@ EXPECTED_OPINION_REPR = "Opinion(" + " ".join((
modified='2016-05-12T08:17:27.000Z',
explanation="%s",
opinion='strongly-disagree',
object_refs=['relationship--16d2358f-3b0d-4c88-b047-0da2f7ed4471']
object_refs=['relationship--16d2358f-3b0d-4c88-b047-0da2f7ed4471'],
revoked=False
""" % EXPLANATION
).split()) + ")"
@ -56,7 +57,7 @@ def test_opinion_with_required_properties():
explanation=EXPLANATION,
)
assert str(opi) == EXPECTED_OPINION
assert opi.serialize(pretty=True) == EXPECTED_OPINION
rep = re.sub(r"(\[|=| )u('|\"|\\\'|\\\")", r"\g<1>\g<2>", repr(opi))
assert rep == EXPECTED_OPINION_REPR

View File

@ -486,7 +486,7 @@ def test_embedded_property_dict_custom():
def test_extension_property_valid():
ext_prop = ExtensionsProperty(spec_version='2.1', enclosing_type='file')
ext_prop = ExtensionsProperty(spec_version='2.1')
result = ext_prop.clean(
{
'windows-pebinary-ext': {
@ -515,13 +515,13 @@ def test_extension_property_valid():
def test_extension_property_invalid1():
ext_prop = ExtensionsProperty(spec_version='2.1', enclosing_type='file')
ext_prop = ExtensionsProperty(spec_version='2.1')
with pytest.raises(ValueError):
ext_prop.clean(1, False)
def test_extension_property_invalid2():
ext_prop = ExtensionsProperty(spec_version='2.1', enclosing_type='file')
ext_prop = ExtensionsProperty(spec_version='2.1')
with pytest.raises(CustomContentError):
ext_prop.clean(
{
@ -543,7 +543,7 @@ def test_extension_property_invalid2():
def test_extension_property_invalid3():
ext_prop = ExtensionsProperty(spec_version="2.1", enclosing_type='file')
ext_prop = ExtensionsProperty(spec_version="2.1")
with pytest.raises(ExtraPropertiesError):
ext_prop.clean(
{
@ -571,20 +571,6 @@ def test_extension_property_invalid3():
assert result[1]
def test_extension_property_invalid_type():
ext_prop = ExtensionsProperty(spec_version='2.1', enclosing_type='indicator')
with pytest.raises(CustomContentError) as excinfo:
ext_prop.clean(
{
'windows-pebinary-ext': {
'pe_type': 'exe',
},
},
False,
)
assert "Can't parse unknown extension" in str(excinfo.value)
def test_extension_at_least_one_property_constraint():
with pytest.raises(AtLeastOnePropertyError):
stix2.v21.TCPExt()

View File

@ -33,7 +33,7 @@ def test_relationship_all_required_properties():
source_ref=INDICATOR_ID,
target_ref=MALWARE_ID,
)
assert str(rel) == EXPECTED_RELATIONSHIP
assert rel.serialize(pretty=True) == EXPECTED_RELATIONSHIP
def test_relationship_autogenerated_properties(relationship):

View File

@ -49,7 +49,7 @@ def test_report_example():
],
)
assert str(report) == EXPECTED
assert report.serialize(pretty=True) == EXPECTED
def test_report_example_objects_in_object_refs():
@ -69,7 +69,7 @@ def test_report_example_objects_in_object_refs():
],
)
assert str(report) == EXPECTED
assert report.serialize(pretty=True) == EXPECTED
def test_report_example_objects_in_object_refs_with_bad_id():

View File

@ -38,7 +38,7 @@ BAD_SIGHTING = """{
def test_sighting_all_required_properties():
now = dt.datetime(2016, 4, 6, 20, 6, 37, tzinfo=pytz.utc)
s = stix2.v21.Sighting(
sighting = stix2.v21.Sighting(
type='sighting',
id=SIGHTING_ID,
created=now,
@ -46,7 +46,7 @@ def test_sighting_all_required_properties():
sighting_of_ref=INDICATOR_ID,
where_sighted_refs=[IDENTITY_ID, LOCATION_ID],
)
assert str(s) == EXPECTED_SIGHTING
assert sighting.serialize(pretty=True) == EXPECTED_SIGHTING
def test_sighting_bad_where_sighted_refs():

View File

@ -34,7 +34,7 @@ def test_threat_actor_example():
threat_actor_types=["crime-syndicate"],
)
assert str(threat_actor) == EXPECTED
assert threat_actor.serialize(pretty=True) == EXPECTED
@pytest.mark.parametrize(

View File

@ -45,7 +45,7 @@ def test_tool_example():
tool_types=["remote-access"],
)
assert str(tool) == EXPECTED
assert tool.serialize(pretty=True) == EXPECTED
@pytest.mark.parametrize(

View File

@ -37,7 +37,7 @@ def test_vulnerability_example():
],
)
assert str(vulnerability) == EXPECTED
assert vulnerability.serialize(pretty=True) == EXPECTED
@pytest.mark.parametrize(

View File

@ -82,26 +82,18 @@ OBJ_MAP_OBSERVABLE = {
}
EXT_MAP = {
'file': {
'archive-ext': ArchiveExt,
'ntfs-ext': NTFSExt,
'pdf-ext': PDFExt,
'raster-image-ext': RasterImageExt,
'windows-pebinary-ext': WindowsPEBinaryExt,
},
'network-traffic': {
'http-request-ext': HTTPRequestExt,
'icmp-ext': ICMPExt,
'socket-ext': SocketExt,
'tcp-ext': TCPExt,
},
'process': {
'windows-process-ext': WindowsProcessExt,
'windows-service-ext': WindowsServiceExt,
},
'user-account': {
'unix-account-ext': UNIXAccountExt,
},
}

View File

@ -20,7 +20,7 @@ class Bundle(_STIXBase20):
# Not technically correct: STIX 2.0 spec doesn't say spec_version must
# have this value, but it's all we support for now.
('spec_version', StringProperty(fixed='2.0')),
('objects', ListProperty(STIXObjectProperty(spec_version="2.0"))),
('objects', ListProperty(STIXObjectProperty(spec_version='2.0'))),
])
def __init__(self, *args, **kwargs):

View File

@ -75,7 +75,6 @@ class TLPMarking(_STIXBase20):
`the STIX 2.0 specification <http://docs.oasis-open.org/cti/stix/v2.0/cs01/part1-stix-core/stix-v2.0-cs01-part1-stix-core.html#_Toc496709287>`__.
"""
# TODO: don't allow the creation of any other TLPMarkings than the ones below
_type = 'tlp'
_properties = OrderedDict([
('tlp', StringProperty(required=True)),
@ -131,7 +130,7 @@ class MarkingDefinition(_STIXBase20, _MarkingsMixin):
])
def __init__(self, **kwargs):
if set(('definition_type', 'definition')).issubset(kwargs.keys()):
if {'definition_type', 'definition'}.issubset(kwargs.keys()):
# Create correct marking type object
try:
marking_type = OBJ_MAP_MARKING[kwargs['definition_type']]

View File

@ -31,8 +31,8 @@ class Artifact(_Observable):
('mime_type', StringProperty()),
('payload_bin', BinaryProperty()),
('url', StringProperty()),
('hashes', HashesProperty(HASHING_ALGORITHM, spec_version="2.0")),
('extensions', ExtensionsProperty(spec_version="2.0", enclosing_type=_type)),
('hashes', HashesProperty(HASHING_ALGORITHM, spec_version='2.0')),
('extensions', ExtensionsProperty(spec_version='2.0')),
])
def _check_object_constraints(self):
@ -52,7 +52,7 @@ class AutonomousSystem(_Observable):
('number', IntegerProperty(required=True)),
('name', StringProperty()),
('rir', StringProperty()),
('extensions', ExtensionsProperty(spec_version="2.0", enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.0')),
])
@ -71,7 +71,7 @@ class Directory(_Observable):
('modified', TimestampProperty()),
('accessed', TimestampProperty()),
('contains_refs', ListProperty(ObjectReferenceProperty(valid_types=['file', 'directory']))),
('extensions', ExtensionsProperty(spec_version="2.0", enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.0')),
])
@ -85,7 +85,7 @@ class DomainName(_Observable):
('type', TypeProperty(_type, spec_version='2.0')),
('value', StringProperty(required=True)),
('resolves_to_refs', ListProperty(ObjectReferenceProperty(valid_types=['ipv4-addr', 'ipv6-addr', 'domain-name']))),
('extensions', ExtensionsProperty(spec_version="2.0", enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.0')),
])
@ -100,7 +100,7 @@ class EmailAddress(_Observable):
('value', StringProperty(required=True)),
('display_name', StringProperty()),
('belongs_to_ref', ObjectReferenceProperty(valid_types='user-account')),
('extensions', ExtensionsProperty(spec_version="2.0", enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.0')),
])
@ -139,11 +139,11 @@ class EmailMessage(_Observable):
('bcc_refs', ListProperty(ObjectReferenceProperty(valid_types='email-addr'))),
('subject', StringProperty()),
('received_lines', ListProperty(StringProperty)),
('additional_header_fields', DictionaryProperty(spec_version="2.0")),
('additional_header_fields', DictionaryProperty(spec_version='2.0')),
('body', StringProperty()),
('body_multipart', ListProperty(EmbeddedObjectProperty(type=EmailMIMEComponent))),
('raw_email_ref', ObjectReferenceProperty(valid_types='artifact')),
('extensions', ExtensionsProperty(spec_version="2.0", enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.0')),
])
def _check_object_constraints(self):
@ -200,7 +200,7 @@ class PDFExt(_Extension):
_properties = OrderedDict([
('version', StringProperty()),
('is_optimized', BooleanProperty()),
('document_info_dict', DictionaryProperty(spec_version="2.0")),
('document_info_dict', DictionaryProperty(spec_version='2.0')),
('pdfid0', StringProperty()),
('pdfid1', StringProperty()),
])
@ -217,7 +217,7 @@ class RasterImageExt(_Extension):
('image_width', IntegerProperty()),
('bits_per_pixel', IntegerProperty()),
('image_compression_algorithm', StringProperty()),
('exif_tags', DictionaryProperty(spec_version="2.0")),
('exif_tags', DictionaryProperty(spec_version='2.0')),
])
@ -324,7 +324,7 @@ class File(_Observable):
('decryption_key', StringProperty()),
('contains_refs', ListProperty(ObjectReferenceProperty)),
('content_ref', ObjectReferenceProperty(valid_types='artifact')),
('extensions', ExtensionsProperty(spec_version="2.0", enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.0')),
])
def _check_object_constraints(self):
@ -344,7 +344,7 @@ class IPv4Address(_Observable):
('value', StringProperty(required=True)),
('resolves_to_refs', ListProperty(ObjectReferenceProperty(valid_types='mac-addr'))),
('belongs_to_refs', ListProperty(ObjectReferenceProperty(valid_types='autonomous-system'))),
('extensions', ExtensionsProperty(spec_version="2.0", enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.0')),
])
@ -359,7 +359,7 @@ class IPv6Address(_Observable):
('value', StringProperty(required=True)),
('resolves_to_refs', ListProperty(ObjectReferenceProperty(valid_types='mac-addr'))),
('belongs_to_refs', ListProperty(ObjectReferenceProperty(valid_types='autonomous-system'))),
('extensions', ExtensionsProperty(spec_version="2.0", enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.0')),
])
@ -372,7 +372,7 @@ class MACAddress(_Observable):
_properties = OrderedDict([
('type', TypeProperty(_type, spec_version='2.0')),
('value', StringProperty(required=True)),
('extensions', ExtensionsProperty(spec_version="2.0", enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.0')),
])
@ -385,7 +385,7 @@ class Mutex(_Observable):
_properties = OrderedDict([
('type', TypeProperty(_type, spec_version='2.0')),
('name', StringProperty(required=True)),
('extensions', ExtensionsProperty(spec_version="2.0", enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.0')),
])
@ -399,7 +399,7 @@ class HTTPRequestExt(_Extension):
('request_method', StringProperty(required=True)),
('request_value', StringProperty(required=True)),
('request_version', StringProperty()),
('request_header', DictionaryProperty(spec_version="2.0")),
('request_header', DictionaryProperty(spec_version='2.0')),
('message_body_length', IntegerProperty()),
('message_body_data_ref', ObjectReferenceProperty(valid_types='artifact')),
])
@ -452,7 +452,7 @@ class SocketExt(_Extension):
],
),
),
('options', DictionaryProperty(spec_version="2.0")),
('options', DictionaryProperty(spec_version='2.0')),
(
'socket_type', EnumProperty(
allowed=[
@ -501,12 +501,12 @@ class NetworkTraffic(_Observable):
('dst_byte_count', IntegerProperty()),
('src_packets', IntegerProperty()),
('dst_packets', IntegerProperty()),
('ipfix', DictionaryProperty(spec_version="2.0")),
('ipfix', DictionaryProperty(spec_version='2.0')),
('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')),
('extensions', ExtensionsProperty(spec_version="2.0", enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.0')),
])
def _check_object_constraints(self):
@ -526,7 +526,7 @@ class WindowsProcessExt(_Extension):
('priority', StringProperty()),
('owner_sid', StringProperty()),
('window_title', StringProperty()),
('startup_info', DictionaryProperty(spec_version="2.0")),
('startup_info', DictionaryProperty(spec_version='2.0')),
])
@ -595,13 +595,13 @@ class Process(_Observable):
('cwd', StringProperty()),
('arguments', ListProperty(StringProperty)),
('command_line', StringProperty()),
('environment_variables', DictionaryProperty(spec_version="2.0")),
('environment_variables', DictionaryProperty(spec_version='2.0')),
('opened_connection_refs', ListProperty(ObjectReferenceProperty(valid_types='network-traffic'))),
('creator_user_ref', ObjectReferenceProperty(valid_types='user-account')),
('binary_ref', ObjectReferenceProperty(valid_types='file')),
('parent_ref', ObjectReferenceProperty(valid_types='process')),
('child_refs', ListProperty(ObjectReferenceProperty('process'))),
('extensions', ExtensionsProperty(spec_version="2.0", enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.0')),
])
def _check_object_constraints(self):
@ -632,7 +632,7 @@ class Software(_Observable):
('languages', ListProperty(StringProperty)),
('vendor', StringProperty()),
('version', StringProperty()),
('extensions', ExtensionsProperty(spec_version="2.0", enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.0')),
])
@ -645,7 +645,7 @@ class URL(_Observable):
_properties = OrderedDict([
('type', TypeProperty(_type, spec_version='2.0')),
('value', StringProperty(required=True)),
('extensions', ExtensionsProperty(spec_version="2.0", enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.0')),
])
@ -684,7 +684,7 @@ class UserAccount(_Observable):
('password_last_changed', TimestampProperty()),
('account_first_login', TimestampProperty()),
('account_last_login', TimestampProperty()),
('extensions', ExtensionsProperty(spec_version="2.0", enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.0')),
])
@ -733,7 +733,7 @@ class WindowsRegistryKey(_Observable):
('modified', TimestampProperty()),
('creator_user_ref', ObjectReferenceProperty(valid_types='user-account')),
('number_of_subkeys', IntegerProperty()),
('extensions', ExtensionsProperty(spec_version="2.0", enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.0')),
])
@ -784,7 +784,7 @@ class X509Certificate(_Observable):
('subject_public_key_modulus', StringProperty()),
('subject_public_key_exponent', IntegerProperty()),
('x509_v3_extensions', EmbeddedObjectProperty(type=X509V3ExtensionsType)),
('extensions', ExtensionsProperty(spec_version="2.0", enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.0')),
])
@ -807,16 +807,16 @@ def CustomObservable(type='x-custom-observable', properties=None):
itertools.chain.from_iterable([
[('type', TypeProperty(type, spec_version='2.0'))],
properties,
[('extensions', ExtensionsProperty(spec_version="2.0", enclosing_type=type))],
[('extensions', ExtensionsProperty(spec_version='2.0'))],
]),
)
return _custom_observable_builder(cls, type, _properties, '2.0', _Observable)
return wrapper
def CustomExtension(observable=None, type='x-custom-observable-ext', properties=None):
def CustomExtension(type='x-custom-observable-ext', properties=None):
"""Decorator for custom extensions to STIX Cyber Observables.
"""
def wrapper(cls):
return _custom_extension_builder(cls, observable, type, properties, '2.0', _Extension)
return _custom_extension_builder(cls, type, properties, '2.0', _Extension)
return wrapper

View File

@ -216,7 +216,7 @@ class ObservedData(_DomainObject):
('first_observed', TimestampProperty(required=True)),
('last_observed', TimestampProperty(required=True)),
('number_observed', IntegerProperty(min=1, max=999999999, required=True)),
('objects', ObservableProperty(spec_version="2.0", required=True)),
('objects', ObservableProperty(spec_version='2.0', required=True)),
('revoked', BooleanProperty(default=lambda: False)),
('labels', ListProperty(StringProperty)),
('external_references', ListProperty(ExternalReference)),

View File

@ -19,24 +19,23 @@ from .base import (
)
from .bundle import Bundle
from .common import (
TLP_AMBER, TLP_GREEN, TLP_RED, TLP_WHITE, CustomMarking, ExternalReference,
GranularMarking, KillChainPhase, LanguageContent, MarkingDefinition,
StatementMarking, TLPMarking,
TLP_AMBER, TLP_GREEN, TLP_RED, TLP_WHITE, CustomExtension, CustomMarking,
ExtensionDefinition, ExternalReference, GranularMarking, KillChainPhase,
LanguageContent, MarkingDefinition, StatementMarking, TLPMarking,
)
from .observables import (
URL, AlternateDataStream, ArchiveExt, Artifact, AutonomousSystem,
CustomExtension, CustomObservable, Directory, DomainName, EmailAddress,
EmailMessage, EmailMIMEComponent, File, HTTPRequestExt, ICMPExt,
IPv4Address, IPv6Address, MACAddress, Mutex, NetworkTraffic, NTFSExt,
PDFExt, Process, RasterImageExt, SocketExt, Software, TCPExt,
UNIXAccountExt, UserAccount, WindowsPEBinaryExt,
WindowsPEOptionalHeaderType, WindowsPESection, WindowsProcessExt,
WindowsRegistryKey, WindowsRegistryValueType, WindowsServiceExt,
X509Certificate, X509V3ExtensionsType,
CustomObservable, Directory, DomainName, EmailAddress, EmailMessage,
EmailMIMEComponent, File, HTTPRequestExt, ICMPExt, IPv4Address,
IPv6Address, MACAddress, Mutex, NetworkTraffic, NTFSExt, PDFExt, Process,
RasterImageExt, SocketExt, Software, TCPExt, UNIXAccountExt, UserAccount,
WindowsPEBinaryExt, WindowsPEOptionalHeaderType, WindowsPESection,
WindowsProcessExt, WindowsRegistryKey, WindowsRegistryValueType,
WindowsServiceExt, X509Certificate, X509V3ExtensionsType,
)
from .sdo import (
AttackPattern, Campaign, CourseOfAction, CustomObject, Grouping, Identity,
Indicator, Infrastructure, IntrusionSet, Location, Malware,
Incident, Indicator, Infrastructure, IntrusionSet, Location, Malware,
MalwareAnalysis, Note, ObservedData, Opinion, Report, ThreatActor, Tool,
Vulnerability,
)
@ -49,6 +48,7 @@ OBJ_MAP = {
'course-of-action': CourseOfAction,
'grouping': Grouping,
'identity': Identity,
'incident': Incident,
'indicator': Indicator,
'infrastructure': Infrastructure,
'intrusion-set': IntrusionSet,
@ -65,6 +65,7 @@ OBJ_MAP = {
'threat-actor': ThreatActor,
'tool': Tool,
'sighting': Sighting,
'extension-definition': ExtensionDefinition,
'vulnerability': Vulnerability,
}
@ -90,38 +91,29 @@ OBJ_MAP_OBSERVABLE = {
}
EXT_MAP = {
'file': {
'archive-ext': ArchiveExt,
'ntfs-ext': NTFSExt,
'pdf-ext': PDFExt,
'raster-image-ext': RasterImageExt,
'windows-pebinary-ext': WindowsPEBinaryExt,
},
'network-traffic': {
'http-request-ext': HTTPRequestExt,
'icmp-ext': ICMPExt,
'socket-ext': SocketExt,
'tcp-ext': TCPExt,
},
'process': {
'windows-process-ext': WindowsProcessExt,
'windows-service-ext': WindowsServiceExt,
},
'user-account': {
'unix-account-ext': UNIXAccountExt,
},
}
# Ensure star-imports from this module get the right symbols. "base" is a
# known problem, since there are multiple modules with that name and one can
# accidentally overwrite another.
__all__ = """
Bundle,
TLP_AMBER, TLP_GREEN, TLP_RED, TLP_WHITE, CustomMarking, ExternalReference,
GranularMarking, KillChainPhase, LanguageContent, MarkingDefinition,
StatementMarking, TLPMarking,
TLP_AMBER, TLP_GREEN, TLP_RED, TLP_WHITE, CustomMarking, ExtensionDefinition,
ExternalReference, GranularMarking, KillChainPhase, LanguageContent,
MarkingDefinition, StatementMarking, TLPMarking,
URL, AlternateDataStream, ArchiveExt, Artifact, AutonomousSystem,
CustomExtension, CustomObservable, Directory, DomainName, EmailAddress,
@ -134,7 +126,7 @@ __all__ = """
X509Certificate, X509V3ExtensionsType,
AttackPattern, Campaign, CourseOfAction, CustomObject, Grouping, Identity,
Indicator, Infrastructure, IntrusionSet, Location, Malware,
Incident, Indicator, Infrastructure, IntrusionSet, Location, Malware,
MalwareAnalysis, Note, ObservedData, Opinion, Report, ThreatActor, Tool,
Vulnerability,

View File

@ -10,11 +10,24 @@ class _STIXBase21(_STIXBase):
class _Observable(_Observable, _STIXBase21):
pass
def __init__(self, **kwargs):
super(_Observable, self).__init__(**kwargs)
if 'id' not in kwargs:
# Specific to 2.1+ observables: generate a deterministic ID
id_ = self._generate_id()
# Spec says fall back to UUIDv4 if no contributing properties were
# given. That's what already happened (the following is actually
# overwriting the default uuidv4), so nothing to do here.
if id_ is not None:
# Can't assign to self (we're immutable), so slip the ID in
# more sneakily.
self._inner["id"] = id_
class _Extension(_Extension, _STIXBase21):
pass
extension_type = None
class _DomainObject(_DomainObject, _STIXBase21):

View File

@ -10,7 +10,7 @@ from .base import _STIXBase21
class Bundle(_STIXBase21):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_nuwp4rox8c7r>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_gms872kuzdmg>`__.
"""
_type = 'bundle'
@ -37,7 +37,7 @@ class Bundle(_STIXBase21):
def get_obj(self, obj_uuid):
if "objects" in self._inner:
found_objs = [elem for elem in self.objects if elem['id'] == obj_uuid]
if found_objs == []:
if not found_objs:
raise KeyError("'%s' does not match the id property of any of the bundle's objects" % obj_uuid)
return found_objs
else:

View File

@ -2,23 +2,25 @@
from collections import OrderedDict
from ..custom import _custom_marking_builder
from ..exceptions import InvalidValueError
from . import _Extension
from ..custom import _custom_extension_builder, _custom_marking_builder
from ..exceptions import InvalidValueError, PropertyPresenceError
from ..markings import _MarkingsMixin
from ..markings.utils import check_tlp_marking
from ..properties import (
BooleanProperty, DictionaryProperty, HashesProperty, IDProperty,
IntegerProperty, ListProperty, Property, ReferenceProperty,
SelectorProperty, StringProperty, TimestampProperty, TypeProperty,
BooleanProperty, DictionaryProperty, EnumProperty, ExtensionsProperty,
HashesProperty, IDProperty, IntegerProperty, ListProperty, Property,
ReferenceProperty, SelectorProperty, StringProperty, TimestampProperty,
TypeProperty,
)
from ..utils import NOW, _get_dict
from .base import _STIXBase21
from .vocab import HASHING_ALGORITHM
from .vocab import EXTENSION_TYPE, HASHING_ALGORITHM
class ExternalReference(_STIXBase21):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_bajcvqteiard>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_72bcfr3t79jx>`__.
"""
_properties = OrderedDict([
@ -52,7 +54,7 @@ class ExternalReference(_STIXBase21):
class KillChainPhase(_STIXBase21):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_i4tjv75ce50h>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_i4tjv75ce50h>`__.
"""
_properties = OrderedDict([
@ -63,7 +65,7 @@ class KillChainPhase(_STIXBase21):
class GranularMarking(_STIXBase21):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_robezi5egfdr>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_robezi5egfdr>`__.
"""
_properties = OrderedDict([
@ -79,7 +81,7 @@ class GranularMarking(_STIXBase21):
class LanguageContent(_STIXBase21):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_nfwr8z9ax2bi>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_z9r1cwtu8jja>`__.
"""
_type = 'language-content'
@ -91,9 +93,9 @@ class LanguageContent(_STIXBase21):
('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('object_ref', ReferenceProperty(valid_types=["SCO", "SDO", "SRO"], 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.
# TODO: 'object_modified' MUST be an exact match for the modified time of the STIX Object being referenced
('object_modified', TimestampProperty(precision='millisecond')),
# TODO: 'contents' https://docs.google.com/document/d/1ShNq4c3e1CkfANmD9O--mdZ5H0O_GLnjN28a_yrEaco/edit#heading=h.cfz5hcantmvx
# TODO: Implement 'contents' property requirements as defined in STIX 2.1 CS02
('contents', DictionaryProperty(spec_version='2.1', required=True)),
('revoked', BooleanProperty(default=lambda: False)),
('labels', ListProperty(StringProperty)),
@ -101,12 +103,55 @@ class LanguageContent(_STIXBase21):
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
class ExtensionDefinition(_STIXBase21):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_32j232tfvtly>`__.
"""
_type = 'extension-definition'
_properties = OrderedDict([
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1', required=True)),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('name', StringProperty(required=True)),
('description', StringProperty()),
('schema', StringProperty(required=True)),
('version', StringProperty(required=True)),
(
'extension_types', ListProperty(
EnumProperty(
allowed=EXTENSION_TYPE,
), required=True,
),
),
('extension_properties', ListProperty(StringProperty)),
('revoked', BooleanProperty(default=lambda: False)),
('labels', ListProperty(StringProperty)),
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
])
def CustomExtension(type='x-custom-ext', properties=None):
"""Custom STIX Object Extension decorator.
"""
def wrapper(cls):
return _custom_extension_builder(cls, type, properties, '2.1', _Extension)
return wrapper
class TLPMarking(_STIXBase21):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_yd3ar14ekwrs>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_yd3ar14ekwrs>`__.
"""
_type = 'tlp'
@ -117,7 +162,7 @@ class TLPMarking(_STIXBase21):
class StatementMarking(_STIXBase21):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_3ru8r05saera>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_3ru8r05saera>`__.
"""
_type = 'statement'
@ -147,26 +192,27 @@ class MarkingProperty(Property):
class MarkingDefinition(_STIXBase21, _MarkingsMixin):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_hr5vgqxjk7ns>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_k5fndj2c7c1k>`__.
"""
_type = 'marking-definition'
_properties = OrderedDict([
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type)),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('definition_type', StringProperty(required=True)),
('definition_type', StringProperty()),
('name', StringProperty()),
('definition', MarkingProperty(required=True)),
('definition', MarkingProperty()),
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
def __init__(self, **kwargs):
if set(('definition_type', 'definition')).issubset(kwargs.keys()):
if {'definition_type', 'definition'}.issubset(kwargs.keys()):
# Create correct marking type object
try:
marking_type = OBJ_MAP_MARKING[kwargs['definition_type']]
@ -181,6 +227,18 @@ class MarkingDefinition(_STIXBase21, _MarkingsMixin):
def _check_object_constraints(self):
super(MarkingDefinition, self)._check_object_constraints()
definition = self.get("definition")
definition_type = self.get("definition_type")
extensions = self.get("extensions")
if not (definition_type and definition) and not extensions:
raise PropertyPresenceError(
"MarkingDefinition objects must have the properties "
"'definition_type' and 'definition' if 'extensions' is not present",
MarkingDefinition,
)
check_tlp_marking(self, '2.1')
def serialize(self, pretty=False, include_optional_defaults=False, **kwargs):
@ -194,7 +252,7 @@ OBJ_MAP_MARKING = {
}
def CustomMarking(type='x-custom-marking', properties=None):
def CustomMarking(type='x-custom-marking', properties=None, extension_name=None):
"""Custom STIX Marking decorator.
Example:
@ -209,6 +267,16 @@ def CustomMarking(type='x-custom-marking', properties=None):
"""
def wrapper(cls):
if extension_name:
@CustomExtension(type=extension_name, properties=properties)
class NameExtension:
extension_type = 'property-extension'
extension = extension_name.split('--')[1]
extension = extension.replace('-', '')
NameExtension.__name__ = 'ExtensionDefinition' + extension
cls.with_extension = extension_name
return _custom_marking_builder(cls, type, MarkingDefinition._properties, '2.1', _STIXBase21)
return _custom_marking_builder(cls, type, properties, '2.1', _STIXBase21)
return wrapper

View File

@ -8,7 +8,7 @@ _Observable and do not have a ``_type`` attribute.
from collections import OrderedDict
import itertools
from ..custom import _custom_extension_builder, _custom_observable_builder
from ..custom import _custom_observable_builder
from ..exceptions import AtLeastOnePropertyError, DependentPropertiesError
from ..properties import (
BinaryProperty, BooleanProperty, DictionaryProperty,
@ -18,7 +18,7 @@ from ..properties import (
TypeProperty,
)
from .base import _Extension, _Observable, _STIXBase21
from .common import GranularMarking
from .common import CustomExtension, GranularMarking
from .vocab import (
ACCOUNT_TYPE, ENCRYPTION_ALGORITHM, HASHING_ALGORITHM,
NETWORK_SOCKET_ADDRESS_FAMILY, NETWORK_SOCKET_TYPE,
@ -29,7 +29,7 @@ from .vocab import (
class Artifact(_Observable):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_rqwyxo6gp7cv>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_4jegwl6ojbes>`__.
"""
_type = 'artifact'
@ -46,7 +46,7 @@ class Artifact(_Observable):
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('defanged', BooleanProperty(default=lambda: False)),
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
_id_contributing_properties = ["hashes", "payload_bin"]
@ -58,7 +58,7 @@ class Artifact(_Observable):
class AutonomousSystem(_Observable):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_bxebwa6l91fb>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_27gux0aol9e3>`__.
"""
_type = 'autonomous-system'
@ -72,14 +72,14 @@ class AutonomousSystem(_Observable):
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('defanged', BooleanProperty(default=lambda: False)),
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
_id_contributing_properties = ["number"]
class Directory(_Observable):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_vhpkn06q7fvl>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_lyvpga5hlw52>`__.
"""
_type = 'directory'
@ -97,14 +97,14 @@ class Directory(_Observable):
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('defanged', BooleanProperty(default=lambda: False)),
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
_id_contributing_properties = ["path"]
class DomainName(_Observable):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_i2zf5h7vnrd9>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_prhhksbxbg87>`__.
"""
_type = 'domain-name'
@ -117,14 +117,14 @@ class DomainName(_Observable):
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('defanged', BooleanProperty(default=lambda: False)),
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
_id_contributing_properties = ["value"]
class EmailAddress(_Observable):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_am7srelb9c14>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_wmenahkvqmgj>`__.
"""
_type = 'email-addr'
@ -138,19 +138,19 @@ class EmailAddress(_Observable):
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('defanged', BooleanProperty(default=lambda: False)),
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
_id_contributing_properties = ["value"]
class EmailMIMEComponent(_STIXBase21):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_kzv52qqc0xw1>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_qpo5x7d8mefq>`__.
"""
_properties = OrderedDict([
('body', StringProperty()),
('body_raw_ref', ReferenceProperty(valid_types=['artifact', 'file'], spec_version="2.1")),
('body_raw_ref', ReferenceProperty(valid_types=['artifact', 'file'], spec_version='2.1')),
('content_type', StringProperty()),
('content_disposition', StringProperty()),
])
@ -162,7 +162,7 @@ class EmailMIMEComponent(_STIXBase21):
class EmailMessage(_Observable):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_loz634bn09om>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_grboc7sq5514>`__.
"""
_type = 'email-message'
@ -188,7 +188,7 @@ class EmailMessage(_Observable):
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('defanged', BooleanProperty(default=lambda: False)),
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
_id_contributing_properties = ["from_ref", "subject", "body"]
@ -202,19 +202,19 @@ class EmailMessage(_Observable):
class ArchiveExt(_Extension):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_mm25z9wuw4tr>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_xi3g7dwaigs6>`__.
"""
_type = 'archive-ext'
_properties = OrderedDict([
('contains_refs', ListProperty(ReferenceProperty(valid_types=['file', 'directory'], spec_version="2.1"), required=True)),
('contains_refs', ListProperty(ReferenceProperty(valid_types=['file', 'directory'], spec_version='2.1'), required=True)),
('comment', StringProperty()),
])
class AlternateDataStream(_STIXBase21):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_nbqgazg6fsma>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_8i2ts0xicqea>`__.
"""
_properties = OrderedDict([
@ -226,7 +226,7 @@ class AlternateDataStream(_STIXBase21):
class NTFSExt(_Extension):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_tb77nk1g3y6f>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_o6cweepfrsci>`__.
"""
_type = 'ntfs-ext'
@ -238,7 +238,7 @@ class NTFSExt(_Extension):
class PDFExt(_Extension):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_30hzxqrmkg8w>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_8xmpb2ghp9km>`__.
"""
_type = 'pdf-ext'
@ -253,7 +253,7 @@ class PDFExt(_Extension):
class RasterImageExt(_Extension):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_20mnz0u5ppxr>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_u5z7i2ox8w4x>`__.
"""
_type = 'raster-image-ext'
@ -267,7 +267,7 @@ class RasterImageExt(_Extension):
class WindowsPEOptionalHeaderType(_STIXBase21):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_wyp5qdc2wugy>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_29l09w731pzc>`__.
"""
_properties = OrderedDict([
@ -311,7 +311,7 @@ class WindowsPEOptionalHeaderType(_STIXBase21):
class WindowsPESection(_STIXBase21):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_wiqw87xsov3t>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_ioapwyd8oimw>`__.
"""
_properties = OrderedDict([
@ -324,7 +324,7 @@ class WindowsPESection(_STIXBase21):
class WindowsPEBinaryExt(_Extension):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_5f9bgdmj91h5>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_gg5zibddf9bs>`__.
"""
_type = 'windows-pebinary-ext'
@ -346,7 +346,7 @@ class WindowsPEBinaryExt(_Extension):
class File(_Observable):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_vq03pryd7u32>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_99bl2dibcztv>`__.
"""
_type = 'file'
@ -369,7 +369,7 @@ class File(_Observable):
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('defanged', BooleanProperty(default=lambda: False)),
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
_id_contributing_properties = ["hashes", "name", "parent_directory_ref", "extensions"]
@ -380,7 +380,7 @@ class File(_Observable):
class IPv4Address(_Observable):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_ta83c412bfsc>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_ki1ufj1ku8s0>`__.
"""
_type = 'ipv4-addr'
@ -394,14 +394,14 @@ class IPv4Address(_Observable):
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('defanged', BooleanProperty(default=lambda: False)),
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
_id_contributing_properties = ["value"]
class IPv6Address(_Observable):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_f76hsv2pvwwq>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_oeggeryskriq>`__.
"""
_type = 'ipv6-addr'
@ -415,14 +415,14 @@ class IPv6Address(_Observable):
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('defanged', BooleanProperty(default=lambda: False)),
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
_id_contributing_properties = ["value"]
class MACAddress(_Observable):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_6lhrrdef8852>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_f92nr9plf58y>`__.
"""
_type = 'mac-addr'
@ -434,14 +434,14 @@ class MACAddress(_Observable):
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('defanged', BooleanProperty(default=lambda: False)),
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
_id_contributing_properties = ["value"]
class Mutex(_Observable):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_u65ia5eoc7cv>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_84hwlkdmev1w>`__.
"""
_type = 'mutex'
@ -453,14 +453,14 @@ class Mutex(_Observable):
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('defanged', BooleanProperty(default=lambda: False)),
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
_id_contributing_properties = ["name"]
class HTTPRequestExt(_Extension):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_60k6dn28qicj>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_b0e376hgtml8>`__.
"""
_type = 'http-request-ext'
@ -470,14 +470,13 @@ class HTTPRequestExt(_Extension):
('request_version', StringProperty()),
('request_header', DictionaryProperty(spec_version='2.1')),
('message_body_length', IntegerProperty()),
('message_body_data_ref', ReferenceProperty(valid_types='artifact', spec_version="2.1")),
('message_body_data_ref', ReferenceProperty(valid_types='artifact', spec_version='2.1')),
])
class ICMPExt(_Extension):
# TODO: Add link
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_3g6wds21zwzl>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_ozypx0lmkebv>`__.
"""
_type = 'icmp-ext'
@ -489,7 +488,7 @@ class ICMPExt(_Extension):
class SocketExt(_Extension):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_f54f1hripxsg>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_8jamupj9ubdv>`__.
"""
_type = 'socket-ext'
@ -519,7 +518,7 @@ class SocketExt(_Extension):
class TCPExt(_Extension):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_2z78x4m8ewcw>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_k2njqio7f142>`__.
"""
_type = 'tcp-ext'
@ -531,7 +530,7 @@ class TCPExt(_Extension):
class NetworkTraffic(_Observable):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_e5nyr5squmsd>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_rgnc3w40xy>`__.
"""
_type = 'network-traffic'
@ -559,7 +558,7 @@ class NetworkTraffic(_Observable):
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('defanged', BooleanProperty(default=lambda: False)),
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
_id_contributing_properties = ["start", "end", "src_ref", "dst_ref", "src_port", "dst_port", "protocols", "extensions"]
@ -586,7 +585,7 @@ class NetworkTraffic(_Observable):
class WindowsProcessExt(_Extension):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_4wfs4ve800kf>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_oyegq07gjf5t>`__.
"""
_type = 'windows-process-ext'
@ -603,7 +602,7 @@ class WindowsProcessExt(_Extension):
class WindowsServiceExt(_Extension):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_s2rmoe7djlt>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_lbcvc2ahx1s0>`__.
"""
_type = 'windows-service-ext'
@ -613,7 +612,7 @@ class WindowsServiceExt(_Extension):
('display_name', StringProperty()),
('group_name', StringProperty()),
('start_type', EnumProperty(WINDOWS_SERVICE_START_TYPE)),
('service_dll_refs', ListProperty(ReferenceProperty(valid_types='file', spec_version="2.1"))),
('service_dll_refs', ListProperty(ReferenceProperty(valid_types='file', spec_version='2.1'))),
('service_type', EnumProperty(WINDOWS_SERVICE_TYPE)),
('service_status', EnumProperty(WINDOWS_SERVICE_STATUS)),
])
@ -621,7 +620,7 @@ class WindowsServiceExt(_Extension):
class Process(_Observable):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_ur7snm473t1d>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_hpppnm86a1jm>`__.
"""
_type = 'process'
@ -644,7 +643,7 @@ class Process(_Observable):
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('defanged', BooleanProperty(default=lambda: False)),
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
_id_contributing_properties = []
@ -665,7 +664,7 @@ class Process(_Observable):
class Software(_Observable):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_jru33yeokrmh>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_7rkyhtkdthok>`__.
"""
_type = 'software'
@ -682,14 +681,14 @@ class Software(_Observable):
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('defanged', BooleanProperty(default=lambda: False)),
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
_id_contributing_properties = ["name", "cpe", "swid", "vendor", "version"]
class URL(_Observable):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_6bsklda6vc0c>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_ah3hict2dez0>`__.
"""
_type = 'url'
@ -701,14 +700,14 @@ class URL(_Observable):
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('defanged', BooleanProperty(default=lambda: False)),
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
_id_contributing_properties = ["value"]
class UNIXAccountExt(_Extension):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_z25gmwyz67kl>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_hodiamlggpw5>`__.
"""
_type = 'unix-account-ext'
@ -722,7 +721,7 @@ class UNIXAccountExt(_Extension):
class UserAccount(_Observable):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_hah33g4ntxnx>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_azo70vgj1vm2>`__.
"""
_type = 'user-account'
@ -747,14 +746,14 @@ class UserAccount(_Observable):
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('defanged', BooleanProperty(default=lambda: False)),
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
_id_contributing_properties = ["account_type", "user_id", "account_login"]
class WindowsRegistryValueType(_STIXBase21):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_6jiqabgqp2hp>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_u7n4ndghs3qq>`__.
"""
_type = 'windows-registry-value-type'
@ -767,7 +766,7 @@ class WindowsRegistryValueType(_STIXBase21):
class WindowsRegistryKey(_Observable):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_bdim4of4dl37>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_luvw8wjlfo3y>`__.
"""
_type = 'windows-registry-key'
@ -784,14 +783,14 @@ class WindowsRegistryKey(_Observable):
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('defanged', BooleanProperty(default=lambda: False)),
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
_id_contributing_properties = ["key", "values"]
class X509V3ExtensionsType(_STIXBase21):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_c1kt4dheb6vz>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_oudvonxzdlku>`__.
"""
_type = 'x509-v3-extensions-type'
@ -817,7 +816,7 @@ class X509V3ExtensionsType(_STIXBase21):
class X509Certificate(_Observable):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_g3kniyun8ykv>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_8abcy1o5x9w1>`__.
"""
_type = 'x509-certificate'
@ -841,7 +840,7 @@ class X509Certificate(_Observable):
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('defanged', BooleanProperty(default=lambda: False)),
('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=_type)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
_id_contributing_properties = ["hashes", "serial_number"]
@ -858,7 +857,7 @@ class X509Certificate(_Observable):
self._check_at_least_one_property(att_list)
def CustomObservable(type='x-custom-observable', properties=None, id_contrib_props=None):
def CustomObservable(type='x-custom-observable', properties=None, id_contrib_props=None, extension_name=None):
"""Custom STIX Cyber Observable Object type decorator.
Example:
@ -874,24 +873,29 @@ def CustomObservable(type='x-custom-observable', properties=None, id_contrib_pro
"""
def wrapper(cls):
_properties = list(
itertools.chain.from_iterable([
[('type', TypeProperty(type, spec_version='2.1'))],
[('spec_version', StringProperty(fixed='2.1'))],
[('id', IDProperty(type, spec_version='2.1'))],
itertools.chain(
[
('type', TypeProperty(type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(type, spec_version='2.1')),
],
properties,
[('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1')))],
[('granular_markings', ListProperty(GranularMarking))],
[('defanged', BooleanProperty(default=lambda: False))],
[('extensions', ExtensionsProperty(spec_version='2.1', enclosing_type=type))],
]),
[
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('defanged', BooleanProperty(default=lambda: False)),
('extensions', ExtensionsProperty(spec_version='2.1')),
],
),
)
if extension_name:
@CustomExtension(type=extension_name, properties={})
class NameExtension:
extension_type = 'new-sco'
extension = extension_name.split('--')[1]
extension = extension.replace('-', '')
NameExtension.__name__ = 'ExtensionDefinition' + extension
cls.with_extension = extension_name
return _custom_observable_builder(cls, type, _properties, '2.1', _Observable, id_contrib_props)
return wrapper
def CustomExtension(observable=None, type='x-custom-observable-ext', properties=None):
"""Decorator for custom extensions to STIX Cyber Observables.
"""
def wrapper(cls):
return _custom_extension_builder(cls, observable, type, properties, '2.1', _Extension)
return wrapper

View File

@ -1,7 +1,6 @@
"""STIX 2.1 Domain Objects."""
from collections import OrderedDict
import itertools
from urllib.parse import quote_plus
import warnings
@ -12,13 +11,16 @@ from ..exceptions import (
InvalidValueError, PropertyPresenceError, STIXDeprecationWarning,
)
from ..properties import (
BooleanProperty, EnumProperty, FloatProperty, IDProperty, IntegerProperty,
ListProperty, ObservableProperty, OpenVocabProperty, PatternProperty,
ReferenceProperty, StringProperty, TimestampProperty, TypeProperty,
BooleanProperty, EnumProperty, ExtensionsProperty, FloatProperty,
IDProperty, IntegerProperty, ListProperty, ObservableProperty,
OpenVocabProperty, PatternProperty, ReferenceProperty, StringProperty,
TimestampProperty, TypeProperty,
)
from ..utils import NOW
from .base import _DomainObject
from .common import ExternalReference, GranularMarking, KillChainPhase
from .common import (
CustomExtension, ExternalReference, GranularMarking, KillChainPhase,
)
from .vocab import (
ATTACK_MOTIVATION, ATTACK_RESOURCE_LEVEL, GROUPING_CONTEXT, IDENTITY_CLASS,
IMPLEMENTATION_LANGUAGE, INDICATOR_TYPE, INDUSTRY_SECTOR,
@ -31,7 +33,7 @@ from .vocab import (
class AttackPattern(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_4ohsa4pay4h4>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_axjijf603msy>`__.
"""
_type = 'attack-pattern'
@ -53,12 +55,13 @@ class AttackPattern(_DomainObject):
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
class Campaign(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_vvysvm8mt434>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_pcpvfz4ik6d6>`__.
"""
_type = 'campaign'
@ -82,6 +85,7 @@ class Campaign(_DomainObject):
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
def _check_object_constraints(self):
@ -97,7 +101,7 @@ class Campaign(_DomainObject):
class CourseOfAction(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_d5yf99f0a230>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_a925mpw39txn>`__.
"""
_type = 'course-of-action'
@ -117,12 +121,13 @@ class CourseOfAction(_DomainObject):
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
class Grouping(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_9e3uldaqqha2>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_t56pn7elv6u7>`__.
"""
_type = 'grouping'
@ -144,12 +149,13 @@ class Grouping(_DomainObject):
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
class Identity(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_ru8fmldl2p6w>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_wh296fiwpklp>`__.
"""
_type = 'identity'
@ -173,12 +179,40 @@ class Identity(_DomainObject):
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
class Incident(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_sczfhw64pjxt>`__.
"""
_type = 'incident'
_properties = OrderedDict([
('type', TypeProperty(_type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
('id', IDProperty(_type, spec_version='2.1')),
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('name', StringProperty(required=True)),
('description', StringProperty()),
('kill_chain_phases', ListProperty(KillChainPhase)),
('revoked', BooleanProperty(default=lambda: False)),
('labels', ListProperty(StringProperty)),
('confidence', IntegerProperty()),
('lang', StringProperty()),
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
class Indicator(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_wfiae74706sw>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_muftrcpnf89v>`__.
"""
_type = 'indicator'
@ -205,6 +239,7 @@ class Indicator(_DomainObject):
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
def __init__(self, *args, **kwargs):
@ -237,7 +272,7 @@ class Indicator(_DomainObject):
class Infrastructure(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_l2alfbbcmfep>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_jo3k1o6lr9>`__.
"""
_type = 'infrastructure'
@ -262,6 +297,7 @@ class Infrastructure(_DomainObject):
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
def _check_object_constraints(self):
@ -277,7 +313,7 @@ class Infrastructure(_DomainObject):
class IntrusionSet(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_ticprjb32bc4>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_jo3k1o6lr9>`__.
"""
_type = 'intrusion-set'
@ -304,6 +340,7 @@ class IntrusionSet(_DomainObject):
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
def _check_object_constraints(self):
@ -319,7 +356,7 @@ class IntrusionSet(_DomainObject):
class Location(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_sqez6sri9vtz>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_th8nitr8jb4k>`__.
"""
_type = 'location'
@ -348,6 +385,7 @@ class Location(_DomainObject):
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
def _check_object_constraints(self):
@ -426,7 +464,7 @@ class Location(_DomainObject):
class Malware(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_gc4ooz6oaz7y>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_s5l7katgbp09>`__.
"""
_type = 'malware'
@ -457,6 +495,7 @@ class Malware(_DomainObject):
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
def _check_object_constraints(self):
@ -478,7 +517,7 @@ class Malware(_DomainObject):
class MalwareAnalysis(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_dw67pa20zss5>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_6hdrixb3ua4j>`__.
"""
_type = 'malware-analysis'
@ -512,6 +551,7 @@ class MalwareAnalysis(_DomainObject):
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
def _check_object_constraints(self):
@ -522,7 +562,7 @@ class MalwareAnalysis(_DomainObject):
class Note(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_hr77jvcbs9jk>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_gudodcg1sbb9>`__.
"""
_type = 'note'
@ -544,12 +584,13 @@ class Note(_DomainObject):
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
class ObservedData(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_h1590esrzg5f>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_p49j1fwoxldc>`__.
"""
_type = 'observed-data'
@ -564,7 +605,7 @@ class ObservedData(_DomainObject):
('last_observed', TimestampProperty(required=True)),
('number_observed', IntegerProperty(min=1, max=999999999, required=True)),
('objects', ObservableProperty(spec_version='2.1')),
('object_refs', ListProperty(ReferenceProperty(valid_types=["SCO", "SRO"], spec_version="2.1"))),
('object_refs', ListProperty(ReferenceProperty(valid_types=["SCO", "SRO"], spec_version='2.1'))),
('revoked', BooleanProperty(default=lambda: False)),
('labels', ListProperty(StringProperty)),
('confidence', IntegerProperty()),
@ -572,6 +613,7 @@ class ObservedData(_DomainObject):
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
def __init__(self, *args, **kwargs):
@ -602,7 +644,7 @@ class ObservedData(_DomainObject):
class Opinion(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_sr2hswmu5t1>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_ht1vtzfbtzda>`__.
"""
_type = 'opinion'
@ -624,12 +666,13 @@ class Opinion(_DomainObject):
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
class Report(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_ha4fpad0r9pf>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_n8bjzg1ysgdq>`__.
"""
_type = 'report'
@ -652,12 +695,13 @@ class Report(_DomainObject):
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
class ThreatActor(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_2wowmlcbkqst>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_k017w16zutw>`__.
"""
_type = 'threat-actor'
@ -688,6 +732,7 @@ class ThreatActor(_DomainObject):
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
def _check_object_constraints(self):
@ -703,7 +748,7 @@ class ThreatActor(_DomainObject):
class Tool(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_m21z3a1f3lou>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_z4voa9ndw8v>`__.
"""
_type = 'tool'
@ -727,12 +772,13 @@ class Tool(_DomainObject):
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
class Vulnerability(_DomainObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_d9f0iay06wtx>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_q5ytzmajn6re>`__.
"""
_type = 'vulnerability'
@ -752,10 +798,11 @@ class Vulnerability(_DomainObject):
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
def CustomObject(type='x-custom-type', properties=None):
def CustomObject(type='x-custom-type', properties=None, extension_name=None, is_sdo=True):
"""Custom STIX Object type decorator.
Example:
@ -785,8 +832,8 @@ def CustomObject(type='x-custom-type', properties=None):
"""
def wrapper(cls):
_properties = list(
itertools.chain.from_iterable([
extension_properties = [x for x in properties if not x[0].startswith('x_')]
_properties = (
[
('type', TypeProperty(type, spec_version='2.1')),
('spec_version', StringProperty(fixed='2.1')),
@ -794,9 +841,9 @@ def CustomObject(type='x-custom-type', properties=None):
('created_by_ref', ReferenceProperty(valid_types='identity', spec_version='2.1')),
('created', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
('modified', TimestampProperty(default=lambda: NOW, precision='millisecond', precision_constraint='min')),
],
[x for x in properties if not x[0].startswith('x_')],
[
]
+ extension_properties
+ [
('revoked', BooleanProperty(default=lambda: False)),
('labels', ListProperty(StringProperty)),
('confidence', IntegerProperty()),
@ -804,10 +851,23 @@ def CustomObject(type='x-custom-type', properties=None):
('external_references', ListProperty(ExternalReference)),
('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]),
]),
('extensions', ExtensionsProperty(spec_version='2.1')),
]
+ sorted((x for x in properties if x[0].startswith('x_')), key=lambda x: x[0])
)
if extension_name:
@CustomExtension(type=extension_name, properties={})
class NameExtension:
if is_sdo:
extension_type = 'new-sdo'
else:
extension_type = 'new-sro'
extension = extension_name.split('--')[1]
extension = extension.replace('-', '')
NameExtension.__name__ = 'ExtensionDefinition' + extension
cls.with_extension = extension_name
return _custom_object_builder(cls, type, _properties, '2.1', _DomainObject)
return wrapper

View File

@ -3,8 +3,9 @@
from collections import OrderedDict
from ..properties import (
BooleanProperty, IDProperty, IntegerProperty, ListProperty,
ReferenceProperty, StringProperty, TimestampProperty, TypeProperty,
BooleanProperty, ExtensionsProperty, IDProperty, IntegerProperty,
ListProperty, ReferenceProperty, StringProperty, TimestampProperty,
TypeProperty,
)
from ..utils import NOW
from .base import _RelationshipObject
@ -13,7 +14,7 @@ from .common import ExternalReference, GranularMarking
class Relationship(_RelationshipObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_al0fb8fcd9e7>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_e2e1szrqfoan>`__.
"""
_invalid_source_target_types = ['bundle', 'language-content', 'marking-definition', 'relationship', 'sighting']
@ -39,6 +40,7 @@ class Relationship(_RelationshipObject):
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
# Explicitly define the first three kwargs to make readable Relationship declarations.
@ -69,7 +71,7 @@ class Relationship(_RelationshipObject):
class Sighting(_RelationshipObject):
"""For more detailed information on this object's properties, see
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs01/stix-v2.1-cs01.html#_7p0n81ikux8f>`__.
`the STIX 2.1 specification <https://docs.oasis-open.org/cti/stix/v2.1/cs02/stix-v2.1-cs02.html#_a795guqsap3r>`__.
"""
_type = 'sighting'
@ -95,6 +97,7 @@ class Sighting(_RelationshipObject):
('external_references', ListProperty(ExternalReference)),
('object_marking_refs', ListProperty(ReferenceProperty(valid_types='marking-definition', spec_version='2.1'))),
('granular_markings', ListProperty(GranularMarking)),
('extensions', ExtensionsProperty(spec_version='2.1')),
])
# Explicitly define the first kwargs to make readable Sighting declarations.

View File

@ -87,6 +87,22 @@ ENCRYPTION_ALGORITHM = [
]
EXTENSION_TYPE_NEW_SDO = "new-sdo"
EXTENSION_TYPE_NEW_SCO = "new-sco"
EXTENSION_TYPE_NEW_SRO = "new-sro"
EXTENSION_TYPE_PROPERTY_EXTENSION = "property-extension"
EXTENSION_TYPE_TOPLEVEL_PROPERTY_EXTENSION = "toplevel-property-extension"
EXTENSION_TYPE = [
EXTENSION_TYPE_NEW_SDO,
EXTENSION_TYPE_NEW_SCO,
EXTENSION_TYPE_NEW_SRO,
EXTENSION_TYPE_PROPERTY_EXTENSION,
EXTENSION_TYPE_TOPLEVEL_PROPERTY_EXTENSION,
]
GROUPING_CONTEXT_SUSPICIOUS_ACTIVITY = "suspicious-activity"
GROUPING_CONTEXT_MALWARE_ANALYSIS = "malware-analysis"
GROUPING_CONTEXT_UNSPECIFIED = "unspecified"